W3C

– DRAFT –
Web Fonts Working Group Teleconference

12 September 2023

Attendees

Present
bberning, chris, drott, Garret, Rod_S, RodS, Vlad
Regrets
-
Chair
-
Scribe
myles, RodS

Meeting minutes

hello

<jimmym> testing.

Garret: I'll give an overview of what is patch subset. It's relevant.

Garret: we have currently proposed: incremental font transfer. Idea is taking a font, transferring parts, then transferring more of it. Slowly building up the font. Goal: Save bytes

A More Static Friendly version of Patch Subset

<Vlad> https://lists.w3.org/Archives/Public/public-webfonts-wg/2023Sep/0003.html

Garret: There are 2 ways to do this. 1. Patch subset, 2. range request (or perhaps binned)

Garret: For patch subset: The browser looks at all the code points. It sends an HTTP message saying please give me a font for these code points." If it needs more, it will send another message, saying "give me a patch - i have these, and i need some other ones"

Garret: There is a dynamic server side involved. It will look at this message and produce the appropriate patch on demand

Garret: There are repeated concerns raised from different parties about requiring a smart server. Most people want to just stick static files on a server or CDN. A server-side computation makes things complicated and costly

Garret: I've been trying to think about improving patch subset so it can work both statically or dynamically if so desired. Can we make it fully compatible with sticking font files on a CDN? And have an option for services that want a dynamic reactive version as well. That's what motivated this proposal.

Garret: Let's jump in to the idea. Patch subset works by:

Garret: You have a font, and you have a subset to add to the font, and you get a patch that upgrades the font. We'll keep the framework, but focus on the message.

<RodS> Just in case not everyone has seen it, https://lists.w3.org/Archives/Public/public-webfonts-wg/2023Sep/0003.html is a written description of the proposal Garret is describing

Garret: Proposal: The first font file will include a custom table, which will include a map of additional subset patches that are available

Garret: ... to a URL which hosts that patch.

Garret: This way, you can form a graph the client can walk to get whatever it needs. The graph of patches can be stuck on a server and served statically

Garret: The nice thing about this change is it obfuscates that message which normally would have been formed dynamically by the client, and makes that an implementation detail. Dynamic version: The URLs point to URLs the server can respond to dynamically

Garret: There are 2 main drawbacks we'll have to deal with

Garret: 1. We can't download patches in parallel

Garret: If you need 2 subsets, you have to get one, resolve it, then get the second one, then resolve it. you can't apply the second patch on top of the first one.

Garret: 2. For CJK fonts, if you did any fine-grained segmentation, the graph will result in being enormous. Might not be viable to host in a static context.

Garret: I have ideas about how to work around these.

drott: Does this change anything about the HTTP wire protocal? Are there headers?

Garret: No. It's pure, normal HTTP. No preflights for the custom header. Don't have to use POST (to avoid preflights)

chris: So we don't need query any more?

Garret: Correct.

drott: This is better for proxying, where proxies don't forward the headers right

Garret: This makes it much more predictable for caching, since whatever set of files you form, you can do it in a way that's compatible with how you want to cache them

Garret: if you want to make sure that some subset is always available, you can do so

Vlad: Consider a user looking at the page that's dynamically updated. Those dynamic updates generate requests. If a second user joins the page at the same time, can you trace the graph to determine what the state of the incremental font should be?

Garret: If you had a dynamic implementation, you could restart someone somewhere else in the graph

Vlad: could the server do it in the background?

Garret: yes. You'll probably watch what's being requested, and make that available as a static URL. And you could change that over time.

Garret: But with a static one you wouldn't do that

<drott> myles: don't the urls have to be baked into the font?

Vlad: If you have the graph generated as you update the font, you could update the static subset to make it larger

<drott> garret: when you serve the files, you can update them

<drott> myles: in the "dumb server" approach - there's the initial request, then following one: what's the sequence relationship?

<drott> garret: there's a graph: from the first one, you can get to the next layer - the first point will point to the additional fonts

<drott> myles: I would compute the optimal way through the graph?

<drott> garret: you only see the next layer

<drott> myles: what if I need to fetch multiple sets from the next layer?

<drott> garret: that's the issue of parallel downloads I'll talk about later

Garret: one thing I want to point out: for CJK, this is a lot more challenging. But this scheme works well in the non CJK space. Imagine full extended latin font (with diacritics)

Garret: You get the initial font which just has ASCII. Beyond that, you probably only need 1 subset. Like, Polish can be one patch, and Vietnamese can be another patch. With a good segmentation, you can probably get what you need in 1 hop, maybe 2

Garret: There are ideas of parallel downloads.

Garret: Let's talk about the parallel case

Garret: The typical non-CJK use cases, the parallel cases are not important. But let's try to solve it for CJK

Garret: If we have the option to be backed this dynamically, we could have an optional feature to have hte client create a merged url. There could be a URL template, and the client could concatenate multiple identifiers. You'd need a dynamic server. But the client could get X out of Y subsets and get them all in a single patch

Garret: The other approach is more useful for static serving. The way we serve fonts today is we would break them up to actual subsets and use unicode range to have the browser pick the ones it needs. Depending on how you cut that subsets, you can break layout rules between 2 characters. Most fonts can still be split up to some degree without breaking anything. Usually there are independent chunks.

Garret: So, before you apply this graph subset thing, you could break up the font as much as possible without affecting layout rules. This has a positive impact on reducing the size of the graph. If you can split the font into 3 pieces, it's a huge divider on the total number of graph nodes you need. This works well for CJK, where most CJK fonts will be fairly aggressively subdivided without breaking anything

Garret: Especially for the CJK parts. So you could have a hybrid solution where you chunk the font into chunks, then use augmentation within the chunk to get what you need. Ideally it would work better than pure unicode-range. This helps with parallelization. Also, the different chunks can be downloaded in parallel. If you choose chunks intelligently you should get pretty good performance

drott: You are suggesting an approach where an element of dynamic generation of the URLs, where you have something like tags, and to form a URL you would combine multiple tags

Garret: Yes. That's similar to current patch subset. It's just forming a regular URL. No custom headers.

Garret: Purely optional.

drott: It depends a little bit how you would define what's in the table and how you navigate from one layer to the next. One approach there is to ... generally that table would be a definition of ranges. or sets of codepoints (how to get from one layer to the next)

drott: If the ranges can be overlapping, there would be an argument for choosing which overlapped set to use, you could express the same thing with that

Garret: I should have mentioned that. It's legal to have sets that are supersets of other ranges (or overlapping). You might get too many entries, though. 2^n where n == 100

Garret: If you have a good idea of what's common, you can stick some common ones in there

Garret: originally I talked about it as a map from a subset to a URL. But you'll probably have a header saying "here is some number of URL templates, and here is where you can substitute identifiers into it". This is mostly for performance reason. You have a set of URLs with a common prefix, you don't want to repeat that hundreds of times in the font table

drott: It's a tradeoff between complexity and granularity.

<drott> myles: first request must include rules that cover anything in the entire font?

<drott> Garret: first request doesn't have to give you all layout rules? it gives you a font with a basic set, common CJK set? in a latin oriented font, core ASCII - enough to get you started. As you patch in, you'll get more layout data.

<drott> Garret: it covers all data, not table- or format- specific.

<drott> myles: in the first response - there must be rules for how to fetch the rest of the font?! The font file tells me I need to download two different things.

<drott> myles: you say, I can don't download them in parallel - but why?

<drott> myles: I download two things in parallel - now I have to branches, one with 13, one with 17?

<drott> myles: what do I do?

<drott> Garret: that's why I am saying parallel downloads would be a problem

<drott> myles: So I download the one that has the 13, and this one would tell me where do I download the next ones?

<drott> Garret: yes

<drott> Garret: so that's why I was proposing you start with a set of splits defined by unicode-range

<drott> myles: and the other option, as I mentioned: forming sets / merged requests

<drott> ^ was Garret:

<Zakim> chris, you wanted to ask about axis-subsetted variable fonts

chris: supposed you had a variable font that was subsetted down. Could you use this mechanism to say "actually i just want a single weight"?

Garret: yes. When I say "code points" what i actually mean is general subset. That's a benefit of this: it can deal with the variation stuff.

chris: I think that dealing with very large many-axis variable fonts is important

Garret: I agree. that needs to work.

Garret: Imagine you have a font and you don't even care about the code points - you can use this just to instance

Vlad: That's something else we need to discuss. If you want to do the same thing with another approach, it has to be specified. You can't expect people to know what the next part of the discussion.

Garret: I raised a comment on skef's draft. "What do you want to do with variable fonts? probably something"

drott: If I understand right, you're suggesting a new key type for requesting the next url. If you thought about unicode range, there are code points. It's clear to the browser which code points are missing. But for variable fonts, you don't havea that information from the CSS perspective. Initially you'd need to know which axes exist, even if the first font doesn't have support for these axes.

drott: Then there has to be a way for the browser to request a range of the present axes

drott: So CSS needs something. "What is the active set of axes for this font"

drott: So when this interacts with font-variant that uses these axes....

Garret: The information that comes back with the first font request, it says "this is what's available of the entire font". We'd need to do something similar here. Variation space is defined in fvar.

<drott> myles: the initial font doesn't have a full cmap - similarly, it wouldn't have full fvar

<drott> myles: so we'd need the possible wider fvar in the new table

Garret: The browser then says "i'm attempting to render a font at this point in the variation space, so i'm going to request what i need"

Garret: Browsers will say "these are the instances that i'm attempting to render at. Go fetch what I need"

drott: Consider font synthesis for italics. It's tricky. You don't know what the font has.

drott: If you assume every patch subsetted font has all the variations, then you might be wrong, but you won't notice that you're wrong until the request came back

drott: The original request will return information about the variation space. You could ship a skeleton fvar table (slimmed down)

drott: This is the visibility of transitions of the graph where you can go

RodS: Question: Could you assemble it so that you do have patches which could be applied arbitrarily? If you wanted, it might actually be possible to apply 2 independent patches

RodS: You could be able to build something like "i'll ship you a 0d glyph an patch in pieces of it"

Garret: You lose properties about not caring about the font format

RodS: You'd want it on the table for CJK

RodS: It might be possible.

Garret: The patch type is a content encoding. There could be more than one. There could be one that annotates itself that is able to apply multiple patches to the same thing

Garret: In the CJK case, that actually probably is possible

Garret: You'll need a custom patch format

RodS: if you don't reference the shared parts, it might be possible

Garret: it relates to the work i did last year about a custom brotli encoder. I limited the dictionary of the window that the encoder could see, to form my own diffing logic

<RodS> I may have misspoke, but ^ should be if you don't modify the shared parts as you apply patches

Garret: That might be do-able

sergeym: I was making sure that patch can be applied independently of everything else. I want to save space. Specifying the patch can be applid universally, you can make it part of the patch, and you can do it without changing the font. This is not what we have, but it's already applied.

sergeym: If there is a patch that is applied, and the patches are different, but 2 patches may have a large part big part in common. Outlines are independent, but other parts are different, then you can save on download.

<drott> myles: the direction this conversation was going: being able to be applicable 2 patchsets independently

<drott> myles: it would be useful, and similar to something i had in mind with initial proposal / range request

<drott> myles: the encoder can make flexible decisions - is my claim

<drott> myles: this is were I experimenting with patch subset - getting to a point where independent patches would work in parallel

<drott> myles: we are not tied to brotli, if there's a different compressor that can do this

drott: If we want to design something where we can apply multiple patches in parallel, assuming we're still on brotli, we'd need to define segment boundaries. There would be only parts visible to the decoder and encoder that the data is based on. In many of these situations we end up defining segments that are dependent on knowledge about the font format. At least on the sfont level, we'd need to define ranges

drott: I'm a bit concerned that we shouldn't get into the space where we are closely dependent on the font format

drott: I think you need to be aware of at least the loca table. you need to be able to stick glyphs in good places relative to other glyphs. You need the loca table.

<drott> myles: loca and cmap together - as loca itself woudn't be useful

myles: loca and CMAP

Garret: If this solves the CJK problem, it might be a better tradeoff. It's worth investigating a fancy encoder. We'd want to look at as few parts of the font format as possible

drott: Then we're already in fvar, to an extent

<drott> myles: if you have a smart server, you can treat it all as bytes

<drott> myles: if you want a static / pre-computed set - you need make good files by looking at the font format

<drott> myles: there's two different levels of requirement - "must-level" requirement - and a set of requirements for getting good performance

Garret: If we had a font-specific encoding, it could be a separate document

myles: or an appendix

Garret: yes

Vlad: we need to be more generic than that

Vlad: if you want to subset along the variation axis, for something that would enable one font out of a colleciton, then you might... these generic recommendations would be appropriate. Anything else about specific subsets guided by content

<drott> myles: content related things shouldn't be in the set

<drott> myles: language related things can be in the spec - like a recommendation for which are the most common chinese and where to put them

Garret: It may be possible to do this without knowledge of the font format, but i think it's necessary

drott: If we break things up by things in the font format that are unlikely to change, or well-established, but that's fine. But if we go to subtable-level of particular tables, then we are creating a dependency which makes it more difficult to evolve the font format

drott: loca and CMAP are unlikely to chnage

Garret: behdad is proposing cubic glyphs, but that might not be affected

Vlad: to be font-format independent, all we need to do is to say "here is an external document that determines font format. A subsetter should be able to read a font file and produce a subset that is conformant with that document.

Vlad: The internal working of the subset would not be in-scope.

Garret: If there was a new patch encoding, imagine you have a font and you have inserted some number of glyphs, you don't know which ave been inserted, how do you encode a patch which builds on top of it? it needs to know what's already there.

<jimmym> FYI: TPAC break time is 11-11:30 (started 7 minutes ago). If anyone needs coffee, snack, bathroom it's out the door next to the registration desk on 1st flooe.

Vlad: for a client, you have to know what is the original font. When you ask for a font, you don't know what's in there, until it's finished downloading. This concern is about an independent patch. If you have 2 patches, and you want to apply them in either order, the patch decoder needs to have knowledge about "go look in loca, then change the bytes that it points to"

RodS: you could go back to tachyfont. You could choose to use it in a model where you say "my initial skeleton has a long empty glyf table, and my patches fill it in"

Garret: That would solve the problem

RodS: It seems at least possible to do this at the byte-level

Garret: If you fix the addresses of all the byte data, it might be possible

<drott> Rods: I believe we're suggesting serial bootstrapping - root font, + things that you can go and get. that means there'll be two roundtrips

<drott> RodS: Could we move some of that to CSS - place the initial fan-out there? So we'd avoid the extra roundtrips?

Garret: agrees the mapping could be in CSS, worth exploring

Garret: just declaring what's in subset and a way to get a url

(discussion of filing GH issues, consensus we will)

Garret: Garret will investigate independent patch encoding, brotli or otherwise

Garret: Investigate the map to subset available outside the font, such as CSS, to get the client started quicker

Garret: no spec proposal yet so many of these things will come up as we write real specese

drott: perhaps also overlapping ranges vs merged?

Garret: we should at least note it's allowed

Garret: might be useful outside CJK, you need several things together

Garret: we've talked about parallelism, second issue, somewhat related

Garret: we have a graph where at each step you can take multiple paths, it can get big. 10 pieces as a full graph with every possible traversal yields ~300k paths so there is work to do to reduce that.

Garret: independent patching may be useful here, sometimes you can grab in any order

Garret: furthermore, we can pre-split the font at safe points (editorial: where layout isn't damaged)

Garret: if you are using dynamic serving you have the option to not pre-generate some

Chris: what's presplitting?

Garret: 10 pieces naively is 9!. If you can cut the initial font in half it's 4! + 4!, which is dramatically smaller.

Garret: For example, a latin+arabic font might be amenable to splitting

Garret: independent patching could be game changing here

Garret: lastly, why do this vs iftb

Garret: the key advantage is it's not just outlines that get cut up. Outside CJK outlines are not the dominant user of space. Variable fonts, complex layout (editorial: ex Arabic and Indic), etc

Garret: that's my pitch! Early stages, I think next steps are a more formal proposal. We can adopt much of the patch subset text, dump some, likely reuse sparse bitsets to specify codepoint subsets.

Garret: Nice to keep some of the work we've done to date :)

Vlad: does anyone have concerns with the proposed approach?

Garret: +1, reasons to NOT go down this path?

Chris: I understand the goal to have good caching. I worry improving caching means worse perf for the individual users. Instead of getting exactly the bits they want they have to do work. We're making a tradeoff and we shouldn't push it too far.

Chris: if it's too degraded nobody will use it, akin to the conventional wisdom of "No CJK webfonts" (editorial: in the past)

Garret: I think you can still have fine grained segments

Chris: We have a dial to turn, this reduces my concern here

Garret: Agrees, that's a good benefit

Myles: speaking with someone who serves fonts they said cacheability was deal-breaking, if it's bad they cant' use this

drott: if you think about self hosting it's a big step to go static => dynamic, suddenly load spikes, slashdotted etc becomes hard

Myles: we discussed cutting up by characters, or ranges of variation axes (subspaces). Mentioned it's unfortunate to compute glyph closure. Could we have a third way, glyph by glyph.

Garret: worth thinking about. Being able to do subsetting after glyph closure is beneficial for some fonts.

Myles: for some fonts

Garret: indeed, for example icon fonts.

Rod: emoji too

Garret: codepoints don't work too well in that case

Myles: maybe it's not worth the complexity

Garret: worth thinking about, will file another issue

drott: when we break up by axes or gid's or new concepts other than codepoints we need new algorithms to integrate that with the UA, when should it do that?

Myles: ...and glyph ids might shift...

(discussion of fixing glyph ids)

Chris: impact on rendered glyph caching?

drott: a new font probably drops any such cache

drott: perhaps we could optimize that, probably not in a first implementation

Myles: we'd need a new algorithm ... that's true, to do shaping you need the rules but not the glyphs

Rod: reintroduces serialization

Myles: first horizon agrees on gids

<drott> RodS: if we declare the initial fan/horizon in CSS - ...

then we don't have to do serial requests on startup

<drott> myles: it's a little bit scary - as it becomes font-format / technology specific

myles: if they just point to a font and don't turn on the new stuff ... it won't quite work

chris: should we resolve to proceed?

(consensus we do)

garret: suggests a draft PR with updates

vlad: suggests we explicitly accept the proposal and decide to proceed with evaluation, drafting spec changes

vlad: opening vs closing the door

myles: lets be explicit this is *instead* of the prior path

vlad: back when we had iftb initially presented we discussed it replacing range request. We never formalized elimination of range request.

myles: I thought we did

vlad: we didn't capture in writing, so the second resolution I would like to make is that range request is replaced.

myles: concurs

RESOLUTION: RESOLVED

RESOLUTION: replace range request with a more static friendly approach

RESOLUTION: draft specification for a static-friendly patch subset mechanism

RESOLUTION: Garret shall come up with a cool acronym

Garret: should we move on to next agenda topics? e.g iftb

Vlad: Hard to discuss iftb w/o skef

Garret: should we give an overview, review concerns, etc?

Chris: would find ^ useful

Vlad: can we share the PR on screen?

(discussion veers toward conformance testing)

Garret: perhaps there is no server conformance now

Vlad: maybe just sample responses a client should handle

Garret pulls up a PR!

<Garret> Link to preview of the IFTB PR: https://pr-preview.s3.amazonaws.com/skef/IFT/pull/151.html

Garret: Skef worked to develop an alternative to range requests that avoids CORS preflight

Garret: also, range request downloads the file up to glyph data then stops the connection. Http and browser people suggest this is not good behavior. IFTB tries to focus instead on static files and take advantage of http/2 efficient multiplexing of many requests on a connection.

Garret: you take the glyphs in the font, bin them, map from glyph id to bin index, and each bin has a file on the server

Garret: uses the old trick of zeroing glyf which then transfers efficiently

Garret: client resolves text to glyph ids, figures out what urls to fetch, then merges the chunks into the font

Garret: introduces a new opentype tag to indicate special handling required, just ordering and the new glyph mapping table. IFTB defines a chunk format, a header in front of glyph data.

Garret: There is also a map from layout features to additional bins, e.g. small caps might have a bin or bins

Garret: (possibly oversimplifying)

Garret: and that's the gist of it! You figure out what chunks you need, fetch, and integrate into the font.

Garret: This is effectively a subset of the proposed mechanism. If we can have independent patches we can fold the ideas together.

Chris: the whole handshaking, how to decide what method, etc business goes away?

Garret: yes

Garret: we would have a format or tech keyword, just one

Garret: we should demonstrate it, but I believe we can match IFTB from a perf perspective

Garret: I worked with Skef to make a demo of IFTB

Garret: no public url but code is on GH

Garret: in demo IFTB is using wide chunks so it performs similarly to unicode-range. Smaller chunks might help. ALso the skeleton has a number of things where you pay per glyph, hmtx, etc.

Garret: There are opportunities to further tune, but I think we would land somewhat better than unicode-range, significantly worse than patch/subset.

Chris: demo shows perf but not impacts on rendering fidelity

Garret: good point

Garret: does show it works, client implementation wasn't too bad

Garret: That's an overview, is there anything we should talk about now? It's a bit difficult w/o Skef

Vlad: it will be helpful to compare side by side with the proposed update, maybe we can reduce to one mechanism

Vlad: important to keep the dial of using finer buckets for higher performance

Vlad: even if that was less cache friendly

Garret: last thing to discuss is conformance

Vlad: Lunch is in 30 minutes, early lunch and then we discuss conformance testing?

(the room is pro-lunch)

(discussion of what to have for lunch)

<jimmym> FYI: TPAC break time is 11-11:30 (started 7 minutes ago). If anyone needs coffee, snack, bathroom it's out the door next to the registration desk on 1st flooe.*

<jimmym> oops

<jimmym> (*dinner) was what I meant to type

<jimmym> Vlad proposes https://restaurantehummo.com/

<Vlad> The meeting will resume after lunch break at 14:30 CET

(some discussion of conformance, use of woff2 test suite or inspiration)

Myles: we need to deal with the css font loading (javascript) API and how it should handle IFT

<myles> Myles: it is a requirement for the test suite to function

vlad: as we put normative (must/must not) statements into the spec we need to define how to test each one

garret: we've already started marking spans with test ids so we can begin to ensure those tests actually exist. Must remember to do this in the modified spec too.

myles: Trying to imagine the test suite. We could make a lot of fonts, constellation of files with links, test suite could verify augmentation goes from file to file and detect sentinel data ... fine. Makes sense. Doesn't test smart server; do we need to?

garret: from the specs perspective it doesn't matter, just urls with responses

myles: test suite is conceptually clear then

garret: no smart server in spec simplifies considerably

vlad: woff2 took ~2 years to completion and then 3 more for conformance test suite

garret: would prefer not to wait that long

vlad: and after conformance of woff2 was done we had to wait for second implementation

garret: hopefully we can be faster

rod: what second implementation?

garret: Chrome and hopefully one more user agent

myles: cannot comment on future products or releases

garret: we will ping Mozilla too

vlad: woff2 had many browsers but they all shipped one library, the Google reference implementation

(discussion of whether an open source implementation that is reused counts; consensus not)

garret: perhaps it's not a browser as the second implementation

rod: for brotli we just paid to have a second implementation written from the spec

chris: Mozilla has a repo where you can ask for standards positions

<myles> WebKit/standards-positions

(discussion of seeking Mozilla involvement in IFT in general)

garret: we won't seek formal positions quite yet, need to advance new work identified today

garret: testing concerns are DONE

vlad: perhaps we can quickly go through open issues and close range request issues if they no longer apply

Closed w3c/IFT#110

w3c/IFT#109 retained

w3c/IFT#74 closed

w3c/IFT#79 closed

w3c/IFT#67 closed

w3c/IFT#61 closed

w3c/IFT#60 closed

w3c/IFT#59 closed

w3c/IFT#58 closed

w3c/IFT#34 closed

is w3c/IFT#101 Shared Brotli ID is expired still relevant?

garret: it has an incomplete section that may not be complete soon

(compression jokes)

garret: will followup with them about perhaps finishing this and publishing w/o the missing content

(further compression jokes)

w3c/IFT#103 is valid in as much as it covers css font loading but it's not entirely obvious, needs either cleanup or closing in favor of a new issue. Garret will take care of it.

garret: TAG had some discussion, I will update them with new current state. Hopefully some commenters will be pleased.

garret: issues complete!

vlad: and that brings us to the TAG review comments

vlad: two main issues

vlad: 1) making our implementation more cache friendly, which is in flight with Garrets proposal

vlad: 2) font-specific solution shouldn't be a deal breaker, not being generic enough shouldn't block

vlad: woff1 opened the door to web fonts and showed the value of font specific tech, leading to woff2

garret: I see a strong argument for font-specific IFT

vlad: would like to proceed with a cache-friendly model, and not block on need for smart server

garret: spec will no longer require a smart server

garret: also not using custom headers, http extensions

garret: client *does* have to understand fonts and know how to interact with themn

chris: the domain-specific knowledge is key to making it a *lot* smaller

vlad: serving incrementally is about usability. You might server the whole thing but in increments.

garret: broken subsets are common today, this fixes them

(See w3ctag/design-reviews#849 discussions)

myles: in the old model the font creator doesn't have to know about serving, just hand it over and it may get chopped up ... it's fine. So, what is the deliverable from creator to the customer who hosts the font?

myles: how do folks make the set of files they need, would the creator establish a set of files?

garret: relative urls help

garret: you get a set of files

garret: and you can upload them. Perhaps there's a simple open source cli that does it.

rod: I imagined it with the public cli, you run it and get some files you can uplaod to a cdn or w/e

drott: did you see the responsibility for segmentation falling on the font creator or ...?

drott: if there is a cli tool it's largely a question of licensing, are you allowed to slice and dice

myles: right now font files have no urls, the urls are in css. What if, as brought up earlier, the extra info wasn't in the font, it was in css or on the server on it's own.

(discussion of this, how it might work to avoid baking urls into the font)

myles: we have two populations, one very comfortable with urls and another less so

garret: you could bake identifiers in but not actual urls, those go outside, say a pattern in css

drott: if you consider dynamic generation with urls that might have security implications

chris: we had a notion of overdelivering to reduce fingerprinting and tracking before, how does that fit now?

garret: might need a minimum chunk size on the client side. Maybe it's invalid to declare on single character urls.

myles: or the UA over-fetches

garret: single char per url is probably over-granular

myles: if I need two patches maybe I don't always take the patch with the most codepoints, but that fights against caching.

garret: if we can have independent patches the graph shrinks

myles: it's still not a tremendously satisfying answer

(some discussion of how this compares to unicode-range which also allows specification of url per codepoint)

garret: still thinking in the same general direction, client should reduce granularity. We simulated and this seemed effective.

myles: do you have numbers wrt how many fragments for file?

garret: if the patches are independent ... today we use 100ish for CJK on Google Fonts, maybe you'd go a bit higher but not dramatically.

myles: average chain length would be interesting as well, esp for CJK content

garret: simulation should be able to help here

garret: interesting beyond cjk, if you broke up by say language is the chain often 1

rod: seems like we need to try it

myles: excited about potentially having independent patches, that largely solves CJK

garret: I have an idea for how to do that

myles: glyf full of zeroes isn't necessarily awesome, requires compression to be useful

garret: I think we can do better

(so do Rod and Myles)

garret: as Skef remarked, this is made or broken by a good encoder

rod: hopefully that's a win, we improve the encoder and don't have to update clients, etc

garret: closing remarks?

Summary of resolutions

  1. RESOLVED
  2. replace range request with a more static friendly approach
  3. draft specification for a static-friendly patch subset mechanism
  4. Garret shall come up with a cool acronym
Minutes manually created (not a transcript), formatted by scribe.perl version 221 (Fri Jul 21 14:01:30 2023 UTC).

Diagnostics

Succeeded: s/CFF/CMAP/

Succeeded: s/we break up by axes/we break up by axes or gid's or new concepts other than codepoints/

Maybe present: myles, Rod, sergeym

All speakers: chris, drott, Garret, myles, Rod, RodS, sergeym, Vlad

Active on IRC: bberning, chris, drott, Garret, jimmym, myles, Rod_S, RodS, sergeym, Vlad