I am loading the OpenType webfont Open Sans
via the Google Fonts API / CSS.
In both Chrome 43 (Linux+Windows) and Internet Explorer 11 (Windows) the browser renders the text exactly as specified in the font. However, in Firefox 38.0.5, the text width and/or spacing is rendered differently for some characters. All font variants are at the default value ("normal").
As an example, we can use the characters 1
, a
, b
, and i
. Open Sans "unitsPerEm" is 2048. Therefore, at a font size of 18.0px, the width of 30 characters of each of the above characters should be as follows based on 1/u * p * c * w where u = 2048, p = 18.0, c = 30, and w is the advance width of each char (Wolfram Alpha equation).
+----------------------------------------+-----------+ | char | font(px) | numChars | advance | width(px) | +------+----------+----------+-----------+-----------+ | 1 | 18.0 | 30 | 1171 | 308.76 | | a | 18.0 | 30 | 1139 | 300.322 | | b | 18.0 | 30 | 1255 | 330.908 | | i | 18.0 | 30 | 518 | 136.582 | +----------------------------------------+-----------+
This (JSFiddle) uses the canvas method measureText
to output the width in pixels of 30 characters of each of 1
, a
, b
, and i
.
Chrome text lengths match the expected values exactly:
Firefox Linux text lengths do not match for any of the characters except a
, even after accounting for the fact that Firefox does not provide subpixel accuracy:
I have confirmed that the width reported by canvas is indeed what is output by both Chrome and Firefox -- the following image shows a red background, with Chrome's text in black, and Firefox's text in white -- the widths match the outputs above according to the Gimp "Measure" tool. Firefox's b
and i
is too wide, and 1
is too narrow:
And as a side note, Firefox Windows text lengths are not even consistent with Firefox Linux -- the a
and b
widths are now as expected, but 1
and i
are still incorrect:
This is a clean Firefox profile with default settings and no extensions installed.
Can someone explain what is going on, and how to force Firefox to render the font according to the font specification?
UPDATE: On Windows, setting the preference gfx.font_rendering.directwrite.enabled
to true
fixes the problem (which I believe is the Firefox default when hardware acceleration is available, this setting just forces it on even if hardware acceleration is unavailable, such as on my test VMWare system). DirectWrite has been the default in Chrome on Windows since version 37. The Linux behavior is still unexplained. This blog post explains more about DirectWrite rendering in Firefox on Windows.