aboutsummaryrefslogtreecommitdiff
path: root/Lib/fontTools/varLib/merger.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/fontTools/varLib/merger.py')
-rw-r--r--Lib/fontTools/varLib/merger.py57
1 files changed, 55 insertions, 2 deletions
diff --git a/Lib/fontTools/varLib/merger.py b/Lib/fontTools/varLib/merger.py
index b4b17059..cd16ace4 100644
--- a/Lib/fontTools/varLib/merger.py
+++ b/Lib/fontTools/varLib/merger.py
@@ -2,6 +2,8 @@
Merge OpenType Layout tables (GDEF / GPOS / GSUB).
"""
from __future__ import print_function, division, absolute_import
+import copy
+from operator import ior
from fontTools.misc.py23 import *
from fontTools.misc.fixedTools import otRound
from fontTools.misc import classifyTools
@@ -12,6 +14,7 @@ from fontTools.varLib import builder, models, varStore
from fontTools.varLib.models import nonNone, allNone, allEqual, allEqualTo
from fontTools.varLib.varStore import VarStoreInstancer
from functools import reduce
+from fontTools.otlLib.builder import buildSinglePos
class Merger(object):
@@ -455,7 +458,7 @@ def _PairPosFormat2_align_matrices(self, lst, font, transparent=False):
exemplarGlyph = next(iter(classSet))
klass = classDef2.get(exemplarGlyph, 0)
rec2 = oldClass2Records[klass]
- class2Records.append(rec2)
+ class2Records.append(copy.deepcopy(rec2))
class1Records.append(rec1new)
new_matrices.append(class1Records)
matrices = new_matrices
@@ -726,6 +729,30 @@ def _Lookup_PairPos_subtables_canonicalize(lst, font):
return lst
+def _Lookup_SinglePos_subtables_flatten(lst, font, min_inclusive_rec_format):
+ glyphs, _ = _merge_GlyphOrders(font,
+ [v.Coverage.glyphs for v in lst], None)
+ num_glyphs = len(glyphs)
+ new = ot.SinglePos()
+ new.Format = 2
+ new.ValueFormat = min_inclusive_rec_format
+ new.Coverage = ot.Coverage()
+ new.Coverage.glyphs = glyphs
+ new.ValueCount = num_glyphs
+ new.Value = [None] * num_glyphs
+ for singlePos in lst:
+ if singlePos.Format == 1:
+ val_rec = singlePos.Value
+ for gname in singlePos.Coverage.glyphs:
+ i = glyphs.index(gname)
+ new.Value[i] = copy.deepcopy(val_rec)
+ elif singlePos.Format == 2:
+ for j, gname in enumerate(singlePos.Coverage.glyphs):
+ val_rec = singlePos.Value[j]
+ i = glyphs.index(gname)
+ new.Value[i] = copy.deepcopy(val_rec)
+ return [new]
+
@AligningMerger.merger(ot.Lookup)
def merge(merger, self, lst):
subtables = merger.lookup_subtables = [l.SubTable for l in lst]
@@ -745,12 +772,28 @@ def merge(merger, self, lst):
isPairPos = self.SubTable and isinstance(self.SubTable[0], ot.PairPos)
if isPairPos:
-
# AFDKO and feaLib sometimes generate two Format1 subtables instead of one.
# Merge those before continuing.
# https://github.com/fonttools/fonttools/issues/719
self.SubTable = _Lookup_PairPos_subtables_canonicalize(self.SubTable, merger.font)
subtables = merger.lookup_subtables = [_Lookup_PairPos_subtables_canonicalize(st, merger.font) for st in subtables]
+ else:
+ isSinglePos = self.SubTable and isinstance(self.SubTable[0], ot.SinglePos)
+ if isSinglePos:
+ numSubtables = [len(st) for st in subtables]
+ if not all([nums == numSubtables[0] for nums in numSubtables]):
+ # Flatten list of SinglePos subtables to single Format 2 subtable,
+ # with all value records set to the rec format type.
+ # We use buildSinglePos() to optimize the lookup after merging.
+ valueFormatList = [t.ValueFormat for st in subtables for t in st]
+ # Find the minimum value record that can accomodate all the singlePos subtables.
+ mirf = reduce(ior, valueFormatList)
+ self.SubTable = _Lookup_SinglePos_subtables_flatten(self.SubTable, merger.font, mirf)
+ subtables = merger.lookup_subtables = [
+ _Lookup_SinglePos_subtables_flatten(st, merger.font, mirf) for st in subtables]
+ flattened = True
+ else:
+ flattened = False
merger.mergeLists(self.SubTable, subtables)
self.SubTableCount = len(self.SubTable)
@@ -768,6 +811,16 @@ def merge(merger, self, lst):
self.SubTable.pop(-1)
self.SubTableCount -= 1
+ elif isSinglePos and flattened:
+ singlePosTable = self.SubTable[0]
+ glyphs = singlePosTable.Coverage.glyphs
+ # We know that singlePosTable is Format 2, as this is set
+ # in _Lookup_SinglePos_subtables_flatten.
+ singlePosMapping = {
+ gname: valRecord
+ for gname, valRecord in zip(glyphs, singlePosTable.Value)
+ }
+ self.SubTable = buildSinglePos(singlePosMapping, merger.font.getReverseGlyphMap())
merger.mergeObjects(self, lst, exclude=['SubTable', 'SubTableCount'])
del merger.lookup_subtables