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.
For GPOS type 2, the OpenType Feature File format makes a semantic
difference between `glyph` and `[glyph]`, so we need to pass the
syntax tree for the kerned glyphs and glyph classes down to the builder.
Previously, we were expanding syntax tree nodes to glyphSets at
parsing time. Therefore, the builder could not distinguish a statement
for kerning two single glyphs from a statement for kerning two glyph
glasses, where each glyph class would consist of a singleton
glyph. (Debating whether or not it makes much sense to have this
distinction is outside the scope of fonttools; we want to implement
the language in its present form).
The builder does not yet use this information for building different
tables. This change is just about plumbing.
Again, this will be needed for eventually distinguishing `glyph`
from `[glyph]` or `@CLASS`, which makes a semantic difference
when building GPOS type 2 tables.
This will be needed for implementing class-based kerning. According
to the OpenType Feature File specification, a different table needs to
be built for `glyph` versus `[glyph]`.
Before this fix, the parser failed to process statements of the form
`lookupflag MarkAttachmentType @GLYPHCLASS;` when no other flag
were set after the glyph class. However, statements like
`lookupflag MarkAttachmentType @GLYPHCLASS RightToLeft;` were
getting recognized perfectly fine.
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.
While not really documented in the OpenType Feature File specification,
the AFDKO makeotf tool handles the `markClass` statement this way.
Also, some examples in the specification seem to imply this semantics.