Re: [css-font-loading] load, check and testing for character coverage

Tab Atkins wrote:

> Whether check() should be answering "is a load needed?" or "is
> everything you might need to render available?" is the question at
> hand; you can't just assume it.
>
> We got feedback from early users that the former question yields
> confusing answers in degenerate cases; misspelling a font name would
> return true, same as correctly spelling the font and having it loaded.
> Apparently people prefer to ask the latter question, so I adjusted the
> degenerate case answer to match.

To be clear, these API's in no way provide answers to "is everything you
might need to render available?", since system fallback can occur with any
fontlist. Whether system fallback occurs or not does not matter for the
load/check use cases. What matters is whether all possible fonts have
loaded or not.

Spec'ing the degenerate case produces some definite inconsistencies between
the load() and check() methods:

  document.fonts.load("16px HellishVetica").then(function() {
    // load promise resolves, everything ready to go!!
    // but wait, check returns false!?!
    alert(document.fonts.check("16px HellishVetica"));
  }

I think it would be totally appropriate for browser dev tools to post a "no
fonts found in list warning" but I don't see what use case it serves to
return false here.

As spec'ed now, the 'check' method is conflating 'check whether font is
loaded' with 'check if fonts exist and need to be loaded'. I think the
existence check is unnecessary and inconsistent, since if *some* fonts
exist the behavior will be different from none existing.

Or put another way, what's the need / use case for having a "fonts exist or
not?" method?

A sidenote is that I don't think we would ever ship with this behavior
since it makes font fingerprinting trivially easy.

> > Assuming "Flaming Balls of Phlegm" is a non-existent font family, in
none of
> > these cases is a font load needed. The 'check' method should always
return
> > 'true' otherwise authors are going to run into some nasty gothca's with
this
> > method.
>
> Can you describe what gotchas you envision? The current behavior is
> intended to avoid a particular gotcha, that misspellings acted like
> successful loads.

I don't really see the misspelling case as all that common and the author
is not going to get "correct" results no matter what if they are used a
mispelled font name. How is altering the default behavior of this method
helping the author? When rendering some sort of fallback font will be used.

I think the gotchas are that you're introducing a weird inconsistency
between fontlists that include fallback fonts and ones that don't, even
when the same actual fonts are used to render text:

  document.fonts.check("16px HellishVetica, serif") ==> true, default serif
used
  document.fonts.check("16px HellishVetica") ==> false, default serif used

This is more likely that it would seem, especially on platforms such as
Linux that lack the common default font families used in fontlists:

  /* true on Windows/OSX, false on Linux */
  document.fonts.check("16px HellishVetica, Calibri, Verdana")

> > I should also point out here that the "allow system fonts" flag is
> > unnecessary in the 'find the matching faces' algorithm. The spec doesn't
> > really define what it is, so best to remove it I think.
>
> ??? Yes it does.  It controls whether system fonts show up in the
> returned list; that's well-described in the algorithm.  load() sets it
> to false, because it's only concerned with loadable fonts, and system
> fonts are irrelevant and would clunk up the array the promise resolves
> to for no benefit.  check() sets it to true, so you can use the same
> "font" string in check() and your actual code, with system fonts
> included.

Hmmm, that use of this parameter is not included in either the load() or
check() method definition!! And it's not really needed anyways, you just
need to use the font matching algorithm defined in section 5.2 of the Fonts
spec, and for the load() and check() algorithms, treat system fonts as
"already loaded". This is a better match to what implementations are
actually doing. They are not writing separate font matching code just to
support these methods.

>From the matching algorithm:

> 3. Let font family list be the list of font families parsed from
>    font, and font style be the other font style attributes parsed
>    from font.
> 4. Let available font faces be the font faces within source. If
>    the allow system fonts flag is specified, add all system fonts
>    to available font faces.

You really should just combine these and refer to the font matching
algorithm in the Fonts spec. This description doesn't correctly describe
the prioritization of font names (i.e. an @font-face font using 'Arial'
takes precedence over a system font named 'Arial').

Cheers,

John Daggett

​

Received on Monday, 18 May 2015 05:54:06 UTC