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
|
ok = 1
|
||||||
return ok
|
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):
|
def splitAlternateSubst(oldSubTable, newSubTable, overflowRecord):
|
||||||
ok = 1
|
ok = 1
|
||||||
newSubTable.Format = oldSubTable.Format
|
newSubTable.Format = oldSubTable.Format
|
||||||
@ -1413,7 +1439,7 @@ def splitMarkBasePos(oldSubTable, newSubTable, overflowRecord):
|
|||||||
|
|
||||||
splitTable = { 'GSUB': {
|
splitTable = { 'GSUB': {
|
||||||
# 1: splitSingleSubst,
|
# 1: splitSingleSubst,
|
||||||
# 2: splitMultipleSubst,
|
2: splitMultipleSubst,
|
||||||
3: splitAlternateSubst,
|
3: splitAlternateSubst,
|
||||||
4: splitLigatureSubst,
|
4: splitLigatureSubst,
|
||||||
# 5: splitContextSubst,
|
# 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():
|
def test_splitMarkBasePos():
|
||||||
from fontTools.otlLib.builder import buildAnchor, buildMarkBasePosSubtable
|
from fontTools.otlLib.builder import buildAnchor, buildMarkBasePosSubtable
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user