Posted by Dr. Ken Lunde

 Comments (31)

Created

March 28, 2013

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:

  1. Include Adobe Blank as a data URI in the CSS file.
  2. 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.
  3. Check the width of the DOM element. If it’s zero, SomeWebFont hasn’t loaded yet. If it’s greater than zero, it has.

An example real-world use case for Adobe Blank is the Adobe Edge Web Fonts extension for Brackets, which is available on GitHub.

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

COMMENTS

  • By Rafael Rinaldi - 5:01 PM on March 28, 2013  

    That’s a very interesting solution. Might try it out.

  • By Ramanan - 5:53 PM on March 28, 2013  

    Interesting.

    Already using.

    Can we have woff and other versions of “Adobe Blank” ? I tried fontsquirrel but didnt’ work.

    • By Dr. Ken Lunde - 8:21 AM on March 29, 2013  

      I’ll need to look into this.

      • By Ramanan - 10:02 AM on March 29, 2013  

        Thanks.

    • By Paul - 10:58 AM on March 29, 2013  

      I believe I am able to generate the woff and other web formats successfully from the OTF using a combination of FontForge, sfnt2woff and ttf2eot. If you’d like to use the script that glues them all together, take a look at: https://github.com/ppicazo/css3FontConverter

  • By Dave P - 12:58 AM on March 29, 2013  

    Confused. You provide a .otf file, yet fontforge can’t open it?
    is there further work to do please Ken?

    • By Dr. Ken Lunde - 8:20 AM on March 29, 2013  

      If fontforge cannot open this font, it suggests that fontforge has a bug, because this is a completely well-formed OpenType/CFF font. My guess is that the large number of mappings in the ‘cmap’ table is tripping up fontforge. Our AFDKO tools have no problem dealing with it.

    • By Ramanan - 10:07 AM on March 29, 2013  

      I can open it in fontforge and see a lot of blanks! but can’t view the lookups.

      • By Dr. Ken Lunde - 1:32 PM on March 29, 2013  

        Lookups? What lookups?

        • By Ramanan - 1:45 PM on March 29, 2013  

          Oh in Fontforge, if I do “Element” from the Menu and click “Font Info …” , I can’t choose the “Lookups” on the left.

          This is the place where one sees the mappings in usual fonts but for Adobe Blank, Fontforge doesn’t seem to read it.

          • By Dr. Ken Lunde - 2:20 PM on March 29, 2013  

            Lookups are usually associated with GSUB or GPOS features, and this particular font includes neither, which would explain why fontforge cannot read any.

  • By Pascal - 4:51 AM on March 29, 2013  

    Please, let me see your content !
    I do NOT want a blank page waiting for your font

    • By Joel Brandt - 8:34 PM on April 2, 2013  

      Hi Pascal,

      That’s a very good point — I agree that this font should *not* be used to hide a page’s main content until a webfont loads!

      We’re using Adobe Blank in very specialized situations. For example, we use it as the fallback font in an interface for rendering previews of fonts (i.e. a font chooser). In that particular case, if we can’t actually load the font, then we do not want to mistakenly preview it in a fallback font.

      This font can also be used in a similar way to check if a font is present on a user’s system. To do this, the web page places an element off screen with some text in it, and sets the font-family CSS property to:

      font-family: FontInQuestion, AdobeBlank

      If the offscreen element has a non-zero width, then “FontInQuestion” is indeed on the user’s system.

      I hope this clarifies things. We never intended the font to be used to *hide* the main content of a webpage.

  • By Ramanan - 10:17 AM on March 29, 2013  

    Very useful Ken.

    Even though Google FontLoader can be used to hide FOUT, I still see the FOUT sometimes. I think with Adobe Blank, the chances of FOUT is effectively zero or at least highly reduced.

  • By Cosmo - 7:17 AM on March 30, 2013  

    For the less technically inclined, any chance of how to actually use this on a typical site — let’s say, WordPress? Or is for the developer elite?

    Thanks

    • By Joel Brandt - 8:38 PM on April 2, 2013  

      Unfortunately, it’s difficult to make productive use of this font on a web site without also writing some JavaScript. Take a look at my comment to Pascal above. In that comment, I give one use case that doesn’t involve any JavaScript: rendering font previews. In a “font chooser” interface, it doesn’t make sense to render sample text in a fallback font. So, if AdobeBlank is used as the fallback, it will either a.) render in the intended font, or b.) not render at all.

  • By Dr. Ken Lunde - 2:53 PM on March 31, 2013  

    Here are some mentions of Adobe Blank in the media: TechCrunch‘s March 29, 2013 Adobe Launches Blank, An Open Source Fallback Font You Can’t See article by Frederic Lardinois (also in Japanese), The Inquisitr‘s March 29, 2013 ‘Adobe Blank’: A New Invisible Font That Actually Makes Sense article, Typedia‘s March 30, 2013 Type News: 25% Invisible article by Erik Vorhes, The H‘s April 2, 2013 Adobe open sources Blank font article.

  • By Darren - 10:48 AM on April 1, 2013  

    In closing, I’d be interested to hear from other developers whether they can think of other use cases for Adobe Blank…

    How about using it for text (e.g., HTML5 section headings) that’s intended to improve UX/accessibility for Users with screen readers (but shouldn’t be rendered in normal Web browsers)?

    I’d be interested to see how Adobe Blank might compare to these other methods of hiding content for accessibility.

    • By Joel Brandt - 8:40 PM on April 2, 2013  

      (Caveat: I’m not an accessibility expert.)

      If the only goal is for accessibility, then some of the other methods you link to are probably more appropriate. For one, those methods do not require downloading an extra font into the user’s browser. The font is 39K gzipped, which isn’t huge. But, it’s wasted data transfer for content that is hidden by other means.

  • By Bryan Crow - 9:09 PM on April 1, 2013  

    Seems too large to be practical for most use cases (1 or 2 Open Type fonts on a site). At a cost of 80KB (or 39KB gzip’d css in a data url) just to be able to tell when the next open type font loads?

    It would be more efficient to just create a data URL for the open type font(s) you want to use instead, setting the browser cache duration to something very large. That’d get you the render blocking you want while the CSS declaration using a data url downloads for the first time, without the extra 39KB payload.

    So, unless you’re downloading several custom fonts, this doesn’t seem all that practical.

    • By Joel Brandt - 8:44 PM on April 2, 2013  

      This is a good point, Bryan. Our use case was _very_ specific. First, we weren’t worried about download size because we were building a desktop application. Second, we needed this fallback font for both Webfonts and system installed (or missing) fonts.

      We use AdobeBlank in a font picker interface. In that font picker, we include any font that is mentioned in the CSS file the user is currently editing. They might have a font “Foo” mentioned somewhere in their CSS file that is both a.) not installed on their system, and b.) not available in our Webfont service. We have no way of knowing whether “Foo” is installed on their system.

      So, by rendering the Sample text with the CSS property “font-family: Foo, AdobeBlank”, we’re guaranteed that a.) they see the sample text correctly if they do have “Foo” on their system, and b.) they don’t see erroneous sample text in a fallback font if “Foo” is missing.

      Here’s a screenshot of the font picker interface in question, in case that helps make things more clear:
      http://cl.ly/image/1X1g0o0q1g2m

  • By Rick Viscomi - 1:16 PM on April 2, 2013  

    Curious about the implications of this font on SEO. Will crawlers detect that the text is not visible and therefore not index it? One practical reason to behave this way would be to prevent fraudulent keyword spamming on a page.

    • By Joel Brandt - 8:47 PM on April 2, 2013  

      (Caveat: I do not have any expertise in SEO.)

      I suspect that if this became a problem, web crawlers from the big players in search would add code to detect this and down-rank pages that use such a technique. So, it might work for a very short while, but would not be a foolproof spamming technique. Fortunately, search companies work very hard to prevent spam.

  • By Mike "Pomax" Kamermans - 9:19 AM on April 3, 2013  

    Someone mentioned Adobe Blank to me, and that it reminded them of my tiny font implementation I did a while ago (if you were on the opentype mailing list you might have seen that go by). It might be possible to create a minimal full-unicode font by using format 4 and 12 CMAP entries with full-range segments, both pointing to the non-spacing, non-marking glyph. This would probably give us a legal OpenType font that’s around 1kb. I’ll see if I can play around with that over the weekend. If I can, I’ll put it on github.

    • By Dr. Ken Lunde - 2:21 PM on April 3, 2013  

      Please keep me posted.

  • By Rick Viscomi - 8:18 AM on April 4, 2013  

    I was really excited to use Adobe Blank to mitigate the flash of unstyled text problem when asynchronously loading third party web fonts (ie Google Web Fonts).

    The applicable use case, as described in the article is “Invoking this font, as a temporary measure, prevents OS- or application-level font-fallback from kicking in before the intended font can be rendered.”

    However, the suggested implementation leads to very undesirable behavior in the event of a single point of failure involving that third party font provider.

    The suggested implementation is “Specify ‘font-family: SomeWebFont, “Adobe Blank” in the CSS rule for some DOM element that contains text”.

    The key benefit to asynchronous font loading is that it is resistant to the effects of SPOF. However, if an outage occurs, the custom web font never loads and the ‘AdobeBlank’ font persists.

    The CSS rule gives precedence to Adobe Blank before any other fallback font, even built-in ones.

    Here is a WebPagetets comparison view of Adobe Blank in action under normal and SPOF conditions: http://www.webpagetest.org/video/compare.php?tests=130404_ZA_7dad41dc9d4f7b51d15e376c0f5e706a,130404_64_309ef70571a1953951b04c4883f04dc6

    • By Ramanan - 7:30 AM on April 6, 2013  

      Can’t you use Google FontLoader in combination with Adobe Blank?

      So something like

      h1 {
      font-family: “Adobe Blank”;
      }

      .wf-loading h1 {
      font-family: “garamond-premier-pro”, “Adobe Blank”;
      }

      .wf-active h1 {
      font-family: “garamond-premier-pro”, “Times New Roman”;
      }

      .wf-inactive h1 {
      font-family: “garamond-premier-pro”, “Times New Roman”;
      }

      • By Rick Viscomi - 11:23 AM on April 19, 2013  

        The premise of the original problem is that the third party web font provider is unavailable. So if you’re using Google Web Fonts and they’re down, you’re not going to have the benefit of their WebFont Loader because they’re all hosted on the same hostname.

  • By smnh - 10:39 AM on April 14, 2013  

    Hi Ken,
    Thank you for your great work!

    In the last year I’ve been working on a project heavily relying on web fonts requiring knowledge about their load state. Lately, I’ve discovered a method to receive notification when fonts are loaded without using the traditional JavaScript timeouts or intervals to poll for element dimensions. Yet it still suffered from other issues like the issue related to metric compatible fonts. But now with AdobeBlank this method is sealed!

    Here is the link for the basic JavaScript class called FontLoader that utilizes AdobeBlank and notifies when specified font families are loaded and ready for use inside a web page:
    https://github.com/smnh/FontLoader

    For additional info on font loading detection without timers:
    http://smnh.me/web-font-loading-detection-without-timers/

    • By Dr. Ken Lunde - 6:29 AM on April 15, 2013  

      Thank you. I am glad to hear that Adobe Blank has proven to be useful. Also, thank you for the details of your implementation, which other no doubt will find helpful.

  • By B - 3:27 PM on December 23, 2013  

    I found this article via:
    http://scottkellum.com/2013/10/25/the-new-kellum-method.html
    That seemed like a pretty good, real-world, use case to me.
    I’d love to know how to apply this technique using FontLab Studio.