javafontsfontmetrics

What causes FontMetrics stringWidth to return different values on different machines?


The following code prints different values when ran on different machines:

import java.awt.*;
import java.awt.image.BufferedImage;

public class Main {

     public static void main(String []args){
        Graphics g = new BufferedImage(100, 100, BufferedImage.TYPE_BYTE_BINARY).getGraphics();
        g.setFont(new Font("Arial", Font.BOLD, 10));
        FontMetrics fontMetrics = g.getFontMetrics();
        
        int width = fontMetrics.stringWidth("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
        
        System.out.println(width);
     }
}

I was expecting the output of the program to be the same if I run the code on different computers, but I ran it on two machines and one prints 606 while the other prints 699.

What can cause this behavior? Does string width calculation depend on the environment? (jdk, operating system, etc?)


Solution

  • Note that you're not loading the same font on both computers. You're loading "whatever the system has installed" that resolves through the name Arial. Just like other software, fonts are versioned, so if things look or behave differently between machines you want to check which actual fonts are being used on those machines.

    For example, on my Windows 10 machine, "Arial" is Monotype's Arial v7.00 from 2017. On an older version of Windows Arial could be v6.89 (win8) or 5.22 (win7), which may have subtly or radically different text metrics depending on the text you're typesetting.

    If you to need to guarantee the same font metrics across devices, you'd have to bundle the actual font file your application and then load your font from that file instead of loading it by name for the OS to handle.

    However: remember that fonts at exactly the same as any other software in that they have licenses, and you can't just distribute them without permission. Arial, for example, may not be freely distributed without a license from Monotype, so you'd have to find a free-to-distribute font to use instead. (And note that for legal purposes, a free font without a license is not free, but "you have no idea what the license is so you might be breaking the law simply by downloading it at all". Real free fonts come with an open source software license like the SIL font license that explicitly allow you to redistribute them)