Follow through on my fontready patch

I recently created a patch for Firefox that allows one to listen to the ready state of fonts loaded via @font-face.

I have some examples on it.

First to get a more visual example, I will show images as to why this is useful and needed badly inside the browser.
This is an image of a div using some custom font, and a canvas drawing some text using the same font. As you can see above, the fonts are different. What is actually happening is there is a moment where the div is also incorrectly drawn, then when the font is loaded, it gets updated. This has been coined as
FOUT. The canvas never gets the update, or the FOUT, because it never knows to clear the canvas and redraw the text. One way around this is to constantly clear the canvas and redraw, and once the font it loaded, it will update, and bring along the FOUT with it. Also, you could setup an offscreen div, and measure text on it until it is not the same size as the default font, meaning your new font is most likely ready to go. Both solutions are hacks and suboptimal.

In my last post, I talk about my attempt to listen for font ready states. Given the same example above, this is now what I get on the first load:

As you can see, both fonts are the same. This is because I setup a listener for “fontready” and draw my canvas in there. This also gets rid of the FOUT. The event looks like this:

      var setupCanvas = function( e ) {
      
        var canvas = document.getElementById( "canvas" );
        var ctx = canvas.getContext( "2d" );

        ctx.font = "20pt dekar";
        ctx.strokeText("Hello World!", 50, 50);  
      };
    
      document.addEventListener( "fontready", setupCanvas, false );

One annoyance I noticed with this is fontready and DOMContentLoaded may become a race condition if not carefully implemented, because the dom must be loaded before the canvas can be drawn to. Example of this is if the font is ready before the document, and thus the canvas is not ready, and the font loading is lost. There are ways around this, though, and is not a huge deal, just something that must be accounted for, and is quite common in web development. I solved this by creating the font inside my DOMContentLoaded event. Looked like this:

      document.addEventListener( "DOMContentLoaded", function( e ) {
      
        var fileref=document.createElement("style");
        fileref.setAttribute("rel", "stylesheet");
        fileref.setAttribute("type", "text/css");
        fileref.innerHTML = "@font-face { font-family: dekar; src: url('Dekar.otf'); } div { font-family: dekar; }";

        document.getElementsByTagName("head")[0].appendChild(fileref);

        setupCanvas();
      }, false );

This is just one way to ensure things happen in the desired order. I just create a style element and insert it after the dom is ready, and my fontready event has been created.

There is a Firefox ticket for this very feature, along with a beginning of a proposed spec for a font API. I have been looking these over, and will have an opinion compiled shortly.

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: