def merge(merger, self, lst): self.classDefs = {} # We only care about the .classDefs self = self.classDefs lst = [l.classDefs for l in lst] allKeys = set() allKeys.update(*[l.keys() for l in lst]) for k in allKeys: allValues = nonNone(l.get(k) for l in lst) assert allEqual(allValues), allValues if not allValues: self[k] = None else: self[k] = allValues[0]
def merge(merger, self, lst): if self is None: assert allNone(lst), (lst) return self.classDefs = {} # We only care about the .classDefs self = self.classDefs lst = [l.classDefs for l in lst] allKeys = set() allKeys.update(*[l.keys() for l in lst]) for k in allKeys: allValues = nonNone(l.get(k) for l in lst) assert allEqual(allValues), allValues if not allValues: self[k] = None else: self[k] = allValues[0]
def merge(merger, self, lst): if self is None: if not allNone(lst): raise VarLibMergeError(lst) return lst = [l.classDefs for l in lst] self.classDefs = {} # We only care about the .classDefs self = self.classDefs allKeys = set() allKeys.update(*[l.keys() for l in lst]) for k in allKeys: allValues = nonNone(l.get(k) for l in lst) if not allEqual(allValues): raise VarLibMergeError(allValues) if not allValues: self[k] = None else: self[k] = allValues[0]
def merge(merger, self, lst): if self is None: if not allNone(lst): raise NotANone(merger, expected=None, got=lst) return lst = [l.classDefs for l in lst] self.classDefs = {} # We only care about the .classDefs self = self.classDefs allKeys = set() allKeys.update(*[l.keys() for l in lst]) for k in allKeys: allValues = nonNone(l.get(k) for l in lst) if not allEqual(allValues): raise ShouldBeConstant(merger, expected=allValues[0], got=lst, stack=["." + k]) if not allValues: self[k] = None else: self[k] = allValues[0]
def _merge_TTHinting(font, masterModel, master_ttfs): log.info("Merging TT hinting") assert "cvar" not in font # Check that the existing hinting is compatible # fpgm and prep table for tag in ("fpgm", "prep"): all_pgms = [m[tag].program for m in master_ttfs if tag in m] if len(all_pgms) == 0: continue if tag in font: font_pgm = font[tag].program else: font_pgm = Program() if any(pgm != font_pgm for pgm in all_pgms): log.warning( "Masters have incompatible %s tables, hinting is discarded." % tag) _remove_TTHinting(font) return # glyf table for name, glyph in font["glyf"].glyphs.items(): all_pgms = [ m["glyf"][name].program for m in master_ttfs if name in m['glyf'] and hasattr(m["glyf"][name], "program") ] if not any(all_pgms): continue glyph.expand(font["glyf"]) if hasattr(glyph, "program"): font_pgm = glyph.program else: font_pgm = Program() if any(pgm != font_pgm for pgm in all_pgms if pgm): log.warning( "Masters have incompatible glyph programs in glyph '%s', hinting is discarded." % name) # TODO Only drop hinting from this glyph. _remove_TTHinting(font) return # cvt table all_cvs = [ Vector(m["cvt "].values) if 'cvt ' in m else None for m in master_ttfs ] nonNone_cvs = models.nonNone(all_cvs) if not nonNone_cvs: # There is no cvt table to make a cvar table from, we're done here. return if not models.allEqual(len(c) for c in nonNone_cvs): log.warning( "Masters have incompatible cvt tables, hinting is discarded.") _remove_TTHinting(font) return variations = [] deltas, supports = masterModel.getDeltasAndSupports( all_cvs, round=round ) # builtin round calls into Vector.__round__, which uses builtin round as we like for i, (delta, support) in enumerate(zip(deltas[1:], supports[1:])): if all(v == 0 for v in delta): continue var = TupleVariation(support, delta) variations.append(var) # We can build the cvar table now. if variations: cvar = font["cvar"] = newTable('cvar') cvar.version = 1 cvar.variations = variations
def _merge_TTHinting(font, masterModel, master_ttfs, tolerance=0.5): log.info("Merging TT hinting") assert "cvar" not in font # Check that the existing hinting is compatible # fpgm and prep table for tag in ("fpgm", "prep"): all_pgms = [m[tag].program for m in master_ttfs if tag in m] if len(all_pgms) == 0: continue if tag in font: font_pgm = font[tag].program else: font_pgm = Program() if any(pgm != font_pgm for pgm in all_pgms): log.warning("Masters have incompatible %s tables, hinting is discarded." % tag) _remove_TTHinting(font) return # glyf table for name, glyph in font["glyf"].glyphs.items(): all_pgms = [ m["glyf"][name].program for m in master_ttfs if name in m['glyf'] and hasattr(m["glyf"][name], "program") ] if not any(all_pgms): continue glyph.expand(font["glyf"]) if hasattr(glyph, "program"): font_pgm = glyph.program else: font_pgm = Program() if any(pgm != font_pgm for pgm in all_pgms if pgm): log.warning("Masters have incompatible glyph programs in glyph '%s', hinting is discarded." % name) # TODO Only drop hinting from this glyph. _remove_TTHinting(font) return # cvt table all_cvs = [Vector(m["cvt "].values) if 'cvt ' in m else None for m in master_ttfs] nonNone_cvs = models.nonNone(all_cvs) if not nonNone_cvs: # There is no cvt table to make a cvar table from, we're done here. return if not models.allEqual(len(c) for c in nonNone_cvs): log.warning("Masters have incompatible cvt tables, hinting is discarded.") _remove_TTHinting(font) return # We can build the cvar table now. cvar = font["cvar"] = newTable('cvar') cvar.version = 1 cvar.variations = [] deltas, supports = masterModel.getDeltasAndSupports(all_cvs) for i,(delta,support) in enumerate(zip(deltas[1:], supports[1:])): delta = [otRound(d) for d in delta] if all(abs(v) <= tolerance for v in delta): continue var = TupleVariation(support, delta) cvar.variations.append(var)