foliojs / fontkit

An advanced font engine for Node and the browser
1.44k stars 210 forks source link

Handle avar table version 2 #316

Open Lorp opened 12 months ago

Lorp commented 12 months ago

An updated version of the avar table is going through the standardization process, having already been implemented in Apple (macOS and iOS), FreeType and Harfbuzz. The new table allows for the location of one variation axis to be influenced by the locations of other variation axes. This helps multi-axis fonts behave more flexibly and intuitively.

It is described here: boring-expansion-spec/avar2.md

A JavaScript implementation that builds on Fontkit’s existing ItemVariationStore code can potentially be very short. For example, here is the code that Samsa runs each time a new instance is requested:


// at this point, tuple is an array of length axisCount, containing one value per axis, each of which has been normalized by avar v1

const deltas = font.itemVariationStoreInstantiate(avar.itemVariationStore, tuple);
for (let a=0; a<axisCount; a++) {
    const [outer, inner] = avar.axisIndexMap[ Math.min(a, avar.axisIndexMap.length - 1) ]; // use the a’th entry or the last entry of axisIndexMap
    if (outer != 0xffff && inner != 0xffff) {
        tuple[a] += deltas[outer][inner] / 0x4000; // add the interpolated delta to tuple[a]
        tuple[a] = clamp(tuple[a], -1, 1); // clamp the result to [-1,1]
    }
}

// round each tuple entry to nearest 1/16384 here