def test_buildCaretValueForPoint(self): caret = builder.buildCaretValueForPoint(23) assert getXML(caret.toXML) == [ '<CaretValue Format="2">', ' <CaretValuePoint value="23"/>', "</CaretValue>", ]
def test_buildCaretValueForCoord(self): caret = builder.buildCaretValueForCoord(500) assert getXML(caret.toXML) == [ '<CaretValue Format="1">', ' <Coordinate value="500"/>', "</CaretValue>", ]
def test_buildAnchor_format3(self): anchor = builder.buildAnchor( 23, 42, deviceX=builder.buildDevice({ 1: 1, 0: 0 }), deviceY=builder.buildDevice({7: 7}), ) assert getXML(anchor.toXML) == [ '<Anchor Format="3">', ' <XCoordinate value="23"/>', ' <YCoordinate value="42"/>', " <XDeviceTable>", ' <StartSize value="0"/>', ' <EndSize value="1"/>', ' <DeltaFormat value="1"/>', ' <DeltaValue value="[0, 1]"/>', " </XDeviceTable>", " <YDeviceTable>", ' <StartSize value="7"/>', ' <EndSize value="7"/>', ' <DeltaFormat value="2"/>', ' <DeltaValue value="[7]"/>', " </YDeviceTable>", "</Anchor>", ]
def test_buildLigatureAttach(self): anchor = builder.buildAnchor attach = builder.buildLigatureAttach([[anchor(500, -10), None], [None, anchor(300, -20), None]]) assert getXML(attach.toXML) == [ "<LigatureAttach>", " <!-- ComponentCount=2 -->", ' <ComponentRecord index="0">', ' <LigatureAnchor index="0" Format="1">', ' <XCoordinate value="500"/>', ' <YCoordinate value="-10"/>', " </LigatureAnchor>", ' <LigatureAnchor index="1" empty="1"/>', " </ComponentRecord>", ' <ComponentRecord index="1">', ' <LigatureAnchor index="0" empty="1"/>', ' <LigatureAnchor index="1" Format="1">', ' <XCoordinate value="300"/>', ' <YCoordinate value="-20"/>', " </LigatureAnchor>", ' <LigatureAnchor index="2" empty="1"/>', " </ComponentRecord>", "</LigatureAttach>", ]
def test_buildCursivePos(self): pos = builder.buildCursivePos({ "two": (self.ANCHOR1, self.ANCHOR2), "four": (self.ANCHOR3, self.ANCHOR1) }, self.GLYPHMAP) self.assertEqual(getXML(pos.toXML), '<CursivePos Format="1">' ' <Coverage>' ' <Glyph value="two"/>' ' <Glyph value="four"/>' ' </Coverage>' ' <!-- EntryExitCount=2 -->' ' <EntryExitRecord index="0">' ' <EntryAnchor Format="1">' ' <XCoordinate value="11"/>' ' <YCoordinate value="-11"/>' ' </EntryAnchor>' ' <ExitAnchor Format="1">' ' <XCoordinate value="22"/>' ' <YCoordinate value="-22"/>' ' </ExitAnchor>' ' </EntryExitRecord>' ' <EntryExitRecord index="1">' ' <EntryAnchor Format="1">' ' <XCoordinate value="33"/>' ' <YCoordinate value="-33"/>' ' </EntryAnchor>' ' <ExitAnchor Format="1">' ' <XCoordinate value="11"/>' ' <YCoordinate value="-11"/>' ' </ExitAnchor>' ' </EntryExitRecord>' '</CursivePos>')
def test_buildAnchor_format1(self): anchor = builder.buildAnchor(23, 42) self.assertEqual(getXML(anchor.toXML), '<Anchor Format="1">' ' <XCoordinate value="23"/>' ' <YCoordinate value="42"/>' '</Anchor>')
def test_buildMarkArray(self): markArray = builder.buildMarkArray( { "acute": (7, builder.buildAnchor(300, 800)), "grave": (2, builder.buildAnchor(10, 80)), }, self.GLYPHMAP, ) assert self.GLYPHMAP["grave"] < self.GLYPHMAP["acute"] assert getXML(markArray.toXML) == [ "<MarkArray>", " <!-- MarkCount=2 -->", ' <MarkRecord index="0">', ' <Class value="2"/>', ' <MarkAnchor Format="1">', ' <XCoordinate value="10"/>', ' <YCoordinate value="80"/>', " </MarkAnchor>", " </MarkRecord>", ' <MarkRecord index="1">', ' <Class value="7"/>', ' <MarkAnchor Format="1">', ' <XCoordinate value="300"/>', ' <YCoordinate value="800"/>', " </MarkAnchor>", " </MarkRecord>", "</MarkArray>", ]
def test_toXML_horiz(self): table = self.font["trak"] table.horizData = TrackData(SKIA_TRACK_ENTRIES) add_name(self.font, "Tight", nameID=275) add_name(self.font, "Normal", nameID=303) add_name(self.font, "Loose", nameID=276) self.assertEqual(SKIA_TRAK_TABLE_XML, getXML(table, self.font))
def test_toXML_v1(self): name = FakeNameTable({258: "Spring theme", 259: "Winter theme", 513: "darks", 515: "lights"}) cpal = newTable('CPAL') ttFont = {"name": name, "CPAL": cpal} cpal.decompile(CPAL_DATA_V1, ttFont) self.assertEqual(getXML(cpal.toXML, ttFont), '<version value="1"/>' '<numPaletteEntries value="3"/>' '<palette index="0" label="258" type="1">' ' <!-- Spring theme -->' ' <color index="0" value="#CAFECAFE"/>' ' <color index="1" value="#22110033"/>' ' <color index="2" value="#66554477"/>' '</palette>' '<palette index="1" label="259" type="2">' ' <!-- Winter theme -->' ' <color index="0" value="#59413127"/>' ' <color index="1" value="#42424242"/>' ' <color index="2" value="#13330037"/>' '</palette>' '<paletteEntryLabels>' ' <label index="0" value="513"/><!-- darks -->' ' <label index="1" value="514"/>' ' <label index="2" value="515"/><!-- lights -->' '</paletteEntryLabels>')
def test_buildCursivePos(self): pos = builder.buildCursivePosSubtable({ "two": (self.ANCHOR1, self.ANCHOR2), "four": (self.ANCHOR3, self.ANCHOR1) }, self.GLYPHMAP) self.assertEqual(getXML(pos.toXML), '<CursivePos Format="1">' ' <Coverage>' ' <Glyph value="two"/>' ' <Glyph value="four"/>' ' </Coverage>' ' <!-- EntryExitCount=2 -->' ' <EntryExitRecord index="0">' ' <EntryAnchor Format="1">' ' <XCoordinate value="11"/>' ' <YCoordinate value="-11"/>' ' </EntryAnchor>' ' <ExitAnchor Format="1">' ' <XCoordinate value="22"/>' ' <YCoordinate value="-22"/>' ' </ExitAnchor>' ' </EntryExitRecord>' ' <EntryExitRecord index="1">' ' <EntryAnchor Format="1">' ' <XCoordinate value="33"/>' ' <YCoordinate value="-33"/>' ' </EntryAnchor>' ' <ExitAnchor Format="1">' ' <XCoordinate value="11"/>' ' <YCoordinate value="-11"/>' ' </ExitAnchor>' ' </EntryExitRecord>' '</CursivePos>')
def test_buildCoverage(self): cov = builder.buildCoverage({"two", "four"}, {"two": 2, "four": 4}) self.assertEqual(getXML(cov.toXML), '<Coverage>' ' <Glyph value="two"/>' ' <Glyph value="four"/>' '</Coverage>')
def test_buildBaseArray(self): anchor = builder.buildAnchor baseArray = builder.buildBaseArray({ "a": {2: anchor(300, 80)}, "c": {1: anchor(300, 80), 2: anchor(300, -20)} }, numMarkClasses=4, glyphMap=self.GLYPHMAP) self.assertEqual(getXML(baseArray.toXML), '<BaseArray>' ' <!-- BaseCount=2 -->' ' <BaseRecord index="0">' ' <BaseAnchor index="0" empty="1"/>' ' <BaseAnchor index="1" empty="1"/>' ' <BaseAnchor index="2" Format="1">' ' <XCoordinate value="300"/>' ' <YCoordinate value="80"/>' ' </BaseAnchor>' ' <BaseAnchor index="3" empty="1"/>' ' </BaseRecord>' ' <BaseRecord index="1">' ' <BaseAnchor index="0" empty="1"/>' ' <BaseAnchor index="1" Format="1">' ' <XCoordinate value="300"/>' ' <YCoordinate value="80"/>' ' </BaseAnchor>' ' <BaseAnchor index="2" Format="1">' ' <XCoordinate value="300"/>' ' <YCoordinate value="-20"/>' ' </BaseAnchor>' ' <BaseAnchor index="3" empty="1"/>' ' </BaseRecord>' '</BaseArray>')
def test_toXML_horiz(self): table = self.font['trak'] table.horizData = TrackData(SKIA_TRACK_ENTRIES) add_name(self.font, 'Tight', nameID=275) add_name(self.font, 'Normal', nameID=303) add_name(self.font, 'Loose', nameID=276) self.assertEqual(SKIA_TRAK_TABLE_XML, getXML(table.toXML, self.font))
def test_buildLigCaretList(self): carets = builder.buildLigCaretList({"f_f_i": [300, 600]}, {"c_t": [42]}, self.GLYPHMAP) assert getXML(carets.toXML) == [ "<LigCaretList>", " <Coverage>", ' <Glyph value="f_f_i"/>', ' <Glyph value="c_t"/>', " </Coverage>", " <!-- LigGlyphCount=2 -->", ' <LigGlyph index="0">', " <!-- CaretCount=2 -->", ' <CaretValue index="0" Format="1">', ' <Coordinate value="300"/>', " </CaretValue>", ' <CaretValue index="1" Format="1">', ' <Coordinate value="600"/>', " </CaretValue>", " </LigGlyph>", ' <LigGlyph index="1">', " <!-- CaretCount=1 -->", ' <CaretValue index="0" Format="2">', ' <CaretValuePoint value="42"/>', " </CaretValue>", " </LigGlyph>", "</LigCaretList>", ]
def test_subset_svg_missing_glyph(empty_svg_font, tmp_path): font = empty_svg_font svg = new_svg() etree.SubElement(svg, "rect", {"id": "glyph1", "x": "1", "y": "2"}) font["SVG "].docList.append(( etree.tostring(svg).decode(), 1, # the range endGlyphID=2 declares two glyphs however our svg contains # only one glyph element with id="glyph1", the "glyph2" one is absent. # Techically this would be invalid according to the OT-SVG spec. 2, )) svg_font_path = tmp_path / "TestSVG.ttf" font.save(svg_font_path) subset_path = svg_font_path.with_suffix(".subset.ttf") # make sure we don't crash when we don't find the expected "glyph2" element subset.main( [str(svg_font_path), f"--output-file={subset_path}", f"--gids=1"]) subset_font = TTFont(subset_path) assert getXML(subset_font["SVG "].toXML, subset_font) == [ '<svgDoc endGlyphID="1" startGlyphID="1">', ' <![CDATA[<svg xmlns="http://www.w3.org/2000/svg"><rect id="glyph1" x="1" y="2"/></svg>]]>', "</svgDoc>", ] # ignore the missing gid even if included in the subset; in this test case we # end up with an empty svg document--which is dropped, along with the empty table subset.main( [str(svg_font_path), f"--output-file={subset_path}", f"--gids=2"]) assert "SVG " not in TTFont(subset_path)
def test_buildLigatureAttach_noComponents(self): attach = builder.buildLigatureAttach([]) assert getXML(attach.toXML) == [ "<LigatureAttach>", " <!-- ComponentCount=0 -->", "</LigatureAttach>", ]
def test_toXML_vert(self): table = self.font["trak"] table.vertData = TrackData(OSAKA_VERT_TRACK_ENTRIES) add_name(self.font, "Tight", nameID=265) add_name(self.font, "Normal", nameID=266) add_name(self.font, "Loose", nameID=267) self.assertEqual(OSAKA_VERT_ONLY_TRAK_TABLE_XML, getXML(table, self.font))
def test_buildLigCaretList(self): carets = builder.buildLigCaretList( {"f_f_i": [300, 600]}, {"c_t": [42]}, self.GLYPHMAP) self.assertEqual(getXML(carets.toXML), '<LigCaretList>' ' <Coverage>' ' <Glyph value="f_f_i"/>' ' <Glyph value="c_t"/>' ' </Coverage>' ' <!-- LigGlyphCount=2 -->' ' <LigGlyph index="0">' ' <!-- CaretCount=2 -->' ' <CaretValue index="0" Format="1">' ' <Coordinate value="300"/>' ' </CaretValue>' ' <CaretValue index="1" Format="1">' ' <Coordinate value="600"/>' ' </CaretValue>' ' </LigGlyph>' ' <LigGlyph index="1">' ' <!-- CaretCount=1 -->' ' <CaretValue index="0" Format="2">' ' <CaretValuePoint value="42"/>' ' </CaretValue>' ' </LigGlyph>' '</LigCaretList>')
def test_buildMarkArray(self): markArray = builder.buildMarkArray( { "acute": (7, builder.buildAnchor(300, 800)), "grave": (2, builder.buildAnchor(10, 80)) }, self.GLYPHMAP) self.assertLess(self.GLYPHMAP["grave"], self.GLYPHMAP["acute"]) self.assertEqual( getXML(markArray.toXML), '<MarkArray>' ' <!-- MarkCount=2 -->' ' <MarkRecord index="0">' ' <Class value="2"/>' ' <MarkAnchor Format="1">' ' <XCoordinate value="10"/>' ' <YCoordinate value="80"/>' ' </MarkAnchor>' ' </MarkRecord>' ' <MarkRecord index="1">' ' <Class value="7"/>' ' <MarkAnchor Format="1">' ' <XCoordinate value="300"/>' ' <YCoordinate value="800"/>' ' </MarkAnchor>' ' </MarkRecord>' '</MarkArray>')
def test_buildLigatureArray(self): anchor = builder.buildAnchor ligatureArray = builder.buildLigatureArray( { "f_i": [{ 2: anchor(300, -20) }, {}], "c_t": [{}, { 1: anchor(500, 350), 2: anchor(1300, -20) }] }, numMarkClasses=4, glyphMap=self.GLYPHMAP) self.maxDiff = None self.assertEqual( getXML(ligatureArray.toXML), '<LigatureArray>' ' <!-- LigatureCount=2 -->' ' <LigatureAttach index="0">' # f_i ' <!-- ComponentCount=2 -->' ' <ComponentRecord index="0">' ' <LigatureAnchor index="0" empty="1"/>' ' <LigatureAnchor index="1" empty="1"/>' ' <LigatureAnchor index="2" Format="1">' ' <XCoordinate value="300"/>' ' <YCoordinate value="-20"/>' ' </LigatureAnchor>' ' <LigatureAnchor index="3" empty="1"/>' ' </ComponentRecord>' ' <ComponentRecord index="1">' ' <LigatureAnchor index="0" empty="1"/>' ' <LigatureAnchor index="1" empty="1"/>' ' <LigatureAnchor index="2" empty="1"/>' ' <LigatureAnchor index="3" empty="1"/>' ' </ComponentRecord>' ' </LigatureAttach>' ' <LigatureAttach index="1">' ' <!-- ComponentCount=2 -->' ' <ComponentRecord index="0">' ' <LigatureAnchor index="0" empty="1"/>' ' <LigatureAnchor index="1" empty="1"/>' ' <LigatureAnchor index="2" empty="1"/>' ' <LigatureAnchor index="3" empty="1"/>' ' </ComponentRecord>' ' <ComponentRecord index="1">' ' <LigatureAnchor index="0" empty="1"/>' ' <LigatureAnchor index="1" Format="1">' ' <XCoordinate value="500"/>' ' <YCoordinate value="350"/>' ' </LigatureAnchor>' ' <LigatureAnchor index="2" Format="1">' ' <XCoordinate value="1300"/>' ' <YCoordinate value="-20"/>' ' </LigatureAnchor>' ' <LigatureAnchor index="3" empty="1"/>' ' </ComponentRecord>' ' </LigatureAttach>' '</LigatureArray>')
def test_buildLigatureArray(self): anchor = builder.buildAnchor ligatureArray = builder.buildLigatureArray( { "f_i": [{ 2: anchor(300, -20) }, {}], "c_t": [{}, { 1: anchor(500, 350), 2: anchor(1300, -20) }], }, numMarkClasses=4, glyphMap=self.GLYPHMAP, ) assert getXML(ligatureArray.toXML) == [ "<LigatureArray>", " <!-- LigatureCount=2 -->", ' <LigatureAttach index="0">', # f_i " <!-- ComponentCount=2 -->", ' <ComponentRecord index="0">', ' <LigatureAnchor index="0" empty="1"/>', ' <LigatureAnchor index="1" empty="1"/>', ' <LigatureAnchor index="2" Format="1">', ' <XCoordinate value="300"/>', ' <YCoordinate value="-20"/>', " </LigatureAnchor>", ' <LigatureAnchor index="3" empty="1"/>', " </ComponentRecord>", ' <ComponentRecord index="1">', ' <LigatureAnchor index="0" empty="1"/>', ' <LigatureAnchor index="1" empty="1"/>', ' <LigatureAnchor index="2" empty="1"/>', ' <LigatureAnchor index="3" empty="1"/>', " </ComponentRecord>", " </LigatureAttach>", ' <LigatureAttach index="1">', " <!-- ComponentCount=2 -->", ' <ComponentRecord index="0">', ' <LigatureAnchor index="0" empty="1"/>', ' <LigatureAnchor index="1" empty="1"/>', ' <LigatureAnchor index="2" empty="1"/>', ' <LigatureAnchor index="3" empty="1"/>', " </ComponentRecord>", ' <ComponentRecord index="1">', ' <LigatureAnchor index="0" empty="1"/>', ' <LigatureAnchor index="1" Format="1">', ' <XCoordinate value="500"/>', ' <YCoordinate value="350"/>', " </LigatureAnchor>", ' <LigatureAnchor index="2" Format="1">', ' <XCoordinate value="1300"/>', ' <YCoordinate value="-20"/>', " </LigatureAnchor>", ' <LigatureAnchor index="3" empty="1"/>', " </ComponentRecord>", " </LigatureAttach>", "</LigatureArray>", ]
def test_buildCoverage(self): cov = builder.buildCoverage({"two", "four"}, {"two": 2, "four": 4}) assert getXML(cov.toXML) == [ "<Coverage>", ' <Glyph value="two"/>', ' <Glyph value="four"/>', "</Coverage>", ]
def testDecompileToXML(self): a = otTables.InsertionMorphAction() actionReader = OTTableReader( deHexStr("DEAD BEEF 0002 0001 0004 0002 0003 DEAD BEEF")) a.decompile(OTTableReader(deHexStr("1234 FC43 0005 0002")), self.font, actionReader) toXML = lambda w, f: a.toXML(w, f, {"Test": "Foo"}, "Transition") self.assertEqual(getXML(toXML, self.font), self.MORPH_ACTION_XML)
def test_buildLigatureAttach_emptyComponents(self): attach = builder.buildLigatureAttach([[], None]) self.assertEqual(getXML(attach.toXML), '<LigatureAttach>' ' <!-- ComponentCount=2 -->' ' <ComponentRecord index="0" empty="1"/>' ' <ComponentRecord index="1" empty="1"/>' '</LigatureAttach>')
def test_toXML_vert(self): table = self.font['trak'] table.vertData = TrackData(OSAKA_VERT_TRACK_ENTRIES) add_name(self.font, 'Tight', nameID=265) add_name(self.font, 'Normal', nameID=266) add_name(self.font, 'Loose', nameID=267) self.assertEqual(OSAKA_VERT_ONLY_TRAK_TABLE_XML, getXML(table.toXML, self.font))
def test_buildAnchor_format1(self): anchor = builder.buildAnchor(23, 42) assert getXML(anchor.toXML) == [ '<Anchor Format="1">', ' <XCoordinate value="23"/>', ' <YCoordinate value="42"/>', "</Anchor>", ]
def test_toXML_version_11_as_float(self): vhea = self.font['vhea'] vhea.tableVersion = 1.0625 with CapturingLogHandler(log, "WARNING") as captor: self.assertEqual(getXML(vhea.toXML), VHEA_XML_VERSION_11) self.assertTrue( len([r for r in captor.records if "Table version value is a float" in r.msg]) == 1)
def test_buildAttachPoint(self): attachPoint = builder.buildAttachPoint([7, 3]) self.assertEqual(getXML(attachPoint.toXML), '<AttachPoint>' ' <!-- PointCount=2 -->' ' <PointIndex index="0" value="3"/>' ' <PointIndex index="1" value="7"/>' '</AttachPoint>')
def test_toXML_version_as_float(self): hhea = self.font['hhea'] hhea.tableVersion = 1.0 with CapturingLogHandler(log, "WARNING") as captor: self.assertEqual(getXML(hhea.toXML), HHEA_XML) self.assertTrue( len([r for r in captor.records if "Table version value is a float" in r.msg]) == 1)
def test_buildLigatureAttach_emptyComponents(self): attach = builder.buildLigatureAttach([[], None]) assert getXML(attach.toXML) == [ "<LigatureAttach>", " <!-- ComponentCount=2 -->", ' <ComponentRecord index="0" empty="1"/>', ' <ComponentRecord index="1" empty="1"/>', "</LigatureAttach>", ]
def test_buildLigGlyph_points(self): lig = builder.buildLigGlyph(None, [2]) self.assertEqual(getXML(lig.toXML), '<LigGlyph>' ' <!-- CaretCount=1 -->' ' <CaretValue index="0" Format="2">' ' <CaretValuePoint value="2"/>' ' </CaretValue>' '</LigGlyph>')
def test_buildDevice_format3(self): device = builder.buildDevice([(5, 3), (1, 77)]) self.assertEqual(getXML(device.toXML), '<Device>' ' <StartSize value="1"/>' ' <EndSize value="5"/>' ' <DeltaFormat value="3"/>' ' <DeltaValue value="[77, 0, 0, 0, 3]"/>' '</Device>')
def test_round_trip_xml(self, font): colr = table_C_O_L_R_() for name, attrs, content in parseXML(COLR_V0_XML): colr.fromXML(name, attrs, content, font) compiled = colr.compile(font) colr = table_C_O_L_R_() colr.decompile(compiled, font) assert getXML(colr.toXML, font) == COLR_V0_XML
def test_buildDevice_format2(self): device = builder.buildDevice([(1, 2), (-1, 1), (0, 0)]) self.assertEqual(getXML(device.toXML), '<Device>' ' <StartSize value="-1"/>' ' <EndSize value="1"/>' ' <DeltaFormat value="2"/>' ' <DeltaValue value="[1, 0, 2]"/>' '</Device>')
def test_toXML_no_transform(self): comp = GlyphComponent() comp.glyphName = "a" comp.flags = ARGS_ARE_XY_VALUES comp.x, comp.y = 1, 2 assert getXML(comp.toXML) == [ '<component glyphName="a" x="1" y="2" flags="0x2"/>' ]
def test_round_trip_ttx(font): table = table_S_V_G_() for name, attrs, content in parseXML(OTSVG_TTX): table.fromXML(name, attrs, content, font) compiled = table.compile(font) table = table_S_V_G_() table.decompile(compiled, font) assert getXML(table.toXML, font) == OTSVG_TTX
def test_buildDevice_format1(self): device = builder.buildDevice({1:1, 0:0}) self.assertEqual(getXML(device.toXML), '<Device>' ' <StartSize value="0"/>' ' <EndSize value="1"/>' ' <DeltaFormat value="1"/>' ' <DeltaValue value="[0, 1]"/>' '</Device>')
def test_buildAttachPoint(self): attachPoint = builder.buildAttachPoint([7, 3]) assert getXML(attachPoint.toXML) == [ "<AttachPoint>", " <!-- PointCount=2 -->", ' <PointIndex index="0" value="3"/>', ' <PointIndex index="1" value="7"/>', "</AttachPoint>", ]
def test_buildDevice_format2(self): device = builder.buildDevice({2:2, 0:1, 1:0}) self.assertEqual(getXML(device.toXML), '<Device>' ' <StartSize value="0"/>' ' <EndSize value="2"/>' ' <DeltaFormat value="2"/>' ' <DeltaValue value="[1, 0, 2]"/>' '</Device>')
def test_buildMarkRecord(self): rec = builder.buildMarkRecord(17, builder.buildAnchor(500, -20)) self.assertEqual(getXML(rec.toXML), '<MarkRecord> ' ' <Class value="17"/>' ' <MarkAnchor Format="1">' ' <XCoordinate value="500"/>' ' <YCoordinate value="-20"/>' ' </MarkAnchor>' '</MarkRecord>')
def test_toXML(self): font = self.makeFont(numGlyphs=2, numberOfMetrics=2) mtxTable = font[self.tag] = newTable(self.tag) mtxTable.metrics = {'B': (632, 79), 'A': (674, -11)} self.assertEqual( getXML(mtxTable.toXML), ('<mtx name="A" %s="674" %s="-11"/>\n' '<mtx name="B" %s="632" %s="79"/>' % ( (self.tableClass.advanceName, self.tableClass.sideBearingName) * 2)).split('\n'))
def test_buildSinglePos_ValueFormat0(self): subtables = builder.buildSinglePos({ "zero": builder.buildValue({}) }, self.GLYPHMAP) self.assertEqual(''.join([getXML(t.toXML) for t in subtables]), '<SinglePos Format="1">' ' <Coverage>' ' <Glyph value="zero"/>' ' </Coverage>' ' <ValueFormat value="0"/>' '</SinglePos>')
def test_buildLigGlyph_coords(self): lig = builder.buildLigGlyph([500, 800], None) self.assertEqual(getXML(lig.toXML), '<LigGlyph>' ' <!-- CaretCount=2 -->' ' <CaretValue index="0" Format="1">' ' <Coordinate value="500"/>' ' </CaretValue>' ' <CaretValue index="1" Format="1">' ' <Coordinate value="800"/>' ' </CaretValue>' '</LigGlyph>')
def test_buildPairPosClassesSubtable(self): d20 = builder.buildValue({"XPlacement": -20}) d50 = builder.buildValue({"XPlacement": -50}) d0 = builder.buildValue({}) d8020 = builder.buildValue({"XPlacement": -80, "YPlacement": -20}) subtable = builder.buildPairPosClassesSubtable({ (tuple("A",), tuple(["zero"])): (d0, d50), (tuple("A",), tuple(["one", "two"])): (None, d20), (tuple(["B", "C"]), tuple(["zero"])): (d8020, d50), }, self.GLYPHMAP) self.maxDiff = None self.assertEqual(getXML(subtable.toXML), '<PairPos Format="2">' ' <Coverage>' ' <Glyph value="A"/>' ' <Glyph value="B"/>' ' <Glyph value="C"/>' ' </Coverage>' ' <ValueFormat1 value="3"/>' ' <ValueFormat2 value="1"/>' ' <ClassDef1>' ' <ClassDef glyph="A" class="1"/>' ' </ClassDef1>' ' <ClassDef2>' ' <ClassDef glyph="one" class="1"/>' ' <ClassDef glyph="two" class="1"/>' ' <ClassDef glyph="zero" class="2"/>' ' </ClassDef2>' ' <!-- Class1Count=2 -->' ' <!-- Class2Count=3 -->' ' <Class1Record index="0">' ' <Class2Record index="0">' ' </Class2Record>' ' <Class2Record index="1">' ' </Class2Record>' ' <Class2Record index="2">' ' <Value1 XPlacement="-80" YPlacement="-20"/>' ' <Value2 XPlacement="-50"/>' ' </Class2Record>' ' </Class1Record>' ' <Class1Record index="1">' ' <Class2Record index="0">' ' </Class2Record>' ' <Class2Record index="1">' ' <Value2 XPlacement="-20"/>' ' </Class2Record>' ' <Class2Record index="2">' ' <Value1/>' ' <Value2 XPlacement="-50"/>' ' </Class2Record>' ' </Class1Record>' '</PairPos>')
def testDecompileToXML(self): r = otTables.RearrangementMorphAction() r.decompile(OTTableReader(deHexStr("1234fffd")), self.font, actionReader=None) toXML = lambda w, f: r.toXML(w, f, {"Test": "Foo"}, "Transition") self.assertEqual(getXML(toXML, self.font), [ '<Transition Test="Foo">', ' <NewState value="4660"/>', # 0x1234 = 4660 ' <Flags value="MarkFirst,DontAdvance,MarkLast"/>', ' <ReservedFlags value="0x1FF0"/>', ' <Verb value="13"/><!-- ABxCD ⇒ CDxBA -->', '</Transition>', ])
def test_buildSinglePosSubtable_format1(self): subtable = builder.buildSinglePosSubtable({ "one": builder.buildValue({"XPlacement": 777}), "two": builder.buildValue({"XPlacement": 777}), }, self.GLYPHMAP) self.assertEqual(getXML(subtable.toXML), '<SinglePos Format="1">' ' <Coverage>' ' <Glyph value="one"/>' ' <Glyph value="two"/>' ' </Coverage>' ' <ValueFormat value="1"/>' ' <Value XPlacement="777"/>' '</SinglePos>')
def testDecompileToXML(self): a = otTables.ContextualMorphAction() a.decompile(OTTableReader(deHexStr("1234f117deadbeef")), self.font, actionReader=None) toXML = lambda w, f: a.toXML(w, f, {"Test": "Foo"}, "Transition") self.assertEqual(getXML(toXML, self.font), [ '<Transition Test="Foo">', ' <NewState value="4660"/>', # 0x1234 = 4660 ' <Flags value="SetMark,DontAdvance"/>', ' <ReservedFlags value="0x3117"/>', ' <MarkIndex value="57005"/>', # 0xDEAD = 57005 ' <CurrentIndex value="48879"/>', # 0xBEEF = 48879 '</Transition>', ])
def test_toXML_v0(self): cpal = newTable('CPAL') cpal.decompile(CPAL_DATA_V0, ttFont=None) self.assertEqual(getXML(cpal.toXML), '<version value="0"/>' '<numPaletteEntries value="2"/>' '<palette index="0">' ' <color index="0" value="#000000FF"/>' ' <color index="1" value="#66CCFFFF"/>' '</palette>' '<palette index="1">' ' <color index="0" value="#000000FF"/>' ' <color index="1" value="#800000FF"/>' '</palette>')
def test_buildLigatureArray(self): anchor = builder.buildAnchor ligatureArray = builder.buildLigatureArray({ "f_i": [{2: anchor(300, -20)}, {}], "c_t": [{}, {1: anchor(500, 350), 2: anchor(1300, -20)}] }, numMarkClasses=4, glyphMap=self.GLYPHMAP) self.maxDiff = None self.assertEqual(getXML(ligatureArray.toXML), '<LigatureArray>' ' <!-- LigatureCount=2 -->' ' <LigatureAttach index="0">' # f_i ' <!-- ComponentCount=2 -->' ' <ComponentRecord index="0">' ' <LigatureAnchor index="0" empty="1"/>' ' <LigatureAnchor index="1" empty="1"/>' ' <LigatureAnchor index="2" Format="1">' ' <XCoordinate value="300"/>' ' <YCoordinate value="-20"/>' ' </LigatureAnchor>' ' <LigatureAnchor index="3" empty="1"/>' ' </ComponentRecord>' ' <ComponentRecord index="1">' ' <LigatureAnchor index="0" empty="1"/>' ' <LigatureAnchor index="1" empty="1"/>' ' <LigatureAnchor index="2" empty="1"/>' ' <LigatureAnchor index="3" empty="1"/>' ' </ComponentRecord>' ' </LigatureAttach>' ' <LigatureAttach index="1">' ' <!-- ComponentCount=2 -->' ' <ComponentRecord index="0">' ' <LigatureAnchor index="0" empty="1"/>' ' <LigatureAnchor index="1" empty="1"/>' ' <LigatureAnchor index="2" empty="1"/>' ' <LigatureAnchor index="3" empty="1"/>' ' </ComponentRecord>' ' <ComponentRecord index="1">' ' <LigatureAnchor index="0" empty="1"/>' ' <LigatureAnchor index="1" Format="1">' ' <XCoordinate value="500"/>' ' <YCoordinate value="350"/>' ' </LigatureAnchor>' ' <LigatureAnchor index="2" Format="1">' ' <XCoordinate value="1300"/>' ' <YCoordinate value="-20"/>' ' </LigatureAnchor>' ' <LigatureAnchor index="3" empty="1"/>' ' </ComponentRecord>' ' </LigatureAttach>' '</LigatureArray>')