[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):
|
def build(self):
|
||||||
markClasses = self.buildMarkClasses_(self.marks)
|
markClasses = self.buildMarkClasses_(self.marks)
|
||||||
markClassList = sorted(markClasses.keys(), key=markClasses.get)
|
|
||||||
marks = {mark: (markClasses[mc], anchor)
|
marks = {mark: (markClasses[mc], anchor)
|
||||||
for mark, (mc, anchor) in self.marks.items()}
|
for mark, (mc, anchor) in self.marks.items()}
|
||||||
ligs = {}
|
ligs = {}
|
||||||
@ -992,16 +991,8 @@ class MarkLigPosBuilder(LookupBuilder):
|
|||||||
ligs[lig] = []
|
ligs[lig] = []
|
||||||
for c in components:
|
for c in components:
|
||||||
ligs[lig].append({markClasses[mc]: a for mc, a in c.items()})
|
ligs[lig].append({markClasses[mc]: a for mc, a in c.items()})
|
||||||
|
subtables = otl.buildMarkLigPos(marks, ligs, self.glyphMap)
|
||||||
st = otTables.MarkLigPos()
|
return self.buildLookup_(subtables)
|
||||||
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])
|
|
||||||
|
|
||||||
|
|
||||||
class MarkMarkPosBuilder(LookupBuilder):
|
class MarkMarkPosBuilder(LookupBuilder):
|
||||||
|
@ -211,7 +211,7 @@ def buildMarkArray(marks, glyphMap):
|
|||||||
def buildMarkBasePos(marks, bases, glyphMap):
|
def buildMarkBasePos(marks, bases, glyphMap):
|
||||||
"""Build a list of MarkBasePos subtables.
|
"""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)}
|
marks = {"acute": (0, a1), "grave": (0, a1), "cedilla": (1, a2)}
|
||||||
bases = {"a": {0: a3, 1: a5}, "b": {0: a4, 1: a5}}
|
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):
|
def buildMarkBasePosSubtable(marks, bases, glyphMap):
|
||||||
"""Build a single MarkBasePos subtable.
|
"""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)}
|
marks = {"acute": (0, a1), "grave": (0, a1), "cedilla": (1, a2)}
|
||||||
bases = {"a": {0: a3, 1: a5}, "b": {0: a4, 1: a5}}
|
bases = {"a": {0: a3, 1: a5}, "b": {0: a4, 1: a5}}
|
||||||
"""
|
"""
|
||||||
@ -246,6 +246,37 @@ def buildMarkBasePosSubtable(marks, bases, glyphMap):
|
|||||||
return self
|
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):
|
def buildMarkRecord(classID, anchor):
|
||||||
assert isinstance(classID, int)
|
assert isinstance(classID, int)
|
||||||
assert isinstance(anchor, ot.Anchor)
|
assert isinstance(anchor, ot.Anchor)
|
||||||
|
@ -632,6 +632,100 @@ class BuilderTest(unittest.TestCase):
|
|||||||
def test_buildMarkGlyphSetsDef_None(self):
|
def test_buildMarkGlyphSetsDef_None(self):
|
||||||
self.assertIsNone(builder.buildMarkGlyphSetsDef(None, self.GLYPHMAP))
|
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):
|
def test_buildMarkRecord(self):
|
||||||
rec = builder.buildMarkRecord(17, builder.buildAnchor(500, -20))
|
rec = builder.buildMarkRecord(17, builder.buildAnchor(500, -20))
|
||||||
self.assertEqual(getXML(rec.toXML),
|
self.assertEqual(getXML(rec.toXML),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user