Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8139176

[macosx] java.awt.TextLayout does not handle correctly the bolded logical fonts (Serif)

XMLWordPrintable

    • 2d
    • b135
    • x86
    • os_x

      FULL PRODUCT VERSION :
      java version "1.8.0_60"
      Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
      Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Mac OS X El Capitan 10.11

      Darwin Developers-iMac.local 15.0.0 Darwin Kernel Version 15.0.0: Wed Aug 26 16:57:32 PDT 2015; root:xnu-3247.1.106~1/RELEASE_X86_64 x86_64

      A DESCRIPTION OF THE PROBLEM :
      I noticed that the bolded text painted with the help of java.awt.TextLayout.draw method looks completely different than the one painted with Graphics.drawString.

      The letters painted with the bold font are painted at exactly the same x advance as for the plain font, which is wrong. The letters are wider because of the bold style and because of that they are starting to overlap.

      The problem occurs only for logical fonts, like "Serif".

      Using a physical font, "Times New Roman" for instance, does not display the problem.





      REGRESSION. Last worked in version 6u45

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the sample on a Mac with Java 1.8_060
      Check the last text line from the displayed frame. This should be the same width and aspect as its sibling above it, but it is more compact and harder to read.


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The bolded text should have no letter overlapping.
      ACTUAL -
      The letters painted with the bold font are painted at the same x advance as for the plain font. The letters are wider because of the bold style and they are starting to overlap.

      On Windows this does not happen.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------

      import java.awt.Font;
      import java.awt.Graphics;
      import java.awt.Graphics2D;
      import java.awt.font.TextLayout;

      import javax.swing.JFrame;
      import javax.swing.JPanel;

      /**
       * The TextLayout paints letters too close together (Serif, bold ).
       *
       * jre1.8.0_60-x64, but can be reproduced with Java 1.7.
       */
      public class PaintingDifferenceTest {

        public static void main(String[] args) {
          
          // This happens with jre1.8.0_60-x64
          System.out.println(System.getProperty("java.home"));
          
          final JFrame frame = new JFrame();
          frame.setSize(600, 600);
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          
          final Font plain = new Font("Serif", Font.PLAIN, 32);
          final Font bold = new Font("Serif", Font.BOLD, 32);
          
          final JPanel panel = new JPanel(){
            
            /**
             * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
             */
            @Override
            protected void paintComponent(Graphics g) {
              
              String txt = "Gerbera";
           
              
              // Ok.
              // For the PLAIN font, the text painted by g.drawString and the text layout are the same.
              g.setFont(plain);
              g.drawString(txt, 50, 150);
              int width = g.getFontMetrics(plain).stringWidth(txt);
              g.drawRect(50, 150, width, 10);

              
              TextLayout tl = new TextLayout(txt,
                  plain,
                  g.getFontMetrics(plain).getFontRenderContext());
              tl.draw((Graphics2D) g, 50, 200);
              width = (int) tl.getAdvance();
              g.drawRect(50, 200, width, 10);
              
              
              
              // Not Ok.
              // For the BOLD font, the text painted by g.drawString and the text layout are NOT the same.
              g.setFont(bold);
              g.drawString(txt, 50, 250);
              width = g.getFontMetrics(bold).stringWidth(txt);
              g.drawRect(50, 250, width, 10);
              
              tl = new TextLayout(txt,
                  bold,
                  g.getFontMetrics(bold).getFontRenderContext());
              // Letters are overlapping..
              tl.draw((Graphics2D) g, 50, 300);
              width = (int) tl.getAdvance();
              g.drawRect(50, 300, width, 10);

            }
          };
          frame.getContentPane().add(panel);
          frame.setVisible(true);
        }
        
      }

      ---------- END SOURCE ----------

            prr Philip Race
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: