- From: John Daggett <jdaggett@mozilla.com>
- Date: Fri, 15 May 2015 14:10:35 +0900
- To: "Tab Atkins Jr." <jackalmage@gmail.com>
- Cc: www-style list <www-style@w3.org>
- Message-ID: <CALYZoVMfPMcQWt5bE8QF+UR01mY4+tG_gb6RxktAf9AxKsUibA@mail.gmail.com>
I think we need to be careful to distinguish the load/check methods of FontFaceSet from the implicit loading that occurs when text on a page uses downloadable fonts. Specifically, the "matching" behavior of the load method is *not* the matching behavior used by the implicit loading mechanism which effectively only loads fonts as needed to support page content. They don't have the same behavior and, after discussing this with Cameron a bit, I think there are good reasons for them not behaving the same way. I think a couple examples will illustrate this. Simple implicit load example: @font-face { font-family: fontA; src: url(fonts/simple.woff); } <p style="font-family: fontA">This is a simple case</p> When the page is loaded and layout is performed, the 'simple.woff' font resource will be implicitly loaded. *If* it contains Latin glyphs, it will be used for the content of the paragraph element. Complex implicit load example 1: @font-face { font-family: fontB; src: url(fonts/bigfont-fallback.woff); /* no unicode-range descriptor ==> full range of Unicode codepoints */ } @font-face { font-family: fontB; src: url(fonts/bigfont-latin.woff); unicode-range: u+0-2ff, u+21??; /* latin and arrows */ } <p style="font-family: fontB">This is still a simple case</p> When the page is loaded and layout is performed, the 'bigfont-latin.woff' font resource will be implicitly loaded. If it contains Latin glyphs for the characters in the paragraph element, it's the *only* font resource that will be loaded. Complex implicit load example 2: <p style="font-family: fontB">Using the ⇒ arrow!</p> The content here uses the right double arrow (U+21D2), so when layout is performed the 'bigfont-latin.woff' font resource will be implicitly loaded. If this font resource doesn't contain a glyph for the double arrow, 'bigfont-fallback.woff' will also be downloaded. So depending upon the content, more font resources may be loaded. The load method of FontFaceSet on the other hand will load *all* faces for a given family that might contain glyphs for a given string, based on the value of the 'unicode-range' descriptor: document.load("16px fontB", "This is still a simple case").then(function() { // at this point both 'bigfont-latin.woff' and // 'bigfont-fallback.woff' have been loaded }); This is less efficient than the mechanism used by the implicit load mechanism but it's conservative, which is important for the actual use cases, such as canvas text drawing usage: document.load("16px fontB", "Using the ⇒ arrow!").then(function() { // all possible fonts have been loaded at this point ctx.font = "16px fontB"; ctx.fillText("Using the ⇒ arrow!", 50, 50); }); The alternative would be to require the 'load' mechanism to mimic the way implicit loading works but I think that's a bad idea, it adds unnecessary complexity. It would also make check unfeasible, since it couldn't evaluate whether all necessary loads had completed or not. Tab Atkins wrote: > > 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. No, load/check should only consider whether a load is needed or not. System fonts are by definition already loaded. Downloadable fonts are loaded based on the coverage of the unicode-range descriptor. The cmap is irrelevant here. This is the key difference with the implicit loading mechanism. > > 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. This is a bad way to describe load/check. They are *not* guarantees of glyph coverage, they are simply guarantees that all possible font loads have already completed. We should be careful not to conflate these methods with any sort of glyph coverage assurance. I agree strongly with Cameron, step (3) of the algorithm for 'check' should return true and not false as stated in the spec. All the examples below should return 'true', since no font load would occur when attempting to render text in these cases: document.fonts.check("16px Helvetica") ==> spec: true document.fonts.check("16px Helvetica", "") ==> spec: false document.fonts.check("16px Helvetica", "hello") ==> spec: true document.fonts.check("16px Flaming Balls of Phlegm") ==> spec: false document.fonts.check("16px Flaming Balls of Phlegm", "") ==> spec: false document.fonts.check("16px Flaming Balls of Phlegm", "hello") ==> spec: false 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. I think it would be a good idea to include a note about load/check being different from the implicit load mechanism, along with an example illustrating this point. 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. Cheers, John Daggett [1] http://dev.w3.org/csswg/css-font-loading/#font-face-set-check
Received on Friday, 15 May 2015 05:11:04 UTC