예제 #1
0
    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)
예제 #2
0
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
예제 #3
0
def _Lookup_PairPosFormat2_subtables_flatten(lst, font):
    assert allEqual([l.ValueFormat2 == 0 for l in lst
                     if l.Class1Record]), "Report bug against fonttools."

    self = ot.PairPos()
    self.Format = 2
    self.Coverage = ot.Coverage()
    self.ValueFormat1 = reduce(int.__or__, [l.ValueFormat1 for l in lst], 0)
    self.ValueFormat2 = reduce(int.__or__, [l.ValueFormat2 for l in lst], 0)

    # Align them
    glyphs, _ = _merge_GlyphOrders(font, [v.Coverage.glyphs for v in lst])
    self.Coverage.glyphs = glyphs

    matrices = _PairPosFormat2_align_matrices(self,
                                              lst,
                                              font,
                                              transparent=True)

    matrix = self.Class1Record = []
    for rows in zip(*matrices):
        row = ot.Class1Record()
        matrix.append(row)
        row.Class2Record = []
        row = row.Class2Record
        for cols in zip(*list(r.Class2Record for r in rows)):
            col = next(iter(c for c in cols if c is not None))
            row.append(col)

    return self
예제 #4
0
def buildPairPosClassesSubtable(pairs,
                                glyphMap,
                                valueFormat1=None,
                                valueFormat2=None):
    coverage = set()
    classDef1 = ClassDefBuilder(useClass0=True)
    classDef2 = ClassDefBuilder(useClass0=False)
    for gc1, gc2 in sorted(pairs):
        coverage.update(gc1)
        classDef1.add(gc1)
        classDef2.add(gc2)
    self = ot.PairPos()
    self.Format = 2
    self.ValueFormat1 = _getValueFormat(valueFormat1, pairs.values(), 0)
    self.ValueFormat2 = _getValueFormat(valueFormat2, pairs.values(), 1)
    self.Coverage = buildCoverage(coverage, glyphMap)
    self.ClassDef1 = classDef1.build()
    self.ClassDef2 = classDef2.build()
    classes1 = classDef1.classes()
    classes2 = classDef2.classes()
    self.Class1Record = []
    for c1 in classes1:
        rec1 = ot.Class1Record()
        rec1.Class2Record = []
        self.Class1Record.append(rec1)
        for c2 in classes2:
            rec2 = ot.Class2Record()
            rec2.Value1, rec2.Value2 = pairs.get((c1, c2), (None, None))
            rec1.Class2Record.append(rec2)
    self.Class1Count = len(self.Class1Record)
    self.Class2Count = len(classes2)
    return self
예제 #5
0
파일: merger.py 프로젝트: behnam/fonttools
def _Lookup_PairPosFormat2_subtables_recombine(a, b, font):
    """Combine two subtables that have the same general structure already."""
    self = ot.PairPos()
    self.Format = 2
    self.Coverage = ot.Coverage()
    self.Coverage.Format = 1
    glyphs, _ = _merge_GlyphOrders(font, [v.Coverage.glyphs for v in (a, b)])

    self.Coverage.glyphs = glyphs
    self.Class1Count = a.Class1Count + b.Class1Count
    self.ClassDef1 = ot.ClassDef()

    classDefs = self.ClassDef1.classDefs = {}
    offset = a.Class1Count
    # First subtable overrides any possible shared glyph, so add b first.
    sets = _ClassDef_invert(b.ClassDef1, allGlyphs=b.Coverage.glyphs)
    for i, s in enumerate(sets):
        for g in s:
            classDefs[g] = i + offset
    sets = _ClassDef_invert(a.ClassDef1, allGlyphs=a.Coverage.glyphs)
    assert len(sets) <= offset
    for i, s in enumerate(sets):
        for g in s:
            classDefs[g] = i

    records = self.Class1Record = []
    assert a.Class1Count == len(a.Class1Record)
    assert b.Class1Count == len(b.Class1Record)
    records.extend(a.Class1Record)
    records.extend(b.Class1Record)

    for name in ('Class2Count', 'ClassDef2', 'ValueFormat1', 'ValueFormat2'):
        setattr(self, name, getattr(a, name))

    return self
예제 #6
0
def _Lookup_PairPosFormat1_subtables_merge_overlay(lst, font):
	self = ot.PairPos()
	self.Format = 1
	self.Coverage = ot.Coverage()
	self.Coverage.Format = 1
	self.ValueFormat1 = reduce(int.__or__, [l.ValueFormat1 for l in lst], 0)
	self.ValueFormat2 = reduce(int.__or__, [l.ValueFormat2 for l in lst], 0)

	# Align them
	glyphs, padded = _merge_GlyphOrders(font,
					    [v.Coverage.glyphs for v in lst],
					    [v.PairSet for v in lst])

	self.Coverage.glyphs = glyphs
	self.PairSet = [_PairSet_merge_overlay([v for v in values if v is not None], font)
		        for values in zip(*padded)]
	self.PairSetCount = len(self.PairSet)
	return self
예제 #7
0
def _Lookup_PairPosFormat1_subtables_flatten(lst, font):
	assert allEqual([l.ValueFormat2 == 0 for l in lst if l.PairSet]), "Report bug against fonttools."

	self = ot.PairPos()
	self.Format = 1
	self.Coverage = ot.Coverage()
	self.ValueFormat1 = reduce(int.__or__, [l.ValueFormat1 for l in lst], 0)
	self.ValueFormat2 = reduce(int.__or__, [l.ValueFormat2 for l in lst], 0)

	# Align them
	glyphs, padded = _merge_GlyphOrders(font,
					    [v.Coverage.glyphs for v in lst],
					    [v.PairSet for v in lst])

	self.Coverage.glyphs = glyphs
	self.PairSet = [_PairSet_flatten([v for v in values if v is not None], font)
		        for values in zip(*padded)]
	self.PairSetCount = len(self.PairSet)
	return self
예제 #8
0
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