`tables=None` by default will build all supported tables;
To build only some of these and ignore the others, one can pass a
subset of supported tables tags: .e.g. `tables={'GSUB'}` will only
build the GSUB, even if the feature file may contain e.g. GPOS
related features.
Currently, the feature file parser always resolves included files,
parses their content and inserts it in the resulting AST. The original
`include` statement is lost.
This commit introduces an option to not follow inclusions. Instead, the
output AST will contain an `include` statement. This allows to process a
feature file on its own, and allows to round-trip it.
For example in glyphsLib, when going from a UFO to a .glyphs file, a
UFO feature file will be sliced up into Glyphs.app classes (e.g. a
GSFeaturePrefix with code `include(../family.fea);`) and when going back
from .glyphs to UFO, the feature file will be patched back together.
As Martin Hosken reported in https://github.com/fonttools/fonttools/pull/1096,
feaLib currently incorrectly handles the case where a marked input
glyph sequence in a contextual chaining sub/pos rule is split into
multiple runs, rather than being a single continuous run of ' marked
glyphs.
The consensus there was to raise a syntax error like makeotf instead of
second-guessing and silently fixing it like fontforge does.
... instead of a glyphMap dict.
The parser does not actually need a reverse glyph order mapping as
it is not interested in knowing the glyphID from the glyph name,
but only whether a glyph is in the font or not.
This makes it easier for client code (e.g. ufo2ft feature compiler)
to use the feaLib Parser, without having to first construct and pass
it a glyphMap argument.
Before this change, the following glyph class:
@Vowels = [@Vowels.lc @Vowels.uc y Y];
Would be written back as:
@Vowels = [@Vowels.lc = [a e i o u]; @Vowels.uc = [A E I O U]; y Y];
Which is clearly invalid. It seems for GlyphClass.asFea() to work
correctly here we should be using GlyphClassName not GlyphClass
for the nested classes (similar to the code at the beginning of
parse_glyphclass_()).
The syntax tree representation now reflects the syntax of feature files.
Before this change, FeatureNames did not have their own `ast.Block`,
which had made the code quite messy.
Before this change, some table statements would allow empty statements
(just a semicolon) while others would not allow them. After this change,
we're more consistent.
Specifically, contextual positioning statements with in-line single
positioning rules, in horizontal and in vertical contexts. For these
test cases, feaLib and makeotf produce the exact same output.
https://github.com/fonttools/fonttools/issues/633
If a zero value appears in a SinglePos statement, feaLib continues to
produce ValueRecords of format 0. But if a zero value appears in a
PairPos statement inside a horizontal compilation context, feaLib now
produces ValueRecords of format 4. Likewise, if a zero value appears
in a PairPos statement inside a vertical compilation context, feaLib
now produces ValueRecords of format 8.
The OpenType Feature Syntax specification is completely silent about this,
but the new behavior matches that of makeotf.
https://github.com/fonttools/fonttools/issues/633
In context of SinglePos, makeotf compiles zero values to value records
of format 0. feaLib already does the same, but it's good to have tests
to make sure that this doesn't accidentally change.
https://github.com/fonttools/fonttools/issues/633
We now correctly handle nameid statements with surrogate pairs and
old-style macOS-encoded names (provided that fonttools supports the
specified encoding).
Resolves https://github.com/fonttools/fonttools/issues/842.