Fonts are a bit wider in OpenJDK and OracleJDK

I notice differences in font distribution using OpenJDK compared to OracleJDK. I narrowed it down to fonts. They are rendered by OpenJDK a little wider ... A careful visual inspection of the screenshot above shows that the width of the characters is the same, the only difference is the distance. I also confirmed this with programmatically checking font metrics for all A-Za-z0-9 characters.

OpenJDK vs OracleJDK fonts

eg. Line "Dialog - Normal" at 12pt

  • 125 pixels in OpenJDK - my build 8u131-b11
  • 125 pixels in OpenJDK - revolutions per second from redhat disk - 1.8u45-b13
  • 120px on OracleJDK - 8u131-b11 release from Oracle website

, -Dawt.useSystemAAFontSettings, -Dswing.useSystemFontSettings, -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel Java_Runtime_Environment_fonts. , .

sun.font.FontScaler, fontscaler. sun.font.FontUtilities, -Dsun.java2d.font.scaler=t2k, .

: FreetypeFontScaler T2KFontScaler?

if (FontUtilities.isOpenJDK) {
      scalerClass = Class.forName("sun.font.FreetypeFontScaler");
} else {
      scalerClass = Class.forName("sun.font.T2KFontScaler");
}

,

public class FontTester {
    public static void main(String[] args) throws Exception {
        System.out.println(String.format("java.home=%s", System.getProperty("java.home")));

        String family = Font.DIALOG;
        int style = Font.PLAIN;
        describeFont(new Font(family, style, 12));

        JFrame frame = new JFrame();
        frame.setSize(800, 600);
        frame.add(new DemoPanel());
        frame.setVisible(true);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    private static class DemoPanel extends JPanel {

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            String family = Font.DIALOG;
            int style = Font.PLAIN;
            Font font = new Font(family, style, 20);
            g.setFont(font);
            String str = family + " - " + name(font) + " ";
            Rectangle2D bounds = g.getFontMetrics().getStringBounds(str, g);
            str += String.format("%f x %f", bounds.getWidth(), bounds.getHeight());
            g.drawString(str, 10, 50);
        }

        private String name(Font font) {
            List<String> attrs = new ArrayList<>();
            if (font.isBold()) {
                attrs.add("bold");
            }
            if (font.isItalic()) {
                attrs.add("italic");
            }
            if (font.isPlain()) {
                attrs.add("plain");
            }
            return String.join(",", attrs);
        }
    }

    private static void describeFont(Font font) throws Exception {
        Method method = Font.class.getDeclaredMethod("getFont2D");
        method.setAccessible(true);
        Font2D font2d = (Font2D) method.invoke(font);
        System.out.print(String.format("%s: ", font));
        describeFont2D(font2d);
    }

    private static void describeFont2D(Font2D font) {
        if (font instanceof CompositeFont) {
            CompositeFont cf = (CompositeFont) font;
            for (int i = 0; i < cf.getNumSlots(); i++) {
                PhysicalFont pf = cf.getSlotFont(i);
                describeFont2D(pf);
                break;
            }
        } else {
            System.out.print(String.format("-> %s \n", font));
        }
    }
}

, , sun.font.FontStrike.getGlyphMetrics(int) . - 39 ( "D" ) X 14.0px Oracle JDK ( T2KFontScaler), 15.0px OpenJDK ( FreetypeFontScaler)

, "", fontbox Java- , X Glyph-ID 39 HMTX TTF LiberationSans-Regular.ttf. - 1479 , 14.44px 20pt.

"i" - - 76. 4,44 fontbox 4 T2KScaler, FreetypeScaler

/, "" . , Oracle, Open JDK , , Oracle.

g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+4
1

sun.font.FontScaler, fontscaler. sun.font.FontUtilities, -Dsun.java2d.font.scaler = t2k, .

, Oracle OpenJDK - , , .

FontScaler: 97:

if (FontUtilities.isOpenJDK) {
    scalerClass = Class.forName("sun.font.FreetypeFontScaler");
} else {
    scalerClass = Class.forName("sun.font.T2KFontScaler");
}

isOpenJDK? FontUtilities: 125:

File lucidaFile = new File(jreFontDirName + File.separator + LUCIDA_FILE_NAME);
isOpenJDK = !lucidaFile.exists();

:

static final String LUCIDA_FILE_NAME = "LucidaSansRegular.ttf";

- , , .

, ( / ) - Lucida. , (, JRE ), .

+1

Source: https://habr.com/ru/post/1691020/


All Articles