LCD Subpixel Rendering

While I'm on the topic of pixels -- here's another tip. This one is both Mac OSX and NetBeans (well, Swing) specific.

Subpixel rendering, an antialiasing technique, makes text look much sharper (wikipedia article).
Subpixel rendering was added to Java 6, so the NetBeans source editor looks great on Windows and Linux provided you are running Java 6. Antialiasing was never an issue on Macs, where the JDK used its own native graphics renderer which had subpixel rendering all along - until now!!

Here's NetBeans on Linux and Windows:

Let's zoom in. Notice the "strange" colors at the perimiter of the font strokes; they look strange here but oh-so-good at the proper resolution on an LCD:

Unfortunately, when Apple released Java 6 on the Mac, they switched the default graphics renderer over from their own "Quartz" renderer to the standard JDK one. That shouldn't be a problem, since Java already renders LCD text, right? Wrong! For reasons I don't know, subpixel rendering is NOT working on the Mac with the standard renderer. Therefore, by default, NetBeans text looks blurry (because it is only grayscale antialiased) on Macs.

This is easy to "fix". Just switch the rendering back to Quartz. You can do that with the following flag, added to the netbeans.conf config file:

The -J flag just tells the NetBeans launcher that the rest of the flag is a flag for the Java interpreter, and the -D flag says set the system property to true. Therefore, in your own Swing applications you can do the same thing, just drop the -J flag.

(The config file is in a place like /Applications/NetBeans/NetBeans 6.9 and you would add these flags to the netbeans_default_options line.)

Here is a before-versus-after screenshot; this will only make visual sense to you if you're viewing this on an LCD screen!

The subpixel rendering text is on the left.

Here's a zoomed in view, which shows the default (non-LCD renderered text):

And here's what you get when you turn on Quartz:

I presume Apple turned off Quartz by default in Java 6 for a reason. Does anyone know what it is? The JavaFX Release Notes mention some memory leaks. I've been using the flag to turn LCD text back on since I switched to Java 6 on the Mac a year ago, and it doesn't seem to have any adverse effects for normal NetBeans usage (mostly text oriented; I don't do UML editing etc).

More importantly, does anybody know why subpixel rendering from the JDK doesn't work on the Mac since it works everywhere else? Is there a way to trick it to work with rendering hints etc?

P.S. Speaking of launcher arguments - I have one other customization too. I add -J-d32. This tells the JDK that I want a 32-bit VM. I haven't measured personally what this buys me, but I saw that Charlie Nutter recommended it for NetBeans usage, and he certainly knows his way about VM tuning parameters!


Hi Tor,

Is this topic related to the new bug with the latest Apple java update that just came out this week? Specifically it looks like text is misplaced in certain title bars of windows - see this screenshot:

I tried setting the Quartz flag from above but it didn't seem to make a difference.

Posted by Branden on May 20, 2010 at 11:49 AM PDT #

Hi Tor,

Well, just like Branden : I don't really see a difference with the quart switch (OS X 10.6.3, latest Apple JDK 6 Update with the new title bars glitch).

However, the -J-d32 did cut the "real mem" usage of Netbeans by 50% ! (in the Activity Monitor). Now, when I start it with a few open projects, it uses 300MB instead of 600, bringing it more in the line with what I experienced in Windows.

Thanks for the post.

Posted by Michael on May 20, 2010 at 02:48 PM PDT #

I can confirm that there is indeed a difference on OS X 10.6.3 when turning on quartz rendering :)

Posted by Edvin Syse on May 21, 2010 at 01:41 AM PDT #

Have you tried -Dawt.useSystemAAFontSettings ? You can choose which subpixel algorithm is being used.

I think Quartz was dropped because of resolution independence issues with regard to text layout and because of stability and performance problems. Sun created a stable OpenGL renderer and Apple jumped on it.

All my alpha compositing code was f\*\*\*ed up on PPC Quartz. Maybe that was Apple and not me.

Posted by Jan Erik Paulsen on May 21, 2010 at 02:39 AM PDT #

The "UseQuartz=false" path was made the default in Java SE 6 because it provided pixel-exact compatibility with Windows and Linux (which many developers were demanding very loudly for many years).

LCD text antialiasing has simply remained unimplemented in the "UseQuartz=false" path because it requires a significant amount of plumbing to convince the internal CoreText and Quartz routines to render LCD antialiasing onto glyphs that are rendering into bitmap contexts (Mac OS X is fairly persnickety about rendering LCD hinting, and doesn't want to do it unless it knows the graphics context is actually hooked up to a real LCD display).

Quartz is still supported, and is actually the only option if you use a User Interface scale factor greater than 1.0 - however, because it doesn't use the same shaping, fill, and blending algorithms as Oracle's software 2D loops, it will never offer precisely the same rendering as Oracle's software 2D loops.

Posted by Mike Swingler on May 21, 2010 at 05:22 AM PDT #

Thank you everyone for your feedback, and especially Mike for confirming that Quartz is still supported! It's great timing to find out about this, because it turns out NetBeans is considering switching the default in NetBeans 6.9 over to Quartz (issue 177249).

Posted by Tor Norbye on May 21, 2010 at 05:32 AM PDT #

Ha, thank you, thank you, thank you! Ever since I switched to Mac then end of last year, I've been gutted at how my favourite editor, jEdit, renders. Adding this option fixes it beautifully!

Posted by Irumat on July 21, 2010 at 03:42 PM PDT #

Post a Comment:
Comments are closed for this entry.

Tor Norbye


« April 2014