4

I am getting different rendering behavior of a font, "DejaVu Sans Mono", in my Java Swing application if the application loads the font itself vs it being registered with Windows (installed under Windows\Fonts):

Font Rendering Comparison

This difference in behavior is mainly noticeable if Windows display scale preference is at 100%, which is the case on my laptop's 1920x1080 display. Do not get a difference (or at least see any significant difference) when I run the application on a 4K external display with 250% scaling under Windows Display settings.

The font loading code is at the very start of the application, before any Swing/AWT components are created. I am using the Font.createFont() method to load the font using the fontFormat parameter set to Font.TRUETYPE_FONT.

I tried the different values for the awt.useSystemAAFontSettings system property, but the difference is still present, where rendering looks better when the font is installed on Windows vs being loaded via Font.createFont().

Edit: What follows is the utility method in the application that loads the font, where the font file is included in the application's jar file:

 public static Font loadResourceFont(
 String filename
 ) {
 String pathname = "resources/fonts/" + filename;
 java.io.InputStream in = null;
 try {
 in = AppUIFonts.class.getResourceAsStream(pathname);
 if (in == null) {
 log.error("Unable to find resource \""+pathname+"\"");
 return null;
 }
 return Font.createFont(Font.TRUETYPE_FONT, in);
 } catch (Exception e) {
 log.error("Unable to load font \""+filename+"\": "+
 e.getLocalizedMessage(), e);
 } finally {
 IOUtil.closeQuietly(in);
 }
 return null;
 }

Edit: The font rendering difference is only observed when using smaller font sizes. In the screenshot above, the font size is 13. Not sure what the exact threshold is, but I think font sizes at 16 or larger do not exhibit the rendering problem.

Edit: Based on information provided by @gthanop, enabling debug font logging of the JVM, I see the difference in options set on the font when it is loaded by the application vs registered with the operating system. The following is when the font is loaded by app (ignore the size value as I did the log capture when using 4k display at 250% scaling, so effective size is quite large):

INFO: Strike for ** TrueType Font: Family=DejaVu Sans Mono Name=DejaVu Sans Mono style=0 fileName=C:\tmp\+~JF2835760196081226032.tmp at size = 35 use natives = false useJavaRasteriser = true AAHint = 4 Has Embedded bitmaps = false

The following is when font is registered/installed to the system:

INFO: Strike for ** TrueType Font: Family=DejaVu Sans Mono Name=DejaVu Sans Mono style=0 fileName=C:\Users\user\AppData\Local\Microsoft\Windows\Fonts\DejaVuSansMono.ttf at size = 35 use natives = true useJavaRasteriser = false AAHint = 4 Has Embedded bitmaps = false

Notice the difference in the use natives option and the useJavaRasteriser option. Not sure if possible to change these options at the application code level as it appears these options are controlled by internal Java classes.

asked Sep 17, 2025 at 23:06
8
  • The second image looks to me like ClearType is activated. This might only work in case the font is rendered by Window itself. Commented Sep 18, 2025 at 7:11
  • 2
    Can you please post a minimal reproducible example demonstrating the problem? This can answer questions such as how you use createFont (instead of descriptions), as well as what file path you give to createFont. Commented Sep 18, 2025 at 7:11
  • 2
    After trying size 13 I can see there is difference even in PLAIN style indeed. Tried to look at internals a bit of where the font is constructed when calling the constuctor and didn't manage to find out what's wrong (there are several internal classes involved and a registration process which reads fonts from JRE and Windows system directory). Tried to load the font (downloaded from your link) with createFont as well as the corresponding font in Windows system directory and these two have the same behaviour, but are different from the constructor's font, despite also evaluating as equal. Commented Sep 19, 2025 at 14:52
  • 2
    With "evaluating equal" I mean with equals (for all 3 fonts). Also tried setting various RenderingHints while custom painting some text with these fonts, but the problem remains. As an aside, I used System.setProperty("sun.java2d.debugfonts", "true"); which enables logging for internal font implementing classes (using Oracle's JRE) and helped a bit, so it may be useful to take a look at this as a bird's eye view of what's going on internally. There should exist better methods to look into it than digging internals though. I can't look further into all of this for the time being, sorry. Commented Sep 19, 2025 at 14:53
  • 1
    @gthanop Thanks for the comments. The debug property also works for OpenJDK. Lot to sift thru. I do see a difference in rendering options logged for font when font is registered with the system vs loaded by app. I've updated post to show such information since comment formatting limited to provide here. Commented Sep 19, 2025 at 17:36

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.