[otlLib] Move building of MarkArrays from feaLib to otlLib

This commit is contained in:
Sascha Brawer 2016-01-21 16:23:55 +01:00
parent f09de4277d
commit 08fa0f14dd
3 changed files with 55 additions and 21 deletions

View File

@ -751,17 +751,6 @@ class LookupBuilder(object):
coverage = otl.buildCoverage(g, self.glyphMap)
subtable.InputCoverage.append(coverage)
def buildMarkArray_(self, marks, markClassIDs):
"""Helper for Mark{Base,Lig,Mark}PosBuilder."""
array = otTables.MarkArray()
array.MarkCount = len(marks)
array.MarkRecord = []
for mark in sorted(marks.keys(), key=self.glyphMap.__getitem__):
className, anchor = marks[mark]
markrec = otl.buildMarkRecord(markClassIDs[className], anchor)
array.MarkRecord.append(markrec)
return array
class AlternateSubstBuilder(LookupBuilder):
def __init__(self, font, location):
@ -976,13 +965,15 @@ class MarkBasePosBuilder(LookupBuilder):
# allow partitioning into multiple subsets. We should find out
# whether this is the case; if so, implement the optimization.
markClasses = self.buildMarkClasses_(self.marks)
marks = {mark: (markClasses[mc], anchor)
for mark, (mc, anchor) in self.marks.items()}
st = otTables.MarkBasePos()
st.Format = 1
st.MarkCoverage = otl.buildCoverage(self.marks, self.glyphMap)
markClasses = self.buildMarkClasses_(self.marks)
st.MarkCoverage = otl.buildCoverage(marks, self.glyphMap)
st.MarkArray = otl.buildMarkArray(marks, self.glyphMap)
st.ClassCount = len(markClasses)
st.MarkArray = self.buildMarkArray_(self.marks, markClasses)
st.BaseCoverage = otl.buildCoverage(self.bases, self.glyphMap)
st.BaseArray = otTables.BaseArray()
st.BaseArray.BaseCount = len(st.BaseCoverage.glyphs)
@ -1016,11 +1007,14 @@ 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()}
st = otTables.MarkLigPos()
st.Format = 1
st.MarkCoverage = otl.buildCoverage(self.marks, self.glyphMap)
st.MarkCoverage = otl.buildCoverage(marks, self.glyphMap)
st.MarkArray = otl.buildMarkArray(marks, self.glyphMap)
st.ClassCount = len(markClasses)
st.MarkArray = self.buildMarkArray_(self.marks, markClasses)
st.LigatureCoverage = otl.buildCoverage(self.ligatures, self.glyphMap)
st.LigatureArray = otTables.LigatureArray()
st.LigatureArray.LigatureCount = len(self.ligatures)
@ -1056,17 +1050,20 @@ class MarkMarkPosBuilder(LookupBuilder):
return result
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()}
st = otTables.MarkMarkPos()
st.Format = 1
markClasses = self.buildMarkClasses_(self.marks)
st.ClassCount = len(markClasses)
st.Mark1Coverage = otl.buildCoverage(self.marks, self.glyphMap)
st.Mark1Coverage = otl.buildCoverage(marks, self.glyphMap)
st.Mark2Coverage = otl.buildCoverage(self.baseMarks, self.glyphMap)
st.Mark1Array = self.buildMarkArray_(self.marks, markClasses)
st.Mark1Array = otl.buildMarkArray(marks, self.glyphMap)
st.Mark2Array = otTables.Mark2Array()
st.Mark2Array.Mark2Count = len(st.Mark2Coverage.glyphs)
st.Mark2Array.Mark2Record = []
markClassList = sorted(markClasses.keys(), key=markClasses.get)
for base in st.Mark2Coverage.glyphs:
anchors = [self.baseMarks[base].get(mc) for mc in markClassList]
st.Mark2Array.Mark2Record.append(otl.buildMark2Record(anchors))

View File

@ -156,6 +156,18 @@ def buildDevice(device):
return self
def buildMarkArray(marks, glyphMap):
"""{"acute": (markClass, otTables.Anchor)} --> otTables.MarkArray"""
self = ot.MarkArray()
self.MarkCount = len(marks)
self.MarkRecord = []
for mark in sorted(marks.keys(), key=glyphMap.__getitem__):
markClass, anchor = marks[mark]
markrec = buildMarkRecord(markClass, anchor)
self.MarkRecord.append(markrec)
return self
def buildMarkRecord(classID, anchor):
assert isinstance(classID, int)
assert isinstance(anchor, ot.Anchor)

View File

@ -338,6 +338,31 @@ class BuilderTest(unittest.TestCase):
' <MarkFilteringSet value="999"/>'
'</Lookup>')
def test_buildMarkArray(self):
markArray = builder.buildMarkArray({
"acute": (7, builder.buildAnchor(300, 800)),
"grave": (2, builder.buildAnchor(10, 80))
}, self.GLYPHMAP)
self.assertLess(self.GLYPHMAP["grave"], self.GLYPHMAP["acute"])
self.assertEqual(getXML(markArray.toXML),
'<MarkArray>'
' <!-- MarkCount=2 -->'
' <MarkRecord index="0">'
' <Class value="2"/>'
' <MarkAnchor Format="1">'
' <XCoordinate value="10"/>'
' <YCoordinate value="80"/>'
' </MarkAnchor>'
' </MarkRecord>'
' <MarkRecord index="1">'
' <Class value="7"/>'
' <MarkAnchor Format="1">'
' <XCoordinate value="300"/>'
' <YCoordinate value="800"/>'
' </MarkAnchor>'
' </MarkRecord>'
'</MarkArray>')
def test_buildMarkGlyphSetsDef(self):
marksets = builder.buildMarkGlyphSetsDef(
[{"acute", "grave"}, {"cedilla", "grave"}], self.GLYPHMAP)