[otlLib] Move building of MarkLigPos from feaLib to otlLib
This commit is contained in:
parent
036e2ce497
commit
af48e43371
@ -984,7 +984,6 @@ class MarkLigPosBuilder(LookupBuilder):
|
||||
|
||||
def build(self):
|
||||
markClasses = self.buildMarkClasses_(self.marks)
|
||||
markClassList = sorted(markClasses.keys(), key=markClasses.get)
|
||||
marks = {mark: (markClasses[mc], anchor)
|
||||
for mark, (mc, anchor) in self.marks.items()}
|
||||
ligs = {}
|
||||
@ -992,16 +991,8 @@ class MarkLigPosBuilder(LookupBuilder):
|
||||
ligs[lig] = []
|
||||
for c in components:
|
||||
ligs[lig].append({markClasses[mc]: a for mc, a in c.items()})
|
||||
|
||||
st = otTables.MarkLigPos()
|
||||
st.Format = 1
|
||||
st.MarkCoverage = otl.buildCoverage(marks, self.glyphMap)
|
||||
st.MarkArray = otl.buildMarkArray(marks, self.glyphMap)
|
||||
st.ClassCount = max([mc for mc, _ in marks.values()]) + 1
|
||||
st.LigatureCoverage = otl.buildCoverage(ligs, self.glyphMap)
|
||||
st.LigatureArray = \
|
||||
otl.buildLigatureArray(ligs, st.ClassCount, self.glyphMap)
|
||||
return self.buildLookup_([st])
|
||||
subtables = otl.buildMarkLigPos(marks, ligs, self.glyphMap)
|
||||
return self.buildLookup_(subtables)
|
||||
|
||||
|
||||
class MarkMarkPosBuilder(LookupBuilder):
|
||||
|
@ -211,7 +211,7 @@ def buildMarkArray(marks, glyphMap):
|
||||
def buildMarkBasePos(marks, bases, glyphMap):
|
||||
"""Build a list of MarkBasePos subtables.
|
||||
|
||||
a1, a2, a3, a4 = buildAnchor(500, 100), ...
|
||||
a1, a2, a3, a4, a5 = buildAnchor(500, 100), ...
|
||||
marks = {"acute": (0, a1), "grave": (0, a1), "cedilla": (1, a2)}
|
||||
bases = {"a": {0: a3, 1: a5}, "b": {0: a4, 1: a5}}
|
||||
"""
|
||||
@ -232,7 +232,7 @@ def buildMarkBasePos(marks, bases, glyphMap):
|
||||
def buildMarkBasePosSubtable(marks, bases, glyphMap):
|
||||
"""Build a single MarkBasePos subtable.
|
||||
|
||||
a1, a2, a3, a4 = buildAnchor(500, 100), ...
|
||||
a1, a2, a3, a4, a5 = buildAnchor(500, 100), ...
|
||||
marks = {"acute": (0, a1), "grave": (0, a1), "cedilla": (1, a2)}
|
||||
bases = {"a": {0: a3, 1: a5}, "b": {0: a4, 1: a5}}
|
||||
"""
|
||||
@ -246,6 +246,37 @@ def buildMarkBasePosSubtable(marks, bases, glyphMap):
|
||||
return self
|
||||
|
||||
|
||||
def buildMarkLigPos(marks, ligs, glyphMap):
|
||||
"""Build a list of MarkLigPos subtables.
|
||||
|
||||
a1, a2, a3, a4, a5 = buildAnchor(500, 100), ...
|
||||
marks = {"acute": (0, a1), "grave": (0, a1), "cedilla": (1, a2)}
|
||||
ligs = {"f_i": [{0: a3, 1: a5}, {0: a4, 1: a5}], "c_t": [{...}, {...}]}
|
||||
"""
|
||||
# TODO: Consider splitting into multiple subtables to save space,
|
||||
# as with MarkBasePos, this would be a trade-off that would need
|
||||
# profiling. And, depending on how typical fonts are structured,
|
||||
# it might not be worth doing at all.
|
||||
return [buildMarkLigPosSubtable(marks, ligs, glyphMap)]
|
||||
|
||||
|
||||
def buildMarkLigPosSubtable(marks, ligs, glyphMap):
|
||||
"""Build a single MarkLigPos subtable.
|
||||
|
||||
a1, a2, a3, a4, a5 = buildAnchor(500, 100), ...
|
||||
marks = {"acute": (0, a1), "grave": (0, a1), "cedilla": (1, a2)}
|
||||
ligs = {"f_i": [{0: a3, 1: a5}, {0: a4, 1: a5}], "c_t": [{...}, {...}]}
|
||||
"""
|
||||
self = ot.MarkLigPos()
|
||||
self.Format = 1
|
||||
self.MarkCoverage = buildCoverage(marks, glyphMap)
|
||||
self.MarkArray = buildMarkArray(marks, glyphMap)
|
||||
self.ClassCount = max([mc for mc, _ in marks.values()]) + 1
|
||||
self.LigatureCoverage = buildCoverage(ligs, glyphMap)
|
||||
self.LigatureArray = buildLigatureArray(ligs, self.ClassCount, glyphMap)
|
||||
return self
|
||||
|
||||
|
||||
def buildMarkRecord(classID, anchor):
|
||||
assert isinstance(classID, int)
|
||||
assert isinstance(anchor, ot.Anchor)
|
||||
|
@ -632,6 +632,100 @@ class BuilderTest(unittest.TestCase):
|
||||
def test_buildMarkGlyphSetsDef_None(self):
|
||||
self.assertIsNone(builder.buildMarkGlyphSetsDef(None, self.GLYPHMAP))
|
||||
|
||||
def test_buildMarkLigPosSubtable(self):
|
||||
anchor = builder.buildAnchor
|
||||
marks = {
|
||||
"acute": (0, anchor(300, 700)),
|
||||
"cedilla": (1, anchor(300, -100)),
|
||||
"grave": (0, anchor(300, 700))
|
||||
}
|
||||
bases = {
|
||||
"f_i": [{}, {0: anchor(200, 400)}], # nothing on f; only 1 on i
|
||||
"c_t": [
|
||||
{0: anchor(500, 600), 1: anchor(500, -20)}, # c
|
||||
{0: anchor(1300, 800), 1: anchor(1300, -20)} # t
|
||||
]
|
||||
}
|
||||
table = builder.buildMarkLigPosSubtable(marks, bases, self.GLYPHMAP)
|
||||
self.maxDiff = None
|
||||
self.assertEqual(getXML(table.toXML),
|
||||
'<MarkLigPos Format="1">'
|
||||
' <MarkCoverage>'
|
||||
' <Glyph value="grave"/>'
|
||||
' <Glyph value="acute"/>'
|
||||
' <Glyph value="cedilla"/>'
|
||||
' </MarkCoverage>'
|
||||
' <LigatureCoverage>'
|
||||
' <Glyph value="f_i"/>'
|
||||
' <Glyph value="c_t"/>'
|
||||
' </LigatureCoverage>'
|
||||
' <!-- ClassCount=2 -->'
|
||||
' <MarkArray>'
|
||||
' <!-- MarkCount=3 -->'
|
||||
' <MarkRecord index="0">'
|
||||
' <Class value="0"/>'
|
||||
' <MarkAnchor Format="1">'
|
||||
' <XCoordinate value="300"/>'
|
||||
' <YCoordinate value="700"/>'
|
||||
' </MarkAnchor>'
|
||||
' </MarkRecord>'
|
||||
' <MarkRecord index="1">'
|
||||
' <Class value="0"/>'
|
||||
' <MarkAnchor Format="1">'
|
||||
' <XCoordinate value="300"/>'
|
||||
' <YCoordinate value="700"/>'
|
||||
' </MarkAnchor>'
|
||||
' </MarkRecord>'
|
||||
' <MarkRecord index="2">'
|
||||
' <Class value="1"/>'
|
||||
' <MarkAnchor Format="1">'
|
||||
' <XCoordinate value="300"/>'
|
||||
' <YCoordinate value="-100"/>'
|
||||
' </MarkAnchor>'
|
||||
' </MarkRecord>'
|
||||
' </MarkArray>'
|
||||
' <LigatureArray>'
|
||||
' <!-- LigatureCount=2 -->'
|
||||
' <LigatureAttach index="0">'
|
||||
' <!-- ComponentCount=2 -->'
|
||||
' <ComponentRecord index="0">'
|
||||
' <LigatureAnchor index="0" empty="1"/>'
|
||||
' <LigatureAnchor index="1" empty="1"/>'
|
||||
' </ComponentRecord>'
|
||||
' <ComponentRecord index="1">'
|
||||
' <LigatureAnchor index="0" Format="1">'
|
||||
' <XCoordinate value="200"/>'
|
||||
' <YCoordinate value="400"/>'
|
||||
' </LigatureAnchor>'
|
||||
' <LigatureAnchor index="1" empty="1"/>'
|
||||
' </ComponentRecord>'
|
||||
' </LigatureAttach>'
|
||||
' <LigatureAttach index="1">'
|
||||
' <!-- ComponentCount=2 -->'
|
||||
' <ComponentRecord index="0">'
|
||||
' <LigatureAnchor index="0" Format="1">'
|
||||
' <XCoordinate value="500"/>'
|
||||
' <YCoordinate value="600"/>'
|
||||
' </LigatureAnchor>'
|
||||
' <LigatureAnchor index="1" Format="1">'
|
||||
' <XCoordinate value="500"/>'
|
||||
' <YCoordinate value="-20"/>'
|
||||
' </LigatureAnchor>'
|
||||
' </ComponentRecord>'
|
||||
' <ComponentRecord index="1">'
|
||||
' <LigatureAnchor index="0" Format="1">'
|
||||
' <XCoordinate value="1300"/>'
|
||||
' <YCoordinate value="800"/>'
|
||||
' </LigatureAnchor>'
|
||||
' <LigatureAnchor index="1" Format="1">'
|
||||
' <XCoordinate value="1300"/>'
|
||||
' <YCoordinate value="-20"/>'
|
||||
' </LigatureAnchor>'
|
||||
' </ComponentRecord>'
|
||||
' </LigatureAttach>'
|
||||
' </LigatureArray>'
|
||||
'</MarkLigPos>')
|
||||
|
||||
def test_buildMarkRecord(self):
|
||||
rec = builder.buildMarkRecord(17, builder.buildAnchor(500, -20))
|
||||
self.assertEqual(getXML(rec.toXML),
|
||||
|
Loading…
x
Reference in New Issue
Block a user