Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CFF2] uint16 VariationStore.length limitation #159

Open
behdad opened this issue Oct 22, 2024 · 2 comments
Open

[CFF2] uint16 VariationStore.length limitation #159

behdad opened this issue Oct 22, 2024 · 2 comments
Labels

Comments

@behdad
Copy link
Member

behdad commented Oct 22, 2024

Problem statement

The VariationStore.length field in the current CFF2 specification has the type uint16. We have seen complex varfont designs hit this size limitation.

Context

64k ought to be enough, for everybody, right?

Not only it would have been trivial (at the cost of one or two bytes!) to avoid imposing this limitation, as it happens, encoding of the said value itself is completely unnecessary!

See: the processor does not need to know the byte size of the embedded ItemVariationStore. The ItemVariationStore is designed in the style of the GSUB / GPOS / etc tables, where lots of small tables linked together through offsets are used. The CFF / CFF2 tables on the other hand, use either a stack machine (DICT, CharString), or a list of sized data (INDEX), in both cases the length of the payload is encoded explicitly, by necessity. So the people designing how to embed ItemVariationStore in CFF2 decided to encode the byte-length of the structure in there some idea of consistency I suppose.

Background and design notes

It was chosen for CFF2 to encode the actual delta values inline with the CharString as operands to the blend operator. To specify the master configuration however, it was decided to reuse the ItemVariationStore facilities, but not store any actual deltas in there. So, it will include only the master configuration. So somebody thought that cannot need too many bytes and set it to 16 bits instead of eg. 32.

It was initially considered that such ItemVariationStore be added as a new font table, side by side to the CFF2 table itself. It was, however, pointed out that there is no reason to do so, and the variation-store is just yet another operator to add to TopDict as an offset to a ItemVariationStore structure. Did you notice the use of two names: ItemVariationStore and VariationStore. The latter (VariationStore) is a CFF2-specific unnecessary wrapper around the spec-wide ItemVariationStore, just prefixing the actual data with the length of it. Encoding the length is not necessary for any kind of processing whatsoever.

I also want to note how the designers chose to encode such length as a uint16, instead of using a variable-sized operand encoding like those used in TopDICT itself. All numbers in CFF are encoded as variable-sized. If a variable-sized number was used, there would have been no limitation. Alas.

Proposal

Somehow mark this number irrelevant and unused. The way I suggest, and seems like Adobe team agrees as well, is to spec that if the length value is 65,535, it must be ignored and the actual payload might be of any size.

Risks

There is no risk in this change since we are just making more fonts build than that currently possible. Any existing font will continue to behave the same.

It is very likely that no rendering engine has any meaningful check of this number. Even tools like ot-sanitize check for this length field to match the actual payload byte size.

@behdad behdad added the CFF2 label Oct 22, 2024
@Lorp

This comment was marked as outdated.

@skef
Copy link
Contributor

skef commented Oct 22, 2024

I entirely agree this should be fixed. We've also discussed the specific fix you suggest (based on a previous warning about this) and agree that's the way to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants