Merge pull request #1297 from anthrotype/fix-mark-base-overflow
atttempt to fix offset overflows in MarkBasePos subtables
This commit is contained in:
commit
5a1ccf1640
@ -1281,6 +1281,67 @@ def splitPairPos(oldSubTable, newSubTable, overflowRecord):
|
||||
return ok
|
||||
|
||||
|
||||
def splitMarkBasePos(oldSubTable, newSubTable, overflowRecord):
|
||||
# split half of the mark classes to the new subtable
|
||||
classCount = oldSubTable.ClassCount
|
||||
if classCount < 2:
|
||||
# oh well, not much left to split...
|
||||
return False
|
||||
|
||||
oldClassCount = classCount // 2
|
||||
newClassCount = classCount - oldClassCount
|
||||
|
||||
oldMarkCoverage, oldMarkRecords = [], []
|
||||
newMarkCoverage, newMarkRecords = [], []
|
||||
for glyphName, markRecord in zip(
|
||||
oldSubTable.MarkCoverage.glyphs,
|
||||
oldSubTable.MarkArray.MarkRecord
|
||||
):
|
||||
if markRecord.Class < oldClassCount:
|
||||
oldMarkCoverage.append(glyphName)
|
||||
oldMarkRecords.append(markRecord)
|
||||
else:
|
||||
newMarkCoverage.append(glyphName)
|
||||
newMarkRecords.append(markRecord)
|
||||
|
||||
oldBaseRecords, newBaseRecords = [], []
|
||||
for rec in oldSubTable.BaseArray.BaseRecord:
|
||||
oldBaseRecord, newBaseRecord = rec.__class__(), rec.__class__()
|
||||
oldBaseRecord.BaseAnchor = rec.BaseAnchor[:oldClassCount]
|
||||
newBaseRecord.BaseAnchor = rec.BaseAnchor[oldClassCount:]
|
||||
oldBaseRecords.append(oldBaseRecord)
|
||||
newBaseRecords.append(newBaseRecord)
|
||||
|
||||
newSubTable.Format = oldSubTable.Format
|
||||
|
||||
oldSubTable.MarkCoverage.glyphs = oldMarkCoverage
|
||||
newSubTable.MarkCoverage = oldSubTable.MarkCoverage.__class__()
|
||||
newSubTable.MarkCoverage.Format = oldSubTable.MarkCoverage.Format
|
||||
newSubTable.MarkCoverage.glyphs = newMarkCoverage
|
||||
|
||||
# share the same BaseCoverage in both halves
|
||||
newSubTable.BaseCoverage = oldSubTable.BaseCoverage
|
||||
|
||||
oldSubTable.ClassCount = oldClassCount
|
||||
newSubTable.ClassCount = newClassCount
|
||||
|
||||
oldSubTable.MarkArray.MarkRecord = oldMarkRecords
|
||||
newSubTable.MarkArray = oldSubTable.MarkArray.__class__()
|
||||
newSubTable.MarkArray.MarkRecord = newMarkRecords
|
||||
|
||||
oldSubTable.MarkArray.MarkCount = len(oldMarkRecords)
|
||||
newSubTable.MarkArray.MarkCount = len(newMarkRecords)
|
||||
|
||||
oldSubTable.BaseArray.BaseRecord = oldBaseRecords
|
||||
newSubTable.BaseArray = oldSubTable.BaseArray.__class__()
|
||||
newSubTable.BaseArray.BaseRecord = newBaseRecords
|
||||
|
||||
oldSubTable.BaseArray.BaseCount = len(oldBaseRecords)
|
||||
newSubTable.BaseArray.BaseCount = len(newBaseRecords)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
splitTable = { 'GSUB': {
|
||||
# 1: splitSingleSubst,
|
||||
# 2: splitMultipleSubst,
|
||||
@ -1295,7 +1356,7 @@ splitTable = { 'GSUB': {
|
||||
# 1: splitSinglePos,
|
||||
2: splitPairPos,
|
||||
# 3: splitCursivePos,
|
||||
# 4: splitMarkBasePos,
|
||||
4: splitMarkBasePos,
|
||||
# 5: splitMarkLigPos,
|
||||
# 6: splitMarkMarkPos,
|
||||
# 7: splitContextPos,
|
||||
@ -1347,6 +1408,11 @@ def fixSubTableOverFlows(ttf, overflowRecord):
|
||||
try:
|
||||
splitFunc = splitTable[overflowRecord.tableType][subTableType]
|
||||
except KeyError:
|
||||
log.error(
|
||||
"Don't know how to split %s lookup type %s",
|
||||
overflowRecord.tableType,
|
||||
subTableType,
|
||||
)
|
||||
return ok
|
||||
|
||||
ok = splitFunc(subtable, newSubTable, overflowRecord)
|
||||
|
@ -485,6 +485,50 @@ class InsertionMorphActionTest(unittest.TestCase):
|
||||
self.assertEqual(hexStr(writer.getAllData()), "1234fc4300090007")
|
||||
|
||||
|
||||
def test_splitMarkBasePos():
|
||||
from fontTools.otlLib.builder import buildAnchor, buildMarkBasePosSubtable
|
||||
|
||||
marks = {
|
||||
"acutecomb": (0, buildAnchor(0, 600)),
|
||||
"gravecomb": (0, buildAnchor(0, 590)),
|
||||
"cedillacomb": (1, buildAnchor(0, 0)),
|
||||
}
|
||||
bases = {
|
||||
"a": {
|
||||
0: buildAnchor(350, 500),
|
||||
1: None,
|
||||
},
|
||||
"c": {
|
||||
0: buildAnchor(300, 700),
|
||||
1: buildAnchor(300, 0),
|
||||
},
|
||||
}
|
||||
glyphOrder = ["a", "c", "acutecomb", "gravecomb", "cedillacomb"]
|
||||
glyphMap = {g: i for i, g in enumerate(glyphOrder)}
|
||||
|
||||
oldSubTable = buildMarkBasePosSubtable(marks, bases, glyphMap)
|
||||
oldSubTable.MarkCoverage.Format = oldSubTable.BaseCoverage.Format = 1
|
||||
newSubTable = otTables.MarkBasePos()
|
||||
|
||||
ok = otTables.splitMarkBasePos(oldSubTable, newSubTable, overflowRecord=None)
|
||||
|
||||
assert ok
|
||||
assert oldSubTable.Format == newSubTable.Format
|
||||
assert oldSubTable.MarkCoverage.glyphs == [
|
||||
"acutecomb", "gravecomb"
|
||||
]
|
||||
assert newSubTable.MarkCoverage.glyphs == ["cedillacomb"]
|
||||
assert newSubTable.MarkCoverage.Format == 1
|
||||
assert oldSubTable.BaseCoverage.glyphs == newSubTable.BaseCoverage.glyphs
|
||||
assert newSubTable.BaseCoverage.Format == 1
|
||||
assert oldSubTable.ClassCount == newSubTable.ClassCount == 1
|
||||
assert oldSubTable.MarkArray.MarkCount == 2
|
||||
assert newSubTable.MarkArray.MarkCount == 1
|
||||
assert oldSubTable.BaseArray.BaseCount == newSubTable.BaseArray.BaseCount
|
||||
assert newSubTable.BaseArray.BaseRecord[0].BaseAnchor[0] is None
|
||||
assert newSubTable.BaseArray.BaseRecord[1].BaseAnchor[0] == buildAnchor(300, 0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
sys.exit(unittest.main())
|
||||
|
Loading…
x
Reference in New Issue
Block a user