1*e1fe3e4aSElliott Hughesimport unittest 2*e1fe3e4aSElliott Hughes 3*e1fe3e4aSElliott Hughestry: 4*e1fe3e4aSElliott Hughes from fontTools.pens.quartzPen import QuartzPen 5*e1fe3e4aSElliott Hughes 6*e1fe3e4aSElliott Hughes from Quartz.CoreGraphics import CGPathApply 7*e1fe3e4aSElliott Hughes from Quartz.CoreGraphics import kCGPathElementMoveToPoint 8*e1fe3e4aSElliott Hughes from Quartz.CoreGraphics import kCGPathElementAddLineToPoint 9*e1fe3e4aSElliott Hughes from Quartz.CoreGraphics import kCGPathElementAddQuadCurveToPoint 10*e1fe3e4aSElliott Hughes from Quartz.CoreGraphics import kCGPathElementAddCurveToPoint 11*e1fe3e4aSElliott Hughes from Quartz.CoreGraphics import kCGPathElementCloseSubpath 12*e1fe3e4aSElliott Hughes 13*e1fe3e4aSElliott Hughes PATH_ELEMENTS = { 14*e1fe3e4aSElliott Hughes # CG constant key desc num_points 15*e1fe3e4aSElliott Hughes kCGPathElementMoveToPoint: ("moveto", 1), 16*e1fe3e4aSElliott Hughes kCGPathElementAddLineToPoint: ("lineto", 1), 17*e1fe3e4aSElliott Hughes kCGPathElementAddCurveToPoint: ("curveto", 3), 18*e1fe3e4aSElliott Hughes kCGPathElementAddQuadCurveToPoint: ("qcurveto", 2), 19*e1fe3e4aSElliott Hughes kCGPathElementCloseSubpath: ("close", 0), 20*e1fe3e4aSElliott Hughes } 21*e1fe3e4aSElliott Hughes 22*e1fe3e4aSElliott Hughes PYOBJC_AVAILABLE = True 23*e1fe3e4aSElliott Hughesexcept ImportError: 24*e1fe3e4aSElliott Hughes PYOBJC_AVAILABLE = False 25*e1fe3e4aSElliott Hughes 26*e1fe3e4aSElliott Hughes 27*e1fe3e4aSElliott Hughesdef draw(pen): 28*e1fe3e4aSElliott Hughes pen.moveTo((50, 0)) 29*e1fe3e4aSElliott Hughes pen.lineTo((50, 500)) 30*e1fe3e4aSElliott Hughes pen.lineTo((200, 500)) 31*e1fe3e4aSElliott Hughes pen.curveTo((350, 500), (450, 400), (450, 250)) 32*e1fe3e4aSElliott Hughes pen.curveTo((450, 100), (350, 0), (200, 0)) 33*e1fe3e4aSElliott Hughes pen.closePath() 34*e1fe3e4aSElliott Hughes 35*e1fe3e4aSElliott Hughes 36*e1fe3e4aSElliott Hughesdef quartzPathApplier(elements, element): 37*e1fe3e4aSElliott Hughes num_points = 0 38*e1fe3e4aSElliott Hughes elem_type = None 39*e1fe3e4aSElliott Hughes if element.type in PATH_ELEMENTS: 40*e1fe3e4aSElliott Hughes num_points = PATH_ELEMENTS[element.type][1] 41*e1fe3e4aSElliott Hughes elem_type = PATH_ELEMENTS[element.type][0] 42*e1fe3e4aSElliott Hughes elements.append((elem_type, element.points.as_tuple(num_points))) 43*e1fe3e4aSElliott Hughes 44*e1fe3e4aSElliott Hughes 45*e1fe3e4aSElliott Hughesdef quartzPathElements(path): 46*e1fe3e4aSElliott Hughes elements = [] 47*e1fe3e4aSElliott Hughes CGPathApply(path, elements, quartzPathApplier) 48*e1fe3e4aSElliott Hughes return elements 49*e1fe3e4aSElliott Hughes 50*e1fe3e4aSElliott Hughes 51*e1fe3e4aSElliott Hughesdef quartzPathToString(path): 52*e1fe3e4aSElliott Hughes elements = quartzPathElements(path) 53*e1fe3e4aSElliott Hughes output = [] 54*e1fe3e4aSElliott Hughes for element in elements: 55*e1fe3e4aSElliott Hughes elem_type, elem_points = element 56*e1fe3e4aSElliott Hughes path_points = " ".join([f"{p.x} {p.y}" for p in elem_points]) 57*e1fe3e4aSElliott Hughes output.append(f"{elem_type} {path_points}") 58*e1fe3e4aSElliott Hughes return " ".join(output) 59*e1fe3e4aSElliott Hughes 60*e1fe3e4aSElliott Hughes 61*e1fe3e4aSElliott Hughes@unittest.skipUnless(PYOBJC_AVAILABLE, "pyobjc not installed") 62*e1fe3e4aSElliott Hughesclass QuartzPenTest(unittest.TestCase): 63*e1fe3e4aSElliott Hughes def test_draw(self): 64*e1fe3e4aSElliott Hughes pen = QuartzPen(None) 65*e1fe3e4aSElliott Hughes draw(pen) 66*e1fe3e4aSElliott Hughes self.assertEqual( 67*e1fe3e4aSElliott Hughes "moveto 50.0 0.0 lineto 50.0 500.0 lineto 200.0 500.0 curveto 350.0 500.0 450.0 400.0 450.0 250.0 curveto 450.0 100.0 350.0 0.0 200.0 0.0 close ", 68*e1fe3e4aSElliott Hughes quartzPathToString(pen.path), 69*e1fe3e4aSElliott Hughes ) 70*e1fe3e4aSElliott Hughes 71*e1fe3e4aSElliott Hughes def test_empty(self): 72*e1fe3e4aSElliott Hughes pen = QuartzPen(None) 73*e1fe3e4aSElliott Hughes self.assertEqual("", quartzPathToString(pen.path)) 74*e1fe3e4aSElliott Hughes 75*e1fe3e4aSElliott Hughes 76*e1fe3e4aSElliott Hughesif __name__ == "__main__": 77*e1fe3e4aSElliott Hughes import sys 78*e1fe3e4aSElliott Hughes 79*e1fe3e4aSElliott Hughes sys.exit(unittest.main()) 80