This makes the output of feaLib more compact, using a similar technique
as seems to be used by makeotf.
After this change, feaLib generates output that more similar to makeotf:
* For the test cases in `bug512.fea` and `bug463.fea`, feaLib now
generates the exact same output as makeotf v2.0.90.
* For the test cases in `GSUB_6.fea`, it is hard to say because makeotf
crashes on the test file; our test contains language constructs that
are valid according to the spec, but didn't yet get implemented by makeotf.
When commenting out those constructs, feaLib generates the exact same
output as makeotf v2.0.90.
* For the test cases in `feature_aalt.fea`, the output of feaLib is now
structually the same as the output of makeotf v2.0.90. However, two
lookups are in different order. feaLib's ordering reflects the order
of statements in the compiled input source; no idea why makeotf would
want to reverse the ordering. Since this ordering difference only
affects the _targets_ of chain substitutions, there is no semantic
difference.
Resolves https://github.com/behdad/fonttools/issues/512.
Although this construct is in violation of the `ignore sub` grammar
given by the current OpenType Feature File syntax specification,
the very same specification document illustrates (in example 3
of section 5.f.ii) the `ignore sub` statement with a comma-separated
list of backgrack/input/lookahead triples.
See https://github.com/adobe-type-tools/afdko/issues/105 for a request
to amend the OpenType Feature File syntax specification.
After this code change, feaLib can now parse testdata/spec5f_ii_3.fea;
the output is identical to what is generated by Adobe's makeotf tool.
https://github.com/behdad/fonttools/issues/503
For this construct, makeotf throws an error: "Contextual alternate
rule not yet supported". If it had been implemented, we speculate
that the ordering would likely be the same as with other contextual
substitutions (the chain comes before, not after, the dependent lookup).
https://github.com/behdad/fonttools/issues/507
Before this change, the `script` statement had inherited global
defaults. After this change, it overrides them. The new behavior
matches the behavior of makeotf v2.0.90.
Resolves https://github.com/behdad/fonttools/issues/505.
For the test case of https://github.com/behdad/fonttools/issues/501,
which was about an unrelated problem, feaLib now produces the exact
same output as makeotf v2.0.90.
Although the specification writes the exact opposite, makeotf does
accept script and language statements inside named lookup blocks.
Since Glyphs.app (and possibly other tools, too) produce feature files
that make use of this syntax, enforcing the spec would break existing
files.
Resolves https://github.com/behdad/fonttools/issues/501.
After this change, feaLib synthesizes the same lookups as makeotf v2.0.90
for `feature aalt` in the example of section 8.a of the OpenType Feature
File specification.
Before this change, feaLib would group glyph-based pair positionings
by value formats. After this change, this logic happens in otlLib.
But clients can still do their own grouping if they wish, by calling
the buildPairPosGlyphsSubtable() method directly.
Before this change, feaLib had assigned a lookup index at the same
time as compiling each lookup. For chains, the implicit assumption was
that the chain's targets would always come before the contexual chain.
Normally this was indeed the case, but feaLib (and also makeotf)
sometimes merge several chain targets into one single lookup,
and then this assumption was not true anymore.
In the new version, the lookups get compiled in a separate pass,
after assigning lookup indices.
https://github.com/behdad/fonttools/issues/463
Not sure if empty ComponentRecords can be optimized away.
For the time being, leaving the output unchanged so that
the refactoring has no effect on the generated files.