[feaLib] "subtable" in contextual positioning

This commit is contained in:
Khaled Hosny 2019-02-25 23:39:04 +02:00
parent 47d30499a5
commit cc1b6baff7
4 changed files with 209 additions and 12 deletions

View File

@ -1002,28 +1002,19 @@ class Builder(object):
for glyph in glyphs:
lookup.add_pos(location, glyph, value)
def find_chainable_SinglePos_(self, lookups, glyphs, value):
"""Helper for add_single_pos_chained_()"""
for look in lookups:
if all(look.can_add(glyph, value) for glyph in glyphs):
return look
return None
def add_single_pos_chained_(self, location, prefix, suffix, pos):
# https://github.com/fonttools/fonttools/issues/514
chain = self.get_lookup_(location, ChainContextPosBuilder)
targets = []
for _, _, _, lookups in chain.rules:
for lookup in lookups:
if isinstance(lookup, SinglePosBuilder):
targets.append(lookup)
targets.extend(lookups)
subs = []
for glyphs, value in pos:
if value is None:
subs.append(None)
continue
otValue, _ = makeOpenTypeValueRecord(value, pairPosContext=False)
sub = self.find_chainable_SinglePos_(targets, glyphs, otValue)
sub = chain.find_chainable_single_pos(targets, glyphs, otValue)
if sub is None:
sub = self.get_chained_lookup_(location, SinglePosBuilder)
targets.append(sub)
@ -1213,6 +1204,8 @@ class ChainContextPosBuilder(LookupBuilder):
def build(self):
subtables = []
for (prefix, glyphs, suffix, lookups) in self.rules:
if prefix == self.SUBTABLE_BREAK_:
continue
st = otTables.ChainContextPos()
subtables.append(st)
st.Format = 3
@ -1230,6 +1223,21 @@ class ChainContextPosBuilder(LookupBuilder):
st.PosLookupRecord.append(rec)
return self.buildLookup_(subtables)
def find_chainable_single_pos(self, lookups, glyphs, value):
"""Helper for add_single_pos_chained_()"""
res = None
for lookup in lookups[::-1]:
if lookup == self.SUBTABLE_BREAK_:
return res
if isinstance(lookup, SinglePosBuilder) and \
all(lookup.can_add(glyph, value) for glyph in glyphs):
res = lookup
return res
def add_subtable_break(self, location):
self.rules.append((self.SUBTABLE_BREAK_, self.SUBTABLE_BREAK_,
self.SUBTABLE_BREAK_, [self.SUBTABLE_BREAK_]))
class ChainContextSubstBuilder(LookupBuilder):
def __init__(self, font, location):

View File

@ -70,7 +70,7 @@ class BuilderTest(unittest.TestCase):
ZeroValue_SinglePos_horizontal ZeroValue_SinglePos_vertical
ZeroValue_PairPos_horizontal ZeroValue_PairPos_vertical
ZeroValue_ChainSinglePos_horizontal ZeroValue_ChainSinglePos_vertical
PairPosSubtable ChainSubstSubtable
PairPosSubtable ChainSubstSubtable ChainPosSubtable
""".split()
def __init__(self, methodName):

View File

@ -0,0 +1,7 @@
feature test {
pos X [A-B]' -40 B' -40 A' -40 Y;
subtable;
pos X A' -111 Y;
subtable;
pos X B' -40 A' -111 [A-C]' -40 Y;
} test;

View File

@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8"?>
<ttFont>
<GPOS>
<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="8"/>
<LookupFlag value="0"/>
<!-- SubTableCount=3 -->
<ChainContextPos index="0" Format="3">
<!-- BacktrackGlyphCount=1 -->
<BacktrackCoverage index="0">
<Glyph value="X"/>
</BacktrackCoverage>
<!-- InputGlyphCount=3 -->
<InputCoverage index="0">
<Glyph value="A"/>
<Glyph value="B"/>
</InputCoverage>
<InputCoverage index="1">
<Glyph value="B"/>
</InputCoverage>
<InputCoverage index="2">
<Glyph value="A"/>
</InputCoverage>
<!-- LookAheadGlyphCount=1 -->
<LookAheadCoverage index="0">
<Glyph value="Y"/>
</LookAheadCoverage>
<!-- PosCount=3 -->
<PosLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="1"/>
</PosLookupRecord>
<PosLookupRecord index="1">
<SequenceIndex value="1"/>
<LookupListIndex value="1"/>
</PosLookupRecord>
<PosLookupRecord index="2">
<SequenceIndex value="2"/>
<LookupListIndex value="1"/>
</PosLookupRecord>
</ChainContextPos>
<ChainContextPos index="1" Format="3">
<!-- BacktrackGlyphCount=1 -->
<BacktrackCoverage index="0">
<Glyph value="X"/>
</BacktrackCoverage>
<!-- InputGlyphCount=1 -->
<InputCoverage index="0">
<Glyph value="A"/>
</InputCoverage>
<!-- LookAheadGlyphCount=1 -->
<LookAheadCoverage index="0">
<Glyph value="Y"/>
</LookAheadCoverage>
<!-- PosCount=1 -->
<PosLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="2"/>
</PosLookupRecord>
</ChainContextPos>
<ChainContextPos index="2" Format="3">
<!-- BacktrackGlyphCount=1 -->
<BacktrackCoverage index="0">
<Glyph value="X"/>
</BacktrackCoverage>
<!-- InputGlyphCount=3 -->
<InputCoverage index="0">
<Glyph value="B"/>
</InputCoverage>
<InputCoverage index="1">
<Glyph value="A"/>
</InputCoverage>
<InputCoverage index="2">
<Glyph value="A"/>
<Glyph value="B"/>
<Glyph value="C"/>
</InputCoverage>
<!-- LookAheadGlyphCount=1 -->
<LookAheadCoverage index="0">
<Glyph value="Y"/>
</LookAheadCoverage>
<!-- PosCount=3 -->
<PosLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="3"/>
</PosLookupRecord>
<PosLookupRecord index="1">
<SequenceIndex value="1"/>
<LookupListIndex value="3"/>
</PosLookupRecord>
<PosLookupRecord index="2">
<SequenceIndex value="2"/>
<LookupListIndex value="4"/>
</PosLookupRecord>
</ChainContextPos>
</Lookup>
<Lookup index="1">
<LookupType value="1"/>
<LookupFlag value="0"/>
<!-- SubTableCount=1 -->
<SinglePos index="0" Format="1">
<Coverage>
<Glyph value="A"/>
<Glyph value="B"/>
</Coverage>
<ValueFormat value="4"/>
<Value XAdvance="-40"/>
</SinglePos>
</Lookup>
<Lookup index="2">
<LookupType value="1"/>
<LookupFlag value="0"/>
<!-- SubTableCount=1 -->
<SinglePos index="0" Format="1">
<Coverage>
<Glyph value="A"/>
</Coverage>
<ValueFormat value="4"/>
<Value XAdvance="-111"/>
</SinglePos>
</Lookup>
<Lookup index="3">
<LookupType value="1"/>
<LookupFlag value="0"/>
<!-- SubTableCount=1 -->
<SinglePos index="0" Format="2">
<Coverage>
<Glyph value="A"/>
<Glyph value="B"/>
</Coverage>
<ValueFormat value="4"/>
<!-- ValueCount=2 -->
<Value index="0" XAdvance="-111"/>
<Value index="1" XAdvance="-40"/>
</SinglePos>
</Lookup>
<Lookup index="4">
<LookupType value="1"/>
<LookupFlag value="0"/>
<!-- SubTableCount=1 -->
<SinglePos index="0" Format="1">
<Coverage>
<Glyph value="A"/>
<Glyph value="B"/>
<Glyph value="C"/>
</Coverage>
<ValueFormat value="4"/>
<Value XAdvance="-40"/>
</SinglePos>
</Lookup>
</LookupList>
</GPOS>
</ttFont>