Archive for August, 2011

DirectWrite Text Rendering in Firefox 6

Thursday, August 11th, 2011

In Firefox 4, we switched from using the GDI on Windows to using the DirectWrite API on platforms that support it such as Windows 7. This was required for supporting hardware acceleration via Direct2D but DirectWrite also is a more modern API without many of the quirks and foibles that the GDI API still has. DirectWrite is also used by IE9 while Chrome continues to use GDI. Initially, there were DirectWrite bugs related to startup behavior (long delays on cold startup) but those have been fixed by Microsoft.

But some users have complained that text is too light or too “fuzzy” with DirectWrite compared to the way GDI renders the same text. There are a couple related issues that affect this. Depending upon the font, DirectWrite may position glyphs differently compared to GDI and it may rasterize glyphs slightly lighter than GDI.

In Firefox 6 we’ve added the ability to alter prefs that affect the underlying ClearType subpixel anti-aliasing that is used:

These are effectively local overrides of ClearType registry settings that are set by running the ClearType tuner tool (Control Panels > Fonts > ClearType Text Settings). You can alter the values here and only text rendering in Firefox will be affected. These parameters allow you to adjust the contrast and switch the rendering mode. By default Firefox uses DirectWrite natural rendering mode (4) for small text and DirectWrite natural symmetric mode (5) for larger text. Use GDI Classic rendering mode (2) to render text the same way Firefox 3.6 and Chrome render text. Other values are described here.

Subpixel anti-aliasing

But why is this necessary? After all, rendering text on a computer screen should be easy, shouldn’t it? Most devices these days have scalable fonts that define glyphs for a wide range of characters from scripts used across the globe. With a scalable outline rendering text should be a simple matter of filling that outline, something graphics libraries have done for ages. So why is there such variability in text rendering across even two API’s on the same platform?

The answer is that at small pixel sizes (e.g. 9-13px) there just aren’t enough pixels to fully render the ideal outline constructed by a type designer. Effectively a small bitmap font needs to be constructed. Doing that involves some hard choices and this is where solutions diverge. Below is an example of how 10px Cambria is rendered using DirectWrite:

On left is a capital C rendered with simple grayscale anti-aliasing and the two images on the right show how subpixel anti-aliasing uses the geometry of the red, green and blue components of LCD pixels to effectively increase the spatial resolution. The colorful image on the right looks somewhat nonsensical when enlarged but because our eyes are very sensitive to differences in luminance, when these colors are used at the pixel level our eyes tend to perceive a glyph with higher definition than the simple grayscale anti-aliased image on the left.

You can see how subpixel anti-aliasing functions using the simple subpixel explorer tool I put together:

The text in the textbox is rendered with a given font at a given size to the right of the textbox and then that rendering is shown in enlarged form below. The tool allows you to edit the text displayed, change the font, font size, zoom, and shift the text around by fractions of a pixel so that you can see more clearly the effect these have on how text appears. You can switch to subpixel grayscale mode to see the individual RGB subcomponents as grayscale values and toggle the display of glyph outlines.

You can also snapshot individual renderings, then flip through the different snapshots for comparison. To compare GDI text rendering with DirectWrite rendering, use the following steps:

  1. Open the subpixel explorer page
  2. Click on the ‘snapshot’ button to save a snapshot of the default DirectWrite rendering
  3. Open a new tab and enter ‘about:config’ as the URL
  4. Click through the warning
  5. Enter ‘gfx’ in the filter box
  6. Change ‘gfx.font_rendering.cleartype_params.rendering_mode’ to ‘2’ (for GDI Classic mode)
  7. Switch back to the subpixel explorer tab
  8. Click on the ‘redraw’ button
  9. Enter ‘n’ to toggle between the default DirectWrite rendering snapshot and the GDI rendering

Hinting and spacing differences

There are two noticeable differences in the way text renders in the DirectWrite rendering modes versus in GDI Classic mode. The first of these is that DirectWrite spaces text differently, in general it tries to keep the spacing consistent across a range of sizes. This varies depending on the hinting strategy used by the type designer and the target renderer when the font was designed. This is a complex subject, by far the most in-depth explaination is The Raster Tragedy at Low-Resolution Revisited, written by Beat Stamm, one of the original engineers who worked on ClearType at Microsoft.

One place where the difference is evident is on the homepage. Below are snapshots, the first with GDI Classic rendering mode and the second with the default DirectWrite rendering mode:

Note how differently the menu strip at the top is laid out, it’s almost as if different fonts were used! That’s because 10px Verdana is spaced very differently in the two modes. Use subpixel explorer to play around with this, few other fonts show this dramatic a spacing difference.

The image below shows GDI mode hinting and spacing of Verdana varying across a variety of sizes, in this case 9-13px, 16px and 24px in ascending order, rendered with subpixel grayscale values and normalized to the same size. Note how glyphs in 9px Verdana are hinted and spaced very differently from those of 24px Verdana, the capital ‘C’ is radically so:

With DirectWrite rendering, spacings and glyph rendering stays relatively consistent across the same range of sizes:

Variations like this reflect design choices made when a given font was designed. For example, Calibri renders consistently with both GDI and DirectWrite. The first two lines below show 9px and 24px Calibri rendered with GDI and the two lines below that show the same sizes with DirectWrite:

Below is an example showing how the spacing differences between GDI and DirectWrite affects the readability of actual content. The example shows 11px and 12px Tahoma, rendered with GDI and the default DirectWrite rendering modes:

The difference at 11px is quite dramatic, similar to the menu it’s as if a different font was used. But note how with GDI each size seems to be it’s own font with it’s own idiosyncracies. At 12px, Tahoma in GDI tends to have clumps of letters with odd spacing, such as “increasingly”, “Mozilla”, “since”, and “collaborative”. Most users won’t be aware of such subtleties but these are just the sort of thing that trips up the process of scanning through text. The DirectWrite spacing stays fairly even across the two sizes.

It’s tempting to view these differences as just a user preference issue, some will prefer text one way, some the other way. That’s certainly true but there’s also the issue of consistency with an author’s original design intent. Designers tend to choose fonts at small sizes very carefully and when renderings differ so much we need to remember that a designer was probably designing with the GDI rendering in mind.

Rasterization differences

The other key difference between GDI and DirectWrite rendering is that the glyph rasterization is slightly lighter in the DirectWrite modes. The image below shows 12px Segoe UI in GDI and DirectWrite modes:

Microsoft has to some extent recognized the lightness problems in the DirectWrite rendering of some fonts. They recently shipped an update that adjusted the hinting at small sizes on commonly used fonts such as Arial, Tahoma, and Verdana so that DirectWrite would rasterize them more clearly. To confirm that you have the updated fonts, check Windows Update for KB2545698. Or verify the version number on the font, the updated version of Arial Regular is Arial 5.10, the previous version was Arial 5.06.

The image below shows the difference in DirectWrite rendering for Arial, Tahoma and Verdana at 12px both at actual size and enlarged with subpixels rendered as grayscale values. The GDI rendering is unaffected by the update.

Note that this update only affects text rendered at 11px, 12px or 13px sizes, there’s no change for text rendered at other sizes.

Changes for Firefox 7

Because of the large differences between GDI and DirectWrite renderings for some fonts at small text sizes, for Firefox 7 we’ve implemented a pref that specifies a list of fonts for which GDI rendering will be used at sizes below 16px. By default the list contains fonts such as Arial, Tahoma, Verdana, Trebuchet MS, Segoe UI and Consolas. Downloadable fonts will always use DirectWrite.

Users can still force a given rendering mode to be used by default, this will override the list of families that use GDI Classic rendering mode (and also affect downloadable font rendering). Over time we may adjust this list as fonts are updated or as users point out problems with specific fonts.