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

On Thu, Apr 30, 2015 at 6:40 PM, Cameron McCormack <cam@mcc.id.au> wrote:
> I have a few questions/comments about load and check and the tests that
> are done for character coverage using the sample text string.
>
> 1
>
> The “find the matching font faces” algorithm will not include a matching
> font face in its return value if its unicode-range does not include at
> least one of the characters in the sample text string.  The algorithm
> reads like it is written assuming that all font faces have a
> unicode-range attribute, but that isn’t true for system fonts.  Should
> we be checking the actual cmap of the font to see whether we have a
> glyph for a given character?
>
> For example, assuming Helvetica is a system font:
>
>   document.fonts.check("16px Helvetica", "上")
>
> Should this return false, because the font does not have a glyph for the
> specified character, or should it return true as if we treated system
> fonts as having an unspecified unicode-range (and therefore covering all
> characters)?

I'm inclined to say we should assume that unicode-range is set to be
equal to the font's cmap.  The whole point of unicode-range is:

1. to let you skip downloading the font face when you're not using any
of the characters the face supports
2. to let you purposely use only a fraction of the font's characters

If you want #2 for a local font, you can just create a @font-face with
a local() src, so we'll ignore that.  #1, though, is irrelevant if the
font is local; you already have it!  And you have to consult the cmap
at rendering time anyway so you know whether to do fallback or not.
Checking it for check() seems like not a burden.

> 2
>
> For that matter, should a font’s cmap ever affect how load or check
> operate?  If I did:
>
>   var f = new FontFace("Test", "url(Ahem.ttf)");
>   document.fonts.clear();
>   document.fonts.add(f);
>   f.load().then(function() {
>     alert(document.fonts.check("16px Test", "上"));
>   });
>
> per spec I think this should alert true.  It’s a little confusing, since
> the author might think check is actually checking whether we will be
> able to render the given string without using a fallback font, but
> really what it’s doing is determining whether attempting to render that
> string will need to kick off any loads.
>
> I don’t know if the name “check” describes the behaviour of the method
> clearly enough.

Based on the unicode-range you specified when constructing Test, it's
capable of rendering that character.  It's possible that, once a font
is loaded, we could intersect its unicode-range with its cmap, in a
similar way to how I suggest we handle local fonts, but that means
that fs.check(...) with identical arguments can give different results
based on whether a font is loaded or not (as, before it's loaded, we
have to trust its unicode-range).  I don't think this is a great idea.

> 3
>
> In line with the check method meaning “will loads be kicked off”, I
> think it should return true if the list of matching font faces is empty.

It originally did. I changed it to false based on feedback that it was
confusing that the method returns true if you can render without
loads, or if you can't possibly render it at all. ^_^  The current
semantics mean that "true" indicates you can successfully render the
text as desired immediately (assuming you're not lying in
unicode-range), while "false" means you can't - either the necessary
fonts aren't loaded yet, or none of your desired fonts can render it
at all, and you'll fallback to an (undesired) default font.

There's arguments either way, but I don't think either is
overwhelmingly convincing, and I'd rather not churn this.

~TJ

Received on Tuesday, 5 May 2015 18:04:56 UTC