Archive for the 'Fonts' Category

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

DirectWrite text rendering survey

Thursday, June 23rd, 2011

Firefox 4.0 uses the DirectWrite text rendering API if it’s available on your Windows 7 machine. In order to get a better idea of the range of text rendering behavior that Windows 7 users are seeing, we’ve put together a small text rendering survey. The survey renders content using a variety of Cleartype settings and asks you to choose the rendering that looks most readable to you. For each question, there’s also a comment field so you can point out funny artifacts or anything that seems out-of-place to you.

If you’re using Firefox on a Windows 7 machine, please grab a tasty beverage and take a few minutes to help us out!

Instructions:

  1. Download the latest nightly build.
  2. Download the zipfile containing the survey.
  3. Open the readme.html file.
  4. Read through the instructions and click on the link to run the survey.
  5. Click ‘Allow’ in the security dialog to allow the script to modify browser prefs (this is needed to render with various Cleartype settings).
  6. Run through the survey renderings, selecting what looks best to you.
  7. Submit the results.

The submitted results contain the sample renderings and your selections along with basic info about your system Cleartype parameter settings, plus your name and email if you supply it.

Thanks very much for your help with this!

CSS3 Fonts discussion at Typecon 2010

Friday, August 20th, 2010

This week I spoke at Typecon in Los Angeles, a large gathering of folks interested in type. I did a presentation on new features in the CSS3 Fonts spec. Three hours were allotted so there was plenty of time for discussion during the session. I went over the details of font selection, the mechanics of the @font-face rule, and described the proposed new font-variant subproperties for supporting OpenType font features.

Below are the slides from the presentation.

CSS3 Fonts Typecon 2010 slides

Dave Crossland wrote up a nice summary mixed with commentary on his blog.

Thanks to John Hudson and Christopher Slye for coordinating the session.

ウェブフォントの未来

Thursday, July 1st, 2010

昨日の夜アップルストア銀座でウェブフォントについて講演しました。
色々な人々に会って、質問も面白かったです。ありがとうございました。

Web Fonts Future slides

ATypI 2009

Wednesday, November 4th, 2009

Last week Jonathan Kew and I went down to attend and present at ATypI 2009, a typography conference that took place in Mexico City this year. There was an entire day of sessions on web fonts. Jonathan and I presented a session on “Advancing Web Typography”:

ATypI 2009 Advancing Web Typography slides

In a session discussing font rendering, Simon Daniels from Microsoft announced that Microsoft was “considering” support for the WOFF font format! Other presenters focused on the differences in font rendering across platforms/browsers. There was also a lot of interest in better typographic controls in CSS.

Better Postscript CFF font rendering with DirectWrite

Thursday, October 22nd, 2009

For those playing with Windows 7, check out some of the work Bas Schouten has been doing with adding DirectWrite support to Firefox. DirectWrite is Microsoft’s replacement for Uniscribe in Windows 7 and it has much better rendering of Postscript CFF fonts, fonts that are typically labeled “OpenType” with an .otf extension. Many well-known font vendors ship these fonts almost exclusively.

Here’s a waterfall test that uses Jos Buivenga’s Calluna font, a beautiful serif text font that can be used as a downloadable font. In the lower part of the page is the same waterfall with Constantia, one of Microsoft’s ClearType fonts that ships with Vista and Windows 7. Below is a comparison of the default rendering now under XP and Windows 7 and the rendering with the patch Bas is working on:

Text Waterfall comparing GDI to DirectWrite rendering

At very low sizes (e.g. 6px – 9px), the text drawn with the DirectWrite API is much more readable. The reason for this is clearer if you zoom in closely and look at the pixels.

Small text (6px – 8px) drawn with Windows 7 GDI ClearType rendering:

Small text drawn with Windows 7 GDI ClearType

The same text drawn with DirectWrite:

Small text drawn with Windows 7 DirectWrite

Up close neither looks great but slide your chair back a few feet; the text rendered with GDI looks awful and is barely readable, the text rendered with DirectWrite legible. The default GDI rendering doesn’t do subpixel antialiasing so the glyphs appear less defined, they look thinner.

Great stuff!! Hats off to Bas!

Note: platform API’s on Mac OS X and Linux already do a good job rendering Postscript CFF fonts, this just brings them up to parity under Windows 7.

Making font initialization lazier

Monday, October 5th, 2009

Last week I spent some time looking at font system initialization on the Mac (bugs 517045 and 519445). At startup, code in gfx on Mac and Windows currently enumerates all fonts on the system. This information is used for matching font names and for system font fallback (i.e. when a glyph is needed for a character not in the fonts specified by the page). It’s also used to workaround problems with font APIs on various platforms.

Running on a 2.2GHz Mac Mini running vanilla 10.5.8, startup takes roughly 650ms before content is shown. This “warm” startup time is after a couple previous runs, a newly installed or recently rebooted system startup takes longer. Roughly 37ms (or 5% of startup time) is spent in InitFontList, which enumerates fonts on the system. Most of this is spent in Appkit routines, 13ms in [NSFontManager availableFamilies] pulling the complete list of font families and then 22ms in [NSFontManager availableMembersOfFontFamily] to enumerate the styles available for a given font family. Increase the number of fonts on the system and these numbers start to grow dramatically; with the full contents of Adobe’s Font Folio 11 font package installed for a total of 2600 fonts, getting the family list takes 350ms and enumerating all the styles for each family takes 5.7 seconds(!!). That means a user on that machine sees nothing for six seconds!

It would be nice to do this lazily but to draw text font matching needs to take place so it’s tricky to push this all out of the startup process. Jonathan Kew wrote up a patch to use platform routines to lookup font names adhoc until the font list is completely enumerated later but this turns out to be tricky, platform lookups don’t always match as CSS guidelines dictate. For example, CSS allows font names to be used without case sensitivity and lots of sites use this:

body { font-family: arial, helvetica, sans-serif; }

The NSFontManager routine for looking up a font family name expects a case-sensitive name, so lookups of names like ‘arial’ will fail. Plus, this routine has lousy performance when a name lookup miss occurs, it can take 8-12ms to figure out that a font with a given name doesn’t exist. Compare that with our case-insensitive lookup code which only takes a couple microseconds to lookup a name, regardless of whether it exists or not. For the average user, doing adhoc lookups is going to increase startup time, not decrease it, since the failed lookups will end up taking longer than initializing at least the list of families.

So how can we decrease the startup time here? Probably through a combination of enumerating the styles for font families more lazily and investiagating whether more recent font API’s have better performance.

Another aspect of font system initialization is the reading of font character maps (cmaps) for all fonts on the system. This generally doesn’t occur at startup, it only occurs if system font fallback occurs. Consider a simple example:


body { font-family: arial, helvetica, sans-serif; }

<p>Nattō (納豆) is made from fermented soybeans.</p>

For the Japanese characters in the text above, code in gfx looks at all the fonts in the system and tries to pick the one that contains glyphs for the characters and matches the style characteristics of the font used for other text. The process is fairly simple, the code looks at the cmaps of fonts on the system to conclude which fonts have glyphs for a given character. But this could definitely happen more efficiently.

The first thing to note is that fonts rarely change, every once in a while a user adds a font to their fonts folder or fonts are added when installing a given application. So these could be cached. But even this is probably a lot more information than is needed, the nature of fonts is that there are a large number of fonts that support a small range of characters for European languages and a much smaller set of fonts that include glyphs for other codepoint ranges. For characters in common ranges (e.g. U+000-2FF), the font matching could actually be precomputed and cached and only updated when fonts changes occur. For other ranges, a simple precomputed list of fonts with glyphs for that range would reduce the system fallback process to iterating over a small set of fonts as needed. This would be especially helpful to users with large numbers of fonts on their system but it could also speed up text rendering in general since text rendering is typically critical path code.

Note: downloadable fonts are never used for system fallback so they do not affect this process.