Merge pull request #1706 from dscorbett/splitMultipleSubst
Fix MultipleSubst subtable overflows
This commit is contained in:
commit
f2915e7480
@ -1226,6 +1226,32 @@ def fixLookupOverFlows(ttf, overflowRecord):
|
||||
ok = 1
|
||||
return ok
|
||||
|
||||
def splitMultipleSubst(oldSubTable, newSubTable, overflowRecord):
|
||||
ok = 1
|
||||
newSubTable.Format = oldSubTable.Format
|
||||
oldMapping = sorted(oldSubTable.mapping.items())
|
||||
oldLen = len(oldMapping)
|
||||
|
||||
if overflowRecord.itemName in ['Coverage', 'RangeRecord']:
|
||||
# Coverage table is written last. Overflow is to or within the
|
||||
# the coverage table. We will just cut the subtable in half.
|
||||
newLen = oldLen // 2
|
||||
|
||||
elif overflowRecord.itemName == 'Sequence':
|
||||
# We just need to back up by two items from the overflowed
|
||||
# Sequence index to make sure the offset to the Coverage table
|
||||
# doesn't overflow.
|
||||
newLen = overflowRecord.itemIndex - 1
|
||||
|
||||
newSubTable.mapping = {}
|
||||
for i in range(newLen, oldLen):
|
||||
item = oldMapping[i]
|
||||
key = item[0]
|
||||
newSubTable.mapping[key] = item[1]
|
||||
del oldSubTable.mapping[key]
|
||||
|
||||
return ok
|
||||
|
||||
def splitAlternateSubst(oldSubTable, newSubTable, overflowRecord):
|
||||
ok = 1
|
||||
newSubTable.Format = oldSubTable.Format
|
||||
@ -1413,7 +1439,7 @@ def splitMarkBasePos(oldSubTable, newSubTable, overflowRecord):
|
||||
|
||||
splitTable = { 'GSUB': {
|
||||
# 1: splitSingleSubst,
|
||||
# 2: splitMultipleSubst,
|
||||
2: splitMultipleSubst,
|
||||
3: splitAlternateSubst,
|
||||
4: splitLigatureSubst,
|
||||
# 5: splitContextSubst,
|
||||
|
@ -546,6 +546,37 @@ class InsertionMorphActionTest(unittest.TestCase):
|
||||
})
|
||||
|
||||
|
||||
class SplitMultipleSubstTest:
|
||||
def overflow(self, itemName, itemRecord):
|
||||
from fontTools.otlLib.builder import buildMultipleSubstSubtable
|
||||
from fontTools.ttLib.tables.otBase import OverflowErrorRecord
|
||||
|
||||
oldSubTable = buildMultipleSubstSubtable({'e': 1, 'a': 2, 'b': 3, 'c': 4, 'd': 5})
|
||||
oldSubTable.Format = 1
|
||||
newSubTable = otTables.MultipleSubst()
|
||||
|
||||
ok = otTables.splitMultipleSubst(oldSubTable, newSubTable, OverflowErrorRecord((None, None, None, itemName, itemRecord)))
|
||||
|
||||
assert ok
|
||||
assert oldSubTable.Format == newSubTable.Format
|
||||
return oldSubTable.mapping, newSubTable.mapping
|
||||
|
||||
def test_Coverage(self):
|
||||
oldMapping, newMapping = self.overflow('Coverage', None)
|
||||
assert oldMapping == {'a': 2, 'b': 3}
|
||||
assert newMapping == {'c': 4, 'd': 5, 'e': 1}
|
||||
|
||||
def test_RangeRecord(self):
|
||||
oldMapping, newMapping = self.overflow('RangeRecord', None)
|
||||
assert oldMapping == {'a': 2, 'b': 3}
|
||||
assert newMapping == {'c': 4, 'd': 5, 'e': 1}
|
||||
|
||||
def test_Sequence(self):
|
||||
oldMapping, newMapping = self.overflow('Sequence', 4)
|
||||
assert oldMapping == {'a': 2, 'b': 3,'c': 4}
|
||||
assert newMapping == {'d': 5, 'e': 1}
|
||||
|
||||
|
||||
def test_splitMarkBasePos():
|
||||
from fontTools.otlLib.builder import buildAnchor, buildMarkBasePosSubtable
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user