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