JDK-8217731 : Font rendering and glyph spacing changed from jdk-8 to jdk-11
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 11,12,13
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2019-01-21
  • Updated: 2020-08-25
  • Resolved: 2019-06-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 13 JDK 14 Other
11.0.6-oracleFixed 13 b25Fixed 14Fixed openjdk8u232Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Description
A DESCRIPTION OF THE PROBLEM :
We use swing and windows-look-and-feel. In jdk-8 and jdk-11 the default fonts are the same (Tahoma for buttons and Segoe for menus). The font-rendering for Tahoma changed in jdk-11 and gets ugly. For example 'it' has a big space between 'i' and 't'. 
Furthermore the spacing between lines changed. For example in the menu the spacing between the menu items raised.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The example code can reproduce it.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Same rendering as with jdk-8.
ACTUAL -
The font rendering of Tahoma is ugly. For example the spacing of letters (e.g. "it") got wrong.
Line spacing is too big e.g. in the menu.

---------- BEGIN SOURCE ----------
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestRenderer {

    public static void main(String[] args)
            throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

        JFrame f = new JFrame();

        JButton b1 = new JButton("Mitarbeiterdisposition");
        //b1.setFont(UIManager.getDefaults().getFont("Button.font"));
        b1.setBounds(130, 100, 100, 40);//x axis, y axis, width, height
        f.add(b1);
        f.setSize(400, 500);
        f.setLayout(null);
        f.setVisible(true);

        JMenuBar menuBar;
        JMenu menu;
        JMenuItem menuItem;

        //Create the menu bar.
        menuBar = new JMenuBar();

        //Build the first menu.
        menu = new JMenu("A Menu");
        menu.setMnemonic(KeyEvent.VK_A);
        menu.getAccessibleContext().setAccessibleDescription("The only menu in this program that has menu items");
        menuBar.add(menu);

        //a group of JMenuItems
        menuItem = new JMenuItem("A text-only menu item", KeyEvent.VK_T);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription("This doesn't really do anything");
        menu.add(menuItem);

        //a group of JMenuItems
        menuItem = new JMenuItem("A text-only menu item", KeyEvent.VK_T);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription("This doesn't really do anything");
        menu.add(menuItem);

        //a group of JMenuItems
        menuItem = new JMenuItem("A text-only menu item", KeyEvent.VK_T);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription("This doesn't really do anything");
        menu.add(menuItem);

        f.setJMenuBar(menuBar);
    }
}

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

FREQUENCY : always



Comments
Fix request (jdk8u and jdk11u) I would like to backport this to jdk8u and jdk11u. We have had complains from customers about how the fonts are being rendered after we updated Freetype. This solves the issue 8u RFR: https://mail.openjdk.java.net/pipermail/jdk8u-dev/2019-August/010169.html 11u RFR: https://mail.openjdk.java.net/pipermail/jdk-updates-dev/2019-August/001786.html
28-08-2019

Although the same "umbrella" cause of the t2k->freetype switch might affect metrics and rendering it is a bit more complex than that. The overall font metrics which includes line spacing needs to be addressed separately than the per-glyph metrics - with advance being the one that matters - as well as the accompanying glyph image. Setting the interpreter version to 35 to be more compatible (or maybe less "in"-compatible) with T2K and GDI is something I think we can do. it changes the spacing (slightly) for LCD glyphs because we re-use the metrics from freetype even though GDI generates the glyphs there. Switching back to 35 is intended to provide more consistent glyph advance metrics between render modes as well. If the upshot of this is greater similarity with JDK 8 and greater compatibility between render modes, that should satisfy *most* people. And when making the switch to 35 by default, we can allow people who were happy with the newer interpreter to use FREETYPE_PROPERTIES to get that. The overall font metrics (including line spacing) will be addressed (or at least analysed) using bug https://bugs.openjdk.java.net/browse/JDK-8215290: FontMetrics methods return different values in Java 11 compared to Java 8
05-06-2019

Additional Information: According to 2d-dev mailing list, there exists a workaround: "As a temporary workaround, users of OpenJDK distributions can force pre-2.7 font rendering by simply setting an environment variable: FREETYPE_PROPERTIES=truetype:interpreter-version=35" We tested this workaround on windows 7 and 10 with Java11 (Oracle JDK) successfully. In JDK10 the font rendering forks fine (same as in JDK8). The line spacing (menu) is the same in JDK10 and JDK11.
30-04-2019

Received additional comment from submitter: "Additional Information: This ticket treats two different problems: 1. The spacing and scaling of fonts 2. The line spacing in menu The second problem has a workaround: InsetsUIResource margin = (InsetsUIResource) UIManager.get("Menu.margin"); margin.set(0, 0, 0, 0); In jdk8 the margin was (0,0,0,0) per default. In jdk11 it is set to (2,2,2,2). For the first problem we can provide further information: - We tried a different font (Segoe UI). In font size 12 the font looks perfekt, but in font size 11 the spacing between letters is wrong again. - It seams to be related to ticket: https://bugs.openjdk.java.net/browse/JDK-8214538 (other fonts) - As we can not use font size 12 in all cases, we can not see any workaround at the moment. The font in size 11 looks broken an we can not use it. In JDK10 the font rendering forks fine (same as in JDK8). The line spacing (menu) is the same in JDK10 and JDK11."
12-03-2019

OK. So lots of analysis will be needed here since some things are an issue with JDK 10 as well [*] so that points to it being a hidpi issue there. The issues that are new in 11 are likely due to the freetype transition. [*] I am assuming here that the submitter used ORACLE JDK 10 and not OPENJDK 10. Also the claim that JDK 9 can't be downloaded any more is wrong. All releases are archived for download with a warning about their support status : https://www.oracle.com/technetwork/java/javase/archive-139210.html
13-02-2019

Sharing response to above questions from submitter: ========================================= 1. What is the Windows desktop DPI setting ?: small 100% (96DPI) 2. In JDK10 the font rendering forks fine (same as in JDK8). The line spacing (menu) is the same in JDK10 and JDK11. 3. Qns. What happens with JDK 9 and JDK 10. Is is OK like 8, or bad like 11 ? Response: In JDK-10 the menu is as bad as in JDK-11. In JDK-10 the font rendering is OK as in JDK-8. Note: JDK-9 is out of support, therefore I cannot download JDK-9 and test it. 4. Improved test code with invoke later is attached.
08-02-2019

> What happens with JDK 9 and JDK 10. Is is OK like 8, or bad like 11 ? My #1 question was completely ignored. Try again.
01-02-2019

Response from Submitter: ============== I attached a picture showing the differences between Jdk-8 and Jdk-11. On the right hand side it shows the result in Jdk-11. The menu is higher. In Jdk-10 it looks the same. The button label shows the wrong font rendering. There is a big space between 'i' and 't'. The font rendering also has problems with other characters. Furthermore I attached the complete screenshot for jdk-8 and jdk-11. exampleJdk8.PNG, exampleJdk11.PNG, menuDiff8vs11.PNG ==============
01-02-2019

Additional Information from Submitter: >What is the Windows desktop DPI setting ? : small 100% (96DPI) >Can you provide screen shots (png format) of what you see on 8, 9, 10 & 11 ? I can not find a possibility to upload files. >Improved code with invoke later: import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class TestRenderer { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { JFrame f = new JFrame(); JButton b1 = new JButton("Mitarbeiterdisposition"); b1.setBounds(130, 100, 100, 40);//x axis, y axis, width, height f.add(b1); f.setSize(400, 500); f.setLayout(null); f.setVisible(true); JMenuBar menuBar; JMenu menu; JMenuItem menuItem; //Create the menu bar. menuBar = new JMenuBar(); //Build the first menu. menu = new JMenu("A Menu"); menu.setMnemonic(KeyEvent.VK_A); menu.getAccessibleContext().setAccessibleDescription( "The only menu in this program that has menu items"); menuBar.add(menu); //a group of JMenuItems menuItem = new JMenuItem("A text-only menu item", KeyEvent.VK_T); menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK)); menuItem.getAccessibleContext().setAccessibleDescription("This doesn't really do anything"); menu.add(menuItem); //a group of JMenuItems menuItem = new JMenuItem("A text-only menu item", KeyEvent.VK_T); menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK)); menuItem.getAccessibleContext().setAccessibleDescription("This doesn't really do anything"); menu.add(menuItem); //a group of JMenuItems menuItem = new JMenuItem("A text-only menu item", KeyEvent.VK_T); menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK)); menuItem.getAccessibleContext().setAccessibleDescription("This doesn't really do anything"); menu.add(menuItem); f.setJMenuBar(menuBar); } }); } } ------------------------- Requested Submitter to provide screenshots in email. Will update as soon as Submitter shares the same.
01-02-2019

This may be a hi-dpi issue, as well, or maybe instead, of a freetype issue. In JDK 8 the WIndows L&F would scale the fonts to match the desktop size but nothing else is scaled. Now in JDK 9 and later we scale the whole UI. But the fonts should be the same size (as measured by a ruler on the screen) as before. >>>I need some more information from the submitter<<< ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ What happens with JDK 9 and JDK 10. Is is OK like 8, or bad like 11 ? What is the Windows desktop DPI setting ? If it is set to 96 DPI are there still problems ? Can you provide screen shots (png format) of what you see on 8, 9, 10 & 11 ? Also (FYI) the test case does not use invokeLater .. as a result of which it failed to create the menu for me - since it did all the initialisation on the main thread. I needed to re-work the test case code.
25-01-2019

Partially at least, this could duplicate https://bugs.openjdk.java.net/browse/JDK-8215290
24-01-2019

With Windows L&F, Font rendering and line spacing changed from between JDK 8 to JDK 11. Checked with reported version and could confirm the regression. See attached images as reference. Result: ========= 8u201: Pass 9: Pass 10.0.2: Pass 11: Fail 11.0.2: Fail 12 ea b28: Fail 13 ea b04: Fail This is a regression introduced in JDK 11 and is related to JDK-8210447.
24-01-2019