225 lines
7.4 KiB
Python
225 lines
7.4 KiB
Python
from io import StringIO
|
|
from fontTools.pens.pointInsidePen import PointInsidePen
|
|
import unittest
|
|
|
|
|
|
class PointInsidePenTest(unittest.TestCase):
|
|
def test_line(self):
|
|
def draw_triangles(pen):
|
|
pen.moveTo((0,0)); pen.lineTo((10,5)); pen.lineTo((10,0))
|
|
pen.moveTo((9,1)); pen.lineTo((4,1)); pen.lineTo((9,4))
|
|
pen.closePath()
|
|
|
|
self.assertEqual(
|
|
" *********"
|
|
" ** *"
|
|
" ** *"
|
|
" * *"
|
|
" *",
|
|
self.render(draw_triangles, even_odd=True))
|
|
|
|
self.assertEqual(
|
|
" *********"
|
|
" *******"
|
|
" *****"
|
|
" ***"
|
|
" *",
|
|
self.render(draw_triangles, even_odd=False))
|
|
|
|
def test_curve(self):
|
|
def draw_curves(pen):
|
|
pen.moveTo((0,0)); pen.curveTo((9,1), (9,4), (0,5))
|
|
pen.moveTo((10,5)); pen.curveTo((1,4), (1,1), (10,0))
|
|
pen.closePath()
|
|
|
|
self.assertEqual(
|
|
"*** ***"
|
|
"**** ****"
|
|
"*** ***"
|
|
"**** ****"
|
|
"*** ***",
|
|
self.render(draw_curves, even_odd=True))
|
|
|
|
self.assertEqual(
|
|
"*** ***"
|
|
"**********"
|
|
"**********"
|
|
"**********"
|
|
"*** ***",
|
|
self.render(draw_curves, even_odd=False))
|
|
|
|
def test_qCurve(self):
|
|
def draw_qCurves(pen):
|
|
pen.moveTo((0,0)); pen.qCurveTo((15,2), (0,5))
|
|
pen.moveTo((10,5)); pen.qCurveTo((-5,3), (10,0))
|
|
pen.closePath()
|
|
|
|
self.assertEqual(
|
|
"*** **"
|
|
"**** ***"
|
|
"*** ***"
|
|
"*** ****"
|
|
"** ***",
|
|
self.render(draw_qCurves, even_odd=True))
|
|
|
|
self.assertEqual(
|
|
"*** **"
|
|
"**********"
|
|
"**********"
|
|
"**********"
|
|
"** ***",
|
|
self.render(draw_qCurves, even_odd=False))
|
|
|
|
@staticmethod
|
|
def render(draw_function, even_odd):
|
|
result = StringIO()
|
|
for y in range(5):
|
|
for x in range(10):
|
|
pen = PointInsidePen(None, (x + 0.5, y + 0.5), even_odd)
|
|
draw_function(pen)
|
|
if pen.getResult():
|
|
result.write("*")
|
|
else:
|
|
result.write(" ")
|
|
return result.getvalue()
|
|
|
|
|
|
def test_contour_no_solutions(self):
|
|
def draw_contour(pen):
|
|
pen.moveTo( (969, 230) )
|
|
pen.curveTo( (825, 348) , (715, 184) , (614, 202) )
|
|
pen.lineTo( (614, 160) )
|
|
pen.lineTo( (969, 160) )
|
|
pen.closePath()
|
|
|
|
piPen = PointInsidePen(None, (750, 295)) # this point is outside
|
|
draw_contour(piPen)
|
|
self.assertEqual(piPen.getWinding(), 0)
|
|
self.assertEqual(piPen.getResult(), False)
|
|
|
|
piPen = PointInsidePen(None, (835, 190)) # this point is inside
|
|
draw_contour(piPen)
|
|
self.assertEqual(piPen.getWinding(), 1)
|
|
self.assertEqual(piPen.getResult(), True)
|
|
|
|
def test_contour_square_closed(self):
|
|
def draw_contour(pen):
|
|
pen.moveTo( (100, 100) )
|
|
pen.lineTo( (-100, 100) )
|
|
pen.lineTo( (-100, -100) )
|
|
pen.lineTo( (100, -100) )
|
|
pen.closePath()
|
|
|
|
piPen = PointInsidePen(None, (0, 0)) # this point is inside
|
|
draw_contour(piPen)
|
|
self.assertEqual(piPen.getWinding(), 1)
|
|
self.assertEqual(piPen.getResult(), True)
|
|
|
|
def test_contour_square_opened(self):
|
|
def draw_contour(pen):
|
|
pen.moveTo( (100, 100) )
|
|
pen.lineTo( (-100, 100) )
|
|
pen.lineTo( (-100, -100) )
|
|
pen.lineTo( (100, -100) )
|
|
# contour not explicitly closed
|
|
|
|
piPen = PointInsidePen(None, (0, 0)) # this point is inside
|
|
draw_contour(piPen)
|
|
self.assertEqual(piPen.getWinding(), 1)
|
|
self.assertEqual(piPen.getResult(), True)
|
|
|
|
def test_contour_circle(self):
|
|
def draw_contour(pen):
|
|
pen.moveTo( (0, 100) )
|
|
pen.curveTo( (-55, 100) , (-100, 55) , (-100, 0) )
|
|
pen.curveTo( (-100, -55) , (-55, -100) , (0, -100) )
|
|
pen.curveTo( (55, -100) , (100, -55) , (100, 0) )
|
|
pen.curveTo( (100, 55) , (55, 100) , (0, 100) )
|
|
|
|
piPen = PointInsidePen(None, (50, 50)) # this point is inside
|
|
draw_contour(piPen)
|
|
self.assertEqual(piPen.getResult(), True)
|
|
|
|
piPen = PointInsidePen(None, (50, -50)) # this point is inside
|
|
draw_contour(piPen)
|
|
self.assertEqual(piPen.getResult(), True)
|
|
|
|
def test_contour_diamond(self):
|
|
def draw_contour(pen):
|
|
pen.moveTo( (0, 100) )
|
|
pen.lineTo( (100, 0) )
|
|
pen.lineTo( (0, -100) )
|
|
pen.lineTo( (-100, 0) )
|
|
pen.closePath()
|
|
|
|
piPen = PointInsidePen(None, (-200, 0)) # this point is outside
|
|
draw_contour(piPen)
|
|
self.assertEqual(piPen.getWinding(), 0)
|
|
|
|
piPen = PointInsidePen(None, (-200, 100)) # this point is outside
|
|
draw_contour(piPen)
|
|
self.assertEqual(piPen.getWinding(), 0)
|
|
|
|
piPen = PointInsidePen(None, (-200, -100)) # this point is outside
|
|
draw_contour(piPen)
|
|
self.assertEqual(piPen.getWinding(), 0)
|
|
|
|
piPen = PointInsidePen(None, (-200, 50)) # this point is outside
|
|
draw_contour(piPen)
|
|
self.assertEqual(piPen.getWinding(), 0)
|
|
|
|
def test_contour_integers(self):
|
|
def draw_contour(pen):
|
|
pen.moveTo( (728, 697) )
|
|
pen.lineTo( (504, 699) )
|
|
pen.curveTo( (487, 719) , (508, 783) , (556, 783) )
|
|
pen.lineTo( (718, 783) )
|
|
pen.curveTo( (739, 783) , (749, 712) , (728, 697) )
|
|
pen.closePath()
|
|
|
|
piPen = PointInsidePen(None, (416, 783)) # this point is outside
|
|
draw_contour(piPen)
|
|
self.assertEqual(piPen.getWinding(), 0)
|
|
|
|
def test_contour_decimals(self):
|
|
def draw_contour(pen):
|
|
pen.moveTo( (727.546875, 697.0) )
|
|
pen.lineTo( (504.375, 698.515625) )
|
|
pen.curveTo( (487.328125, 719.359375), (507.84375, 783.140625), (555.796875, 783.140625) )
|
|
pen.lineTo( (717.96875, 783.140625) )
|
|
pen.curveTo( (738.890625, 783.140625), (748.796875, 711.5), (727.546875, 697.0) )
|
|
pen.closePath()
|
|
|
|
piPen = PointInsidePen(None, (416.625, 783.140625)) # this point is outside
|
|
draw_contour(piPen)
|
|
self.assertEqual(piPen.getWinding(), 0)
|
|
|
|
def test_contour2_integers(self):
|
|
def draw_contour(pen):
|
|
pen.moveTo( (51, 22) )
|
|
pen.lineTo( (51, 74) )
|
|
pen.lineTo( (83, 50) )
|
|
pen.curveTo( (83, 49) , (82, 48) , (82, 47) )
|
|
pen.closePath()
|
|
|
|
piPen = PointInsidePen(None, (21, 50)) # this point is outside
|
|
draw_contour(piPen)
|
|
self.assertEqual(piPen.getWinding(), 0)
|
|
|
|
def test_contour2_decimals(self):
|
|
def draw_contour(pen):
|
|
pen.moveTo( (51.25, 21.859375) )
|
|
pen.lineTo( (51.25, 73.828125) )
|
|
pen.lineTo( (82.5, 50.0) )
|
|
pen.curveTo( (82.5, 49.09375) , (82.265625, 48.265625) , (82.234375, 47.375) )
|
|
pen.closePath()
|
|
|
|
piPen = PointInsidePen(None, (21.25, 50.0)) # this point is outside
|
|
draw_contour(piPen)
|
|
self.assertEqual(piPen.getWinding(), 0)
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
sys.exit(unittest.main())
|
|
|