def test_fromXML(self): table = otTables.MultipleSubst() for name, attrs, content in parseXML( '<Substitution in="c_t" out="c,t"/>' '<Substitution in="f_f_i" out="f,f,i"/>'): table.fromXML(name, attrs, content, self.font) self.assertEqual(table.mapping, {'c_t': ['c', 't'], 'f_f_i': ['f', 'f', 'i']})
def test_toXML2(self): writer = XMLWriter(StringIO()) table = otTables.MultipleSubst() table.mapping = {"c_t": ["c", "t"], "f_f_i": ["f", "f", "i"]} table.toXML2(writer, self.font) self.assertEqual(writer.file.getvalue().splitlines()[1:], [ '<Substitution in="c_t" out="c,t"/>', '<Substitution in="f_f_i" out="f,f,i"/>', ])
def build(self): lookup = otTables.Lookup() lookup.SubTable = [] st = otTables.MultipleSubst() st.mapping = self.mapping lookup.SubTable.append(st) lookup.LookupFlag = self.lookup_flag lookup.LookupType = self.lookup_type lookup.SubTableCount = len(lookup.SubTable) return lookup
def test_postRead_format1(self): makeSequence = otTables.MultipleSubst.makeSequence_ table = otTables.MultipleSubst() table.Format = 1 rawTable = { "Coverage": makeCoverage(["c_t", "f_f_i"]), "Sequence": [makeSequence(["c", "t"]), makeSequence(["f", "f", "i"])] } table.postRead(rawTable, self.font) self.assertEqual(table.mapping, { "c_t": ["c", "t"], "f_f_i": ["f", "f", "i"] })
def test_fromXML_oldFormat_bug385(self): # https://github.com/behdad/fonttools/issues/385 table = otTables.MultipleSubst() table.Format = 1 for name, attrs, content in parseXML('<Coverage Format="1">' ' <Glyph value="o"/>' ' <Glyph value="l"/>' '</Coverage>' '<Sequence>' ' <Substitute value="o"/>' ' <Substitute value="l"/>' ' <Substitute value="o"/>' '</Sequence>' '<Sequence>' ' <Substitute value="o"/>' '</Sequence>'): table.fromXML(name, attrs, content, self.font) self.assertEqual(table.mapping, {'o': ['o', 'l', 'o'], 'l': ['o']})
def overflow(self, itemName, itemRecord): from fontTools.otlLib.builder import buildMultipleSubstSubtable from fontTools.ttLib.tables.otBase import OverflowErrorRecord oldSubTable = buildMultipleSubstSubtable({ 'e': 1, 'a': 2, 'b': 3, 'c': 4, 'd': 5 }) newSubTable = otTables.MultipleSubst() ok = otTables.splitMultipleSubst( oldSubTable, newSubTable, OverflowErrorRecord((None, None, None, itemName, itemRecord))) assert ok return oldSubTable.mapping, newSubTable.mapping
def test_fromXML_oldFormat(self): table = otTables.MultipleSubst() for name, attrs, content in parseXML( '<Coverage>' ' <Glyph value="c_t"/>' ' <Glyph value="f_f_i"/>' '</Coverage>' '<Sequence index="0">' ' <Substitute index="0" value="c"/>' ' <Substitute index="1" value="t"/>' '</Sequence>' '<Sequence index="1">' ' <Substitute index="0" value="f"/>' ' <Substitute index="1" value="f"/>' ' <Substitute index="2" value="i"/>' '</Sequence>'): table.fromXML(name, attrs, content, self.font) self.assertEqual(table.mapping, {'c_t': ['c', 't'], 'f_f_i': ['f', 'f', 'i']})
def add_watermark(self, ttf): cmap = ttf.getBestCmap() gsub = ttf['GSUB'].table # Obtain Version string m = re.search('^Version (\d*)\.(\d*)', font_data.font_version(ttf)) if not m: raise ValueError('The font does not have proper version string.') major = m.group(1) minor = m.group(2) # Replace the dot with space since NotoColorEmoji does not have glyph for dot. glyphs = [cmap[ord(x)] for x in '%s %s' % (major, minor)] # Update Glyph metrics ttf.getGlyphOrder().append(WATERMARK_NEW_GLYPH_ID) refGlyphId = cmap[WATERMARK_REF_CODE_POINT] ttf['hmtx'].metrics[WATERMARK_NEW_GLYPH_ID] = ttf['hmtx'].metrics[refGlyphId] ttf['vmtx'].metrics[WATERMARK_NEW_GLYPH_ID] = ttf['vmtx'].metrics[refGlyphId] # Add new Glyph to cmap font_data.add_to_cmap(ttf, { WATERMARK_NEW_CODE_POINT : WATERMARK_NEW_GLYPH_ID }) # Add lookup table for the version string. lookups = gsub.LookupList.Lookup new_lookup = otTables.Lookup() new_lookup.LookupType = 2 # Multiple Substitution Subtable. new_lookup.LookupFlag = 0 new_subtable = otTables.MultipleSubst() new_subtable.mapping = { WATERMARK_NEW_GLYPH_ID : tuple(glyphs) } new_lookup.SubTable = [ new_subtable ] new_lookup_index = len(lookups) lookups.append(new_lookup) # Add feature feature = next(x for x in gsub.FeatureList.FeatureRecord if x.FeatureTag == 'ccmp') if not feature: raise ValueError("Font doesn't contain ccmp feature.") feature.Feature.LookupListIndex.append(new_lookup_index)
def build(self): subtable = otTables.MultipleSubst() subtable.mapping = self.mapping return self.buildLookup_([subtable])
def test_preWrite_format1(self): table = otTables.MultipleSubst() table.mapping = {"c_t": ["c", "t"], "f_f_i": ["f", "f", "i"]} rawTable = table.preWrite(self.font) self.assertEqual(table.Format, 1) self.assertEqual(rawTable["Coverage"].glyphs, ["c_t", "f_f_i"])
def test_postRead_formatUnknown(self): table = otTables.MultipleSubst() table.Format = 987 self.assertRaises(AssertionError, table.postRead, {}, self.font)
def buildMultipleSubstSubtable(mapping): if not mapping: return None self = ot.MultipleSubst() self.mapping = dict(mapping) return self