Re: [css3-fonts] FontLoader v2

To give this proposal a home, I've added the latest version to the
editor's draft of CSS3 Fonts.  We can always move it to a separate
spec if necessary.

  http://dev.w3.org/csswg/css3-fonts/#font-load-events

Regards,

John

----- Original Message -----
From: "John Daggett" <jdaggett@mozilla.com>
To: "www-style list" <www-style@w3.org>
Sent: Friday, September 7, 2012 5:18:55 PM
Subject: [css3-fonts] FontLoader v2


I've revised my previous proposal [1] to eliminate the readyState change
event, use an explicit callback for notification when fonts are
ready for use, clarify the order in which events fire and to simplify the 
name of the event when font loading completes.

Event target for font load events, contained as a property of the document:

partial interface Document {
  readonly attribute FontLoader fontloader;
};

[Constructor]
interface FontLoader : EventTarget {

  // -- events for one or more fonts loading and completing
  [TreatNonCallableAsNull] attribute Function? onloading;
  [TreatNonCallableAsNull] attribute Function? onloadingdone;

  // -- events for each individual font load
  [TreatNonCallableAsNull] attribute Function? onload;
  [TreatNonCallableAsNull] attribute Function? onerror;

  // async load
  void loadFont(DOMString font, optional DOMString text);

  // notify after font loads complete or no loads needed
  callback FontsReadyCallback = void ();
  void notifyWhenFontsReady(FontsReadyCallback fontsReady);

  // "idle" or "loading"
  readonly attribute DOMString readyState;
};

When layout determines that a font or a set of fonts defined via
@font-face rules need to be loaded, the readyState switches from the
initial state of "idle" to the "loading" state and the "loading" event
fires.  As each font load completes the "load" event fires (or an
"error" event fires if none of the resources listed for the 'src'
descriptor contain valid data).  After the final font load completes,
the readyState is switched to "idle" and the "load" (or "error") event
fires. Then the "loadingdone" event fires.  For example, if three
fonts are loaded at the same time, a "loading" event followed by three
"load" or "error" events will fire, followed by a "loadingdone" event.

The 'loadFont' method is used to explicitly load a font or set of
fonts, for use with API's like canvas where text drawing operations
need to happen after a specific set of fonts have been loaded.  The
'font' parameter indicates the exact set of families and style to use
and the optional 'text' parameter provides the exact text for which
fonts are to be selected, since the unicode-range descriptor of
@font-face rules indicates which codepoints a font may support.

Because the number of fonts loaded depends on the how many fonts are
used for a given piece of text, in some cases whether fonts need to be
loaded or not may not be known.  The 'notifyWhenFontsReady' method
indicates a callback function to be called the next time layout
completes and the user agent can determine whether fonts need to be
loaded or not based on the current state of layout.  If no fonts need
to be loaded, the callback is called immediately upon layout
completion.  If fonts need to be loaded, the callback is called after
the user agent completes after all font loads.  If fonts are loaded,
the callback is called after the "loadingdone" event fires.  The
callback is only called once, authors need to explicitly call this
method again to have the callback called again.

The "load" and "error" events would fire the event below:

[Constructor]
interface CSSFontFaceLoadEvent : Event {
  readonly attribute CSSFontFaceRule fontface;
  readonly attribute DOMString error;
}

Bubbles: only in my champagne darling
Cancelable: no

Example: show content only after all font loads complete

  document.fontloader.onloadingdone = function() {
    var content = document.getElementById("content");
    content.style.visibility = "visible";
  }

Example: drawing in canvas with a downloadable font

  function drawStuff() {
    var ctx = document.getElementById("c").getContext("2d");

    ctx.fillStyle = "red";
    ctx.font = "50px MyDownloadableFont";
    ctx.fillText("Hello!", 100, 100);
  }

  window.onload = function() {
    document.fontloader.loadFont("100px MyDownloadableFont");
  }

  document.fontloader.onloadingdone = drawStuff;

Example: complicated layout operations, may or may not download fonts

  function measureTextElements() {
    // contents can now be measured using the metrics of
    // the downloadable font(s)
  }

  function doStuff() {

    // content/layout operations that may cause additional font loads

    document.fontloader.notifyWhenFontsReady(measureTextElements);
  }

  // Note: uses explicit callback rather than event handler

Regards,

John Daggett

[1] http://lists.w3.org/Archives/Public/www-style/2012Sep/0101.html

Received on Monday, 10 September 2012 08:12:23 UTC