1*e1fe3e4aSElliott Hughesfrom fontTools.pens.basePen import ( 2*e1fe3e4aSElliott Hughes AbstractPen, 3*e1fe3e4aSElliott Hughes BasePen, 4*e1fe3e4aSElliott Hughes decomposeSuperBezierSegment, 5*e1fe3e4aSElliott Hughes decomposeQuadraticSegment, 6*e1fe3e4aSElliott Hughes) 7*e1fe3e4aSElliott Hughesfrom fontTools.pens.pointPen import AbstractPointPen 8*e1fe3e4aSElliott Hughesfrom fontTools.misc.loggingTools import CapturingLogHandler 9*e1fe3e4aSElliott Hughesimport unittest 10*e1fe3e4aSElliott Hughes 11*e1fe3e4aSElliott Hughes 12*e1fe3e4aSElliott Hughesclass _TestPen(BasePen): 13*e1fe3e4aSElliott Hughes def __init__(self): 14*e1fe3e4aSElliott Hughes BasePen.__init__(self, glyphSet={}) 15*e1fe3e4aSElliott Hughes self._commands = [] 16*e1fe3e4aSElliott Hughes 17*e1fe3e4aSElliott Hughes def __repr__(self): 18*e1fe3e4aSElliott Hughes return " ".join(self._commands) 19*e1fe3e4aSElliott Hughes 20*e1fe3e4aSElliott Hughes def getCurrentPoint(self): 21*e1fe3e4aSElliott Hughes return self._getCurrentPoint() 22*e1fe3e4aSElliott Hughes 23*e1fe3e4aSElliott Hughes def _moveTo(self, pt): 24*e1fe3e4aSElliott Hughes self._commands.append("%s %s moveto" % (pt[0], pt[1])) 25*e1fe3e4aSElliott Hughes 26*e1fe3e4aSElliott Hughes def _lineTo(self, pt): 27*e1fe3e4aSElliott Hughes self._commands.append("%s %s lineto" % (pt[0], pt[1])) 28*e1fe3e4aSElliott Hughes 29*e1fe3e4aSElliott Hughes def _curveToOne(self, bcp1, bcp2, pt): 30*e1fe3e4aSElliott Hughes self._commands.append( 31*e1fe3e4aSElliott Hughes "%s %s %s %s %s %s curveto" 32*e1fe3e4aSElliott Hughes % (bcp1[0], bcp1[1], bcp2[0], bcp2[1], pt[0], pt[1]) 33*e1fe3e4aSElliott Hughes ) 34*e1fe3e4aSElliott Hughes 35*e1fe3e4aSElliott Hughes def _closePath(self): 36*e1fe3e4aSElliott Hughes self._commands.append("closepath") 37*e1fe3e4aSElliott Hughes 38*e1fe3e4aSElliott Hughes def _endPath(self): 39*e1fe3e4aSElliott Hughes self._commands.append("endpath") 40*e1fe3e4aSElliott Hughes 41*e1fe3e4aSElliott Hughes 42*e1fe3e4aSElliott Hughesclass _TestGlyph: 43*e1fe3e4aSElliott Hughes def draw(self, pen): 44*e1fe3e4aSElliott Hughes pen.moveTo((0.0, 0.0)) 45*e1fe3e4aSElliott Hughes pen.lineTo((0.0, 100.0)) 46*e1fe3e4aSElliott Hughes pen.curveTo((50.0, 75.0), (60.0, 50.0), (50.0, 25.0), (0.0, 0.0)) 47*e1fe3e4aSElliott Hughes pen.closePath() 48*e1fe3e4aSElliott Hughes 49*e1fe3e4aSElliott Hughes 50*e1fe3e4aSElliott Hughesclass BasePenTest(unittest.TestCase): 51*e1fe3e4aSElliott Hughes def test_moveTo(self): 52*e1fe3e4aSElliott Hughes pen = _TestPen() 53*e1fe3e4aSElliott Hughes pen.moveTo((0.5, -4.3)) 54*e1fe3e4aSElliott Hughes self.assertEqual("0.5 -4.3 moveto", repr(pen)) 55*e1fe3e4aSElliott Hughes self.assertEqual((0.5, -4.3), pen.getCurrentPoint()) 56*e1fe3e4aSElliott Hughes 57*e1fe3e4aSElliott Hughes def test_lineTo(self): 58*e1fe3e4aSElliott Hughes pen = _TestPen() 59*e1fe3e4aSElliott Hughes pen.moveTo((4, 5)) 60*e1fe3e4aSElliott Hughes pen.lineTo((7, 8)) 61*e1fe3e4aSElliott Hughes self.assertEqual("4 5 moveto 7 8 lineto", repr(pen)) 62*e1fe3e4aSElliott Hughes self.assertEqual((7, 8), pen.getCurrentPoint()) 63*e1fe3e4aSElliott Hughes 64*e1fe3e4aSElliott Hughes def test_curveTo_zeroPoints(self): 65*e1fe3e4aSElliott Hughes pen = _TestPen() 66*e1fe3e4aSElliott Hughes pen.moveTo((0.0, 0.0)) 67*e1fe3e4aSElliott Hughes self.assertRaises(AssertionError, pen.curveTo) 68*e1fe3e4aSElliott Hughes 69*e1fe3e4aSElliott Hughes def test_curveTo_onePoint(self): 70*e1fe3e4aSElliott Hughes pen = _TestPen() 71*e1fe3e4aSElliott Hughes pen.moveTo((0.0, 0.0)) 72*e1fe3e4aSElliott Hughes pen.curveTo((1.0, 1.1)) 73*e1fe3e4aSElliott Hughes self.assertEqual("0.0 0.0 moveto 1.0 1.1 lineto", repr(pen)) 74*e1fe3e4aSElliott Hughes self.assertEqual((1.0, 1.1), pen.getCurrentPoint()) 75*e1fe3e4aSElliott Hughes 76*e1fe3e4aSElliott Hughes def test_curveTo_twoPoints(self): 77*e1fe3e4aSElliott Hughes pen = _TestPen() 78*e1fe3e4aSElliott Hughes pen.moveTo((0.0, 0.0)) 79*e1fe3e4aSElliott Hughes pen.curveTo((6.0, 3.0), (3.0, 6.0)) 80*e1fe3e4aSElliott Hughes self.assertEqual("0.0 0.0 moveto 4.0 2.0 5.0 4.0 3.0 6.0 curveto", repr(pen)) 81*e1fe3e4aSElliott Hughes self.assertEqual((3.0, 6.0), pen.getCurrentPoint()) 82*e1fe3e4aSElliott Hughes 83*e1fe3e4aSElliott Hughes def test_curveTo_manyPoints(self): 84*e1fe3e4aSElliott Hughes pen = _TestPen() 85*e1fe3e4aSElliott Hughes pen.moveTo((0.0, 0.0)) 86*e1fe3e4aSElliott Hughes pen.curveTo((1.0, 1.1), (2.0, 2.1), (3.0, 3.1), (4.0, 4.1)) 87*e1fe3e4aSElliott Hughes self.assertEqual( 88*e1fe3e4aSElliott Hughes "0.0 0.0 moveto " 89*e1fe3e4aSElliott Hughes "1.0 1.1 1.5 1.6 2.0 2.1 curveto " 90*e1fe3e4aSElliott Hughes "2.5 2.6 3.0 3.1 4.0 4.1 curveto", 91*e1fe3e4aSElliott Hughes repr(pen), 92*e1fe3e4aSElliott Hughes ) 93*e1fe3e4aSElliott Hughes self.assertEqual((4.0, 4.1), pen.getCurrentPoint()) 94*e1fe3e4aSElliott Hughes 95*e1fe3e4aSElliott Hughes def test_qCurveTo_zeroPoints(self): 96*e1fe3e4aSElliott Hughes pen = _TestPen() 97*e1fe3e4aSElliott Hughes pen.moveTo((0.0, 0.0)) 98*e1fe3e4aSElliott Hughes self.assertRaises(AssertionError, pen.qCurveTo) 99*e1fe3e4aSElliott Hughes 100*e1fe3e4aSElliott Hughes def test_qCurveTo_onePoint(self): 101*e1fe3e4aSElliott Hughes pen = _TestPen() 102*e1fe3e4aSElliott Hughes pen.moveTo((0.0, 0.0)) 103*e1fe3e4aSElliott Hughes pen.qCurveTo((77.7, 99.9)) 104*e1fe3e4aSElliott Hughes self.assertEqual("0.0 0.0 moveto 77.7 99.9 lineto", repr(pen)) 105*e1fe3e4aSElliott Hughes self.assertEqual((77.7, 99.9), pen.getCurrentPoint()) 106*e1fe3e4aSElliott Hughes 107*e1fe3e4aSElliott Hughes def test_qCurveTo_manyPoints(self): 108*e1fe3e4aSElliott Hughes pen = _TestPen() 109*e1fe3e4aSElliott Hughes pen.moveTo((0.0, 0.0)) 110*e1fe3e4aSElliott Hughes pen.qCurveTo((6.0, 3.0), (3.0, 6.0)) 111*e1fe3e4aSElliott Hughes self.assertEqual("0.0 0.0 moveto 4.0 2.0 5.0 4.0 3.0 6.0 curveto", repr(pen)) 112*e1fe3e4aSElliott Hughes self.assertEqual((3.0, 6.0), pen.getCurrentPoint()) 113*e1fe3e4aSElliott Hughes 114*e1fe3e4aSElliott Hughes def test_qCurveTo_onlyOffCurvePoints(self): 115*e1fe3e4aSElliott Hughes pen = _TestPen() 116*e1fe3e4aSElliott Hughes pen.moveTo((0.0, 0.0)) 117*e1fe3e4aSElliott Hughes pen.qCurveTo((6.0, -6.0), (12.0, 12.0), (18.0, -18.0), None) 118*e1fe3e4aSElliott Hughes self.assertEqual( 119*e1fe3e4aSElliott Hughes "0.0 0.0 moveto " 120*e1fe3e4aSElliott Hughes "12.0 -12.0 moveto " 121*e1fe3e4aSElliott Hughes "8.0 -8.0 7.0 -3.0 9.0 3.0 curveto " 122*e1fe3e4aSElliott Hughes "11.0 9.0 13.0 7.0 15.0 -3.0 curveto " 123*e1fe3e4aSElliott Hughes "17.0 -13.0 16.0 -16.0 12.0 -12.0 curveto", 124*e1fe3e4aSElliott Hughes repr(pen), 125*e1fe3e4aSElliott Hughes ) 126*e1fe3e4aSElliott Hughes self.assertEqual((12.0, -12.0), pen.getCurrentPoint()) 127*e1fe3e4aSElliott Hughes 128*e1fe3e4aSElliott Hughes def test_closePath(self): 129*e1fe3e4aSElliott Hughes pen = _TestPen() 130*e1fe3e4aSElliott Hughes pen.lineTo((3, 4)) 131*e1fe3e4aSElliott Hughes pen.closePath() 132*e1fe3e4aSElliott Hughes self.assertEqual("3 4 lineto closepath", repr(pen)) 133*e1fe3e4aSElliott Hughes self.assertEqual(None, pen.getCurrentPoint()) 134*e1fe3e4aSElliott Hughes 135*e1fe3e4aSElliott Hughes def test_endPath(self): 136*e1fe3e4aSElliott Hughes pen = _TestPen() 137*e1fe3e4aSElliott Hughes pen.lineTo((3, 4)) 138*e1fe3e4aSElliott Hughes pen.endPath() 139*e1fe3e4aSElliott Hughes self.assertEqual("3 4 lineto endpath", repr(pen)) 140*e1fe3e4aSElliott Hughes self.assertEqual(None, pen.getCurrentPoint()) 141*e1fe3e4aSElliott Hughes 142*e1fe3e4aSElliott Hughes def test_addComponent(self): 143*e1fe3e4aSElliott Hughes pen = _TestPen() 144*e1fe3e4aSElliott Hughes pen.glyphSet["oslash"] = _TestGlyph() 145*e1fe3e4aSElliott Hughes pen.addComponent("oslash", (2, 3, 0.5, 2, -10, 0)) 146*e1fe3e4aSElliott Hughes self.assertEqual( 147*e1fe3e4aSElliott Hughes "-10.0 0.0 moveto " 148*e1fe3e4aSElliott Hughes "40.0 200.0 lineto " 149*e1fe3e4aSElliott Hughes "127.5 300.0 131.25 290.0 125.0 265.0 curveto " 150*e1fe3e4aSElliott Hughes "118.75 240.0 102.5 200.0 -10.0 0.0 curveto " 151*e1fe3e4aSElliott Hughes "closepath", 152*e1fe3e4aSElliott Hughes repr(pen), 153*e1fe3e4aSElliott Hughes ) 154*e1fe3e4aSElliott Hughes self.assertEqual(None, pen.getCurrentPoint()) 155*e1fe3e4aSElliott Hughes 156*e1fe3e4aSElliott Hughes def test_addComponent_skip_missing(self): 157*e1fe3e4aSElliott Hughes pen = _TestPen() 158*e1fe3e4aSElliott Hughes with CapturingLogHandler(pen.log, "WARNING") as captor: 159*e1fe3e4aSElliott Hughes pen.addComponent("nonexistent", (1, 0, 0, 1, 0, 0)) 160*e1fe3e4aSElliott Hughes captor.assertRegex("glyph '.*' is missing from glyphSet; skipped") 161*e1fe3e4aSElliott Hughes 162*e1fe3e4aSElliott Hughes 163*e1fe3e4aSElliott Hughesclass DecomposeSegmentTest(unittest.TestCase): 164*e1fe3e4aSElliott Hughes def test_decomposeSuperBezierSegment(self): 165*e1fe3e4aSElliott Hughes decompose = decomposeSuperBezierSegment 166*e1fe3e4aSElliott Hughes self.assertRaises(AssertionError, decompose, []) 167*e1fe3e4aSElliott Hughes self.assertRaises(AssertionError, decompose, [(0, 0)]) 168*e1fe3e4aSElliott Hughes self.assertRaises(AssertionError, decompose, [(0, 0), (1, 1)]) 169*e1fe3e4aSElliott Hughes self.assertEqual( 170*e1fe3e4aSElliott Hughes [((0, 0), (1, 1), (2, 2))], decompose([(0, 0), (1, 1), (2, 2)]) 171*e1fe3e4aSElliott Hughes ) 172*e1fe3e4aSElliott Hughes self.assertEqual( 173*e1fe3e4aSElliott Hughes [((0, 0), (2, -2), (4, 0)), ((6, 2), (8, 8), (12, -12))], 174*e1fe3e4aSElliott Hughes decompose([(0, 0), (4, -4), (8, 8), (12, -12)]), 175*e1fe3e4aSElliott Hughes ) 176*e1fe3e4aSElliott Hughes 177*e1fe3e4aSElliott Hughes def test_decomposeQuadraticSegment(self): 178*e1fe3e4aSElliott Hughes decompose = decomposeQuadraticSegment 179*e1fe3e4aSElliott Hughes self.assertRaises(AssertionError, decompose, []) 180*e1fe3e4aSElliott Hughes self.assertRaises(AssertionError, decompose, [(0, 0)]) 181*e1fe3e4aSElliott Hughes self.assertEqual([((0, 0), (4, 8))], decompose([(0, 0), (4, 8)])) 182*e1fe3e4aSElliott Hughes self.assertEqual( 183*e1fe3e4aSElliott Hughes [((0, 0), (2, 4)), ((4, 8), (9, -9))], decompose([(0, 0), (4, 8), (9, -9)]) 184*e1fe3e4aSElliott Hughes ) 185*e1fe3e4aSElliott Hughes self.assertEqual( 186*e1fe3e4aSElliott Hughes [((0, 0), (2.0, 4.0)), ((4, 8), (6.5, -0.5)), ((9, -9), (10, 10))], 187*e1fe3e4aSElliott Hughes decompose([(0, 0), (4, 8), (9, -9), (10, 10)]), 188*e1fe3e4aSElliott Hughes ) 189*e1fe3e4aSElliott Hughes 190*e1fe3e4aSElliott Hughes 191*e1fe3e4aSElliott Hughesif __name__ == "__main__": 192*e1fe3e4aSElliott Hughes import sys 193*e1fe3e4aSElliott Hughes 194*e1fe3e4aSElliott Hughes sys.exit(unittest.main()) 195