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