Technote 1149Smoothing FontsBy Joseph MaurerMac OS Engineering |
CONTENTS Smooth Edges | Mac OS 8.5 came with a "Smooth all fonts on screen" checkbox in the Appearance control panel, accompanied by a setting of the minimum text size required for turning on anti-aliasing. In this Technote, I briefly explain the current implementation of this feature, and discuss its limitations and the possible compatibility problems with existing applications. I then document the new APIs that allow applications to take control over anti-aliased text rendering. Finally, I explain why anti-aliased text looks so bad when highlighted (in particular with dark highlight colors), and what you can do to solve the problem. |
With all these possible consequences of turning font smoothing on, it is clear that applications need a programmatic way to interfere with a user's setting. More positively, they should also get the possibility to selectively turn anti-aliasing on, even on systems where the user chose not to enable font smoothing. It is equally clear that applications need to restore the system's state as soon as they are done with their text-rendering job that required a different setting. Setting and restoring the flag of font smoothing carries no performance penalty at all (in contrast to what seasoned Mac OS programmers might assume, based on experience with pre-8.5 versions of the FontManager ). However, it is a system-wide global setting (not a per-GrafPort or per-context one), and as such, it affects all text redrawing of background processes and system-owned text drawing as well. It would not make a good impression to have text rendering switch unpredictably between anti-aliasing and not.Here are the API calls, as contained in the latest versions of the Fonts.h include file: |
Boolean IsAntiAliasedTextEnabled(SInt16* outMinFontSize); |
The first function returns a Boolean with the obvious interpretation. If you are interested in the minimum size for which anti-aliasing is enabled, *outMinFontSize returns this value as set by the user in the Appearance control panel, provided the function value is TRUE; if the function value is FALSE, *outMinFontSize is undefined. If you do not care about this minimum font size, pass NULL as parameter. The second function allows to set the state of anti-aliased text; if inEnable is TRUE, the inMinFontSize parameter is put in the place where a user-selected minimum font size value would go. Because the rendering quality of anti-aliased text for small point sizes is currently perceived as unsatisfactory, minimum sizes below 12 are not allowed, and are, in fact, replaced by 12. The function always returns noErr .Here is an example of how to use these functions to turn anti-aliased text temporarily OFF (if it's enabled): |
//------------------------------------------------- Boolean userWantsSmoothText ; SInt16 previousMinSize; userWantsSmoothText = IsAntiAliasedTextEnabled(&previousMinSize); if (userWantsSmoothText) (void)SetAntiAliasedTextEnabled(false, 0); // second parameter is ignored when first parameter is FALSE // draw text the "jaggy" way, here // and then set it back to what the user wants: if (userWantsSmoothText) (void)SetAntiAliasedTextEnabled(true, previousMinSize); //------------------------------------------------- |
One more thing: the symbols IsAntiAliasedTextEnabled and SetAntiAliasedTextEnabled are exported from the FontManager code fragment in the System, but the InterfaceLib you are using with your development tools may not yet include them. To make the Linker happy, you may need to create a little "FontManager " stub library that exports these symbols and contains empty implementations of the functions, until the next revision of the InterfaceLib .What Happened to Highlighting?The "Imaging With QuickDraw" volume of Inside Macintosh explains on pages 4-41 through 4-44 how the highlighting concept has been designed in QuickDraw. Here are the two crucial features:a) highlighting only affects pixels with either the background or the highlight color;Clearly, there was no anticipation of anti-aliasing in the original design of QuickDraw. When a bitmap edge gets smoothed by using shades of colors that blend the foreground color into the background color, the fringe of intermediate shades does not participate in the highlighting algorithm. Assume that the foreground color is black, the background white, and the highlight color pretty saturated (like a dark blue or red). With anti-aliased text, there will be a fringe of more or less light-gray pixels around the original black bitmap, to blend the contours into white. When highlighting is applied, the white background pixels are replaced by the relatively dark highlight color, whereas the "fringe" pixels keep their original values. The effect is an ugly sparkling around the contour, which can make the text nearly unreadable in small sizes and certain type faces. Apple tried hard to find a solution to this problem, but the evidence of the facts won. It is not possible in practice to maintain feature b) above (a requirement for compatibility with existing code), while modifying feature a) such that contours blend correctly into whatever the background pixels are (highlighted or not). The solution has to come from a different approach to highlighting. Either the highlighted areas are first erased to the desired state (highlighted or not), before the text is drawn into the area, or we provide two different API calls for Highlighting and Unhighlighting and implement them in a way that takes anti-aliased text into account. (See the functions ATSUHighlightText and ATSUUnHighlightText in ATSUnicode.h for an example.)For the time being, we recommend you use a pastel-like highlight color which minimizes the ugliness, or to turn off anti-aliased text altogether if you are frequently editing text in sizes and type faces that make the defect particularly annoying. SummaryMac OS 8.5 introduced the feature of anti-aliased text, which provides a substantial esthetic improvement in many text drawing cases, in particular for slanted type faces. However, it became apparent that it may conflict with assumptions made in legacy code, and that it comes with other undesirable side effects. Expect that the future will bring certain improvements.On the other hand, perhaps we should follow the recommendation "enjoy moderately and wisely" not only for some other good things in life, but also for font smoothing. |
Thanks to the reviewers Eric Simenel, Ingrid Kelly, Lee Collins, and David Opstad for pertinent feedback.