123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- # 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)]
|