Font glyph not rendering with Graphics2D drawString since Java 7u13
Asked Answered
M

1

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?

Mahalia answered 27/6, 2017 at 13:20 Comment(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.Phonetic
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).Mahalia
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.Phonetic
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.Mahalia
M
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.

Mahalia answered 2/10, 2017 at 14:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.