Introducing Adobe Blank
Earlier this year, the Adobe Type Team was approached by one of our other development teams to produce a special-purpose font with two fascinating—at least to me—characteristics:
- All Unicode code points are covered.
- All code points are rendered using a non-spacing and non-marking glyph.
I decided to take on this task, because I immediately recognized that the special-purpose Adobe-Identity-0 ROS was the appropriate vehicle for developing such a font.
The font itself was developed early this year, and I finally got around to releasing it on Open@Adobe as a new open-source project named Adobe Blank OpenType Font. I will soon mirror it on GitHub for those who prefer to get their open-source material from there.
So, what in the world is such a font good for? According to the developer who made the request, Joel Brandt, it serves the following two purposes:
- Invoking this font, as a temporary measure, prevents OS- or application-level font-fallback from kicking in before the intended font can be rendered.
- Related to the above, using the font allows one to detect when a web font is actually loaded, which is arguably a hack to overcome a limitation in CSS.
About the second purpose, the actual usage is as follows:
- Include Adobe Blank as a data URI in the CSS file.
- Specify ‘font-family: SomeWebFont, “Adobe Blank” in the CSS rule for some DOM element that contains text (and would therefore have a non-zero width when rendered using a regular font). One example would be a <span> element that is absolutely positioned offscreen.
- Check the width of the DOM element. If it’s zero, SomeWebFont hasn’t loaded yet. If it’s greater than zero, it has.
In terms of implementation details, I tried the following three approaches, in terms of the number of actual glyphs in the font resource:
- 2 glyphs: The mandatory “.notdef” glyph at GID+0 plus a single functional (though non-spacing and non-marking) glyph at GID+1.
- 257 glyphs: The mandatory “.notdef” glyph at GID+0 plus 256 functional (though non-spacing and non-marking) glyphs from GIDs 1 through 256.
- 65,535 glyphs: The mandatory “.notdef” glyph at GID+0 plus 65,534 functional (though non-spacing and non-marking) glyphs from GIDs 1 through 65534.
For those who are curious, the non-spacing and non-marking glyph description is as follows:
0 width endchar
The other aspect of the implementation details is about mapping all Unicode code points to these glyphs. 1,111,998 Unicode code points are covered. Note that the 2,048 High and Low Surrogates (U+D800 through U+DFFF), the two noncharacters in the BMP and in each of the 16 Supplementary Planes (FFFE and FFFF), and the 32 noncharacters in the range U+FDD0 through U+FDEF are explicitly and intentionally excluded. This involved creating a UTF-32 CMap resource with 1,111,998 mappings.
What I found is that the version that includes 257 glyphs provided the best efficiency, in terms of the number of glyphs and the number of mapping ranges in the ‘cmap‘ table, and that is what was released. Interestingly, the two-glyph version could not be built. I even tried ttx, but apparently 1,111,998 single mappings are too many. The table below shows the sizes, in bytes, of the ‘CFF‘, ‘cmap‘, ‘hmtx‘, and ‘vmtx‘ tables of all three versions:
|Number of Glyphs||CFF||cmap||hmtx||vmtx|
|2||259 bytes||>13MB (estimated)||8 bytes||6 bytes|
|257||1,081 bytes||54,228 bytes||518 bytes||516 bytes|
|65,535||262,419 bytes||328 bytes||131,074 bytes||131,072 bytes|
It should be obvious from the data in the table above why the 257-glyph version was chosen to be released. Of course, this font was built using only AFDKO tools.
In closing, I’d be interested to hear from other developers whether they can think of other use cases for Adobe Blank…
…beyond anecdotally suggesting that government and other bureaucratic agencies use it for rendering and printing their documents. ☺