Open jakearchibald opened 3 years ago
In terms of other issues:
Before OT:
Stuff which has a major impact on API design:
Lower priority stuff:
To me, this reads like a disadvantage of local fonts, and an advantage of web fonts. As in, if you want your files to look the same once shared, you shouldn't rely on system fonts.
It occurs for WebFonts as well.
The main issue with the web stack is that it's meant for rendering content and part of its tasks is to make the content feel "natural" in the deployment platform. On Windows, ClearType
might be applied to a font, for instance, to make all fonts look the same based on the operating system settings.
When consistency is important, in e.g. a photo editor, it is important not to apply such modifications, but rather, to let the application handle the rendering (and modification of) the raw font data, so it reflects the designer's intent, on any platform and on any medium, including screens, printed, etc.
Do you think I should reference the different use-cases and ClearType
directly as an example in that bullet point?
Developers may have legacy font stacks for their applications that they are bringing to the web. To use these stacks, they usually require direct access to font data, something web fonts do not provide.
This point seems a bit weak hand-wavy. Is there a more concrete example?
WebFonts do not provide a raw data API. While WebFonts
does not have an API like blob()
, one could read the bytes and interpret in script, e.g. using something like opentype.js.
I suppose that it's not that WebFonts
does not provide the data, it's that the web font rendering stack is meant for a different purpose than this API. There is no WebFont
enumeration API for local fonts, for instance, and second, there is no aforementioned "raw data" API.
Both of those capabilities are needed to be used for a class of currently non-web applications.
The level of access isn't clear here. Maybe:
A font enumeration API, which allows users to grant access to the full set of available system font metadata. π
glyf table for glyph vector data, the GPOS table for glyph placement, and the GSUB table for ligatures and other glyph substitution
Nit: Only "glyf" is linked to its definition. Maybe link to GPOS and GSUB too? π
Ensure UAs are free to return anything they like. If a browser implementation prefers, they may choose to only provide a set of default fonts built into the browser.
Enable access to all browser-allowed font tables (may vary per browser)
These two sound bad on the surface as they encourage breaking interoperability. Maybe detail why these are desirable?
They are detailed in the Privacy and Security Considerations. WDYT of something like:
* Ensure UAs are free to return anything they like. If a browser implementation prefers, for privacy and security, they may choose to only provide a set of default fonts built into the browser.
- Logging of likely-available fonts to improve server-side font rule generation.
- Scripts to generate style rules based on "similar" local fonts, perhaps saving a download
I don't really understand these. Given that the process may involve a permission prompt, this sounds pretty intrusive vs just specifying a long list of fonts in
font-family
.
The idea is not to render the fonts. A long list of fonts in font-family
is not precise enough.
For example, instead of showing "Arial", one could want to present "Arial MT Bold", "Helvetica Bold", etc.
Not all fonts have "Bold" as an available style.
The context that's missing is that the kinds of applications the enumeration API enables is for the creation of font-based content. I suppose "user-generated content" is not descriptive enough.
Would a preamble before the bullet list explaining creation vs consumption be good enough context?
const fonts_iterator = navigator.fonts.query();
Nit: In JavaScript names are generally camelcased. Same goes for
font_select
in the next example. π
option.value = metadata.fullName;
You don't need this line. If no value is provided, it defaults to the text. I changed the example in #47 It is actually preferable to use
postscriptName
as value, because according to the spec, it is in ASCII.
It is used as a unique identifier of sorts. I'll find some way to explain that.
document.body.appendChild(font_select);
Kinda nitty, but this code produces a useless select if permission isn't granted. Maybe move the
<select>
creation/append until after permission is granted? π
option.setAttribute("postscriptName", metadata.postscriptName);
We shouldn't encourage the use of non-standard attribute names. π
If in doubt, pass code through https://prettier.io/playground/. Oh actually, it could just be:
// Slice out only the bytes we need: the first 4 bytes are the SFNT // version info. // Spec: https://docs.microsoft.com/en-us/typography/opentype/spec/otff#organization-of-an-opentype-font const sfntVersion = await sfnt.slice(0, 4).text();
π Thanks! Much more concise and legible!
FontFaceSource
isn't an iterator, butFontFaceSet
is. πThe
FontFaceSet
is exposed in pages asdocument.fonts
, which doesn't seem like a good fit for this feature as it's of the system, not of the document. π That's a good point. I'll add it to the explanations."ensure identical behavior across browsers" - this seems to clash with the earlier claim "UAs are not required to provide table data exactly as it appears on disk".
For WebFonts, Chrome and Firefox uses the OTS library to filter some tables out from font files for security purposes. Those tables in theory should not affect what's rendered, but should prevent code from a foreign origin embedded in font files to break the font rendering code.
While we did consider it before, in the case of local fonts, Chrome has decided to return the data verbatim from disk. If the system fonts have been compromised, that means that the system has already been compromised. However, Perhaps we should let UA's make the call on their own? It's a non-normative option.
Also, it isn't clear what the conclusion is for this section. Is it being considered in future, or dismissed?
We're not considering them as part of this effort yet. That said, there could be shaping/metrics data we could expose as additional metadata, perhaps saving the cost on developers loading e.g. HarfBuzz or fontconfig.
I'll add a sentence with this explanation.
It isn't clear to me from reading this if the API presented is exhaustive. Eg, is there anything else hanging off
navigator.fonts
or is it justquery
? For now justquery
. In the future, we might expose other things. Top of mind right now for me:
navigator.fonts.requestPermission()
navigator.fonts.chooseFonts()
It might be worth adding an MDN-like description of the API, aimed at developers.
Styling with Local Fonts
It isn't clear to me which bit of metadata I'd use in CSS's
font-family
. Ah. Yes. One would use@font-face src: local
option, with eitherfullName
orpostscriptName
. Description here
I'll re-work the example.
My assumption would be
metadata.family
, since that's closest in naming tofont-family
, but the example suggests otherwise, as that's the one bit of metadata that isn't used.
Your assumption is correct. And yes, that metadata isn't used in this example. One could use it to group fonts together.
Can fonts contain direct personal information that might be exposed here? Eg, name of the user in some kind of licencing information?
The fonts can contain licensing information. And these can be identifying, but it won't be the name of the user. It would be the name of the author of the font. That said, these are required table entries as defined by the OpenType spec under ID 13.
Small things in the explainer:
To me, this reads like a disadvantage of local fonts, and an advantage of web fonts. As in, if you want your files to look the same once shared, you shouldn't rely on system fonts.
This point seems a bit weak hand-wavy. Is there a more concrete example?
The level of access isn't clear here. Maybe:
A font enumeration API, which allows users to grant access to the full set of available system font metadata.
Nit: Only "glyf" is linked to its definition. Maybe link to GPOS and GSUB too?
These two sound bad on the surface as they encourage breaking interoperability. Maybe detail why these are desirable?
I don't really understand these. Given that the process may involve a permission prompt, this sounds pretty intrusive vs just specifying a long list of fonts in
font-family
.Nit: In JavaScript names are generally camelcased. Same goes for
font_select
in the next example.I also agree with @domenic that this isn't an iterator, so maybe call it
systemFonts
?You don't need this line. If no value is provided, it defaults to the text.
Kinda nitty, but this code produces a useless select if permission isn't granted. Maybe move the
<select>
creation/append until after permission is granted?We shouldn't encourage the use of non-standard attribute names.
Instead, either use a data attribute:
Or create associated data:
Some of the formatting here is a little unusual. I'd go with:
If in doubt, pass code through https://prettier.io/playground/. Oh actually, it could just be:
FontFaceSource
isn't an iterator, butFontFaceSet
is.The
FontFaceSet
is exposed in pages asdocument.fonts
, which doesn't seem like a good fit for this feature as it's of the system, not of the document."ensure identical behavior across browsers" - this seems to clash with the earlier claim "UAs are not required to provide table data exactly as it appears on disk".
Also, it isn't clear what the conclusion is for this section. Is it being considered in future, or dismissed?
It isn't clear to me from reading this if the API presented is exhaustive. Eg, is there anything else hanging off
navigator.fonts
or is it justquery
?It might be worth adding an MDN-like description of the API, aimed at developers.
It isn't clear to me which bit of metadata I'd use in CSS's
font-family
.My assumption would be
metadata.family
, since that's closest in naming tofont-family
, but the example suggests otherwise, as that's the one bit of metadata that isn't used.Can fonts contain direct personal information that might be exposed here? Eg, name of the user in some kind of licencing information?
π’
Nice callout at the end, thanks for adding that.
I'll create issues for things that might need further discussion.