Of Fonts and Java2D
The other day I googled for information on nice-looking fonts
for Java2D and found nothing; this entry is largely to help future
A poorly-rendered typeface can really ruin my day. I'm passionate
about creating beautiful software. Well, for the sake of those who've
seen my code, I should clarify: beautiful user interfaces.
Generally, I'm satisfied that when my attempts fall short of my ideals,
I'm the weak link in the process. After all, I control every pixel
on the screen, so whether they look purty or not is my problem.
Except for the fonts. Ah, the fonts. Translating typefaces into pixels
is a complex problem I'm all too happy to leave to others
to solve. But of course, that's the double-edged sword; I'm stuck with
other people's solutions, be they good, bad, or somewhere
I often find myself building user interfaces in Java Swing. Interestingly,
Swing typically renders its own fonts--it doesn't rely on the underlying
operating system. (Apple's JRE lets developers choose between having the OS
or Java2D do the font rendering, but in the future, it appears this choice
will go away in favor of Java2D). This could be a really good thing, if
Java2D rendered better than the OS. Unfortunately, when compared to Windows
and OS X, it doesn't. (It might render better than Linux, but I've never cared about
This characteristic of Java GUIs is still arguably a good thing, because Java
applications render consistently across differently platforms; consistently
subpar rendering to many is better than inconsistent rendering behavior,
which could lead to all kinds of problems when the bounds of strings are different
on different operating systems.
The Problems with Java2D Fonts
I've been blabbing about how Java2D font rendering is worse than that of
Windows and OS X. In what way is it worse? Back in 2004, I identified and documented what I
judged to be the four most serious problems.
I'll summarize these issues here:
- Swing makes it difficult to use anti-aliasing. Back then, you had
to either create your own UI delegates or subclass components.
Nowadays, Swing either does the right thing and/or lets you configure
global anti-aliasing with system properties.
- Java2D mis-renders many glyphs. At the time, I listed these examples:
- Arial 13pt (compare to Windows' 10pt rendering): x, S, X
- Microsoft Sans Serif 11pt (Windows' 8pt): x, C, M, Q, 8, 9, )
- Times New Roman 16pt (Windows' 12pt): 8
- Tahoma 12pt (Windows' 9 pt): D
- Tahoma 13pt (Windows' 10 pt): q
- Tahoma 16pt (Windows' 12 pt): a, 0
Here's one screenshot from the document that illustrates the problem:
Today, I glanced at the same font in the image with Java 6
running on Windows XP today:
We've come a ways: the 'S' looks great, but the 'x' and 'X' are probematic.
That doesn't bother me too much, however, because of the next point.
- Java2D lacks sub-pixel anti-aliasing. Well, not anymore. As Chet explained at
length some time ago, Java2D now uses sub-pixel anti-aliasing when rendering
fonts. The Arial 13pt example above now looks like this:
How do you like them apples? In my experience, Java2D glyphs look really nice
with the new sub-pixel anti-aliasing, and it makes Swing look really
competitive with Windows XP font rendering with ClearType, as you can see:
In the image above, Windows is on the top and Java2D is on the bottom. I
prefer the weightier Windows rendering, but the Java2D rendering is nice.
- Java2D needs higher-quality font rendering techniques, such as
better glyph layout. Admittedly, this is a bit of a catch-all, but features
like ligatures and properly spaced characters make a big difference in
the quality of type. Unfortunately, I can't see that this has gotten much better.
A Problem of Spacing
To get a feel for the problem of spacing, check out how both OS X and Java2D
(Java 1.6, Windows XP) rendering the same text with Lucida Grande Bold (11 points,
Java2D text attributes set to PLAIN):
It's pretty amazing how gorgeous OS X's rendering of the text is; it's as though
a magazine climbed into my LCD. The Java rendering looks pretty rough, due to both
the glyph quality and their spacing.
Check out the difference in character spacing in the word "quick"
versus the word "brown" or how the "ps" in "jumps" is floating a bit too far to
the right; also, note how Java renders the 'e', 'q', and 'w' compared to the Mac.
It's pretty hard to argue that one could prefer the Java rendering, though the
increased intensity of the pure white hue is a potential benefit.
Am I Crazy?
I know there are a large swath of folks who are just happy if they can get their
app to do something and view my rambling on about fonts as silliness. I have
no problem with such.
My point here is that when you want to create gorgeous applications, these
things really do matter, and they matter quite a bit. If you disagree with this
assertion, well, we'll just have to disagree. (I'm reminded of a recent Wall
Street Journal column by Lee Gomes in which he said audiophiles are divided into
two camps: the crazy and the totally insane.)
What To Do?
I've had the opportunity to meet Phil Race, the font guru on the Java2D team,
and I'm satisfied that he's smarter than I'll ever be, that he knows about these
problems, and that he'd fix them if Sun's priorities and resources
permitted such to happen. And who knows but that such fixes are already in the
pipeline? (Well, I guess Phil knows.)
That doesn't relate to my problem: I've got an app that I need to make gorgeous
today. So, what do I do? I don't have time to render fonts myself. That's
Hard Stuff. But, I could lay out the individual glyphs myself and do a better job
than the Sun folks. But, having met Phil, I assume if that problem were non-trivial,
he'd have improved it himself by now. However, by only caring how fonts look in
applications, as opposed to the entire world's set of Swing apps, perhaps I can
get some results in this area.
Finding the Best Fonts for Java2D
In a past life, I did lay out glyphs myself, but that code no longer belongs to
me, and I'm not in the mood to write it again. So the easiest solution is simply
to check how Java2D renders fonts at different
sizes and see which ones look best. I created a simple program and rendered some
test output for Java2D using sub-pixel anti-aliasing (HRGB) with all of the fonts
available to the JRE in a default Windows XP installation (along with Lucida Grande
Bold), split into three
My favorites are:
- Arial 11pt Plain (12 and 13 ain't bad either):
- Franklin Gothic Medium 9pt Plain--what an attractive small typeface! 10 and 11
are pretty good as well:
- Georgia 9pt Plain, a seriffed answer to Franklin Gothic's clarity (10-13 are
also really nice):
- Lucida Sans Regular 12pt Plain (11 is also nice):
- Microsoft Sans Serif 12pt Plain
- Segoe UI 11pt Plain
- Verdana 9pt and 11pt Plain
I was surprised at just how good some of these fonts look. Thanks Phil!
Did I miss some other good ones? Are there other fonts that you've used with good
results in Java2D? What are your "go to" fonts for beautiful type at large sizes?
Update: Whoops. I put together this blog entry in a bit of a hurry whilst flying from Point A to Point B and I included some faulty images (due to a bug I introduced in the program I wrote to display the fonts; the last 2/3 of the fonts weren't sub-pixel AA'd):
- The comparison between Lucida Grande Bold Java2D vs. OS X originally showed the Java2D rendering without sub-pixel AA; this was a mistake. I updated it with a sub-pixel AA version, as shown above. Note that the observations about subpar glyph formations and layout still remain valid (as I originally noticed them with properly sub-pixel anti-aliases imagery).
- Two of the three large images I linked to were not sub-pixel anti-aliases as claimed. This has been fixed.
- Six of the seven fonts displayed at the end of the blog entry were not sub-pixel anti-aliased; this has been fixed.
The observations that drove me to write this blog entry were with properly sub-pixel anti-aliased type; so the content stands. Sorry for the goof-up.