1*e1fe3e4aSElliott Hughesfrom io import StringIO 2*e1fe3e4aSElliott Hughesfrom fontTools.pens.pointInsidePen import PointInsidePen 3*e1fe3e4aSElliott Hughesimport unittest 4*e1fe3e4aSElliott Hughes 5*e1fe3e4aSElliott Hughes 6*e1fe3e4aSElliott Hughesclass PointInsidePenTest(unittest.TestCase): 7*e1fe3e4aSElliott Hughes def test_line(self): 8*e1fe3e4aSElliott Hughes def draw_triangles(pen): 9*e1fe3e4aSElliott Hughes pen.moveTo((0, 0)) 10*e1fe3e4aSElliott Hughes pen.lineTo((10, 5)) 11*e1fe3e4aSElliott Hughes pen.lineTo((10, 0)) 12*e1fe3e4aSElliott Hughes pen.moveTo((9, 1)) 13*e1fe3e4aSElliott Hughes pen.lineTo((4, 1)) 14*e1fe3e4aSElliott Hughes pen.lineTo((9, 4)) 15*e1fe3e4aSElliott Hughes pen.closePath() 16*e1fe3e4aSElliott Hughes 17*e1fe3e4aSElliott Hughes self.assertEqual( 18*e1fe3e4aSElliott Hughes " *********" " ** *" " ** *" " * *" " *", 19*e1fe3e4aSElliott Hughes self.render(draw_triangles, even_odd=True), 20*e1fe3e4aSElliott Hughes ) 21*e1fe3e4aSElliott Hughes 22*e1fe3e4aSElliott Hughes self.assertEqual( 23*e1fe3e4aSElliott Hughes " *********" " *******" " *****" " ***" " *", 24*e1fe3e4aSElliott Hughes self.render(draw_triangles, even_odd=False), 25*e1fe3e4aSElliott Hughes ) 26*e1fe3e4aSElliott Hughes 27*e1fe3e4aSElliott Hughes def test_curve(self): 28*e1fe3e4aSElliott Hughes def draw_curves(pen): 29*e1fe3e4aSElliott Hughes pen.moveTo((0, 0)) 30*e1fe3e4aSElliott Hughes pen.curveTo((9, 1), (9, 4), (0, 5)) 31*e1fe3e4aSElliott Hughes pen.moveTo((10, 5)) 32*e1fe3e4aSElliott Hughes pen.curveTo((1, 4), (1, 1), (10, 0)) 33*e1fe3e4aSElliott Hughes pen.closePath() 34*e1fe3e4aSElliott Hughes 35*e1fe3e4aSElliott Hughes self.assertEqual( 36*e1fe3e4aSElliott Hughes "*** ***" "**** ****" "*** ***" "**** ****" "*** ***", 37*e1fe3e4aSElliott Hughes self.render(draw_curves, even_odd=True), 38*e1fe3e4aSElliott Hughes ) 39*e1fe3e4aSElliott Hughes 40*e1fe3e4aSElliott Hughes self.assertEqual( 41*e1fe3e4aSElliott Hughes "*** ***" "**********" "**********" "**********" "*** ***", 42*e1fe3e4aSElliott Hughes self.render(draw_curves, even_odd=False), 43*e1fe3e4aSElliott Hughes ) 44*e1fe3e4aSElliott Hughes 45*e1fe3e4aSElliott Hughes def test_qCurve(self): 46*e1fe3e4aSElliott Hughes def draw_qCurves(pen): 47*e1fe3e4aSElliott Hughes pen.moveTo((0, 0)) 48*e1fe3e4aSElliott Hughes pen.qCurveTo((15, 2), (0, 5)) 49*e1fe3e4aSElliott Hughes pen.moveTo((10, 5)) 50*e1fe3e4aSElliott Hughes pen.qCurveTo((-5, 3), (10, 0)) 51*e1fe3e4aSElliott Hughes pen.closePath() 52*e1fe3e4aSElliott Hughes 53*e1fe3e4aSElliott Hughes self.assertEqual( 54*e1fe3e4aSElliott Hughes "*** **" "**** ***" "*** ***" "*** ****" "** ***", 55*e1fe3e4aSElliott Hughes self.render(draw_qCurves, even_odd=True), 56*e1fe3e4aSElliott Hughes ) 57*e1fe3e4aSElliott Hughes 58*e1fe3e4aSElliott Hughes self.assertEqual( 59*e1fe3e4aSElliott Hughes "*** **" "**********" "**********" "**********" "** ***", 60*e1fe3e4aSElliott Hughes self.render(draw_qCurves, even_odd=False), 61*e1fe3e4aSElliott Hughes ) 62*e1fe3e4aSElliott Hughes 63*e1fe3e4aSElliott Hughes @staticmethod 64*e1fe3e4aSElliott Hughes def render(draw_function, even_odd): 65*e1fe3e4aSElliott Hughes result = StringIO() 66*e1fe3e4aSElliott Hughes for y in range(5): 67*e1fe3e4aSElliott Hughes for x in range(10): 68*e1fe3e4aSElliott Hughes pen = PointInsidePen(None, (x + 0.5, y + 0.5), even_odd) 69*e1fe3e4aSElliott Hughes draw_function(pen) 70*e1fe3e4aSElliott Hughes if pen.getResult(): 71*e1fe3e4aSElliott Hughes result.write("*") 72*e1fe3e4aSElliott Hughes else: 73*e1fe3e4aSElliott Hughes result.write(" ") 74*e1fe3e4aSElliott Hughes return result.getvalue() 75*e1fe3e4aSElliott Hughes 76*e1fe3e4aSElliott Hughes def test_contour_no_solutions(self): 77*e1fe3e4aSElliott Hughes def draw_contour(pen): 78*e1fe3e4aSElliott Hughes pen.moveTo((969, 230)) 79*e1fe3e4aSElliott Hughes pen.curveTo((825, 348), (715, 184), (614, 202)) 80*e1fe3e4aSElliott Hughes pen.lineTo((614, 160)) 81*e1fe3e4aSElliott Hughes pen.lineTo((969, 160)) 82*e1fe3e4aSElliott Hughes pen.closePath() 83*e1fe3e4aSElliott Hughes 84*e1fe3e4aSElliott Hughes piPen = PointInsidePen(None, (750, 295)) # this point is outside 85*e1fe3e4aSElliott Hughes draw_contour(piPen) 86*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getWinding(), 0) 87*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getResult(), False) 88*e1fe3e4aSElliott Hughes 89*e1fe3e4aSElliott Hughes piPen = PointInsidePen(None, (835, 190)) # this point is inside 90*e1fe3e4aSElliott Hughes draw_contour(piPen) 91*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getWinding(), 1) 92*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getResult(), True) 93*e1fe3e4aSElliott Hughes 94*e1fe3e4aSElliott Hughes def test_contour_square_closed(self): 95*e1fe3e4aSElliott Hughes def draw_contour(pen): 96*e1fe3e4aSElliott Hughes pen.moveTo((100, 100)) 97*e1fe3e4aSElliott Hughes pen.lineTo((-100, 100)) 98*e1fe3e4aSElliott Hughes pen.lineTo((-100, -100)) 99*e1fe3e4aSElliott Hughes pen.lineTo((100, -100)) 100*e1fe3e4aSElliott Hughes pen.closePath() 101*e1fe3e4aSElliott Hughes 102*e1fe3e4aSElliott Hughes piPen = PointInsidePen(None, (0, 0)) # this point is inside 103*e1fe3e4aSElliott Hughes draw_contour(piPen) 104*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getWinding(), 1) 105*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getResult(), True) 106*e1fe3e4aSElliott Hughes 107*e1fe3e4aSElliott Hughes def test_contour_square_opened(self): 108*e1fe3e4aSElliott Hughes def draw_contour(pen): 109*e1fe3e4aSElliott Hughes pen.moveTo((100, 100)) 110*e1fe3e4aSElliott Hughes pen.lineTo((-100, 100)) 111*e1fe3e4aSElliott Hughes pen.lineTo((-100, -100)) 112*e1fe3e4aSElliott Hughes pen.lineTo((100, -100)) 113*e1fe3e4aSElliott Hughes # contour not explicitly closed 114*e1fe3e4aSElliott Hughes 115*e1fe3e4aSElliott Hughes piPen = PointInsidePen(None, (0, 0)) # this point is inside 116*e1fe3e4aSElliott Hughes draw_contour(piPen) 117*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getWinding(), 1) 118*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getResult(), True) 119*e1fe3e4aSElliott Hughes 120*e1fe3e4aSElliott Hughes def test_contour_circle(self): 121*e1fe3e4aSElliott Hughes def draw_contour(pen): 122*e1fe3e4aSElliott Hughes pen.moveTo((0, 100)) 123*e1fe3e4aSElliott Hughes pen.curveTo((-55, 100), (-100, 55), (-100, 0)) 124*e1fe3e4aSElliott Hughes pen.curveTo((-100, -55), (-55, -100), (0, -100)) 125*e1fe3e4aSElliott Hughes pen.curveTo((55, -100), (100, -55), (100, 0)) 126*e1fe3e4aSElliott Hughes pen.curveTo((100, 55), (55, 100), (0, 100)) 127*e1fe3e4aSElliott Hughes 128*e1fe3e4aSElliott Hughes piPen = PointInsidePen(None, (50, 50)) # this point is inside 129*e1fe3e4aSElliott Hughes draw_contour(piPen) 130*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getResult(), True) 131*e1fe3e4aSElliott Hughes 132*e1fe3e4aSElliott Hughes piPen = PointInsidePen(None, (50, -50)) # this point is inside 133*e1fe3e4aSElliott Hughes draw_contour(piPen) 134*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getResult(), True) 135*e1fe3e4aSElliott Hughes 136*e1fe3e4aSElliott Hughes def test_contour_diamond(self): 137*e1fe3e4aSElliott Hughes def draw_contour(pen): 138*e1fe3e4aSElliott Hughes pen.moveTo((0, 100)) 139*e1fe3e4aSElliott Hughes pen.lineTo((100, 0)) 140*e1fe3e4aSElliott Hughes pen.lineTo((0, -100)) 141*e1fe3e4aSElliott Hughes pen.lineTo((-100, 0)) 142*e1fe3e4aSElliott Hughes pen.closePath() 143*e1fe3e4aSElliott Hughes 144*e1fe3e4aSElliott Hughes piPen = PointInsidePen(None, (-200, 0)) # this point is outside 145*e1fe3e4aSElliott Hughes draw_contour(piPen) 146*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getWinding(), 0) 147*e1fe3e4aSElliott Hughes 148*e1fe3e4aSElliott Hughes piPen = PointInsidePen(None, (-200, 100)) # this point is outside 149*e1fe3e4aSElliott Hughes draw_contour(piPen) 150*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getWinding(), 0) 151*e1fe3e4aSElliott Hughes 152*e1fe3e4aSElliott Hughes piPen = PointInsidePen(None, (-200, -100)) # this point is outside 153*e1fe3e4aSElliott Hughes draw_contour(piPen) 154*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getWinding(), 0) 155*e1fe3e4aSElliott Hughes 156*e1fe3e4aSElliott Hughes piPen = PointInsidePen(None, (-200, 50)) # this point is outside 157*e1fe3e4aSElliott Hughes draw_contour(piPen) 158*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getWinding(), 0) 159*e1fe3e4aSElliott Hughes 160*e1fe3e4aSElliott Hughes def test_contour_integers(self): 161*e1fe3e4aSElliott Hughes def draw_contour(pen): 162*e1fe3e4aSElliott Hughes pen.moveTo((728, 697)) 163*e1fe3e4aSElliott Hughes pen.lineTo((504, 699)) 164*e1fe3e4aSElliott Hughes pen.curveTo((487, 719), (508, 783), (556, 783)) 165*e1fe3e4aSElliott Hughes pen.lineTo((718, 783)) 166*e1fe3e4aSElliott Hughes pen.curveTo((739, 783), (749, 712), (728, 697)) 167*e1fe3e4aSElliott Hughes pen.closePath() 168*e1fe3e4aSElliott Hughes 169*e1fe3e4aSElliott Hughes piPen = PointInsidePen(None, (416, 783)) # this point is outside 170*e1fe3e4aSElliott Hughes draw_contour(piPen) 171*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getWinding(), 0) 172*e1fe3e4aSElliott Hughes 173*e1fe3e4aSElliott Hughes def test_contour_decimals(self): 174*e1fe3e4aSElliott Hughes def draw_contour(pen): 175*e1fe3e4aSElliott Hughes pen.moveTo((727.546875, 697.0)) 176*e1fe3e4aSElliott Hughes pen.lineTo((504.375, 698.515625)) 177*e1fe3e4aSElliott Hughes pen.curveTo( 178*e1fe3e4aSElliott Hughes (487.328125, 719.359375), 179*e1fe3e4aSElliott Hughes (507.84375, 783.140625), 180*e1fe3e4aSElliott Hughes (555.796875, 783.140625), 181*e1fe3e4aSElliott Hughes ) 182*e1fe3e4aSElliott Hughes pen.lineTo((717.96875, 783.140625)) 183*e1fe3e4aSElliott Hughes pen.curveTo( 184*e1fe3e4aSElliott Hughes (738.890625, 783.140625), (748.796875, 711.5), (727.546875, 697.0) 185*e1fe3e4aSElliott Hughes ) 186*e1fe3e4aSElliott Hughes pen.closePath() 187*e1fe3e4aSElliott Hughes 188*e1fe3e4aSElliott Hughes piPen = PointInsidePen(None, (416.625, 783.140625)) # this point is outside 189*e1fe3e4aSElliott Hughes draw_contour(piPen) 190*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getWinding(), 0) 191*e1fe3e4aSElliott Hughes 192*e1fe3e4aSElliott Hughes def test_contour2_integers(self): 193*e1fe3e4aSElliott Hughes def draw_contour(pen): 194*e1fe3e4aSElliott Hughes pen.moveTo((51, 22)) 195*e1fe3e4aSElliott Hughes pen.lineTo((51, 74)) 196*e1fe3e4aSElliott Hughes pen.lineTo((83, 50)) 197*e1fe3e4aSElliott Hughes pen.curveTo((83, 49), (82, 48), (82, 47)) 198*e1fe3e4aSElliott Hughes pen.closePath() 199*e1fe3e4aSElliott Hughes 200*e1fe3e4aSElliott Hughes piPen = PointInsidePen(None, (21, 50)) # this point is outside 201*e1fe3e4aSElliott Hughes draw_contour(piPen) 202*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getWinding(), 0) 203*e1fe3e4aSElliott Hughes 204*e1fe3e4aSElliott Hughes def test_contour2_decimals(self): 205*e1fe3e4aSElliott Hughes def draw_contour(pen): 206*e1fe3e4aSElliott Hughes pen.moveTo((51.25, 21.859375)) 207*e1fe3e4aSElliott Hughes pen.lineTo((51.25, 73.828125)) 208*e1fe3e4aSElliott Hughes pen.lineTo((82.5, 50.0)) 209*e1fe3e4aSElliott Hughes pen.curveTo((82.5, 49.09375), (82.265625, 48.265625), (82.234375, 47.375)) 210*e1fe3e4aSElliott Hughes pen.closePath() 211*e1fe3e4aSElliott Hughes 212*e1fe3e4aSElliott Hughes piPen = PointInsidePen(None, (21.25, 50.0)) # this point is outside 213*e1fe3e4aSElliott Hughes draw_contour(piPen) 214*e1fe3e4aSElliott Hughes self.assertEqual(piPen.getWinding(), 0) 215*e1fe3e4aSElliott Hughes 216*e1fe3e4aSElliott Hughes 217*e1fe3e4aSElliott Hughesif __name__ == "__main__": 218*e1fe3e4aSElliott Hughes import sys 219*e1fe3e4aSElliott Hughes 220*e1fe3e4aSElliott Hughes sys.exit(unittest.main()) 221