Merge pull request #2016 from simoncozens/gsub5-gpos7-lookups

Generate GSUB5/GPOS7 lookups (See #1856)
This commit is contained in:
Simon Cozens 2020-07-11 21:51:47 +01:00 committed by GitHub
commit cbe6d3a3f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 446 additions and 186 deletions

View File

@ -172,6 +172,13 @@ class LookupBuilder(object):
coverage = buildCoverage(g, self.glyphMap)
subtable.InputCoverage.append(coverage)
def setCoverage_(self, glyphs, subtable):
subtable.GlyphCount = len(glyphs)
subtable.Coverage = []
for g in glyphs:
coverage = buildCoverage(g, self.glyphMap)
subtable.Coverage.append(coverage)
def build_subst_subtables(self, mapping, klass):
substitutions = [{}]
for key in mapping:
@ -244,11 +251,71 @@ class AlternateSubstBuilder(LookupBuilder):
self.alternates[(self.SUBTABLE_BREAK_, location)] = self.SUBTABLE_BREAK_
class ChainContextualRuleset():
def __init__(self):
self.rules = []
def addRule(self, prefix, glyphs, suffix, lookups):
self.rules.append((prefix, glyphs, suffix, lookups))
@property
def hasPrefixOrSuffix(self):
# Do we have any prefixes/suffixes? If this is False for all
# rulesets, we can express the whole lookup as GPOS5/GSUB7.
for (prefix, glyphs, suffix, lookups) in self.rules:
if len(prefix) > 0 or len(suffix) > 0:
return True
return False
@property
def hasAnyGlyphClasses(self):
# Do we use glyph classes anywhere in the rules? If this is False
# we can express this subtable as a Format 1.
for (prefix, glyphs, suffix, lookups) in self.rules:
for coverage in (prefix, glyphs, suffix):
if any(len(x) > 1 for x in coverage):
return True
return False
def format2ClassDefs(self):
PREFIX, GLYPHS, SUFFIX = 0,1,2
classDefBuilders = []
for ix in [PREFIX, GLYPHS, SUFFIX]:
context = []
for r in self.rules:
context.append(r[ix])
classes = self._classBuilderForContext(context)
if not classes:
return None
classDefBuilders.append(classes)
return classDefBuilders
def _classBuilderForContext(self, context):
classdefbuilder = ClassDefBuilder(useClass0=False)
for position in context:
for glyphset in position:
if not classdefbuilder.canAdd(glyphset):
return None
classdefbuilder.add(glyphset)
return classdefbuilder
class ChainContextualBuilder(LookupBuilder):
def equals(self, other):
return (LookupBuilder.equals(self, other) and
self.rules == other.rules)
def rulesets(self):
# Return a list of ChainContextRuleset objects, taking explicit
# subtable breaks into account
ruleset = [ChainContextualRuleset()]
for (prefix, glyphs, suffix, lookups) in self.rules:
if prefix == self.SUBTABLE_BREAK_:
ruleset.append(ChainContextualRuleset())
continue
ruleset[-1].addRule(prefix, glyphs, suffix, lookups)
# Squish any empty subtables
return [x for x in ruleset if len(x.rules) > 0]
def build(self):
"""Build the lookup.
@ -257,15 +324,26 @@ class ChainContextualBuilder(LookupBuilder):
contextual positioning lookup.
"""
subtables = []
for (prefix, glyphs, suffix, lookups) in self.rules:
if prefix == self.SUBTABLE_BREAK_:
continue
st = self.newSubtable_()
subtables.append(st)
chaining = False
rulesets = self.rulesets()
chaining = any(ruleset.hasPrefixOrSuffix for ruleset in rulesets)
for ruleset in rulesets:
for rule in ruleset.rules:
subtables.append(self.buildFormat3Subtable(rule, chaining))
# If we are not chaining, lookup type will be automatically fixed by
# buildLookup_
return self.buildLookup_(subtables)
def buildFormat3Subtable(self, rule, chaining=True):
(prefix, glyphs, suffix, lookups) = rule
st = self.newSubtable_(chaining=chaining)
st.Format = 3
if chaining:
self.setBacktrackCoverage_(prefix, st)
self.setLookAheadCoverage_(suffix, st)
self.setInputCoverage_(glyphs, st)
else:
self.setCoverage_(glyphs, st)
for sequenceIndex, lookupList in enumerate(lookups):
if lookupList is not None:
@ -281,16 +359,56 @@ class ChainContextualBuilder(LookupBuilder):
raise OpenTypeLibError('Missing index of the specified '
f'lookup, might be a {other} lookup',
self.location)
rec = self.newLookupRecord_()
rec = self.newLookupRecord_(st)
rec.SequenceIndex = sequenceIndex
rec.LookupListIndex = l.lookup_index
self.addLookupRecordToSubtable_(st, rec)
return self.buildLookup_(subtables)
return st
def add_subtable_break(self, location):
self.rules.append((self.SUBTABLE_BREAK_, self.SUBTABLE_BREAK_,
self.SUBTABLE_BREAK_, [self.SUBTABLE_BREAK_]))
def newSubtable_(self, chaining=True):
subtablename = f"Context{self.subtable_type}"
if chaining:
subtablename = "Chain"+subtablename
st = getattr(ot,subtablename)() # ot.ChainContextPos()/ot.ChainSubst()/etc.
setattr(st, f"{self.subtable_type}Count", 0)
setattr(st, f"{self.subtable_type}LookupRecord", [])
return st
def attachSubtableWithCount_(self, st,
subtable_name, count_name,
existing=None,
index=None, chaining=False):
if chaining:
subtable_name = "Chain"+subtable_name
count_name = "Chain"+count_name
if not hasattr(st, count_name):
setattr(st, count_name, 0)
setattr(st, subtable_name, [])
if existing:
new_subtable = existing
else:
# Create a new, empty subtable from otTables
new_subtable = getattr(ot, subtable_name)()
setattr(st, count_name, getattr(st, count_name) + 1)
if index:
getattr(st, subtable_name).insert(index, new_subtable)
else:
getattr(st, subtable_name).append(new_subtable)
return new_subtable
def newLookupRecord_(self, st):
return self.attachSubtableWithCount_(st,
f"{self.subtable_type}LookupRecord",
f"{self.subtable_type}Count",
chaining=False) # Oddly, it isn't ChainSubstLookupRecord
class ChainContextPosBuilder(ChainContextualBuilder):
"""Builds a Chained Contextual Positioning (GPOS8) lookup.
@ -321,19 +439,7 @@ class ChainContextPosBuilder(ChainContextualBuilder):
def __init__(self, font, location):
LookupBuilder.__init__(self, font, location, 'GPOS', 8)
self.rules = [] # (prefix, input, suffix, lookups)
def newSubtable_(self):
st = ot.ChainContextPos()
st.PosCount = 0
st.PosLookupRecord = []
return st
def newLookupRecord_(self):
return ot.PosLookupRecord()
def addLookupRecordToSubtable_(self, st, rec):
st.PosCount += 1
st.PosLookupRecord.append(rec)
self.subtable_type = "Pos"
def find_chainable_single_pos(self, lookups, glyphs, value):
"""Helper for add_single_pos_chained_()"""
@ -376,19 +482,7 @@ class ChainContextSubstBuilder(ChainContextualBuilder):
def __init__(self, font, location):
LookupBuilder.__init__(self, font, location, 'GSUB', 6)
self.rules = [] # (prefix, input, suffix, lookups)
def newSubtable_(self):
st = ot.ChainContextSubst()
st.SubstCount = 0
st.SubstLookupRecord = []
return st
def newLookupRecord_(self):
return ot.SubstLookupRecord()
def addLookupRecordToSubtable_(self, st, rec):
st.SubstCount += 1
st.SubstLookupRecord.append(rec)
self.subtable_type = "Subst"
def getAlternateGlyphs(self):
result = {}

View File

@ -69,10 +69,10 @@ class BuilderTest(unittest.TestCase):
ZeroValue_SinglePos_horizontal ZeroValue_SinglePos_vertical
ZeroValue_PairPos_horizontal ZeroValue_PairPos_vertical
ZeroValue_ChainSinglePos_horizontal ZeroValue_ChainSinglePos_vertical
PairPosSubtable ChainSubstSubtable ChainPosSubtable LigatureSubtable
AlternateSubtable MultipleSubstSubtable SingleSubstSubtable
aalt_chain_contextual_subst AlternateChained MultipleLookupsPerGlyph
MultipleLookupsPerGlyph2
PairPosSubtable ChainSubstSubtable SubstSubtable ChainPosSubtable
LigatureSubtable AlternateSubtable MultipleSubstSubtable
SingleSubstSubtable aalt_chain_contextual_subst AlternateChained
MultipleLookupsPerGlyph MultipleLookupsPerGlyph2
""".split()
def __init__(self, methodName):

View File

@ -1,9 +1,9 @@
feature test {
sub G' by G.swash;
sub A G' by G.swash;
subtable;
sub H' by H.swash;
sub A H' by H.swash;
subtable;
sub G' by g;
sub A G' by g;
subtable;
sub H' by H.swash;
sub A H' by H.swash;
} test;

View File

@ -34,7 +34,10 @@
<LookupFlag value="0"/>
<!-- SubTableCount=4 -->
<ChainContextSubst index="0" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- BacktrackGlyphCount=1 -->
<BacktrackCoverage index="0">
<Glyph value="A"/>
</BacktrackCoverage>
<!-- InputGlyphCount=1 -->
<InputCoverage index="0">
<Glyph value="G"/>
@ -47,7 +50,10 @@
</SubstLookupRecord>
</ChainContextSubst>
<ChainContextSubst index="1" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- BacktrackGlyphCount=1 -->
<BacktrackCoverage index="0">
<Glyph value="A"/>
</BacktrackCoverage>
<!-- InputGlyphCount=1 -->
<InputCoverage index="0">
<Glyph value="H"/>
@ -60,7 +66,10 @@
</SubstLookupRecord>
</ChainContextSubst>
<ChainContextSubst index="2" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- BacktrackGlyphCount=1 -->
<BacktrackCoverage index="0">
<Glyph value="A"/>
</BacktrackCoverage>
<!-- InputGlyphCount=1 -->
<InputCoverage index="0">
<Glyph value="G"/>
@ -73,7 +82,10 @@
</SubstLookupRecord>
</ChainContextSubst>
<ChainContextSubst index="3" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- BacktrackGlyphCount=1 -->
<BacktrackCoverage index="0">
<Glyph value="A"/>
</BacktrackCoverage>
<!-- InputGlyphCount=1 -->
<InputCoverage index="0">
<Glyph value="H"/>

View File

@ -0,0 +1,9 @@
feature test {
sub G' by G.swash;
subtable;
sub H' by H.swash;
subtable;
sub G' by g;
subtable;
sub H' by H.swash;
} test;

View File

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<ttFont>
<GSUB>
<Version value="0x00010000"/>
<ScriptList>
<!-- ScriptCount=1 -->
<ScriptRecord index="0">
<ScriptTag value="DFLT"/>
<Script>
<DefaultLangSys>
<ReqFeatureIndex value="65535"/>
<!-- FeatureCount=1 -->
<FeatureIndex index="0" value="0"/>
</DefaultLangSys>
<!-- LangSysCount=0 -->
</Script>
</ScriptRecord>
</ScriptList>
<FeatureList>
<!-- FeatureCount=1 -->
<FeatureRecord index="0">
<FeatureTag value="test"/>
<Feature>
<!-- LookupCount=1 -->
<LookupListIndex index="0" value="0"/>
</Feature>
</FeatureRecord>
</FeatureList>
<LookupList>
<!-- LookupCount=5 -->
<Lookup index="0">
<LookupType value="5"/>
<LookupFlag value="0"/>
<!-- SubTableCount=4 -->
<ContextSubst index="0" Format="3">
<!-- GlyphCount=1 -->
<!-- SubstCount=1 -->
<Coverage index="0">
<Glyph value="G"/>
</Coverage>
<SubstLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="1"/>
</SubstLookupRecord>
</ContextSubst>
<ContextSubst index="1" Format="3">
<!-- GlyphCount=1 -->
<!-- SubstCount=1 -->
<Coverage index="0">
<Glyph value="H"/>
</Coverage>
<SubstLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="2"/>
</SubstLookupRecord>
</ContextSubst>
<ContextSubst index="2" Format="3">
<!-- GlyphCount=1 -->
<!-- SubstCount=1 -->
<Coverage index="0">
<Glyph value="G"/>
</Coverage>
<SubstLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="3"/>
</SubstLookupRecord>
</ContextSubst>
<ContextSubst index="3" Format="3">
<!-- GlyphCount=1 -->
<!-- SubstCount=1 -->
<Coverage index="0">
<Glyph value="H"/>
</Coverage>
<SubstLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="4"/>
</SubstLookupRecord>
</ContextSubst>
</Lookup>
<Lookup index="1">
<LookupType value="1"/>
<LookupFlag value="0"/>
<!-- SubTableCount=1 -->
<SingleSubst index="0">
<Substitution in="G" out="G.swash"/>
</SingleSubst>
</Lookup>
<Lookup index="2">
<LookupType value="1"/>
<LookupFlag value="0"/>
<!-- SubTableCount=1 -->
<SingleSubst index="0">
<Substitution in="H" out="H.swash"/>
</SingleSubst>
</Lookup>
<Lookup index="3">
<LookupType value="1"/>
<LookupFlag value="0"/>
<!-- SubTableCount=1 -->
<SingleSubst index="0">
<Substitution in="G" out="g"/>
</SingleSubst>
</Lookup>
<Lookup index="4">
<LookupType value="1"/>
<LookupFlag value="0"/>
<!-- SubTableCount=1 -->
<SingleSubst index="0">
<Substitution in="H" out="H.swash"/>
</SingleSubst>
</Lookup>
</LookupList>
</GSUB>
</ttFont>

View File

@ -30,25 +30,23 @@
<LookupList>
<!-- LookupCount=2 -->
<Lookup index="0">
<LookupType value="6"/>
<LookupType value="5"/>
<LookupFlag value="0"/>
<!-- SubTableCount=1 -->
<ChainContextSubst index="0" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- InputGlyphCount=2 -->
<InputCoverage index="0">
<Glyph value="f"/>
</InputCoverage>
<InputCoverage index="1">
<Glyph value="i"/>
</InputCoverage>
<!-- LookAheadGlyphCount=0 -->
<ContextSubst index="0" Format="3">
<!-- GlyphCount=2 -->
<!-- SubstCount=1 -->
<Coverage index="0">
<Glyph value="f"/>
</Coverage>
<Coverage index="1">
<Glyph value="i"/>
</Coverage>
<SubstLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="1"/>
</SubstLookupRecord>
</ChainContextSubst>
</ContextSubst>
</Lookup>
<Lookup index="1">
<LookupType value="4"/>

View File

@ -30,33 +30,29 @@
<LookupList>
<!-- LookupCount=2 -->
<Lookup index="0">
<LookupType value="6"/>
<LookupType value="5"/>
<LookupFlag value="0"/>
<!-- SubTableCount=2 -->
<ChainContextSubst index="0" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- InputGlyphCount=1 -->
<InputCoverage index="0">
<Glyph value="A"/>
</InputCoverage>
<!-- LookAheadGlyphCount=0 -->
<ContextSubst index="0" Format="3">
<!-- GlyphCount=1 -->
<!-- SubstCount=0 -->
</ChainContextSubst>
<ChainContextSubst index="1" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- InputGlyphCount=1 -->
<InputCoverage index="0">
<Coverage index="0">
<Glyph value="A"/>
</Coverage>
</ContextSubst>
<ContextSubst index="1" Format="3">
<!-- GlyphCount=1 -->
<!-- SubstCount=1 -->
<Coverage index="0">
<Glyph value="A"/>
<Glyph value="A.sc"/>
<Glyph value="A.alt1"/>
</InputCoverage>
<!-- LookAheadGlyphCount=0 -->
<!-- SubstCount=1 -->
</Coverage>
<SubstLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="1"/>
</SubstLookupRecord>
</ChainContextSubst>
</ContextSubst>
</Lookup>
<Lookup index="1">
<LookupType value="1"/>

View File

@ -30,61 +30,53 @@
<LookupList>
<!-- LookupCount=3 -->
<Lookup index="0">
<LookupType value="6"/>
<LookupType value="5"/>
<LookupFlag value="0"/>
<!-- SubTableCount=4 -->
<ChainContextSubst index="0" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- InputGlyphCount=1 -->
<InputCoverage index="0">
<Glyph value="G"/>
</InputCoverage>
<!-- LookAheadGlyphCount=0 -->
<ContextSubst index="0" Format="3">
<!-- GlyphCount=1 -->
<!-- SubstCount=1 -->
<Coverage index="0">
<Glyph value="G"/>
</Coverage>
<SubstLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="1"/>
</SubstLookupRecord>
</ChainContextSubst>
<ChainContextSubst index="1" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- InputGlyphCount=1 -->
<InputCoverage index="0">
<Glyph value="H"/>
</InputCoverage>
<!-- LookAheadGlyphCount=0 -->
</ContextSubst>
<ContextSubst index="1" Format="3">
<!-- GlyphCount=1 -->
<!-- SubstCount=1 -->
<Coverage index="0">
<Glyph value="H"/>
</Coverage>
<SubstLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="1"/>
</SubstLookupRecord>
</ChainContextSubst>
<ChainContextSubst index="2" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- InputGlyphCount=1 -->
<InputCoverage index="0">
</ContextSubst>
<ContextSubst index="2" Format="3">
<!-- GlyphCount=1 -->
<!-- SubstCount=1 -->
<Coverage index="0">
<Glyph value="G"/>
</InputCoverage>
<!-- LookAheadGlyphCount=0 -->
<!-- SubstCount=1 -->
</Coverage>
<SubstLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="2"/>
</SubstLookupRecord>
</ChainContextSubst>
<ChainContextSubst index="3" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- InputGlyphCount=1 -->
<InputCoverage index="0">
</ContextSubst>
<ContextSubst index="3" Format="3">
<!-- GlyphCount=1 -->
<!-- SubstCount=1 -->
<Coverage index="0">
<Glyph value="H"/>
</InputCoverage>
<!-- LookAheadGlyphCount=0 -->
<!-- SubstCount=1 -->
</Coverage>
<SubstLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="2"/>
</SubstLookupRecord>
</ChainContextSubst>
</ContextSubst>
</Lookup>
<Lookup index="1">
<LookupType value="1"/>

View File

@ -112,25 +112,23 @@
</MarkBasePos>
</Lookup>
<Lookup index="2">
<LookupType value="8"/>
<LookupType value="7"/>
<LookupFlag value="0"/>
<!-- SubTableCount=1 -->
<ChainContextPos index="0" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- InputGlyphCount=3 -->
<InputCoverage index="0">
<ContextPos index="0" Format="3">
<!-- GlyphCount=3 -->
<!-- PosCount=2 -->
<Coverage index="0">
<Glyph value="T"/>
</InputCoverage>
<InputCoverage index="1">
</Coverage>
<Coverage index="1">
<Glyph value="c"/>
<Glyph value="o"/>
</InputCoverage>
<InputCoverage index="2">
</Coverage>
<Coverage index="2">
<Glyph value="grave"/>
<Glyph value="acute"/>
</InputCoverage>
<!-- LookAheadGlyphCount=0 -->
<!-- PosCount=2 -->
</Coverage>
<PosLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="0"/>
@ -139,7 +137,7 @@
<SequenceIndex value="2"/>
<LookupListIndex value="1"/>
</PosLookupRecord>
</ChainContextPos>
</ContextPos>
</Lookup>
</LookupList>
</GPOS>

View File

@ -30,25 +30,23 @@
<LookupList>
<!-- LookupCount=2 -->
<Lookup index="0">
<LookupType value="8"/>
<LookupType value="7"/>
<LookupFlag value="0"/>
<!-- SubTableCount=1 -->
<ChainContextPos index="0" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- InputGlyphCount=2 -->
<InputCoverage index="0">
<Glyph value="L"/>
</InputCoverage>
<InputCoverage index="1">
<Glyph value="quoteright"/>
</InputCoverage>
<!-- LookAheadGlyphCount=0 -->
<ContextPos index="0" Format="3">
<!-- GlyphCount=2 -->
<!-- PosCount=1 -->
<Coverage index="0">
<Glyph value="L"/>
</Coverage>
<Coverage index="1">
<Glyph value="quoteright"/>
</Coverage>
<PosLookupRecord index="0">
<SequenceIndex value="1"/>
<LookupListIndex value="1"/>
</PosLookupRecord>
</ChainContextPos>
</ContextPos>
</Lookup>
<Lookup index="1">
<LookupType value="1"/>

View File

@ -1392,6 +1392,57 @@ def test_stat_infinities():
assert struct.pack(">l", posInf) == b"\x7f\xff\xff\xff"
class ChainContextualRulesetTest(object):
def test_makeRulesets(self):
font = ttLib.TTFont()
font.setGlyphOrder(["a","b","c","d","A","B","C","D","E"])
sb = builder.ChainContextSubstBuilder(font, None)
prefix, input_, suffix, lookups = [["a"], ["b"]], [["c"]], [], [None]
sb.rules.append((prefix, input_, suffix, lookups))
prefix, input_, suffix, lookups = [["a"], ["d"]], [["c"]], [], [None]
sb.rules.append((prefix, input_, suffix, lookups))
sb.add_subtable_break(None)
# Second subtable has some glyph classes
prefix, input_, suffix, lookups = [["A"]], [["E"]], [], [None]
sb.rules.append((prefix, input_, suffix, lookups))
prefix, input_, suffix, lookups = [["A"]], [["C","D"]], [], [None]
sb.rules.append((prefix, input_, suffix, lookups))
prefix, input_, suffix, lookups = [["A", "B"]], [["E"]], [], [None]
sb.rules.append((prefix, input_, suffix, lookups))
sb.add_subtable_break(None)
# Third subtable has no pre/post context
prefix, input_, suffix, lookups = [], [["E"]], [], [None]
sb.rules.append((prefix, input_, suffix, lookups))
prefix, input_, suffix, lookups = [], [["C","D"]], [], [None]
sb.rules.append((prefix, input_, suffix, lookups))
rulesets = sb.rulesets()
assert len(rulesets) == 3
assert rulesets[0].hasPrefixOrSuffix
assert not rulesets[0].hasAnyGlyphClasses
cd = rulesets[0].format2ClassDefs()
assert set(cd[0].classes()[1:]) == set([("d",),("b",),("a",)])
assert set(cd[1].classes()[1:]) == set([("c",)])
assert set(cd[2].classes()[1:]) == set()
assert rulesets[1].hasPrefixOrSuffix
assert rulesets[1].hasAnyGlyphClasses
assert not rulesets[1].format2ClassDefs()
assert not rulesets[2].hasPrefixOrSuffix
assert rulesets[2].hasAnyGlyphClasses
assert rulesets[2].format2ClassDefs()
cd = rulesets[2].format2ClassDefs()
assert set(cd[0].classes()[1:]) == set()
assert set(cd[1].classes()[1:]) == set([("C","D"), ("E",)])
assert set(cd[2].classes()[1:]) == set()
if __name__ == "__main__":
import sys

View File

@ -83,23 +83,21 @@
</MarkBasePos>
</Lookup>
<Lookup index="2">
<LookupType value="8"/>
<LookupType value="7"/>
<LookupFlag value="0"/>
<!-- SubTableCount=1 -->
<ChainContextPos index="0" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- InputGlyphCount=3 -->
<InputCoverage index="0" Format="1">
<Glyph value="A"/>
</InputCoverage>
<InputCoverage index="1" Format="1">
<Glyph value="a"/>
</InputCoverage>
<InputCoverage index="2" Format="1">
<Glyph value="uni0303"/>
</InputCoverage>
<!-- LookAheadGlyphCount=0 -->
<ContextPos index="0" Format="3">
<!-- GlyphCount=3 -->
<!-- PosCount=2 -->
<Coverage index="0" Format="1">
<Glyph value="A"/>
</Coverage>
<Coverage index="1" Format="1">
<Glyph value="a"/>
</Coverage>
<Coverage index="2" Format="1">
<Glyph value="uni0303"/>
</Coverage>
<PosLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="0"/>
@ -108,7 +106,7 @@
<SequenceIndex value="2"/>
<LookupListIndex value="1"/>
</PosLookupRecord>
</ChainContextPos>
</ContextPos>
</Lookup>
</LookupList>
</GPOS>

View File

@ -83,23 +83,21 @@
</MarkBasePos>
</Lookup>
<Lookup index="2">
<LookupType value="8"/>
<LookupType value="7"/>
<LookupFlag value="0"/>
<!-- SubTableCount=1 -->
<ChainContextPos index="0" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- InputGlyphCount=3 -->
<InputCoverage index="0" Format="1">
<Glyph value="A"/>
</InputCoverage>
<InputCoverage index="1" Format="1">
<Glyph value="a"/>
</InputCoverage>
<InputCoverage index="2" Format="1">
<Glyph value="uni0303"/>
</InputCoverage>
<!-- LookAheadGlyphCount=0 -->
<ContextPos index="0" Format="3">
<!-- GlyphCount=3 -->
<!-- PosCount=2 -->
<Coverage index="0" Format="1">
<Glyph value="A"/>
</Coverage>
<Coverage index="1" Format="1">
<Glyph value="a"/>
</Coverage>
<Coverage index="2" Format="1">
<Glyph value="uni0303"/>
</Coverage>
<PosLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="0"/>
@ -108,7 +106,7 @@
<SequenceIndex value="2"/>
<LookupListIndex value="1"/>
</PosLookupRecord>
</ChainContextPos>
</ContextPos>
</Lookup>
</LookupList>
</GPOS>

View File

@ -748,8 +748,8 @@ class InterpolateLayoutTest(unittest.TestCase):
self.check_ttx_dump(instfont, expected_ttx_path, tables, suffix)
def test_varlib_interpolate_layout_GPOS_only_LookupType_8_same_val_ttf(self):
"""Only GPOS; LookupType 8; same values in all masters.
def test_varlib_interpolate_layout_GPOS_only_LookupType_7_same_val_ttf(self):
"""Only GPOS; LookupType 7; same values in all masters.
"""
suffix = '.ttf'
ds_path = self.get_test_input('InterpolateLayout.designspace')
@ -781,13 +781,13 @@ class InterpolateLayoutTest(unittest.TestCase):
instfont = interpolate_layout(ds_path, {'weight': 500}, finder)
tables = ['GPOS']
expected_ttx_path = self.get_test_output('InterpolateLayoutGPOS_8_same.ttx')
expected_ttx_path = self.get_test_output('InterpolateLayoutGPOS_7_same.ttx')
self.expect_ttx(instfont, expected_ttx_path, tables)
self.check_ttx_dump(instfont, expected_ttx_path, tables, suffix)
def test_varlib_interpolate_layout_GPOS_only_LookupType_8_diff_val_ttf(self):
"""Only GPOS; LookupType 8; different values in each master.
def test_varlib_interpolate_layout_GPOS_only_LookupType_7_diff_val_ttf(self):
"""Only GPOS; LookupType 7; different values in each master.
"""
suffix = '.ttf'
ds_path = self.get_test_input('InterpolateLayout.designspace')
@ -833,7 +833,7 @@ class InterpolateLayoutTest(unittest.TestCase):
instfont = interpolate_layout(ds_path, {'weight': 500}, finder)
tables = ['GPOS']
expected_ttx_path = self.get_test_output('InterpolateLayoutGPOS_8_diff.ttx')
expected_ttx_path = self.get_test_output('InterpolateLayoutGPOS_7_diff.ttx')
self.expect_ttx(instfont, expected_ttx_path, tables)
self.check_ttx_dump(instfont, expected_ttx_path, tables, suffix)