Evolution Programming Resources

  Projects

Java Font Size Considerations on the Windows Platform


Listing 1 shows a small fraction of the rendering code of a component.

Listing 1: Displaying Text in Arial 12pt.
public void paintComponent(Graphics g)
{
    Graphics2D g2d = (Graphics2D)g;
    
    Font font = new Font("Arial", Font.PLAIN, 12);
    
    g2d.setFont(font);
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.drawString("Hello World", 25, 100);
}

If you execute the code on MacOS X and compare the rendered text with the result of a native program rendering the same text using the same font you'll get a totally identical result.

Fig 1: Results on MacOS X
Java Native

If you try the same on Windows (Sun JRE 1.3.1) you will get totally different results. Java renders the font far smaller than the native code.

Fig 2: Results on Windows
Java Native

The is a result of the different screen resolution assumed by Java 2D and Windows. While Java assumes 72 dpi screen resolution Windows uses 96 dpi or 120 dpi depending on your font size setting in the display properties.

To provide resolution independent rendering Java 2D API supplies the getNormalizingTransform() method in the GraphicsConfiguration class. Applying the returned transformation to the Graphics context should produce the same results a the native windows rendering code. But unfortunately this method returns always a identity transformation if it is called for the screen device.

So instead of using getNormalizingTransform() you have to use getScreenResolution() in the Toolkit class and the calculate the correct font size as shown in listing 2.

Listing 2: Font Correction for Screen Resolution
public void paintComponent(Graphics g)
{
    Graphics2D g2d = (Graphics2D)g;
    
    int screenRes = Toolkit.getDefaultToolkit().getScreenResolution();
    int fontSize = (int)Math.round(12.0 * screenRes / 72.0);

    Font font = new Font("Arial", Font.PLAIN, fontSize);
    
    g2d.setFont(font);
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.drawString("Hello World", 25, 100);
}

The code in listing 2 creates almost the same results as the native Windows font rendering. But if you take a closer look you will notice slight differences in kerning and antialiasing. It seems that Java 2D is using its own font renderer instead of the native implementation on Windows.

Fig 3: Results on Windows with Size Correction
Java Native

An alternative solution would be to create a AffineTransform scaling by the factor screenRes / 72.0. The advantage of that solution would be that the transformation allows scaling by fractional numbers while the Font class doesn't support fractional font sizes. In reality the results of both solutions are identical. Also the same font size correction as shown in listing 2 can be used in Java 1.1 code since it doesn't rely on any Java 2D features.


 Top 
 

| © 2003 by 3rd-evolution