DirectWrite Text Rendering in Firefox 6

August 11th, 2011 by John Daggett

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 reddit.com 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 reddit.com 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.

27 Responses to “DirectWrite Text Rendering in Firefox 6”

  1. Karel Koubek Says:

    Thank you for a very informative article.
    As you said, it’s all users’ preference, but I find the GDI rendering much cleaner and easier to scan through text. On the other hand I agree that GDI imprints some “character” of its own on all fonts and they look a bit uniform and similar to each other.
    But the million dollar question: If I use the GDI Classic rendering mode (2), will the hardware acceleration be enabled? It’s all I need – GDI rendering appearance with hardware acceleration. So far I had to resort to turn the acceleration off.

    Thanks for a reply!

  2. Ric Says:

    Please don’t use GDI for any fonts in FF7! It’s nowhere near as good and a step backwards, the main issue people are not used to seeing text looking a little different.

  3. David Naylor Says:

    Very interesting article! Had to check I had Arial v 5.10. I did.

  4. jdaggett Says:

    Karel, yes, with GDI Classic mode set there’s no need to disable hardware acceleration.

  5. Neil Rashbrook Says:

    Does DirectWrite also give you multiple font weights or am I confusing this with some other bug?

  6. Jim B Says:

    This is the main place where I see firefox’s text rendering fall down. The white text on dark background at

    http://velonews.competitor.com/

    (eg, look at the link array at the bottom of the page)

    Firefox 4/5 is really bad on this (win 7). It doesn’t look bad in ie8, ie9, opera, safari, or chrome.

  7. Brian Says:

    I’m confused. I read the entire informative post and you clearly showed how DirectWrite does a superior job of rendering small fonts and preserving the characteristics of the typeface. Then in the very last paragraph you state that you are disabling this improvement(?!). The only justification I could find was that some people liked the old way better, but that’s never a good reason to avoid progress and improvement — there will always be cranky curmudgeons! Did I miss something?

  8. Scott Baker Says:

    Very interesting article thanks for putting it together. I’m curious how anti-aliasing works for non-black fonts. Specifically sub-pixel anti-aliasing. Could you modify your font tool to allow the user to pick the color? It would be interesting to be able to pick the glyph color and the background color.

    Thanks!

  9. Dave Crossland Says:

    Would it be possible to write an extension that allows the GDI font list to be updated from data loaded over the web? (Similar to the way ad blocking extensions load lists of ad servers.)

  10. Hans Says:

    @Karel: It’s not really GDI-rendering just rendering that looks like GDI but is still done by DirectWrite so will still have hardware acceleration. Also note that because the default settings for contrast etc. are different for DW text might still look different than when acceleration is disabled.

  11. Hans Says:

    @JimB:Text on pages rendered in IE9 in IE9 mode should look about the same as Firefox 5 rendering with GPU acceleration enabled since in both cases DirectWrite is used, if it differs substantially this is a bug you should report at https://bugzilla.mozilla.org/

  12. Jim B Says:

    Hans, FF is worse than IE9 whether or not compatibility mode is selected for the page. Part of the responsibility of filing a bug is first checking to see if the bug has already been reported. I’m a bugzilla neophyte, so it will take me a while to try a bunch of keyword searches to see if it exists.

  13. José Pedro Says:

    I agree with the changes for Firefox 6 and i’d be dying to see the changes in Firefox 7 too if I was on Windows.

    I just had an idea, why not hook-up into the text-rendering CSS settings ( https://developer.mozilla.org/en/CSS/text-rendering )? If the author wants to have GDI rendering, he’d use optimizeLegibility, if he wanted Direct Write’s default, he’d use geometricPrecision (because GDI has aggressive hinting that makes fonts crisp and gives them more contrast, while Direct Write tries its best to retain the original appearance of the font) (I mean the GDI rendering and Natural/Natural Symmetric rendering in DirectWrite).

    This would be ideal for when authors wanted downloadable fonts to render some way or another. Nonetheless, the user should have the possibility to override these settings. At least for the default fonts the property should not make anything at all.

    Just a thought that passed by my head. Perhaps it can appear in Firefox 8.

  14. jdaggett Says:

    @Jim B, I’m guessing you’re talking about the footer entitled “Our Other Media Sites”, right? That appears to be some sort of issue with the background and the way it’s blended with foreground elements. Remove the background on that page and the text renders identically to IE9. But I will investigate and file bugs if needed.

  15. jdaggett Says:

    @José Pedro, while there’s an authoring aspect to this problem since hinting and spacing affects layout, this is to a large extent a user preference rather than an author preference. And keep in mind the main problem area here is small text, I doubt many would contest that DirectWrite rendering of heading text is better than GDI. Always using DirectWrite for downloadable fonts simplifies things in the long run, less code complexity to maintain.

  16. jdaggett Says:

    @Neil, yes the DirectWrite API supports font family groupings that can contain multiple weights and widths, beyond the basic regular, bold, italic and bold italic.

  17. jdaggett Says:

    @Jim B, I logged a bug for your problem, bug 678449.

  18. John Daggett Says:

    @Dave, sure, the font list is in a preference which extensions can access.

  19. Mihai Sucan Says:

    Does Firefox 6 (or 7) try to follow the the default font rendering settings on a Windows 7 machine?

    I mean, with these new options I can get font rendering how I want in Firefox, but I’d like it to be in sync with my system settings. Where “in sync” pretty much means “try to match” (since there’s a lot of mess in font rendering across different software).

  20. John Daggett Says:

    @Mihai, the default is to use system settings. The additional prefs introduced in Firefox 6 allow you to override the system settings. To set the system-wide settings run the ClearType tuner. Keep in mind that older apps will use GDI and newer ones will use DirectWrite and the parameters affecting each are different.

  21. Jim B Says:

    This is strange, to say the least. velonews has had the rainbow colored light text on dark background problem for ages. I complained about it here, John filed a bug. Great. But now I don’t see the problem anymore. I don’t know if the large set of windows updates last week somehow changed GDI/DirectWhatever, but the text looks good now for me, and nothing else has changed in my setup (version of FF, nor radeon drivers).

  22. John Daggett Says:

    Not sure if this is relevant to your case but are you viewing things on a external monitor? One connected via a VGA cable? Especially if the cable is long, there will be enough color jitter that it will really exacerbate the rainbow effect.

  23. Beat Stamm Says:

    Thank you for continuing to offer choices to us end-users on how text is rendered for our eyes and on our screens. This can make or break the difference.

    For some fonts at some sizes, the different renditions by GDI and DW can indeed almost make it look like a different font was used. Notice, however, that in case of Tahoma at 11 and 12px (and other sizes or other core fonts) this is due to the selected GDI mode that we called “compatible widths” but not so much due to GDI per se. Back when b&w bi-level rendering was the only method, it was not uncommon (and in fact quite legitimate) for “hinting” to prioritize pixel-level regularity and symmetry, which lead to actual (integer) character widths that differed from their their theoretical (fractional) widths by more than the (expected) ±0.5px (cf. Raster Tragedy 6.2.1, illus. of lc ‘m’).

    By the time ClearType started vying for rendering preference, countless dialog boxes (and websites) had been “optimized” (“hard-wired”) to these pixel-level character widths. In turn, ClearType’s truer-to-the-font-design character widths were implied in “breaking ” these dialog boxes (and websites). Hence I implemented a “clever hack” in the rasterizer to move the vertical stems closer together or further apart to have ClearType match the b&w character widths (“compatible widths”). This may make text look like a bit of a “hybrid” between pixilated bi-level rendering and fully smoothed sub-pixel anti-aliasing. In some cases, there was simply nothing particularly “clever” that could be done—Tahoma has some examples (cf. Raster Tragedy 4.2.0, illus. of lc ‘l’).

    The alternative, between GDI’s “compatible widths” and DW’s fractional widths, is GDI’s “natural widths” mode. In this mode, character widths are kept to an integral number of pixels but without the constraint to match b&w widths. If implemented consistently, this can render “sharp” individual stems without unduly compromising spacing. The following illustration repeats John Daggett’s example, adding GDI’s “natural widths” mode in the center.

    Being limited to full-pixel character widths, GDI’s “natural widths” cannot match DW’s fractional pixel character widths. But it can come fairly close. In fact, as a compilation of (weighted) character average widths illustrates for Calibri, “natural widths” with appropriate “hinting” can outperform DW’s fractional widths with naïve hinting (cf table in Raster Tragedy 6.2.3).

    Surprisingly complex subject, yet for most of us it’s “just” fonts.

  24. Jim B Says:

    “Not sure if this is relevant to your case but are you viewing things on a external monitor?”

    Nope, DVI.

  25. Rodrigo Says:

    I’ve tweaked all around, and Firefox 6 fonts still look ugly. Not only in Windows, but also in Linux. I’ve compared side-by-side with Firefox 3.6, and 3.6 looks good. The problem began with Firefox 4. Chrome looks good on all versions, though.

  26. Soustruh Says:

    Hi, is there a way to turn on antialiasing for large font-sizes and leave it turned off for small ones in Firefox 6/7/8?

    I have ClearType disabled in Windows settings, but I’d love to have large headings antialiased (which is exactly the same behaviour that Chrome does on my AA-disabled system).

  27. Beat Stamm Says:

    @Scott Baker: about how anti-aliasing works for non-black fonts: I’ll distinguish anti-aliasing performed on full pixels (aka gray-scaling) from sub-pixel anti-aliasing (aka ClearType, CoolType, FreeType, or Quartz). For plain gray-scaling I don’t see a problem, but sub-pixel anti-aliasing suffers. Simply put, anti-aliasing uses intermediate shades of gray or color to represent [fractional] pixel coverage. For instance, in gray-scaling, 50% gray represents a pixel that is halfway covered by the character outlines. For sub-pixel anti-aliasing, the respective argument is applied to the individual red, green, and blue sub-pixels, theoretically yielding finer representation of [fractional] pixel coverage.

    Once text is rendered in color, the concept of using intermediate shades of color to represent [fractional] pixel coverage no longer makes sense. Imagine rendering text in red (#FF0000) on a black background. The green and blue sub-pixels will stay dark, not making any contribution to the representation of [fractional] pixel coverage. It is as if only the left third (on an RGB screen) of each pixel were sampled, which is not unlike shifting the character outline 1/3 of a pixel to the right and then rendering it in bi-level (aka B&W, or red-on-black in this example).

    For detailed illustrations on rendering text in color, as well as its sensitivity to gamma correction, see the Raster Tragedy Revisited, specifically 5.2 Rendering Text in Color and 5.3 Gamma Correction (just revised).