diff --git a/Tests/ttLib/tables/_g_l_y_f_test.py b/Tests/ttLib/tables/_g_l_y_f_test.py index f0a42eee7..cec15cce6 100644 --- a/Tests/ttLib/tables/_g_l_y_f_test.py +++ b/Tests/ttLib/tables/_g_l_y_f_test.py @@ -10,6 +10,8 @@ from fontTools.ttLib.tables._g_l_y_f import ( GlyphCoordinates, GlyphComponent, ARGS_ARE_XY_VALUES, + SCALED_COMPONENT_OFFSET, + UNSCALED_COMPONENT_OFFSET, WE_HAVE_A_SCALE, WE_HAVE_A_TWO_BY_TWO, WE_HAVE_AN_X_AND_Y_SCALE, @@ -362,6 +364,114 @@ class GlyfTableTest(unittest.TestCase): self.assertEqual(font["glyf"]["space"].numberOfContours, 0) +class GlyphTest: + + def test_getCoordinates(self): + glyphSet = {} + pen = TTGlyphPen(glyphSet) + pen.moveTo((0, 0)) + pen.lineTo((100, 0)) + pen.lineTo((100, 100)) + pen.lineTo((0, 100)) + pen.closePath() + # simple contour glyph + glyphSet["a"] = a = pen.glyph() + + assert a.getCoordinates(glyphSet) == ( + GlyphCoordinates([(0, 0), (100, 0), (100, 100), (0, 100)]), + [3], + array.array("B", [1, 1, 1, 1]), + ) + + # composite glyph with only XY offset + pen = TTGlyphPen(glyphSet) + pen.addComponent("a", (1, 0, 0, 1, 10, 20)) + glyphSet["b"] = b = pen.glyph() + + assert b.getCoordinates(glyphSet) == ( + GlyphCoordinates([(10, 20), (110, 20), (110, 120), (10, 120)]), + [3], + array.array("B", [1, 1, 1, 1]), + ) + + # composite glyph with a scale (and referencing another composite glyph) + pen = TTGlyphPen(glyphSet) + pen.addComponent("b", (0.5, 0, 0, 0.5, 0, 0)) + glyphSet["c"] = c = pen.glyph() + + assert c.getCoordinates(glyphSet) == ( + GlyphCoordinates([(5, 10), (55, 10), (55, 60), (5, 60)]), + [3], + array.array("B", [1, 1, 1, 1]), + ) + + # composite glyph with unscaled offset (MS-style) + pen = TTGlyphPen(glyphSet) + pen.addComponent("a", (0.5, 0, 0, 0.5, 10, 20)) + glyphSet["d"] = d = pen.glyph() + d.components[0].flags |= UNSCALED_COMPONENT_OFFSET + + assert d.getCoordinates(glyphSet) == ( + GlyphCoordinates([(10, 20), (60, 20), (60, 70), (10, 70)]), + [3], + array.array("B", [1, 1, 1, 1]), + ) + + # composite glyph with a scaled offset (Apple-style) + pen = TTGlyphPen(glyphSet) + pen.addComponent("a", (0.5, 0, 0, 0.5, 10, 20)) + glyphSet["e"] = e = pen.glyph() + e.components[0].flags |= SCALED_COMPONENT_OFFSET + + assert e.getCoordinates(glyphSet) == ( + GlyphCoordinates([(5, 10), (55, 10), (55, 60), (5, 60)]), + [3], + array.array("B", [1, 1, 1, 1]), + ) + + # composite glyph where the 2nd and 3rd components use anchor points + pen = TTGlyphPen(glyphSet) + pen.addComponent("a", (1, 0, 0, 1, 0, 0)) + glyphSet["f"] = f = pen.glyph() + + comp1 = GlyphComponent() + comp1.glyphName = "a" + # aling the new component's pt 0 to pt 2 of contour points added so far + comp1.firstPt = 2 + comp1.secondPt = 0 + comp1.flags = 0 + f.components.append(comp1) + + comp2 = GlyphComponent() + comp2.glyphName = "a" + # aling the new component's pt 0 to pt 6 of contour points added so far + comp2.firstPt = 6 + comp2.secondPt = 0 + comp2.transform = [[0.707107, 0.707107], [-0.707107, 0.707107]] # rotate 45 deg + comp2.flags = WE_HAVE_A_TWO_BY_TWO + f.components.append(comp2) + + coords, end_pts, flags = f.getCoordinates(glyphSet) + assert end_pts == [3, 7, 11] + assert flags == array.array("B", [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) + assert list(sum(coords, ())) == pytest.approx( + [ + 0, 0, + 100, 0, + 100, 100, + 0, 100, + 100, 100, + 200, 100, + 200, 200, + 100, 200, + 200, 200, + 270.7107, 270.7107, + 200.0, 341.4214, + 129.2893, 270.7107, + ] + ) + + class GlyphComponentTest: def test_toXML_no_transform(self): @@ -479,6 +589,29 @@ class GlyphComponentTest: ): assert value == pytest.approx(expected) + def test_toXML_reference_points(self): + comp = GlyphComponent() + comp.glyphName = "a" + comp.flags = 0 + comp.firstPt = 1 + comp.secondPt = 2 + + assert getXML(comp.toXML) == [ + '' + ] + + def test_fromXML_reference_points(self): + comp = GlyphComponent() + for name, attrs, content in parseXML( + [''] + ): + comp.fromXML(name, attrs, content, ttFont=None) + + assert comp.glyphName == "a" + assert comp.flags == 0 + assert (comp.firstPt, comp.secondPt) == (1, 2) + assert not hasattr(comp, "transform") + if __name__ == "__main__": import sys