Saturday, February 4, 2006

Font Smoothing in Pages

Pierre Igot:

I am simply flabbergasted that Apple has not even fixed the font smoothing bug. After a whole year, they still haven’t read the bug reports and noticed that Pages fails to use the font smoothing style selected in “Appearance” in System Preferences? Unbelievable. The only rational explanation is that they somehow “forgot” to take the system’s font smoothing style into account when they first created the text rendering engine used in Pages, and now they would have to redo that text rendering engine itself in order to make it compatible, and they have just decided that it’s not worth the trouble. That doesn’t make it any less scandalous. First of all, how could they neglect to use the system’s font smoothing style in the first place? And now, how can they justify forcing users to cope with text in the wrong font smoothing style, especially given than most recent Macintosh computers use flat panel displays?

I’m not an expert on Quartz, but I don’t believe Pierre’s theory. As I learned several months ago, there are quite a few applications that don’t use the chosen font smoothing style. The pattern I see is that applications like Pages and OmniGraffle draw multiple layers with possibly overlapping elements. A logical way to implement this is to draw the elements separately into off-screen buffers and then composite them together. As far as I know, you can tell Quartz to use font smoothing or not to use it (CGContextSetShouldSmoothFonts), but you can’t tell it which style to use. Quartz automatically chooses the “right” font smoothing style, and the right style for anything but on-screen drawing is to use the CRT style.

Thus, unless your application draws directly into a view, it will sometimes use the “wrong” style. An interesting case is OmniGraffle, which normally uses the CRT style. However, while you’re editing text it uses the LCD style, presumably because the field editor is drawing directly into the view. (If you’ve written one of these drawing applications, please feel free to correct me.)

With the current Quartz API, it doesn’t look to me like this would be easy to fix. It’s not that the text rendering engine would have to change, but that the entire layout and compositing engine would. My guess is that this would reduce performance and needlessly complicate lots of code that’s unrelated to text rendering. It would seem that the best fix would be for Apple to allow the application to choose the font smoothing style, though perhaps it had good reasons for not allowing this in the first place.

8 Comments

Another (possibly related) place this happens is with the menu extras - these also don't use the system setting, but use the CRT setting instead.

I don't know why this would be hard to fix at all - add a new API that sets the font smoothing "method" for a given CGContext and you're done, right? Isn't that the benefit of the CGContext being an opaque type?

Matt: Right. I'm saying that it would be hard for an application developer to fix this without help from Apple (in the form of an additional CGContext function). Why isn't there such a function already? It's obviously desirable and seems easy to add, so it's either a glaring oversight or a harder problem than it seems.

Obviously my comments about the text rendering engine were pure speculation on my part. I am not a developer and have no idea how Pages works in that respect. All I know is that the end result is unacceptable, and Apple's refusal to fix it leaves the door open to speculation about its reasons/motives.

It is very well possible to create an offscreen context that uses LCD antialiasing. I'm assuming it has to do with the color space you pass to CGBitmapContextCreate(). If it's the same color space that the display uses, then the context will use the same kind of font antialiasing. Maybe Pages and other apps use a generic RGB color space instead, which is a little easier to code - a single line of code instead of three.

Michel Fortin has the answer:

The “a” in aRGB stands for alpha — it’s the transparency value for the whole pixel. That’s it, the whole pixel: when aRGB pixels are later composited with other layers, each subpixels is mixed with the same level of transparency. This is incompatible with subpixel antialiasing which require a different transparency level for each of the three subpixels.

I've bumped into similar problems with sub-pixel anti-aliasing when I've been developing. First of all, it often looks awful on dark background, but the main issue is transparent backgrounds.

Fixed in Pages 4.0! Unbelievable!
It took Apple how long?

Stay up-to-date by subscribing to the Comments RSS Feed for this post.

Leave a Comment