Spaces:
Running
Running
# Copyright 2013 Google, Inc. All Rights Reserved. | |
# | |
# Google Author(s): Behdad Esfahbod, Roozbeh Pournader | |
from fontTools.misc.timeTools import timestampNow | |
from fontTools.ttLib.tables.DefaultTable import DefaultTable | |
from functools import reduce | |
import operator | |
import logging | |
log = logging.getLogger("fontTools.merge") | |
# General utility functions for merging values from different fonts | |
def equal(lst): | |
lst = list(lst) | |
t = iter(lst) | |
first = next(t) | |
assert all(item == first for item in t), "Expected all items to be equal: %s" % lst | |
return first | |
def first(lst): | |
return next(iter(lst)) | |
def recalculate(lst): | |
return NotImplemented | |
def current_time(lst): | |
return timestampNow() | |
def bitwise_and(lst): | |
return reduce(operator.and_, lst) | |
def bitwise_or(lst): | |
return reduce(operator.or_, lst) | |
def avg_int(lst): | |
lst = list(lst) | |
return sum(lst) // len(lst) | |
def onlyExisting(func): | |
"""Returns a filter func that when called with a list, | |
only calls func on the non-NotImplemented items of the list, | |
and only so if there's at least one item remaining. | |
Otherwise returns NotImplemented.""" | |
def wrapper(lst): | |
items = [item for item in lst if item is not NotImplemented] | |
return func(items) if items else NotImplemented | |
return wrapper | |
def sumLists(lst): | |
l = [] | |
for item in lst: | |
l.extend(item) | |
return l | |
def sumDicts(lst): | |
d = {} | |
for item in lst: | |
d.update(item) | |
return d | |
def mergeBits(bitmap): | |
def wrapper(lst): | |
lst = list(lst) | |
returnValue = 0 | |
for bitNumber in range(bitmap["size"]): | |
try: | |
mergeLogic = bitmap[bitNumber] | |
except KeyError: | |
try: | |
mergeLogic = bitmap["*"] | |
except KeyError: | |
raise Exception("Don't know how to merge bit %s" % bitNumber) | |
shiftedBit = 1 << bitNumber | |
mergedValue = mergeLogic(bool(item & shiftedBit) for item in lst) | |
returnValue |= mergedValue << bitNumber | |
return returnValue | |
return wrapper | |
class AttendanceRecordingIdentityDict(object): | |
"""A dictionary-like object that records indices of items actually accessed | |
from a list.""" | |
def __init__(self, lst): | |
self.l = lst | |
self.d = {id(v): i for i, v in enumerate(lst)} | |
self.s = set() | |
def __getitem__(self, v): | |
self.s.add(self.d[id(v)]) | |
return v | |
class GregariousIdentityDict(object): | |
"""A dictionary-like object that welcomes guests without reservations and | |
adds them to the end of the guest list.""" | |
def __init__(self, lst): | |
self.l = lst | |
self.s = set(id(v) for v in lst) | |
def __getitem__(self, v): | |
if id(v) not in self.s: | |
self.s.add(id(v)) | |
self.l.append(v) | |
return v | |
class NonhashableDict(object): | |
"""A dictionary-like object mapping objects to values.""" | |
def __init__(self, keys, values=None): | |
if values is None: | |
self.d = {id(v): i for i, v in enumerate(keys)} | |
else: | |
self.d = {id(k): v for k, v in zip(keys, values)} | |
def __getitem__(self, k): | |
return self.d[id(k)] | |
def __setitem__(self, k, v): | |
self.d[id(k)] = v | |
def __delitem__(self, k): | |
del self.d[id(k)] | |