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] Allow more than one vsindex operation and at any place #158

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

[CFF2] Allow more than one vsindex operation and at any place #158

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

Comments

@behdad
Copy link
Member

behdad commented Oct 22, 2024

Problem statement

Currently, the CFF2 spec says:

The vsindex operator may be used only once in a CharString and must precede the first use of the blend operator.

This imposes a snag when compiling fonts built using very common idioms, as well as disable certain optimizations:

Compiling composite glyphs

Imagine a font designer designed atilde glyph as a composite glyph consisting of an a and a tildecomb glyph. When compiling these to a CFF2 font, the glyph needs to be decomposed, because CFF/CFF2 do not really have the concept of composite glyphs in the same sense.

By the restriction quoted in the last section, the two glyphs a and tildecomb must have the same master configuration. If they don't, the compiler has to synthesize some each of the a and tildecomb in some locations and add back into their master configuration, to ensure they share their master configuration. This is not straightforward, and because of the next problem, is also very costly in terms of bytes. It is similar to trying to merge two fonts with different designspaces.

Reduced file size

Different vsindex'es can optimize for different set of "active", ie. non-zero, tent deltas, which is not currently possible. A lot of blends might end up encoding a lot of zeros as a result. If we allow switching the vsindex in the middle of the CharString, the compiler can optimize things better to avoid those zeros. The ItemVariationStore design, for example, when used to store actual deltas, optimizes them by the width needed to encode each delta value. The same can be applied to optimizing the blend operators in a CFF2 font.

Suggested change:

  • Allow multiple vsindex operations and at any place, in both CharStrings and Private dicts.

  • The default vsindex for a CharString is currently defined to be the vsindex set in the relevant Private dict. The text should be updated to say that it's the last vsindex operation in the Private dict that is the default vsindex for processing the CharStrings.

@behdad behdad added the CFF2 label Oct 22, 2024
@skef
Copy link
Contributor

skef commented Oct 22, 2024

This might be controversial.

I get the reduced filesize possibilities. I'm less clear on the first part. If the glyph is decomposed (which you would expect with VARC) then presumably the outlines for a and the outlines for tildecomb to into separate CFF2 glyphs, each of which can have its own vsindex. So I'm not understanding the problem.

@behdad
Copy link
Member Author

behdad commented Oct 22, 2024

If the glyph is decomposed (which you would expect with VARC)

No I'm not talking about VARC.

When building a regular CFF2 variable-font from sources like Glyphs files that have the composite-glyph feature, but those glyphs needs to be flattened to go into CFF2. Currently it's a big hassle if the components have different master configurations.

@skef
Copy link
Contributor

skef commented Oct 22, 2024

Oh, hmm.

The rest of these proposals are probably viable to roll into the spec as clarifications. This would be a very significant change, and I would think at least require upping the minor number on the table. I suspect it would also be a pain to implement across rasterizers and other tools -- a lot of tools expect to be able to set up the model and forget about it.

That said, there's no reason we can't discuss it.

@behdad
Copy link
Member Author

behdad commented Oct 22, 2024

Yes, this is the only change that can break existing rasterizers, but I think we should discuss it. Thank you.

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

2 participants