Description
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 thevsindex
set in the relevant Private dict. The text should be updated to say that it's the lastvsindex
operation in the Private dict that is the defaultvsindex
for processing the CharStrings.