There is no longer a requirement that all the masters have exactly the same base color glyphs as the default masters. Similarly, it's no longer required that all masters' LayerLists have the same total count of layers. It is sufficient that, for a base color glyph in the default master, a non-default master may (or may not) contain one with the same name and same effective number of layers (which in turn can be laid out differently in the respective LayerLists).
This provides greater flexibility when working with variable font project with sparse glyph sets.
previously we only reused the VarIndexBase of a previously seen variable table when the current's varIdxes were _fully_ equal to one of the previous; now we also try to find a match anywhere in the accummulated list of self.varIdxes, including a partial match at the tail of the list.
When multiple variable tables refer to the same delta-sets they can now share the same VarIndexBase so the resulting DeltaSetIndexMap is a bit smaller.
For simplicity, we only reuse VarIndexBase when variable tables fully share (ie. same, and same number of) varIdxes; potentially we could reuse subsets of varIdxes (e.g. a VarColoStop.Alpha has a +0.5 delta, and later on elsewhere a PaintVarSolid.Alpha has a similar +0.5 delta; the latter could have a VarIndexBase that reuses an existing DeltaSetIndexMap entry for the former), but for now this I think is good enough.
Before we were too greedy in the way we converted subtables to VarType. E.g. If a PaintTransform wrapping a PaintRadialGradient contained variations in the Affine2x3, we would incorrectly convert also the gradient's ColorLine (and ColorStops) to VarColorLine, VarColorStop, etc. (even if the gradient was not variable!). Instead we want skip traversing a given subtable including its children when the predicate doesn't match.
This does two things:
Fixes forced-set computation, which was wrong in multiple ways.
Debugged it. Is solid now... Famous last words.
Speeds up DP time by limiting DP lookback length. For Noto Sans,
IUP time drops from 23s down to 9s, with only a slight size increase
in the final font. This basically turns the algorithm from O(n^3) into
O(n).
The exception UnsupportedFormat was defined and then redefined with the same name in varLib.errors, and imported twice from varLib.merger, probably as result of a sweeping find/replace.
Rename it 'InconsistentFormats' as originally intended.
ufoLib's glyph draw() was passing outputImpliedClosingLine=False to
PointToSegmentPen(). This was causing incompatible nodes in
interpolatable tool for certain fonts, like this in NotoSansDevanagari:
Glyph dabhadeva was not compatible:
Node count differs in path 1: 23 in NotoSansDevanagari-Bold, 24 in NotoSansDevanagari-CondensedBold
Node count differs in path 1: 24 in NotoSansDevanagari-CondensedBold, 23 in NotoSansDevanagari-CondensedLight
Because a final lineto before a closepath was being elided or not in
some masters but not others. Wire up the parameter and control it
from interpolatable tool to fix this.
This further found an issue in NotoSansArabic which I visually verified:
Glyph qafLamAlefMaksuraabove-ar was not compatible:
Contour start point differs: NotoSansArabic-CondensedLight, NotoSansArabic-CondensedSemiBold
Contour start point differs: NotoSansArabic-CondensedLight, NotoSansArabic-CondensedSemiBold
Contour start point differs: NotoSansArabic-CondensedSemiBold, NotoSansArabic-Condensed
Contour start point differs: NotoSansArabic-CondensedSemiBold, NotoSansArabic-Condensed
Reduces false-positives, as in this one in NotoSansArabic:
Glyph asteriskArt-ar was not compatible:
Contour order differs: [0, 1, 2, 3, 4, 5] in NotoSansArabic-CondensedBold, [0, 3, 2, 1, 4, 5] in NotoSansArabic-CondensedLight
This seems to work already. Detects the example in the issue.
I also ran this on master-compatible UFOs built from Noto Sans,
and detected several issues. Confirmed visuall in AxisPraxis that
theta.sc for example has wrong starting point in that font:
Glyph theta.sc was not compatible:
Contour start point differs: NotoSans-DisplayRegular, NotoSans-DisplaySemiBoldCondensed
Contour start point differs: NotoSans-DisplayRegular, NotoSans-DisplaySemiBoldCondensed
Contour start point differs: NotoSans-DisplaySemiBoldCondensed, NotoSans-DisplaySemiBold
Contour start point differs: NotoSans-DisplaySemiBoldCondensed, NotoSans-DisplaySemiBold
There's a TODO item left to be done, which is to check for mirrored
contours and rotations thereof.
Towards fixing https://github.com/fonttools/fonttools/issues/1801
When building gvar, some situations cause fontmake/varLib to fail, for example if a component has a coordinate that's >32k or <-32k. This adds a debug line that prints each glyph name for which gvar is built, so it’s easier to pinpoint where the faulty glyph is.