Analyzing Variation Models

I am surprised that nobody actually did a mathematical analysis of the variation model in OpenType. They are simply reusing the concepts of the old MM system, and complicating the things they need.

Standard variations

For almost all places in a current variable font, anything that varies (coordinates, lengths, parameters, etc.) could be expressed in the following model:

{(v)}{=+{ {}m𝔐{x}}D{x}[m]W(m,v)}{(1)}
{W(m,v)}{={ {}a𝔄}Λ(m[a],v[a])}{(2)}

The notation denotes a variable quantity (VQ), which responds to an instance tuple v. is the default value of . 𝔐{x} represents the region set of , and D{x}[m] is the delta associated with this master m. Binary function W(m,v) computes the weight of master m under instance v, which is defined as a product of axis weights.

We can easily conclude that VQs form a linear space, since scalar product and sum can be defined in such manner:

{(s)(v)}{=(s)+{ {}m𝔐{x}}(sD{x}[m])W(m,v)}{(3)}
{(+)(v)}{=(+)+{ {}m𝔐{x}𝔐{y}}(D{x}[m]+D{y}[m])W(m,v)}{(4)}

One thing we could not define yet is the product of two VQs, we’d like to discuss them later.

You’ve noticed that the entire variation model is a sum, instead of blending values across masters. However, conversion from blending into VQ could be easily achieved by solving a linear system.

Nested variations

One interesting special case happens in CFF2: in theory, the blend operators in CFF2 could be nested, so equation (1) would be modified into this form:

{(v)}{=+{ {}m𝔐{x}}{x}[m](v)W(m,v)}{(5)}

The only difference is that the factor {x}[m](v) is now a VQ instead of a number. However the property that VQs form a linear space still holds, since we can recursively scale or sum VQs in (5).

Products of variations

One thing we’d like to extend current standard is allowing products () be representable in the variation system, and that is surprisingly simple by allowing axes to repeat in masters (variation regions). The product

{()(v)}{=}{(6)}
{}{+()(v)}{(7)}
{}{+()(v)}{(8)}
{}{+{ {}m{x}𝔐{x}}{ {}m{y}𝔐{x}}(D{x}[m{x}]D{y}[m{y}])W(m{x},v)W(m{y},v)}{(9)}

The term (6), (7), (8) are simply scales of VQs, but term (9) contains product of weight functions that is not representable in the current standard. However releasing this restriction is surprisingly simple: we can allow masters to contain an axis list, which may have duplicate axes, and associate a “tent” (start-peak-end triplet) to each axis item. In the current standard, the axis list is a fixed list shared across the entire font.

In other terms, the form of (2) would be modified into this form:

{W(m,v)}{={ {}(a,τ)𝔄[m]}Λ(τ,v[a])}{(10)}

Notation 𝔄[m] denotes the “axis-tent” list that forms this master, and we do the same product just like the old definition. Then the product of two weighting functions could be defined as:

{W(m{x},v)W(m{y},v)}{={ {}(a,τ)𝔄[m{x}]𝔄[m{y}]}Λ(τ,v[a])}{(11)}

where notation 𝔄[m{x}]𝔄[m{y}] denotes we simply concatenate the axis-tent lists together.

Mutatormath, etc.

Mutatormath and libraries similar to that defines how we convert a set of peak tuples into a master set, where each master requires each axis’ record having a start and an end, as well as the peak already given. Once the master set is decided, the interpolation part could be easily done by solving linear systems.