w3c / IFT

W3C Incremental Font Transfer
Other
21 stars 11 forks source link

A-la-carte IFT #103

Open skef opened 2 years ago

skef commented 2 years ago

The current spec says:

The collection of IFT technologies utilizes a single shared opt-in mechanism. Each method does not use its own opt-in mechanism; instead, the webpage opts into the IFT technologies as a whole, and the browser and server negotiate to decide which specific method will be employed.

This, and on my reading the rest of the spec, implies that access to IFT facilities is all-or-nothing (beyond the choice between "methods").

This restriction may prevent some services from using any of the new IFT technologies. If, for example, the built-in options for caching were not sufficient for some service it would have to duplicate all of the IFT functionality, presumably with javascript-level code. This is quite restrictive and hinders experimentation that might eventually be folded into future versions of the specification. It's also not in the spirit of contemporary browser technology, which generally allows some control over what happens on the client side via the DOM interface or other Javascript APIs.

It seems as if there are three subsystems of IFT that could provide separate benefits to different implementations:

  1. The scanning of the document to produce a set of subset parameters (code points and features)
  2. The communication protocol with the server
  3. The code that applies an augmentation to an earlier subset or augmentation to produce a new subset font. (And, if it is different from loading a non-subset font, the code that accepts an initial subset.)

Some use cases:

A service wants to use all three subsystems but do some client-side "super-setting" as mentioned in #93. To do that it might include some Javascript that wraps-around or otherwise intervenes between the document scan and the communication protocol to modify the subset parameters.

A service has caching requirements incompatible with the IFT communication protocol. Accordingly, it reuses the document scan and augmentation subsystems but replaces the communication protocol with its own bespoke system.

To increase the likelihood of caching a system uses a coarser grain of subsets and only ever augments those subsets. When subset X has been augmented once and needs to be augmented again, it keeps a copy of X around and re-augments against it. The system therefore needs to intervene both between the document scan and the protocol (to pick the right subset/augmentation combinations) and between the receipt of the subset-or-augmentation and the augmentation code (to provide the right building blocks to the latter).

garretrieger commented 2 years ago

The core, minimum required, part of the specification is just the patch subset + range request client/server protocol. The method negotiation is part of that protocol.

Beyond that the specification does make recommendations on how this might be integrated into a browser user agent, but these are not 'MUST' level requirements. So are not strictly required in implementations. In the example you cited the @font-face part is not strictly required, but section "3. IFT Method Selection" which covers negotiation in the protocol is.

Looking at the three sub-systems you identified:

  1. scanning of the document to produce the parameters: the spec does not currently talk to this at all. I consider this to be out of scope for this specification. Related to this is a javascript API to interact with incremental transfer, the specification currently makes no requirements for a javascript API. I think this is likely something that we want, but I believe this would be best served by being a separate specification.

As an aside on the topic of javascript APIs I would expect that the existing font loading javascript API will be integrated with incremental transfer. The existing API does have a mechanism for specifying the set of characters the font is going to be used to render, today it's used to select appropriate unicode range font faces to download, but I could see that being extended to feed into the incxfer character selection.

  1. The communication protocol: this is the core of the specification.
  2. The code that applies an augmentation to an earlier subset or augmentation to produce a new subset font: this is included in the spec as part of the client side protocol and it's tied pretty tightly to the overall protocol. Specifically the server requirements reference the client side application algorithm. The server is required to provide a response that when fed through the client side application algorithm results in an extended font with a minimum codepoint coverage. (see: https://w3c.github.io/IFT/Overview.html#conform-response-valid-patch) Unfortunately I don't think we can easily decouple these.

Regarding allowing for custom caching, I'll follow up on the caching specific issue.

skef commented 2 years ago

The code that applies an augmentation to an earlier subset or augmentation to produce a new subset font ... Unfortunately I don't think we can easily decouple these.

Can you say a bit more about this? I can see why it might be hard to split the two apart when using the protocol, but I'm not sure why it would be a problem to provide access to the augmentation mechanism when not using the protocol (e.g. in favor of some bespoke protocol).

garretrieger commented 2 years ago

The code that applies an augmentation to an earlier subset or augmentation to produce a new subset font ... Unfortunately I don't think we can easily decouple these.

Can you say a bit more about this? I can see why it might be hard to split the two apart when using the protocol, but I'm not sure why it would be a problem to provide access to the augmentation mechanism when not using the protocol (e.g. in favor of some bespoke protocol).

Ah good point, yes we could probably decouple it just on the client side. Mostly what we'd need to do then is not have the patch application algorithm (https://w3c.github.io/IFT/Overview.html#handling-patch-response) specified specifically in terms of the PatchResponse message and instead move that algorithm to a separate section and give it clearly defined inputs/outputs as I did with the higher level extending the font subset section. Then the existing handling patch response section would call into that new section.

garretrieger commented 2 years ago

Thinking about this some more. I think most of these concerns fall onto the javascript api that would be used to interact with incremental transfer and should be handled there instead of in this specification. For example hooking in a custom protocol would require that a javascript API exists which gives you a way to provide custom code to make the actual network requests in response to a request to augment a font and then provide back a patch that the browser can apply. The existing PatchRequest/PatchResponse provide a fairly reasonable interface already for parts of the system to be swapped out. In the example of implementing a custom protocol the client side custom code would receive a PatchRequest from the browser it could transform that into the custom protocol make network request(s) and then provide back a PatchResponse for the browser to apply.

In this model we can just think of the "server" as running in the browser instead and then you've got a spec compliant implementation that allows the protocol to the actual backend to be swapped out. The server specifications are intentionally pretty vague about how a server actually produces a response so this sort of thing is supported. Additionally the client side algorithm allows for the fetching algorithm to be passed in as an input. This gives lots of flexibility for allowing the browser to have an implementation where it may rely on custom code running locally to produce the response.

skef commented 1 year ago

We just discussed the possibility of adding a draft API to the demonstration platform (presumably hooks into the Web Assembly code).