Allow for making more lookups support subtabe breaks. Although AFDKO’s
makeotf supports subtable breaks only in pair pos lookups, I believe
that is an implementation limit that we don’t have to follow; all
OpenType lookups has subtables and it should be possible to code that in
the feature files.
If Coverage is None then the subtable is a noop that does nothing and
there is no point in building it. As a bonus, it makes OTS happy since
it will reject subtables where coverageOffset is NULL (0) and the spec
does not say whether this is allowed or not.
ufo2ft feature writer calls feaLib builder with tables=[GSUB] first, to run closure
over glyph substitutions; if the GSUB features contains 'featureNames' blocks, then
an AssertionError will be raised; in this case, we can simply skip building the
FeatureParams tables as we haven't build the name records they point to.
all otData arrays are decompiled as lists (see otConverters.BaseConverter.readArray).
If one tries to call the subsetter on a GSUB table that was not read from file
but was just built from feaLib, it crases with a TypeError because it's expecting
list but finds tuples.
Traceback (most recent call last):
File /home/clupo/Github/fonttools/Lib/fontTools/subset/__init__.py, line 1462, in prune_lookups
lookup_indices = self.table.FeatureList.collect_lookups(feature_indices)
File /home/clupo/Github/fonttools/Lib/fontTools/subset/__init__.py, line 1263, in collect_lookups
if i < self.FeatureCount), [])
TypeError: can only concatenate list (not tuple) to list
`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.
The items() of self.markFilterSets_ dictionary are not guaranteed to be always
ordered the same (may vary across python implementations or on subsequent runs).
To ensure deterministic order of Coverage subtables in MarkGlyphSetsDef tables,
we sort the mark sets by the order in which 'UseMarkFilteringSet' statements appear
in the feature file.
Glyph classes from feaLib parser are tuples of strings, with an order and possibly containing duplicates.
However when building MarkGlyphSetsDef or MarkAttachClassDef we are only interested in the *set* of glyphs they contain, i.e. the unordered collection of unique glyph names.
Also, note how in the tests for otlLib.builder.buildMarkGlyphSetsDef, the input is given as set literals, not tuples:
https://github.com/fonttools/fonttools/blob/78ad48e/Tests/otlLib/builder_test.py#L633
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
Also fixes a bug where glyph alternates in MTI feature files were
wrongly sorted by glyph name. After this change, the output is using
the same ordering as in the input MTI feature file.
Fixes https://github.com/fonttools/fonttools/issues/833.
Before, if someone tried to set the language before setting the script
a None/language language system would be created (with actual tag
"None" stored in the feature table). This defaults to tag DFLT and
fails when a non-dflt language is set for DFLT, since that's illegal.
This is to fix what I think was a misunderstanding of the exclude_dflt
keyword (and the implicit include_dflt option active by default).
Rather than including the following lookups in the default language
systems, I think it is used to include the lookups specific to default
language systems in the system defined by the current language
statement. Thus instead of registering a lookup in all default
systems when include_dflt is true, we should exclude the lookups
registered with default systems from the current system when
include_dflt is false.
Since py23 modifies some essential builtins, it's safe to import
everything all the time. At least, that's how it was designed.
It's a bug if importing * breaks some code.