

Re: [css3-fonts] rethinking font load events

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Thu, 6 Sep 2012 23:02:34 -0700
Message-ID: <CAAWBYDDHM_7mYMm9c6gEw8gGDDp39-fRBMwecaMas+HkXY2R8Q@mail.gmail.com>
To: Glenn Adams <glenn@skynav.com>
On Thu, Sep 6, 2012 at 10:27 PM, Glenn Adams <glenn@skynav.com> wrote:
> On Fri, Sep 7, 2012 at 12:39 PM, John Daggett <jdaggett@mozilla.com> wrote:
>> Glenn Adams wrote:
>> > I fail to see the relation between load completion and layout
>> > completion. FontLoader should not be sensitive to layout state, just
>> > font loading state. Again, I don't see a use case for the notify
>> > method as has been described thus far. I'd prefer to discuss on this
>> > ML for the record.
>> Font loads occur due to layout measuring text, which runs font
>> matching, which selects faces for a given run of text, which determines
>> whether fonts need to be loaded or not.  Font loads do not occur if
>> @font-face rules are defined but never used, that's why font loading
>> depends upon layout behavior.
> Yes, I understand all of that. It seems like you may be conflating
> allcomplete with both (1) the layout processing (that may or may not trigger
> a font load) and (2) actual font load processing. If that is the case, then
> I think FontLoader is a bad place to anchor functionality related to layout
> related events.

No, something's missing in your understanding.  I'll try to explain
again, though I fear I'm repeating myself.

You do some work in function A.  A may or may not incidentally kick
off some font loads (for example, it might insert some DOM nodes that
get a 'font' property applied for a new font that hasn't been loaded
yet).  You'd like to execute an additional function B, but if there
are pending font loads, delay B until after they're finished (for
example, B might do some measurements which will be affected by font

Normally, you'd have to do this by adding some code to the end of A
that (1) does a style flush (an ill-defined operation) so that any
font loads that would be triggered by A's work are definitely started,
(2) check FontLoader.readyState, (2a) if it's "idle", assume your work
didn't trigger any font loads and call B immediately, (2b) if it's
"loading", set up a listener for allcomplete that runs B.

notifyAfterCompletion() lets you avoid some of these steps.  At the
end of A, all you have to do is set up a listener for "allcomplete"
that runs B, then call notifyAfterCompletion().  No style flush
necessary, no checking readyState.  If A's work *did* trigger a font
load, notifyAfterCompletion() is a no-op - B just runs when the font
finishes loading, as intended.  If A's work didn't trigger a font
load, notifyAfterCompletion() immediately fires an "allcomplete" event
anyway (even though no fonts actually loaded), so B will run in the
next spin of the event loop.

This is basically a manual hack for promises - if you had the ability
to request an "allcomplete" promise, you could just run B when it's
fulfilled, and you get the same mechanics.

Received on Friday, 7 September 2012 06:03:25 GMT
