[merge] Remove lookup_id() / feature_id(), use custom dict
I added the id() trick because normal objects are not hashable in Python3. Remove that hack and use a custom dict subclass that allows us to use objects as keys as long as they don't change. The custom dict has a different, desirable, property as well: upon seeing keys it does not know, it just adds them to the end of the list. Will use this feature in next commits to merge ScriptList properly.
This commit is contained in:
parent
93763eec0b
commit
d76d6c1a5f
@ -496,9 +496,6 @@ ttLib.getTableClass('MATH').mergeMap = \
|
||||
'table': mergeObjects,
|
||||
}
|
||||
|
||||
lookup_id = id
|
||||
feature_id = id
|
||||
|
||||
@_add_method(ttLib.getTableClass('GSUB'))
|
||||
def merge(self, m, tables):
|
||||
|
||||
@ -506,15 +503,13 @@ def merge(self, m, tables):
|
||||
for i,(table,dups) in enumerate(zip(tables, m.duplicateGlyphsPerFont)):
|
||||
if not dups: continue
|
||||
assert (table is not None and table is not NotImplemented), "Have duplicates to resolve for font %d but no GSUB" % (i + 1)
|
||||
lookupMap = {lookup_id(v):v for v in table.table.LookupList.Lookup}
|
||||
featureMap = {feature_id(v):v for v in table.table.FeatureList.FeatureRecord}
|
||||
synthFeature = None
|
||||
synthLookup = None
|
||||
for script in table.table.ScriptList.ScriptRecord:
|
||||
if script.ScriptTag == 'DFLT': continue # XXX
|
||||
for langsys in [script.Script.DefaultLangSys] + [l.LangSys for l in script.Script.LangSysRecord]:
|
||||
if langsys is None: continue # XXX Create!
|
||||
feature = [featureMap[v] for v in langsys.FeatureIndex if featureMap[v].FeatureTag == 'locl']
|
||||
feature = [v for v in langsys.FeatureIndex if v.FeatureTag == 'locl']
|
||||
assert len(feature) <= 1
|
||||
if feature:
|
||||
feature = feature[0]
|
||||
@ -526,9 +521,8 @@ def merge(self, m, tables):
|
||||
f.FeatureParams = None
|
||||
f.LookupCount = 0
|
||||
f.LookupListIndex = []
|
||||
langsys.FeatureIndex.append(feature_id(synthFeature))
|
||||
featureMap[feature_id(synthFeature)] = synthFeature
|
||||
langsys.FeatureIndex.sort(key=lambda v: featureMap[v].FeatureTag)
|
||||
langsys.FeatureIndex.append(synthFeature)
|
||||
langsys.FeatureIndex.sort(key=lambda v: v.FeatureTag)
|
||||
table.table.FeatureList.FeatureRecord.append(synthFeature)
|
||||
table.table.FeatureList.FeatureCount += 1
|
||||
feature = synthFeature
|
||||
@ -544,7 +538,7 @@ def merge(self, m, tables):
|
||||
table.table.LookupList.Lookup.append(synthLookup)
|
||||
table.table.LookupList.LookupCount += 1
|
||||
|
||||
feature.Feature.LookupListIndex[:0] = [lookup_id(synthLookup)]
|
||||
feature.Feature.LookupListIndex[:0] = [synthLookup]
|
||||
feature.Feature.LookupCount += 1
|
||||
|
||||
DefaultTable.merge(self, m, tables)
|
||||
@ -761,6 +755,21 @@ class Options(object):
|
||||
|
||||
return ret
|
||||
|
||||
class _GregariousDict(dict):
|
||||
"""A dictionary-like object that:
|
||||
1. Allows keys to be unhashable objects, so far as they don't change underneath, and
|
||||
2. Welcomes guests without reservations and adds them to the end of the list.
|
||||
"""
|
||||
|
||||
def __init__(self, lst):
|
||||
self.l = lst
|
||||
self.d = {id(v):i for i,v in enumerate(lst)}
|
||||
|
||||
def __getitem__(self, v):
|
||||
if id(v) not in self.d:
|
||||
self.d[id(v)] = len(self.l)
|
||||
self.l.append(v)
|
||||
return self.d[id(v)]
|
||||
|
||||
class Merger(object):
|
||||
|
||||
@ -874,14 +883,14 @@ class Merger(object):
|
||||
if not t: continue
|
||||
|
||||
if t.table.LookupList:
|
||||
lookupMap = {i:lookup_id(v) for i,v in enumerate(t.table.LookupList.Lookup)}
|
||||
lookupMap = {i:v for i,v in enumerate(t.table.LookupList.Lookup)}
|
||||
t.table.LookupList.mapLookups(lookupMap)
|
||||
if t.table.FeatureList:
|
||||
# XXX Handle present FeatureList but absent LookupList
|
||||
t.table.FeatureList.mapLookups(lookupMap)
|
||||
|
||||
if t.table.FeatureList and t.table.ScriptList:
|
||||
featureMap = {i:feature_id(v) for i,v in enumerate(t.table.FeatureList.FeatureRecord)}
|
||||
featureMap = {i:v for i,v in enumerate(t.table.FeatureList.FeatureRecord)}
|
||||
t.table.ScriptList.mapFeatures(featureMap)
|
||||
|
||||
# TODO GDEF/Lookup MarkFilteringSets
|
||||
@ -899,16 +908,18 @@ class Merger(object):
|
||||
if not t: continue
|
||||
|
||||
if t.table.LookupList:
|
||||
lookupMap = {lookup_id(v):i for i,v in enumerate(t.table.LookupList.Lookup)}
|
||||
lookupMap = _GregariousDict(t.table.LookupList.Lookup)
|
||||
t.table.LookupList.mapLookups(lookupMap)
|
||||
if t.table.FeatureList:
|
||||
# XXX Handle present FeatureList but absent LookupList
|
||||
t.table.FeatureList.mapLookups(lookupMap)
|
||||
t.table.LookupList.LookupCount = len(t.table.LookupList.Lookup)
|
||||
|
||||
if t.table.FeatureList and t.table.ScriptList:
|
||||
# XXX Handle present ScriptList but absent FeatureList
|
||||
featureMap = {feature_id(v):i for i,v in enumerate(t.table.FeatureList.FeatureRecord)}
|
||||
featureMap = _GregariousDict(t.table.FeatureList.FeatureRecord)
|
||||
t.table.ScriptList.mapFeatures(featureMap)
|
||||
t.table.FeatureList.FeatureCount = len(t.table.FeatureList.FeatureRecord)
|
||||
|
||||
# TODO GDEF/Lookup MarkFilteringSets
|
||||
# TODO FeatureParams nameIDs
|
||||
|
Loading…
x
Reference in New Issue
Block a user