1*e1fe3e4aSElliott Hughesfrom fontTools.pens.recordingPen import RecordingPen 2*e1fe3e4aSElliott Hughesfrom fontTools.pens.reverseContourPen import ReverseContourPen 3*e1fe3e4aSElliott Hughesimport pytest 4*e1fe3e4aSElliott Hughes 5*e1fe3e4aSElliott Hughes 6*e1fe3e4aSElliott HughesTEST_DATA = [ 7*e1fe3e4aSElliott Hughes ( 8*e1fe3e4aSElliott Hughes [ 9*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 10*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 11*e1fe3e4aSElliott Hughes ("lineTo", ((2, 2),)), 12*e1fe3e4aSElliott Hughes ("lineTo", ((3, 3),)), # last not on move, line is implied 13*e1fe3e4aSElliott Hughes ("closePath", ()), 14*e1fe3e4aSElliott Hughes ], 15*e1fe3e4aSElliott Hughes False, # outputImpliedClosingLine 16*e1fe3e4aSElliott Hughes [ 17*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 18*e1fe3e4aSElliott Hughes ("lineTo", ((3, 3),)), 19*e1fe3e4aSElliott Hughes ("lineTo", ((2, 2),)), 20*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 21*e1fe3e4aSElliott Hughes ("closePath", ()), 22*e1fe3e4aSElliott Hughes ], 23*e1fe3e4aSElliott Hughes ), 24*e1fe3e4aSElliott Hughes ( 25*e1fe3e4aSElliott Hughes [ 26*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 27*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 28*e1fe3e4aSElliott Hughes ("lineTo", ((2, 2),)), 29*e1fe3e4aSElliott Hughes ("lineTo", ((3, 3),)), # last line does not overlap move... 30*e1fe3e4aSElliott Hughes ("closePath", ()), 31*e1fe3e4aSElliott Hughes ], 32*e1fe3e4aSElliott Hughes True, # outputImpliedClosingLine 33*e1fe3e4aSElliott Hughes [ 34*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 35*e1fe3e4aSElliott Hughes ("lineTo", ((3, 3),)), 36*e1fe3e4aSElliott Hughes ("lineTo", ((2, 2),)), 37*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 38*e1fe3e4aSElliott Hughes ("lineTo", ((0, 0),)), # ... but closing line is NOT implied 39*e1fe3e4aSElliott Hughes ("closePath", ()), 40*e1fe3e4aSElliott Hughes ], 41*e1fe3e4aSElliott Hughes ), 42*e1fe3e4aSElliott Hughes ( 43*e1fe3e4aSElliott Hughes [ 44*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 45*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 46*e1fe3e4aSElliott Hughes ("lineTo", ((2, 2),)), 47*e1fe3e4aSElliott Hughes ("lineTo", ((0, 0),)), # last line overlaps move, explicit line 48*e1fe3e4aSElliott Hughes ("closePath", ()), 49*e1fe3e4aSElliott Hughes ], 50*e1fe3e4aSElliott Hughes False, 51*e1fe3e4aSElliott Hughes [ 52*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 53*e1fe3e4aSElliott Hughes ("lineTo", ((2, 2),)), 54*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 55*e1fe3e4aSElliott Hughes ("closePath", ()), # closing line implied 56*e1fe3e4aSElliott Hughes ], 57*e1fe3e4aSElliott Hughes ), 58*e1fe3e4aSElliott Hughes ( 59*e1fe3e4aSElliott Hughes [ 60*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 61*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 62*e1fe3e4aSElliott Hughes ("lineTo", ((2, 2),)), 63*e1fe3e4aSElliott Hughes ("lineTo", ((0, 0),)), # last line overlaps move... 64*e1fe3e4aSElliott Hughes ("closePath", ()), 65*e1fe3e4aSElliott Hughes ], 66*e1fe3e4aSElliott Hughes True, 67*e1fe3e4aSElliott Hughes [ 68*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 69*e1fe3e4aSElliott Hughes ("lineTo", ((2, 2),)), 70*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 71*e1fe3e4aSElliott Hughes ("lineTo", ((0, 0),)), # ... but line is NOT implied 72*e1fe3e4aSElliott Hughes ("closePath", ()), 73*e1fe3e4aSElliott Hughes ], 74*e1fe3e4aSElliott Hughes ), 75*e1fe3e4aSElliott Hughes ( 76*e1fe3e4aSElliott Hughes [ 77*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 78*e1fe3e4aSElliott Hughes ("lineTo", ((0, 0),)), # duplicate lineTo following moveTo 79*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 80*e1fe3e4aSElliott Hughes ("lineTo", ((2, 2),)), 81*e1fe3e4aSElliott Hughes ("closePath", ()), 82*e1fe3e4aSElliott Hughes ], 83*e1fe3e4aSElliott Hughes False, 84*e1fe3e4aSElliott Hughes [ 85*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 86*e1fe3e4aSElliott Hughes ("lineTo", ((2, 2),)), 87*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 88*e1fe3e4aSElliott Hughes ("lineTo", ((0, 0),)), # extra explicit lineTo is always emitted to 89*e1fe3e4aSElliott Hughes ("lineTo", ((0, 0),)), # disambiguate from an implicit closing line 90*e1fe3e4aSElliott Hughes ("closePath", ()), 91*e1fe3e4aSElliott Hughes ], 92*e1fe3e4aSElliott Hughes ), 93*e1fe3e4aSElliott Hughes ( 94*e1fe3e4aSElliott Hughes [ 95*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 96*e1fe3e4aSElliott Hughes ("lineTo", ((0, 0),)), # duplicate lineTo following moveTo 97*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 98*e1fe3e4aSElliott Hughes ("lineTo", ((2, 2),)), 99*e1fe3e4aSElliott Hughes ("closePath", ()), 100*e1fe3e4aSElliott Hughes ], 101*e1fe3e4aSElliott Hughes True, 102*e1fe3e4aSElliott Hughes [ 103*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 104*e1fe3e4aSElliott Hughes ("lineTo", ((2, 2),)), 105*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 106*e1fe3e4aSElliott Hughes ("lineTo", ((0, 0),)), # duplicate lineTo is retained also in this case, 107*e1fe3e4aSElliott Hughes ("lineTo", ((0, 0),)), # same result as with outputImpliedClosingLine=False 108*e1fe3e4aSElliott Hughes ("closePath", ()), 109*e1fe3e4aSElliott Hughes ], 110*e1fe3e4aSElliott Hughes ), 111*e1fe3e4aSElliott Hughes ( 112*e1fe3e4aSElliott Hughes [ 113*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 114*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 115*e1fe3e4aSElliott Hughes ("closePath", ()), 116*e1fe3e4aSElliott Hughes ], 117*e1fe3e4aSElliott Hughes False, 118*e1fe3e4aSElliott Hughes [ 119*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 120*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 121*e1fe3e4aSElliott Hughes ("closePath", ()), 122*e1fe3e4aSElliott Hughes ], 123*e1fe3e4aSElliott Hughes ), 124*e1fe3e4aSElliott Hughes ( 125*e1fe3e4aSElliott Hughes [ 126*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 127*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 128*e1fe3e4aSElliott Hughes ("closePath", ()), 129*e1fe3e4aSElliott Hughes ], 130*e1fe3e4aSElliott Hughes True, 131*e1fe3e4aSElliott Hughes [ 132*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 133*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 134*e1fe3e4aSElliott Hughes ("lineTo", ((0, 0),)), 135*e1fe3e4aSElliott Hughes ("closePath", ()), 136*e1fe3e4aSElliott Hughes ], 137*e1fe3e4aSElliott Hughes ), 138*e1fe3e4aSElliott Hughes ( 139*e1fe3e4aSElliott Hughes [ 140*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 141*e1fe3e4aSElliott Hughes ("curveTo", ((1, 1), (2, 2), (3, 3))), 142*e1fe3e4aSElliott Hughes ("curveTo", ((4, 4), (5, 5), (0, 0))), # closed curveTo overlaps moveTo 143*e1fe3e4aSElliott Hughes ("closePath", ()), 144*e1fe3e4aSElliott Hughes ], 145*e1fe3e4aSElliott Hughes False, 146*e1fe3e4aSElliott Hughes [ 147*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), # no extra lineTo added here 148*e1fe3e4aSElliott Hughes ("curveTo", ((5, 5), (4, 4), (3, 3))), 149*e1fe3e4aSElliott Hughes ("curveTo", ((2, 2), (1, 1), (0, 0))), 150*e1fe3e4aSElliott Hughes ("closePath", ()), 151*e1fe3e4aSElliott Hughes ], 152*e1fe3e4aSElliott Hughes ), 153*e1fe3e4aSElliott Hughes ( 154*e1fe3e4aSElliott Hughes [ 155*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 156*e1fe3e4aSElliott Hughes ("curveTo", ((1, 1), (2, 2), (3, 3))), 157*e1fe3e4aSElliott Hughes ("curveTo", ((4, 4), (5, 5), (0, 0))), # closed curveTo overlaps moveTo 158*e1fe3e4aSElliott Hughes ("closePath", ()), 159*e1fe3e4aSElliott Hughes ], 160*e1fe3e4aSElliott Hughes True, 161*e1fe3e4aSElliott Hughes [ 162*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), # no extra lineTo added here, same as preceding 163*e1fe3e4aSElliott Hughes ("curveTo", ((5, 5), (4, 4), (3, 3))), 164*e1fe3e4aSElliott Hughes ("curveTo", ((2, 2), (1, 1), (0, 0))), 165*e1fe3e4aSElliott Hughes ("closePath", ()), 166*e1fe3e4aSElliott Hughes ], 167*e1fe3e4aSElliott Hughes ), 168*e1fe3e4aSElliott Hughes ( 169*e1fe3e4aSElliott Hughes [ 170*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 171*e1fe3e4aSElliott Hughes ("curveTo", ((1, 1), (2, 2), (3, 3))), 172*e1fe3e4aSElliott Hughes ("curveTo", ((4, 4), (5, 5), (6, 6))), # closed curve not overlapping move 173*e1fe3e4aSElliott Hughes ("closePath", ()), 174*e1fe3e4aSElliott Hughes ], 175*e1fe3e4aSElliott Hughes False, 176*e1fe3e4aSElliott Hughes [ 177*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 178*e1fe3e4aSElliott Hughes ("lineTo", ((6, 6),)), # the previously implied line 179*e1fe3e4aSElliott Hughes ("curveTo", ((5, 5), (4, 4), (3, 3))), 180*e1fe3e4aSElliott Hughes ("curveTo", ((2, 2), (1, 1), (0, 0))), 181*e1fe3e4aSElliott Hughes ("closePath", ()), 182*e1fe3e4aSElliott Hughes ], 183*e1fe3e4aSElliott Hughes ), 184*e1fe3e4aSElliott Hughes ( 185*e1fe3e4aSElliott Hughes [ 186*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 187*e1fe3e4aSElliott Hughes ("curveTo", ((1, 1), (2, 2), (3, 3))), 188*e1fe3e4aSElliott Hughes ("curveTo", ((4, 4), (5, 5), (6, 6))), # closed curve not overlapping move 189*e1fe3e4aSElliott Hughes ("closePath", ()), 190*e1fe3e4aSElliott Hughes ], 191*e1fe3e4aSElliott Hughes True, 192*e1fe3e4aSElliott Hughes [ 193*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 194*e1fe3e4aSElliott Hughes ("lineTo", ((6, 6),)), # the previously implied line (same as above) 195*e1fe3e4aSElliott Hughes ("curveTo", ((5, 5), (4, 4), (3, 3))), 196*e1fe3e4aSElliott Hughes ("curveTo", ((2, 2), (1, 1), (0, 0))), 197*e1fe3e4aSElliott Hughes ("closePath", ()), 198*e1fe3e4aSElliott Hughes ], 199*e1fe3e4aSElliott Hughes ), 200*e1fe3e4aSElliott Hughes ( 201*e1fe3e4aSElliott Hughes [ 202*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 203*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), # this line becomes implied 204*e1fe3e4aSElliott Hughes ("curveTo", ((2, 2), (3, 3), (4, 4))), 205*e1fe3e4aSElliott Hughes ("curveTo", ((5, 5), (6, 6), (7, 7))), 206*e1fe3e4aSElliott Hughes ("closePath", ()), 207*e1fe3e4aSElliott Hughes ], 208*e1fe3e4aSElliott Hughes False, 209*e1fe3e4aSElliott Hughes [ 210*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 211*e1fe3e4aSElliott Hughes ("lineTo", ((7, 7),)), 212*e1fe3e4aSElliott Hughes ("curveTo", ((6, 6), (5, 5), (4, 4))), 213*e1fe3e4aSElliott Hughes ("curveTo", ((3, 3), (2, 2), (1, 1))), 214*e1fe3e4aSElliott Hughes ("closePath", ()), 215*e1fe3e4aSElliott Hughes ], 216*e1fe3e4aSElliott Hughes ), 217*e1fe3e4aSElliott Hughes ( 218*e1fe3e4aSElliott Hughes [ 219*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 220*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), # this line... 221*e1fe3e4aSElliott Hughes ("curveTo", ((2, 2), (3, 3), (4, 4))), 222*e1fe3e4aSElliott Hughes ("curveTo", ((5, 5), (6, 6), (7, 7))), 223*e1fe3e4aSElliott Hughes ("closePath", ()), 224*e1fe3e4aSElliott Hughes ], 225*e1fe3e4aSElliott Hughes True, 226*e1fe3e4aSElliott Hughes [ 227*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 228*e1fe3e4aSElliott Hughes ("lineTo", ((7, 7),)), 229*e1fe3e4aSElliott Hughes ("curveTo", ((6, 6), (5, 5), (4, 4))), 230*e1fe3e4aSElliott Hughes ("curveTo", ((3, 3), (2, 2), (1, 1))), 231*e1fe3e4aSElliott Hughes ("lineTo", ((0, 0),)), # ... does NOT become implied 232*e1fe3e4aSElliott Hughes ("closePath", ()), 233*e1fe3e4aSElliott Hughes ], 234*e1fe3e4aSElliott Hughes ), 235*e1fe3e4aSElliott Hughes ( 236*e1fe3e4aSElliott Hughes [ 237*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 238*e1fe3e4aSElliott Hughes ("qCurveTo", ((1, 1), (2, 2))), 239*e1fe3e4aSElliott Hughes ("qCurveTo", ((3, 3), (0, 0))), # closed qCurve overlaps move 240*e1fe3e4aSElliott Hughes ("closePath", ()), 241*e1fe3e4aSElliott Hughes ], 242*e1fe3e4aSElliott Hughes False, 243*e1fe3e4aSElliott Hughes [ 244*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), # no extra lineTo added here 245*e1fe3e4aSElliott Hughes ("qCurveTo", ((3, 3), (2, 2))), 246*e1fe3e4aSElliott Hughes ("qCurveTo", ((1, 1), (0, 0))), 247*e1fe3e4aSElliott Hughes ("closePath", ()), 248*e1fe3e4aSElliott Hughes ], 249*e1fe3e4aSElliott Hughes ), 250*e1fe3e4aSElliott Hughes ( 251*e1fe3e4aSElliott Hughes [ 252*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 253*e1fe3e4aSElliott Hughes ("qCurveTo", ((1, 1), (2, 2))), 254*e1fe3e4aSElliott Hughes ("qCurveTo", ((3, 3), (0, 0))), # closed qCurve overlaps move 255*e1fe3e4aSElliott Hughes ("closePath", ()), 256*e1fe3e4aSElliott Hughes ], 257*e1fe3e4aSElliott Hughes True, # <-- 258*e1fe3e4aSElliott Hughes [ 259*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), # no extra lineTo added here, same as above 260*e1fe3e4aSElliott Hughes ("qCurveTo", ((3, 3), (2, 2))), 261*e1fe3e4aSElliott Hughes ("qCurveTo", ((1, 1), (0, 0))), 262*e1fe3e4aSElliott Hughes ("closePath", ()), 263*e1fe3e4aSElliott Hughes ], 264*e1fe3e4aSElliott Hughes ), 265*e1fe3e4aSElliott Hughes ( 266*e1fe3e4aSElliott Hughes [ 267*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 268*e1fe3e4aSElliott Hughes ("qCurveTo", ((1, 1), (2, 2))), 269*e1fe3e4aSElliott Hughes ("qCurveTo", ((3, 3), (4, 4))), # closed qCurve not overlapping move 270*e1fe3e4aSElliott Hughes ("closePath", ()), 271*e1fe3e4aSElliott Hughes ], 272*e1fe3e4aSElliott Hughes False, 273*e1fe3e4aSElliott Hughes [ 274*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 275*e1fe3e4aSElliott Hughes ("lineTo", ((4, 4),)), # the previously implied line 276*e1fe3e4aSElliott Hughes ("qCurveTo", ((3, 3), (2, 2))), 277*e1fe3e4aSElliott Hughes ("qCurveTo", ((1, 1), (0, 0))), 278*e1fe3e4aSElliott Hughes ("closePath", ()), 279*e1fe3e4aSElliott Hughes ], 280*e1fe3e4aSElliott Hughes ), 281*e1fe3e4aSElliott Hughes ( 282*e1fe3e4aSElliott Hughes [ 283*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 284*e1fe3e4aSElliott Hughes ("qCurveTo", ((1, 1), (2, 2))), 285*e1fe3e4aSElliott Hughes ("qCurveTo", ((3, 3), (4, 4))), # closed qCurve not overlapping move 286*e1fe3e4aSElliott Hughes ("closePath", ()), 287*e1fe3e4aSElliott Hughes ], 288*e1fe3e4aSElliott Hughes True, 289*e1fe3e4aSElliott Hughes [ 290*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 291*e1fe3e4aSElliott Hughes ("lineTo", ((4, 4),)), # the previously implied line (same as above) 292*e1fe3e4aSElliott Hughes ("qCurveTo", ((3, 3), (2, 2))), 293*e1fe3e4aSElliott Hughes ("qCurveTo", ((1, 1), (0, 0))), 294*e1fe3e4aSElliott Hughes ("closePath", ()), 295*e1fe3e4aSElliott Hughes ], 296*e1fe3e4aSElliott Hughes ), 297*e1fe3e4aSElliott Hughes ( 298*e1fe3e4aSElliott Hughes [ 299*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 300*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 301*e1fe3e4aSElliott Hughes ("qCurveTo", ((2, 2), (3, 3))), 302*e1fe3e4aSElliott Hughes ("closePath", ()), 303*e1fe3e4aSElliott Hughes ], 304*e1fe3e4aSElliott Hughes False, 305*e1fe3e4aSElliott Hughes [ 306*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 307*e1fe3e4aSElliott Hughes ("lineTo", ((3, 3),)), 308*e1fe3e4aSElliott Hughes ("qCurveTo", ((2, 2), (1, 1))), 309*e1fe3e4aSElliott Hughes ("closePath", ()), 310*e1fe3e4aSElliott Hughes ], 311*e1fe3e4aSElliott Hughes ), 312*e1fe3e4aSElliott Hughes ( 313*e1fe3e4aSElliott Hughes [("addComponent", ("a", (1, 0, 0, 1, 0, 0)))], 314*e1fe3e4aSElliott Hughes False, 315*e1fe3e4aSElliott Hughes [("addComponent", ("a", (1, 0, 0, 1, 0, 0)))], 316*e1fe3e4aSElliott Hughes ), 317*e1fe3e4aSElliott Hughes ([], False, []), 318*e1fe3e4aSElliott Hughes ( 319*e1fe3e4aSElliott Hughes [ 320*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 321*e1fe3e4aSElliott Hughes ("endPath", ()), 322*e1fe3e4aSElliott Hughes ], 323*e1fe3e4aSElliott Hughes False, 324*e1fe3e4aSElliott Hughes [ 325*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 326*e1fe3e4aSElliott Hughes ("endPath", ()), 327*e1fe3e4aSElliott Hughes ], 328*e1fe3e4aSElliott Hughes ), 329*e1fe3e4aSElliott Hughes ( 330*e1fe3e4aSElliott Hughes [ 331*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 332*e1fe3e4aSElliott Hughes ("closePath", ()), 333*e1fe3e4aSElliott Hughes ], 334*e1fe3e4aSElliott Hughes False, 335*e1fe3e4aSElliott Hughes [ 336*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 337*e1fe3e4aSElliott Hughes ("endPath", ()), # single-point paths is always open 338*e1fe3e4aSElliott Hughes ], 339*e1fe3e4aSElliott Hughes ), 340*e1fe3e4aSElliott Hughes ( 341*e1fe3e4aSElliott Hughes [("moveTo", ((0, 0),)), ("lineTo", ((1, 1),)), ("endPath", ())], 342*e1fe3e4aSElliott Hughes False, 343*e1fe3e4aSElliott Hughes [("moveTo", ((1, 1),)), ("lineTo", ((0, 0),)), ("endPath", ())], 344*e1fe3e4aSElliott Hughes ), 345*e1fe3e4aSElliott Hughes ( 346*e1fe3e4aSElliott Hughes [("moveTo", ((0, 0),)), ("curveTo", ((1, 1), (2, 2), (3, 3))), ("endPath", ())], 347*e1fe3e4aSElliott Hughes False, 348*e1fe3e4aSElliott Hughes [("moveTo", ((3, 3),)), ("curveTo", ((2, 2), (1, 1), (0, 0))), ("endPath", ())], 349*e1fe3e4aSElliott Hughes ), 350*e1fe3e4aSElliott Hughes ( 351*e1fe3e4aSElliott Hughes [ 352*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 353*e1fe3e4aSElliott Hughes ("curveTo", ((1, 1), (2, 2), (3, 3))), 354*e1fe3e4aSElliott Hughes ("lineTo", ((4, 4),)), 355*e1fe3e4aSElliott Hughes ("endPath", ()), 356*e1fe3e4aSElliott Hughes ], 357*e1fe3e4aSElliott Hughes False, 358*e1fe3e4aSElliott Hughes [ 359*e1fe3e4aSElliott Hughes ("moveTo", ((4, 4),)), 360*e1fe3e4aSElliott Hughes ("lineTo", ((3, 3),)), 361*e1fe3e4aSElliott Hughes ("curveTo", ((2, 2), (1, 1), (0, 0))), 362*e1fe3e4aSElliott Hughes ("endPath", ()), 363*e1fe3e4aSElliott Hughes ], 364*e1fe3e4aSElliott Hughes ), 365*e1fe3e4aSElliott Hughes ( 366*e1fe3e4aSElliott Hughes [ 367*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 368*e1fe3e4aSElliott Hughes ("lineTo", ((1, 1),)), 369*e1fe3e4aSElliott Hughes ("curveTo", ((2, 2), (3, 3), (4, 4))), 370*e1fe3e4aSElliott Hughes ("endPath", ()), 371*e1fe3e4aSElliott Hughes ], 372*e1fe3e4aSElliott Hughes False, 373*e1fe3e4aSElliott Hughes [ 374*e1fe3e4aSElliott Hughes ("moveTo", ((4, 4),)), 375*e1fe3e4aSElliott Hughes ("curveTo", ((3, 3), (2, 2), (1, 1))), 376*e1fe3e4aSElliott Hughes ("lineTo", ((0, 0),)), 377*e1fe3e4aSElliott Hughes ("endPath", ()), 378*e1fe3e4aSElliott Hughes ], 379*e1fe3e4aSElliott Hughes ), 380*e1fe3e4aSElliott Hughes ( 381*e1fe3e4aSElliott Hughes [("qCurveTo", ((0, 0), (1, 1), (2, 2), None)), ("closePath", ())], 382*e1fe3e4aSElliott Hughes False, 383*e1fe3e4aSElliott Hughes [("qCurveTo", ((0, 0), (2, 2), (1, 1), None)), ("closePath", ())], 384*e1fe3e4aSElliott Hughes ), 385*e1fe3e4aSElliott Hughes ( 386*e1fe3e4aSElliott Hughes [("qCurveTo", ((0, 0), (1, 1), (2, 2), None)), ("endPath", ())], 387*e1fe3e4aSElliott Hughes False, 388*e1fe3e4aSElliott Hughes [ 389*e1fe3e4aSElliott Hughes ("qCurveTo", ((0, 0), (2, 2), (1, 1), None)), 390*e1fe3e4aSElliott Hughes ("closePath", ()), # this is always "closed" 391*e1fe3e4aSElliott Hughes ], 392*e1fe3e4aSElliott Hughes ), 393*e1fe3e4aSElliott Hughes # Test case from: 394*e1fe3e4aSElliott Hughes # https://github.com/googlei18n/cu2qu/issues/51#issue-179370514 395*e1fe3e4aSElliott Hughes ( 396*e1fe3e4aSElliott Hughes [ 397*e1fe3e4aSElliott Hughes ("moveTo", ((848, 348),)), 398*e1fe3e4aSElliott Hughes ("lineTo", ((848, 348),)), # duplicate lineTo point after moveTo 399*e1fe3e4aSElliott Hughes ("qCurveTo", ((848, 526), (649, 704), (449, 704))), 400*e1fe3e4aSElliott Hughes ("qCurveTo", ((449, 704), (248, 704), (50, 526), (50, 348))), 401*e1fe3e4aSElliott Hughes ("lineTo", ((50, 348),)), 402*e1fe3e4aSElliott Hughes ("qCurveTo", ((50, 348), (50, 171), (248, -3), (449, -3))), 403*e1fe3e4aSElliott Hughes ("qCurveTo", ((449, -3), (649, -3), (848, 171), (848, 348))), 404*e1fe3e4aSElliott Hughes ("closePath", ()), 405*e1fe3e4aSElliott Hughes ], 406*e1fe3e4aSElliott Hughes False, 407*e1fe3e4aSElliott Hughes [ 408*e1fe3e4aSElliott Hughes ("moveTo", ((848, 348),)), 409*e1fe3e4aSElliott Hughes ("qCurveTo", ((848, 171), (649, -3), (449, -3), (449, -3))), 410*e1fe3e4aSElliott Hughes ("qCurveTo", ((248, -3), (50, 171), (50, 348), (50, 348))), 411*e1fe3e4aSElliott Hughes ("lineTo", ((50, 348),)), 412*e1fe3e4aSElliott Hughes ("qCurveTo", ((50, 526), (248, 704), (449, 704), (449, 704))), 413*e1fe3e4aSElliott Hughes ("qCurveTo", ((649, 704), (848, 526), (848, 348))), 414*e1fe3e4aSElliott Hughes ("lineTo", ((848, 348),)), # the duplicate point is kept 415*e1fe3e4aSElliott Hughes ("closePath", ()), 416*e1fe3e4aSElliott Hughes ], 417*e1fe3e4aSElliott Hughes ), 418*e1fe3e4aSElliott Hughes # Test case from https://github.com/googlefonts/fontmake/issues/572 419*e1fe3e4aSElliott Hughes # An additional closing lineTo is required to disambiguate a duplicate 420*e1fe3e4aSElliott Hughes # point at the end of a contour from the implied closing line. 421*e1fe3e4aSElliott Hughes ( 422*e1fe3e4aSElliott Hughes [ 423*e1fe3e4aSElliott Hughes ("moveTo", ((0, 651),)), 424*e1fe3e4aSElliott Hughes ("lineTo", ((0, 101),)), 425*e1fe3e4aSElliott Hughes ("lineTo", ((0, 101),)), 426*e1fe3e4aSElliott Hughes ("lineTo", ((0, 651),)), 427*e1fe3e4aSElliott Hughes ("lineTo", ((0, 651),)), 428*e1fe3e4aSElliott Hughes ("closePath", ()), 429*e1fe3e4aSElliott Hughes ], 430*e1fe3e4aSElliott Hughes False, 431*e1fe3e4aSElliott Hughes [ 432*e1fe3e4aSElliott Hughes ("moveTo", ((0, 651),)), 433*e1fe3e4aSElliott Hughes ("lineTo", ((0, 651),)), 434*e1fe3e4aSElliott Hughes ("lineTo", ((0, 101),)), 435*e1fe3e4aSElliott Hughes ("lineTo", ((0, 101),)), 436*e1fe3e4aSElliott Hughes ("closePath", ()), 437*e1fe3e4aSElliott Hughes ], 438*e1fe3e4aSElliott Hughes ), 439*e1fe3e4aSElliott Hughes ( 440*e1fe3e4aSElliott Hughes [ 441*e1fe3e4aSElliott Hughes ("moveTo", ((0, 651),)), 442*e1fe3e4aSElliott Hughes ("lineTo", ((0, 101),)), 443*e1fe3e4aSElliott Hughes ("lineTo", ((0, 101),)), 444*e1fe3e4aSElliott Hughes ("lineTo", ((0, 651),)), 445*e1fe3e4aSElliott Hughes ("lineTo", ((0, 651),)), 446*e1fe3e4aSElliott Hughes ("closePath", ()), 447*e1fe3e4aSElliott Hughes ], 448*e1fe3e4aSElliott Hughes True, 449*e1fe3e4aSElliott Hughes [ 450*e1fe3e4aSElliott Hughes ("moveTo", ((0, 651),)), 451*e1fe3e4aSElliott Hughes ("lineTo", ((0, 651),)), 452*e1fe3e4aSElliott Hughes ("lineTo", ((0, 101),)), 453*e1fe3e4aSElliott Hughes ("lineTo", ((0, 101),)), 454*e1fe3e4aSElliott Hughes ("lineTo", ((0, 651),)), # closing line not implied 455*e1fe3e4aSElliott Hughes ("closePath", ()), 456*e1fe3e4aSElliott Hughes ], 457*e1fe3e4aSElliott Hughes ), 458*e1fe3e4aSElliott Hughes] 459*e1fe3e4aSElliott Hughes 460*e1fe3e4aSElliott Hughes 461*e1fe3e4aSElliott Hughes@pytest.mark.parametrize("contour, outputImpliedClosingLine, expected", TEST_DATA) 462*e1fe3e4aSElliott Hughesdef test_reverse_pen(contour, outputImpliedClosingLine, expected): 463*e1fe3e4aSElliott Hughes recpen = RecordingPen() 464*e1fe3e4aSElliott Hughes revpen = ReverseContourPen(recpen, outputImpliedClosingLine) 465*e1fe3e4aSElliott Hughes for operator, operands in contour: 466*e1fe3e4aSElliott Hughes getattr(revpen, operator)(*operands) 467*e1fe3e4aSElliott Hughes assert recpen.value == expected 468*e1fe3e4aSElliott Hughes 469*e1fe3e4aSElliott Hughes 470*e1fe3e4aSElliott Hughesdef test_reverse_pen_outputImpliedClosingLine(): 471*e1fe3e4aSElliott Hughes recpen = RecordingPen() 472*e1fe3e4aSElliott Hughes revpen = ReverseContourPen(recpen) 473*e1fe3e4aSElliott Hughes revpen.moveTo((0, 0)) 474*e1fe3e4aSElliott Hughes revpen.lineTo((10, 0)) 475*e1fe3e4aSElliott Hughes revpen.lineTo((0, 10)) 476*e1fe3e4aSElliott Hughes revpen.lineTo((0, 0)) 477*e1fe3e4aSElliott Hughes revpen.closePath() 478*e1fe3e4aSElliott Hughes assert recpen.value == [ 479*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 480*e1fe3e4aSElliott Hughes ("lineTo", ((0, 10),)), 481*e1fe3e4aSElliott Hughes ("lineTo", ((10, 0),)), 482*e1fe3e4aSElliott Hughes # ("lineTo", ((0, 0),)), # implied 483*e1fe3e4aSElliott Hughes ("closePath", ()), 484*e1fe3e4aSElliott Hughes ] 485*e1fe3e4aSElliott Hughes 486*e1fe3e4aSElliott Hughes recpen = RecordingPen() 487*e1fe3e4aSElliott Hughes revpen = ReverseContourPen(recpen, outputImpliedClosingLine=True) 488*e1fe3e4aSElliott Hughes revpen.moveTo((0, 0)) 489*e1fe3e4aSElliott Hughes revpen.lineTo((10, 0)) 490*e1fe3e4aSElliott Hughes revpen.lineTo((0, 10)) 491*e1fe3e4aSElliott Hughes revpen.lineTo((0, 0)) 492*e1fe3e4aSElliott Hughes revpen.closePath() 493*e1fe3e4aSElliott Hughes assert recpen.value == [ 494*e1fe3e4aSElliott Hughes ("moveTo", ((0, 0),)), 495*e1fe3e4aSElliott Hughes ("lineTo", ((0, 10),)), 496*e1fe3e4aSElliott Hughes ("lineTo", ((10, 0),)), 497*e1fe3e4aSElliott Hughes ("lineTo", ((0, 0),)), # not implied 498*e1fe3e4aSElliott Hughes ("closePath", ()), 499*e1fe3e4aSElliott Hughes ] 500*e1fe3e4aSElliott Hughes 501*e1fe3e4aSElliott Hughes 502*e1fe3e4aSElliott Hughes@pytest.mark.parametrize("contour, outputImpliedClosingLine, expected", TEST_DATA) 503*e1fe3e4aSElliott Hughesdef test_reverse_point_pen(contour, outputImpliedClosingLine, expected): 504*e1fe3e4aSElliott Hughes from fontTools.pens.pointPen import ( 505*e1fe3e4aSElliott Hughes ReverseContourPointPen, 506*e1fe3e4aSElliott Hughes PointToSegmentPen, 507*e1fe3e4aSElliott Hughes SegmentToPointPen, 508*e1fe3e4aSElliott Hughes ) 509*e1fe3e4aSElliott Hughes 510*e1fe3e4aSElliott Hughes recpen = RecordingPen() 511*e1fe3e4aSElliott Hughes pt2seg = PointToSegmentPen(recpen, outputImpliedClosingLine) 512*e1fe3e4aSElliott Hughes revpen = ReverseContourPointPen(pt2seg) 513*e1fe3e4aSElliott Hughes seg2pt = SegmentToPointPen(revpen) 514*e1fe3e4aSElliott Hughes for operator, operands in contour: 515*e1fe3e4aSElliott Hughes getattr(seg2pt, operator)(*operands) 516*e1fe3e4aSElliott Hughes 517*e1fe3e4aSElliott Hughes assert recpen.value == expected 518