def merge(merger, self, lst): # Align them glyphs, padded = _merge_GlyphOrders(merger.font, [[v.SecondGlyph for v in vs.PairValueRecord] for vs in lst], [vs.PairValueRecord for vs in lst]) self.PairValueRecord = pvrs = [] for glyph in glyphs: pvr = ot.PairValueRecord() pvr.SecondGlyph = glyph pvr.Value1 = otBase.ValueRecord(merger.valueFormat1) if merger.valueFormat1 else None pvr.Value2 = otBase.ValueRecord(merger.valueFormat2) if merger.valueFormat2 else None pvrs.append(pvr) self.PairValueCount = len(self.PairValueRecord) for i,values in enumerate(padded): for j,glyph in enumerate(glyphs): # Fill in value from other subtables v = ot.PairValueRecord() v.SecondGlyph = glyph if values[j] is not None: vpair = values[j] else: vpair = _Lookup_PairPos_get_effective_value_pair(merger.lookup_subtables[i], self._firstGlyph, glyph) if vpair is None: v1, v2 = None, None else: v1, v2 = vpair.Value1, vpair.Value2 v.Value1 = otBase.ValueRecord(merger.valueFormat1, src=v1) if merger.valueFormat1 else None v.Value2 = otBase.ValueRecord(merger.valueFormat2, src=v2) if merger.valueFormat2 else None values[j] = v del self._firstGlyph merger.mergeLists(self.PairValueRecord, padded)
def build(self): subtables = [] # (valueFormat1, valueFormat2) --> [(glyph1, glyph2, value1, value2)*] format1 = {} for (gc1, gc2), (location, value1, value2) in self.pairs.items(): if len(gc1) == 1 and len(gc2) == 1: val1, valFormat1 = makeOpenTypeValueRecord(value1) val2, valFormat2 = makeOpenTypeValueRecord(value2) format1.setdefault(((valFormat1, valFormat2)), []).append( (gc1[0], gc2[0], val1, val2)) for (vf1, vf2), pairs in sorted(format1.items()): p = {} for glyph1, glyph2, val1, val2 in pairs: p.setdefault(glyph1, []).append((glyph2, val1, val2)) st = otTables.PairPos() subtables.append(st) st.Format = 1 st.ValueFormat1, st.ValueFormat2 = vf1, vf2 st.Coverage = self.buildCoverage_(p) st.PairSet = [] for glyph in st.Coverage.glyphs: ps = otTables.PairSet() ps.PairValueRecord = [] st.PairSet.append(ps) for glyph2, val1, val2 in sorted( p[glyph], key=lambda x: self.font.getGlyphID(x[0])): pvr = otTables.PairValueRecord() pvr.SecondGlyph = glyph2 pvr.Value1, pvr.Value2 = val1, val2 ps.PairValueRecord.append(pvr) ps.PairValueCount = len(ps.PairValueRecord) st.PairSetCount = len(st.PairSet) return self.buildLookup_(subtables)
def buildPairPosGlyphsSubtable(pairs, glyphMap, valueFormat1=None, valueFormat2=None): self = ot.PairPos() self.Format = 1 self.ValueFormat1 = _getValueFormat(valueFormat1, pairs.values(), 0) self.ValueFormat2 = _getValueFormat(valueFormat2, pairs.values(), 1) p = {} for (glyphA, glyphB), (valA, valB) in pairs.items(): p.setdefault(glyphA, []).append((glyphB, valA, valB)) self.Coverage = buildCoverage({g for g, _ in pairs.keys()}, glyphMap) self.PairSet = [] for glyph in self.Coverage.glyphs: ps = ot.PairSet() ps.PairValueRecord = [] self.PairSet.append(ps) for glyph2, val1, val2 in \ sorted(p[glyph], key=lambda x: glyphMap[x[0]]): pvr = ot.PairValueRecord() pvr.SecondGlyph = glyph2 pvr.Value1 = val1 if val1 and val1.getFormat() != 0 else None pvr.Value2 = val2 if val2 and val2.getFormat() != 0 else None ps.PairValueRecord.append(pvr) ps.PairValueCount = len(ps.PairValueRecord) self.PairSetCount = len(self.PairSet) return self
def parsePair(lines, font, _lookupMap=None): self = ot.PairPos() self.ValueFormat1 = self.ValueFormat2 = 0 typ = lines.peeks()[0].split()[0].lower() if typ in ('left', 'right'): self.Format = 1 values = {} for line in lines: assert len(line) == 4, line side = line[0].split()[0].lower() assert side in ('left', 'right'), side what = line[0][len(side):].title().replace(' ', '') mask = valueRecordFormatDict[what][0] glyph1, glyph2 = makeGlyphs(line[1:3]) value = int(line[3]) if not glyph1 in values: values[glyph1] = {} if not glyph2 in values[glyph1]: values[glyph1][glyph2] = (ValueRecord(),ValueRecord()) rec2 = values[glyph1][glyph2] if side == 'left': self.ValueFormat1 |= mask vr = rec2[0] else: self.ValueFormat2 |= mask vr = rec2[1] assert not hasattr(vr, what), (vr, what) setattr(vr, what, value) self.Coverage = makeCoverage(set(values.keys()), font) self.PairSet = [] for glyph1 in self.Coverage.glyphs: values1 = values[glyph1] pairset = ot.PairSet() records = pairset.PairValueRecord = [] for glyph2 in sorted(values1.keys(), key=font.getGlyphID): values2 = values1[glyph2] pair = ot.PairValueRecord() pair.SecondGlyph = glyph2 pair.Value1 = values2[0] pair.Value2 = values2[1] if self.ValueFormat2 else None records.append(pair) pairset.PairValueCount = len(pairset.PairValueRecord) self.PairSet.append(pairset) self.PairSetCount = len(self.PairSet) elif typ.endswith('class'): self.Format = 2 classDefs = [None, None] while lines.peeks()[0].endswith("class definition begin"): typ = lines.peek()[0][:-len("class definition begin")].lower() idx,klass = { 'first': (0,ot.ClassDef1), 'second': (1,ot.ClassDef2), }[typ] assert classDefs[idx] is None classDefs[idx] = parseClassDef(lines, font, klass=klass) self.ClassDef1, self.ClassDef2 = classDefs self.Class1Count, self.Class2Count = (1+max(c.classDefs.values()) for c in classDefs) self.Class1Record = [ot.Class1Record() for i in range(self.Class1Count)] for rec1 in self.Class1Record: rec1.Class2Record = [ot.Class2Record() for j in range(self.Class2Count)] for rec2 in rec1.Class2Record: rec2.Value1 = ValueRecord() rec2.Value2 = ValueRecord() for line in lines: assert len(line) == 4, line side = line[0].split()[0].lower() assert side in ('left', 'right'), side what = line[0][len(side):].title().replace(' ', '') mask = valueRecordFormatDict[what][0] class1, class2, value = (int(x) for x in line[1:4]) rec2 = self.Class1Record[class1].Class2Record[class2] if side == 'left': self.ValueFormat1 |= mask vr = rec2.Value1 else: self.ValueFormat2 |= mask vr = rec2.Value2 assert not hasattr(vr, what), (vr, what) setattr(vr, what, value) for rec1 in self.Class1Record: for rec2 in rec1.Class2Record: rec2.Value1 = ValueRecord(self.ValueFormat1, rec2.Value1) rec2.Value2 = ValueRecord(self.ValueFormat2, rec2.Value2) \ if self.ValueFormat2 else None self.Coverage = makeCoverage(set(self.ClassDef1.classDefs.keys()), font) else: assert 0, typ return self