Search |
|||
Ben Galbraith's blogOf Fonts and Java2DPosted by javaben on January 25, 2008 at 8:08 AM PST
The other day I googled for information on nice-looking fonts for Java2D and found nothing; this entry is largely to help future googlers. 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 in-between. 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 that OS.) 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:
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 my 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 large images. My favorites are:
Your Favorites? 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 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. »
Related Topics >>
Java Desktop Comments
Comments are listed in date ascending order (oldest first)
Submitted by jaredmac on Fri, 2008-01-25 19:57.
Our users complain -- rightfully so -- if the Swing application's font is anything other than the system font, so there's no "pick the best looking font" for us.
On XP, where that system default is typically 11pt Tahoma, things look pretty good. But 12pt Segoe UI on Vista just does not look good with Swing's subpixel AA algorithm. Specifically, most letters, especially those with complete enclosures (there's probably a fancy typesetting name for such things) look too thin.
But this is all captured in Sun bug 6449753.
Submitted by benloud on Thu, 2008-01-31 05:44.
Just discovered this, it looks like Sun might be considering switching to using ClearType to rasterize glyphs on Windows: http://bugs.sun.com/view_bug.do?bug_id=6656651
Submitted by i30817 on Wed, 2008-01-30 13:46.
BTW what I'd like, related to fonts and text layout is that the "invisible" Unicode character were interpreted by the swing textviews as "invisible"! not '?'. Those invisible chars are mostly useful in text parsing where if for example i want all text to have a consistent 1 space between words, instead of string buffer or array messing, i'd have a O(1) operation and the cost being delegated to rendering (much more episodic a light you'd agree). Also I'd like if the swing components didn't need to layout all of the text when resizing etc. That is good for full text application like browsers but for paginated application like ebook readers its really awful (and requires a icky view/model incest since viewToModel doesn't really work - or i couldn't get it to work).
Submitted by i30817 on Wed, 2008-01-30 13:35.
You are not crazy. I've created a program just to read ebooks consistently, and without antialiasing I'd go mad. (Admittedly because my screen is dying and has a wierd violet hue if i don't use black as foreground.)
Submitted by cowwoc on Mon, 2008-01-28 15:19.
Clearly Java2D should be trying to catch up with Apple's font rendering, not Microsoft's. It's noticeably better. It would be funny to see Java2D render nicer than the native OS and that could be a good sales point for using it.
Submitted by carcour on Mon, 2008-01-28 08:44.
The best would be to use Kirill Grouchnikov's solution to use the OS native text rendering in Java 7, it will achieve the best quality http://www.pushing-pixels.org/?p=226
Submitted by philrace on Sun, 2008-01-27 20:47.
Mik asks:
>why is there no way to globally turn kerning on for my own apps? I presume you are asking a "Swing" question, since for Graphics, all settings are the state of that graphics and nothing more, there's not a concept of an "app". For Swing the answer for kerning would be the same as for some other hints. There are open Swing RFEs to provide a way to set the hints via some Swing provided API, rather than digging into the graphics which isn't supported, except for on own your own custom rendered components. Eg see http://bugs.sun.com/view_bug.do?bug_id=6485977 -phil.
Submitted by mikaelgrev on Sun, 2008-01-27 16:10.
Phil, why is there no way to globally turn kerning on for my own apps?
Submitted by philrace on Sun, 2008-01-27 11:57.
On Kerning & ligatures :
Kerning and Ligatures are indeed off by default in 1.6, but easily turned on by setting an attribute on the font (no need to use
TextLayout).
The reasons for off by default are
Submitted by javaben on Sun, 2008-01-27 00:15.
benloud: By the way, the font you've rendered in your image is a pixel-perfect match for Java2D's rendering of Arial at 11 points. I think perhaps you've got some wires crossed on your end; Lucida Grande Bold should look very different from Arial.
Submitted by javaben on Sun, 2008-01-27 00:07.
benloud: Jeepers, you're right about the lack of sub-pixel AA! Ugh. I updated the blog entry and noted the correction at the end. Many of the images were AA'd, but many were not. A bug in the program I used to generate the bitmaps for the entry. When I adjusted the code to split the text into three smaller images instead of one huge one, I neglected to set the rendering hints on the new images. So the first third of the samples were AA'd, the others weren't.
As you'll notice from the AA'd version of Lucida Grande Bold (compared to OS X), you'll see that the comments on the glyphs and the issues with layout are... exactly the same.
RE: OS X "grayscale AA only". Hmm. Dunno what to tell you there. Rendered using Keynote against a black background on a 24-bit color display. If Keynote does something that OS X normally doesn't, I'd be surprised. I'll look into it. My "Foot Smoothing Style" is set to "Automatic" and I was using a laptop to make the screen capture.
I noticed from your screen capture that your LCD rendering looks bad on my display; it looks like we have different pixel ordering. Mine is HRGB; what's yours? I'll take a closer look at your samples and mine on Monday.
As for how I rendered it, nothing fancy:
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
g2d.setFont(f);
g2d.drawString(STRING, x, y);
Submitted by benloud on Sat, 2008-01-26 21:18.
I'm still not convinced layout is the problem. Take the image under your "A Problem of Spacing" title. The Java version on the top line is rendered with no anti-aliasing at all, so of course it looks rough. Plus, the OSX version on the bottom line appears to be rendered with grayscale AA only, so it ends up looking gray and blurry instead of white. No wonder the 'e', 'q' and 'w' look completely different because they're rendered with different settings. Render both with LCD AA for a better comparison.
I will admit you have a point that the p in jumps should be one pixel to the left. But I'm not sure what you did here (since theres no AA). When i render the same, white on black, exact same font, and size, with LCD AA, it looks just fine to me. I also tried it with no AA and it still looks fine. (proof: http://benloud.com/aa.html) How exactly did you render these?
Also, those large images you've posted, its worth pointing out that none of them have any AA enabled at all. I'm sure they'd look much better with LCD AA enabled, particularly the small sizes.
Submitted by benloud on Sun, 2008-01-27 01:19.
Argh! You're right. It was Arial. Because I'm on Windows and dont have Lucida Grande. Well spotted!
Submitted by javaben on Sat, 2008-01-26 13:23.
mikael: I turned on ligatures and kerning and... saw no differences whatsoever. I wrote a program to scan the image output with and without kerning and ligatures. For much of the output, there were no different pixels whatsoever. A few fonts do render differently, but the differences I've seen so are quite minute. For example, Franklin Gothic Medium Italic at 12 pts has one difference with kerning/ligatures: the 'e' in 'over' is placed slightly closer to the 'v'.
I'll have to chew over the data a bit more to draw some conclusions.
kirill: I can't wait to take a look at how this works in my applications. Thanks, man.
Submitted by kirillcool on Sat, 2008-01-26 12:35.
Ben, you can follow the links from this entry that detail how SWT native font rasterizing can be used in Swing applications.
Submitted by mikaelgrev on Sat, 2008-01-26 11:14.
> I'm not sure if these are on or off by default;
They are. :( And i guess there is a big performance hit or I can not understand why there is no simple way to turn them on globally. I understand if Sun do not want to turn them n by default (unless we have a COMPATIBILITY API hint hint ;) but if I want to I would like to have them without subclassing every UIDelegate..
But... I guess they do not care about the desktop... (cough).. ;)
Submitted by javaben on Sat, 2008-01-26 10:28.
benloud: Java 1.6 did indeed introduce kerning and ligatures as optional settings. Cool! You can set these at the font level rather than TextLayout:
attrs = new HashMap();
attrs.put(KERNING, KERNING_ON);
attrs.put(LIGATURES, LIGATURES_ON);
font.deriveFont(attrs);
I'm not sure if these are on or off by default; I'll have to read up a bit later and re-run my samples. Hopefully these improve some of the layout spacing issues I've noticed.
Submitted by javaben on Sat, 2008-01-26 09:46.
benloud: Your comment seems to be chiding me into recognizing that rendering fonts is hard and lowering my expectations. Whoops! I thought the general tone of my blog entry was, "Wow, fonts are hard, and at least on Very Smart Person is working on this problem at Sun, and if he's behind the other OS', it's because Sun hasn't given the problem proper priority and resources." I should have done a better job of getting that tone if you didn't pick it up.
Re: Vista vs. OS X. I haven't spent much time w/ Vista, but ClearType on XP is quite good, and many folks compared OS X against XP back in the day and came up preferring one over the other. I personally prefer evenly-spaced characters to clearer glyphs. Stories on this topic (http://www.codinghorror.com/blog/archives/000884.html) quickly descend into opinion wars. Let's not get too caught up here and just point out that both Vista and OS X are much better than Java2D.
Re: Custom glyph layout. The point I *tried* to make here is that I can *control* glyph layout relatively easily, so I could potentially do it better than Java2D does it by default. You state that I'm silly for thinking I can do a better job. Well, I followed up that assertion in my blog with "if it were easy, Phil would have already done it [because he's loads smarter than me]." I then point out that because I only have to worry about my app, and not the entire world's set of apps, perhaps I can do a better job because my problem is so much easier than theirs.
I thought that was enough hedging to avoid snarky comments like "How can you be smarter than them, wise-guy?" but perhaps I should have hedged / re-phrased a bit more.
In any event, given my preference for evenly spaced glyphs, and given how bad some of the spacing can get in Java2D, I think it's quite easy to make improvements in this area if all you care about is how Java2D renders a particular font at a particular size with a subset of characters. I've done it before.
Re: ligatures and kerning. Glad to hear these features are in there, if disabled by default. I'm pretty excited to take a look at see if they've been implemented with any level of quality. Thanks for the tip.
Re: layout. You say "layout... is definitely not the problem." You should take a look at the three large bitmaps with a bunch of other font samples. Layout IS a big problem for many font renderings at many sizes; I personally find the layout of Lucida Grande Bold I compared to OS X as unacceptable for "gorgeous" applications--which is the subject of this blog, not normal "business" apps.
Submitted by javaben on Sat, 2008-01-26 09:26.
jaredmac: Yeah, the folks stuck having to emulate the underlying OS with Swing--I pity them. That's a thankless task. Fortunately, WinXP emulate is possible, just tedious. I haven't looked into Vista; too bad that there's such an apparent disparity between how Java2D renders Segoe and how Vista does. :-(
Submitted by javaben on Sat, 2008-01-26 09:23.
mikael: Kirill composited SWT font rendering in Java2D? That's crazy! :-) Seriously, I'll have to look at that; it could be very cool, especially if you control when the text is composited in the drawing process and if you can apply effects to the text in some way.
Re: White on black. The app I'm working on is drawing text on dark backgrounds. Plus, it makes the bitmaps contrast against the white background of this page.
Submitted by marc_ on Sat, 2008-01-26 07:08.
Although much improved, in my opinion Swing (and Gnome) still have a long way to go before they catch up to Micorosft and Apple. Here's my comparison of these four types of font rendering with 3 different fonts:
http://markmclaren.com/blog/2007/06/14/swing-font-rendering-still-playing-catch-up/
Submitted by benloud on Fri, 2008-01-25 22:11.
I agree that font rendering is the weakest part of the otherwise excellent quality Java2D. Its gotten MUCH better in 6. I use Consolas in NetBeans for editing my code and it looks great. There's still room for improvement though, when you compare it to Windows. But I also dont like to complain, because I understand its such a hard problem to solve, and they're doing their best. Say what you will about Microsoft, but their font rendering truly is superb, especially on Vista, but then, they have an entire team of experts who work full time on it. So I think Java2D holds up pretty well considering that. I dont think its any worse than FreeType (though Id be interested to hear others opinion on this, who spend more time using Linux than I do).
I take issue with one thing you say though. You compain about glyph layout. I could not disagree with you more here. First you compare it to OSX, but I dont like their rendering at all. They preserve the metrics as it would appear on the page, but then you get fuzzy glyphs since they dont lie on pixel boundaries. Microsoft on the other hand, adjust the positions slightly, but so that they can be rendered sharply which makes a huge difference to readability, and allows Windows to have such clear text at very small sizes. But if you prefer Apple's way, you can always enable the fractional metrics rendering hint, that will preserve the laybut accuracy but expect the quality to be worse.
But you even say you could layout the glyphs yourself and do a better job than the Sun folks. You dont mean that do you? You must understand how complex that is, to be able to handle all of the worlds writing systems. There are very few people in the world capable of doing that properly. And its not the "Sun folks", Java2D uses the world class ICU font layout engine, the same engine used in OpenOffice.org and many other products, and generally does a far superior job than the Linux alternatives, Pango and the like.
You mention ligatures, but havent shown any examples. Java2D is perfectly capable of handing ligatures (and kerning) just fine in 6, doing it just as well as any other laybut engine, but I believe they're both off by default. You can certainly enable it using the appropriate TextAttribute in a TextLayout. I'm not sure if they're use during normal Swing rendering though, and if not, I dont know how to enable them gloablly. Would be handy to know though. Perhaps Phil can chime in on this.
So yeah, glph rasterization is generally very good with sub-pixel AA, but still not yet quite on par with ClearType (but thats a big ask). But layout, a seperate issue entirely, is definitely not the problem.
Submitted by mikaelgrev on Fri, 2008-01-25 13:39.
Btw, why did you do white on black when 99% of all text is black on white?
Submitted by mikaelgrev on Fri, 2008-01-25 13:38.
Evolution never stops. Vista is released...;)
http://www.pushing-pixels.org/?p=195
Submitted by jbickers on Sat, 2008-02-16 05:09.
This chap's analysis is pretty interesting, especially with regard to comparing ClearType and Apple with a third party renderer, in this case Linux's Freetype.
http://antigrain.com/research/font_rasterization/index.html It looks like it should be possible to do better than the native OS rendering, and get rendering that scales well. |
CategoriesArchivesRecent Entries |
||
|