6

I have a weird problem when drawing strings with some specific true type fonts in Java 32bit on Windows 10.

Since Java 7u13, whenever a character/glyph of the font is wider than 4 times it's height, it is not rendered at all using Graphics2D.drawString (e.g. glyph 4001em wide with basic font size of 1000em):

public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D)g;
    g2.setFont(new Font("myFontWithWideGlyphForX", Font.PLAIN, 12));
    g2.drawString("XXXX", 10, 10);
}

However, the font renders correctly on a JLabel so after some investigation of the underlying Swing code I have realised that setting the rendering hint KEY_TEXT_ANTIALIASING to VALUE_TEXT_ANTIALIAS_LCD_HRGB makes the text render correctly:

public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D)g;
    g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
    RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
    g2.setFont(new Font("myFontWithWideGlyphForX", Font.PLAIN, 12));
    g2.drawString("XXXX", 10, 10);
}

It seems that the rendering algorithm works differently after setting the subpixel atialiasig and renders the font correctly.

If I switch to Java 7u11 or earlier the text renders without any problems and without setting the VALUE_TEXT_ANTIALIAS_LCD_HRGB.

The same happens for any other font with such wide glyphs - for example this random font has such wide glyph for character "J": http://www.fontspace.com/digital-magic/hdgems5 - it renders ok with Java 7u11 but doesn't render at all with anythig newer than that.

Setting the subpixel antialiasing VALUE_TEXT_ANTIALIAS_LCD_HRGB just to render the font seems hacky, ugly and is not always possible (e.g. when usuing third party libs). Does anyone know what is the reason behind awt not rendering such characters since 7u13? Are such font's just not supported? Or maybe this is a bug?

rince
  • 91
  • 4
  • In Java 8, the characters all render when drawn manually, but with slightly different widths. I’m guessing the metrics and/or hints in the font are not entirely compliant, though I don’t have enough knowledge of Truetype font files to say for sure. – VGR Jun 27 '17 at 14:18
  • On my windows 10 machine jdk8u131 does not render the capital J character in the linked font hdgems5 or any other font, that I have found with such wide characters (using Graphics2d drawString). – rince Jun 27 '17 at 14:37
  • 1
    Neither the JLabel nor custom painting with the rendering hint set displays the J glyph when I test it in Java 1.8.0_131, although it does respect the width of the glyph. I am doing this test in Linux 64-bit, though I would be surprised if that makes a difference, considering the rendering code is all written in Java. – VGR Jun 27 '17 at 15:04
  • Still useful info, I didn't have the opportunity to test this on Linux. I am just baffled why did this used to work on Java7u11 and earlier. The fact that the rendering hint doesn't work for you just proves that this sollution might not work on every system. – rince Jun 28 '17 at 07:19

1 Answers1

1

I was not able to get an answer regarding this problem, however I did find a workaround.

None of the .ttf fonts that I have found rendered Glyphs wider that 4 times the bounding box/glyph height, when using Java 7u13 or newer. This problem persisted no matter the tool used to generate the font.

However .otf fonts seem to work ok, even with such wide glyphs, so as a workaround the font was just converted to otf.

rince
  • 91
  • 4