Spaces:
Running
Running
# Copyright 2013 Google, Inc. All Rights Reserved. | |
# | |
# Google Author(s): Behdad Esfahbod, Roozbeh Pournader | |
from fontTools.ttLib.tables.DefaultTable import DefaultTable | |
import logging | |
log = logging.getLogger("fontTools.merge") | |
def add_method(*clazzes, **kwargs): | |
"""Returns a decorator function that adds a new method to one or | |
more classes.""" | |
allowDefault = kwargs.get("allowDefaultTable", False) | |
def wrapper(method): | |
done = [] | |
for clazz in clazzes: | |
if clazz in done: | |
continue # Support multiple names of a clazz | |
done.append(clazz) | |
assert allowDefault or clazz != DefaultTable, "Oops, table class not found." | |
assert ( | |
method.__name__ not in clazz.__dict__ | |
), "Oops, class '%s' has method '%s'." % (clazz.__name__, method.__name__) | |
setattr(clazz, method.__name__, method) | |
return None | |
return wrapper | |
def mergeObjects(lst): | |
lst = [item for item in lst if item is not NotImplemented] | |
if not lst: | |
return NotImplemented | |
lst = [item for item in lst if item is not None] | |
if not lst: | |
return None | |
clazz = lst[0].__class__ | |
assert all(type(item) == clazz for item in lst), lst | |
logic = clazz.mergeMap | |
returnTable = clazz() | |
returnDict = {} | |
allKeys = set.union(set(), *(vars(table).keys() for table in lst)) | |
for key in allKeys: | |
try: | |
mergeLogic = logic[key] | |
except KeyError: | |
try: | |
mergeLogic = logic["*"] | |
except KeyError: | |
raise Exception( | |
"Don't know how to merge key %s of class %s" % (key, clazz.__name__) | |
) | |
if mergeLogic is NotImplemented: | |
continue | |
value = mergeLogic(getattr(table, key, NotImplemented) for table in lst) | |
if value is not NotImplemented: | |
returnDict[key] = value | |
returnTable.__dict__ = returnDict | |
return returnTable | |
def merge(self, m, tables): | |
if not hasattr(self, "mergeMap"): | |
log.info("Don't know how to merge '%s'.", self.tableTag) | |
return NotImplemented | |
logic = self.mergeMap | |
if isinstance(logic, dict): | |
return m.mergeObjects(self, self.mergeMap, tables) | |
else: | |
return logic(tables) | |