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.
Generated by running example 1 from the Feature File specification
section 5.f.i (Specifying a Chain Sub rule and marking sub-runs)
through AFDKO's makeotf tool, and then decompiling the resulting
GSUB table with ttx.
The actual test is commented out because the current version of feaLib
is not able to produce this output yet; marked with a TODO comment.
It is example 1 in section 5.f.i of the specification, and there
more examples in the same section. For consistency, use the same convention
as the other test cases.
The list of subtables should go in the 'SubTable' attribute of Lookup object.
This also sets the 'LookupType', 'LookupFlag' and 'SubTableCount' attributes.
An earlier change made sure that language tags would always be
four characters in length, even when ending in whitespace.
This made a few test cases in parser_test.py fail. By accident,
I had only run builder_test (instead of all unittest in fonttools)
before committing that change.
Currently, the compiler uses them to figure out which set of
languagesystems would apply for the current scope. However, this
information is not yet used for anything.
Also add ';' to some langaugesystem test cases. This makes the
snippets syntactically valid. The parser is still expected to
reject them for other reasons, just as before this change.
This simplifies the public API to the library. For clients, it does
not matter which exact component was detecting an error. And we will
soon have more components; there would be little point in declaring
CompilerError, TableBuilderError, and so forth.
In the new version, the parse_languagesystem_() function returns
an ast.LanguageSystemStatement, which then gets appended to the
current list of statements by the caller. Before this change,
the parse_languagesystem_() function would always append the
newly parsed statement to the list of top-level statements.
In practice, it does not matter because `languagesystem` is
only valid at the top level, but there is no good reason why
the parser method would have to be different from all other
constructs.
We will soon support additional blocks beyond `feature`,
and keeping this refactoring separate from new functionality
makes it easier for code reviewers to follow the changes.