Resolves https://github.com/behdad/fonttools/issues/445 for single
substitutions. The compact forms for chaining to other GSUB types
are not yet supported; these will get fixed in follow-up changes.
Before this change, we silently generated bad fonts. After this
change, we emit the exact same output like `makeotf` for specific
kerning pairs, and reject the input file for the not yet implemented
class-based kerning. (The implementation of class-based kerning
is coming soon).
Before this change, the compiler would enumerate only the first
glyph class of a kerning pair. However, that behavior did not match
the behavior of the `makeotf` tool.
No output is generated yet, this change is just on the parser.
The OpenType Feature File specification is surprisingly vague about
the exact syntax of chaining contextual positioning rules, so I expect
that we will have to iterate on this parser. However, the test case
in parser_test.py gets recognized by `makeotf`, so the current
implementation is unlikely to be completely wrong.
The class names of tree nodes for substitution and positioning rules
are now consistent with `builder.py`, which in turn is consistent with
`otTables.py`.
The upcoming MarkLigPosBuilder will have some parts in common with
MarkBasePosBuilder. Move these common parts into a helper method,
so that MarkLigPosBuilder will be able to call them.
Also, clean up the structure of MarkBasePosBuilder.
However, not sure how to build the otTables object graph for emitting
GPOS tables with device values; the current code thus silently strips
off any device values. Left a TODO comment for implementing this.
Before this change, feaLib would sort coverage tables by glyph name,
which is against the OpenType specification. The current unittests
happen to use only glyphs where the ordering is identical whether
sorting by name or by ID; but I am about to add unittests (for GPOS)
where the ordering is different.
The ordering cannot be enforced by otTables because otTables does
not have access to the font's glyph order; therefore, the sorting
needs to happen inside feaLib.
The list of subtables should go in the 'SubTable' attribute of Lookup object.
This also sets the 'LookupType', 'LookupFlag' and 'SubTableCount' attributes.