1*c8dee2aaSAndroid Build Coastguard Workerdescribe('Path Behavior', () => { 2*c8dee2aaSAndroid Build Coastguard Worker let container; 3*c8dee2aaSAndroid Build Coastguard Worker 4*c8dee2aaSAndroid Build Coastguard Worker beforeEach(async () => { 5*c8dee2aaSAndroid Build Coastguard Worker await EverythingLoaded; 6*c8dee2aaSAndroid Build Coastguard Worker container = document.createElement('div'); 7*c8dee2aaSAndroid Build Coastguard Worker container.innerHTML = ` 8*c8dee2aaSAndroid Build Coastguard Worker <canvas width=600 height=600 id=test></canvas> 9*c8dee2aaSAndroid Build Coastguard Worker <canvas width=600 height=600 id=report></canvas>`; 10*c8dee2aaSAndroid Build Coastguard Worker document.body.appendChild(container); 11*c8dee2aaSAndroid Build Coastguard Worker }); 12*c8dee2aaSAndroid Build Coastguard Worker 13*c8dee2aaSAndroid Build Coastguard Worker afterEach(() => { 14*c8dee2aaSAndroid Build Coastguard Worker document.body.removeChild(container); 15*c8dee2aaSAndroid Build Coastguard Worker }); 16*c8dee2aaSAndroid Build Coastguard Worker 17*c8dee2aaSAndroid Build Coastguard Worker gm('path_api_example', (canvas) => { 18*c8dee2aaSAndroid Build Coastguard Worker const paint = new CanvasKit.Paint(); 19*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(1.0); 20*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 21*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(CanvasKit.Color(0, 0, 0, 1.0)); 22*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(CanvasKit.PaintStyle.Stroke); 23*c8dee2aaSAndroid Build Coastguard Worker 24*c8dee2aaSAndroid Build Coastguard Worker const path = new CanvasKit.Path(); 25*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(20, 5); 26*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(30, 20); 27*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(40, 10); 28*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(50, 20); 29*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(60, 0); 30*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(20, 5); 31*c8dee2aaSAndroid Build Coastguard Worker 32*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(20, 80); 33*c8dee2aaSAndroid Build Coastguard Worker path.cubicTo(90, 10, 160, 150, 190, 10); 34*c8dee2aaSAndroid Build Coastguard Worker 35*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(36, 148); 36*c8dee2aaSAndroid Build Coastguard Worker path.quadTo(66, 188, 120, 136); 37*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(36, 148); 38*c8dee2aaSAndroid Build Coastguard Worker 39*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(150, 180); 40*c8dee2aaSAndroid Build Coastguard Worker path.arcToTangent(150, 100, 50, 200, 20); 41*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(160, 160); 42*c8dee2aaSAndroid Build Coastguard Worker 43*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(20, 120); 44*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(20, 120); 45*c8dee2aaSAndroid Build Coastguard Worker 46*c8dee2aaSAndroid Build Coastguard Worker path.transform([2, 0, 0, 47*c8dee2aaSAndroid Build Coastguard Worker 0, 2, 0, 48*c8dee2aaSAndroid Build Coastguard Worker 0, 0, 1 ]); 49*c8dee2aaSAndroid Build Coastguard Worker 50*c8dee2aaSAndroid Build Coastguard Worker canvas.drawPath(path, paint); 51*c8dee2aaSAndroid Build Coastguard Worker 52*c8dee2aaSAndroid Build Coastguard Worker const rrect = CanvasKit.RRectXY([100, 10, 140, 62], 10, 4); 53*c8dee2aaSAndroid Build Coastguard Worker 54*c8dee2aaSAndroid Build Coastguard Worker const rrectPath = new CanvasKit.Path().addRRect(rrect, true); 55*c8dee2aaSAndroid Build Coastguard Worker 56*c8dee2aaSAndroid Build Coastguard Worker canvas.drawPath(rrectPath, paint); 57*c8dee2aaSAndroid Build Coastguard Worker 58*c8dee2aaSAndroid Build Coastguard Worker rrectPath.delete(); 59*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 60*c8dee2aaSAndroid Build Coastguard Worker paint.delete(); 61*c8dee2aaSAndroid Build Coastguard Worker // See PathKit for more tests, since they share implementation 62*c8dee2aaSAndroid Build Coastguard Worker }); 63*c8dee2aaSAndroid Build Coastguard Worker 64*c8dee2aaSAndroid Build Coastguard Worker it('can create a path from an SVG string', () => { 65*c8dee2aaSAndroid Build Coastguard Worker //.This is a parallelogram from 66*c8dee2aaSAndroid Build Coastguard Worker // https://upload.wikimedia.org/wikipedia/commons/e/e7/Simple_parallelogram.svg 67*c8dee2aaSAndroid Build Coastguard Worker const path = CanvasKit.Path.MakeFromSVGString( 68*c8dee2aaSAndroid Build Coastguard Worker 'M 205,5 L 795,5 L 595,295 L 5,295 L 205,5 z'); 69*c8dee2aaSAndroid Build Coastguard Worker 70*c8dee2aaSAndroid Build Coastguard Worker const cmds = path.toCmds(); 71*c8dee2aaSAndroid Build Coastguard Worker expect(cmds).toBeTruthy(); 72*c8dee2aaSAndroid Build Coastguard Worker // 1 move, 4 lines, 1 close 73*c8dee2aaSAndroid Build Coastguard Worker // each element in cmds is an array, with index 0 being the verb, and the rest being args 74*c8dee2aaSAndroid Build Coastguard Worker expect(cmds).toEqual(Float32Array.of( 75*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.MOVE_VERB, 205, 5, 76*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 795, 5, 77*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 595, 295, 78*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 5, 295, 79*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 205, 5, 80*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.CLOSE_VERB)); 81*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 82*c8dee2aaSAndroid Build Coastguard Worker }); 83*c8dee2aaSAndroid Build Coastguard Worker 84*c8dee2aaSAndroid Build Coastguard Worker it('can create a path by combining two other paths', () => { 85*c8dee2aaSAndroid Build Coastguard Worker // Get the intersection of two overlapping squares and verify that it is the smaller square. 86*c8dee2aaSAndroid Build Coastguard Worker const pathOne = new CanvasKit.Path(); 87*c8dee2aaSAndroid Build Coastguard Worker pathOne.addRect([10, 10, 20, 20]); 88*c8dee2aaSAndroid Build Coastguard Worker 89*c8dee2aaSAndroid Build Coastguard Worker const pathTwo = new CanvasKit.Path(); 90*c8dee2aaSAndroid Build Coastguard Worker pathTwo.addRect([15, 15, 30, 30]); 91*c8dee2aaSAndroid Build Coastguard Worker 92*c8dee2aaSAndroid Build Coastguard Worker const path = CanvasKit.Path.MakeFromOp(pathOne, pathTwo, CanvasKit.PathOp.Intersect); 93*c8dee2aaSAndroid Build Coastguard Worker const cmds = path.toCmds(); 94*c8dee2aaSAndroid Build Coastguard Worker expect(cmds).toBeTruthy(); 95*c8dee2aaSAndroid Build Coastguard Worker expect(cmds).toEqual(Float32Array.of( 96*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.MOVE_VERB, 15, 15, 97*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 20, 15, 98*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 20, 20, 99*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 15, 20, 100*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.CLOSE_VERB)); 101*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 102*c8dee2aaSAndroid Build Coastguard Worker pathOne.delete(); 103*c8dee2aaSAndroid Build Coastguard Worker pathTwo.delete(); 104*c8dee2aaSAndroid Build Coastguard Worker }); 105*c8dee2aaSAndroid Build Coastguard Worker 106*c8dee2aaSAndroid Build Coastguard Worker it('can create an SVG string from a path', () => { 107*c8dee2aaSAndroid Build Coastguard Worker const cmds = [CanvasKit.MOVE_VERB, 205, 5, 108*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 795, 5, 109*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 595, 295, 110*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 5, 295, 111*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 205, 5, 112*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.CLOSE_VERB]; 113*c8dee2aaSAndroid Build Coastguard Worker const path = CanvasKit.Path.MakeFromCmds(cmds); 114*c8dee2aaSAndroid Build Coastguard Worker 115*c8dee2aaSAndroid Build Coastguard Worker const svgStr = path.toSVGString(); 116*c8dee2aaSAndroid Build Coastguard Worker // We output it in terse form, which is different than Wikipedia's version 117*c8dee2aaSAndroid Build Coastguard Worker expect(svgStr).toEqual('M205 5L795 5L595 295L5 295L205 5Z'); 118*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 119*c8dee2aaSAndroid Build Coastguard Worker }); 120*c8dee2aaSAndroid Build Coastguard Worker 121*c8dee2aaSAndroid Build Coastguard Worker it('can create a path with malloced verbs, points, weights', () => { 122*c8dee2aaSAndroid Build Coastguard Worker const mVerbs = CanvasKit.Malloc(Uint8Array, 6); 123*c8dee2aaSAndroid Build Coastguard Worker const mPoints = CanvasKit.Malloc(Float32Array, 18); 124*c8dee2aaSAndroid Build Coastguard Worker const mWeights = CanvasKit.Malloc(Float32Array, 1); 125*c8dee2aaSAndroid Build Coastguard Worker mVerbs.toTypedArray().set([CanvasKit.MOVE_VERB, CanvasKit.LINE_VERB, 126*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.QUAD_VERB, CanvasKit.CONIC_VERB, CanvasKit.CUBIC_VERB, CanvasKit.CLOSE_VERB 127*c8dee2aaSAndroid Build Coastguard Worker ]); 128*c8dee2aaSAndroid Build Coastguard Worker 129*c8dee2aaSAndroid Build Coastguard Worker mPoints.toTypedArray().set([ 130*c8dee2aaSAndroid Build Coastguard Worker 1,2, // moveTo 131*c8dee2aaSAndroid Build Coastguard Worker 3,4, // lineTo 132*c8dee2aaSAndroid Build Coastguard Worker 5,6,7,8, // quadTo 133*c8dee2aaSAndroid Build Coastguard Worker 9,10,11,12, // conicTo 134*c8dee2aaSAndroid Build Coastguard Worker 13,14,15,16,17,18, // cubicTo 135*c8dee2aaSAndroid Build Coastguard Worker ]); 136*c8dee2aaSAndroid Build Coastguard Worker 137*c8dee2aaSAndroid Build Coastguard Worker mWeights.toTypedArray().set([117]); 138*c8dee2aaSAndroid Build Coastguard Worker 139*c8dee2aaSAndroid Build Coastguard Worker let path = CanvasKit.Path.MakeFromVerbsPointsWeights(mVerbs, mPoints, mWeights); 140*c8dee2aaSAndroid Build Coastguard Worker 141*c8dee2aaSAndroid Build Coastguard Worker let cmds = path.toCmds(); 142*c8dee2aaSAndroid Build Coastguard Worker expect(cmds).toEqual(Float32Array.of( 143*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.MOVE_VERB, 1, 2, 144*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 3, 4, 145*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.QUAD_VERB, 5, 6, 7, 8, 146*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.CONIC_VERB, 9, 10, 11, 12, 117, 147*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.CUBIC_VERB, 13, 14, 15, 16, 17, 18, 148*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.CLOSE_VERB, 149*c8dee2aaSAndroid Build Coastguard Worker )); 150*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 151*c8dee2aaSAndroid Build Coastguard Worker 152*c8dee2aaSAndroid Build Coastguard Worker // If given insufficient points, it stops early (but doesn't read out of bounds). 153*c8dee2aaSAndroid Build Coastguard Worker path = CanvasKit.Path.MakeFromVerbsPointsWeights(mVerbs, mPoints.subarray(0, 10), mWeights); 154*c8dee2aaSAndroid Build Coastguard Worker 155*c8dee2aaSAndroid Build Coastguard Worker cmds = path.toCmds(); 156*c8dee2aaSAndroid Build Coastguard Worker expect(cmds).toEqual(Float32Array.of( 157*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.MOVE_VERB, 1, 2, 158*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 3, 4, 159*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.QUAD_VERB, 5, 6, 7, 8, 160*c8dee2aaSAndroid Build Coastguard Worker )); 161*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 162*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Free(mVerbs); 163*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Free(mPoints); 164*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Free(mWeights); 165*c8dee2aaSAndroid Build Coastguard Worker }); 166*c8dee2aaSAndroid Build Coastguard Worker 167*c8dee2aaSAndroid Build Coastguard Worker it('can create and update a path with verbs and points (no weights)', () => { 168*c8dee2aaSAndroid Build Coastguard Worker const path = CanvasKit.Path.MakeFromVerbsPointsWeights( 169*c8dee2aaSAndroid Build Coastguard Worker [CanvasKit.MOVE_VERB, CanvasKit.LINE_VERB], 170*c8dee2aaSAndroid Build Coastguard Worker [1,2, 3,4]); 171*c8dee2aaSAndroid Build Coastguard Worker let cmds = path.toCmds(); 172*c8dee2aaSAndroid Build Coastguard Worker expect(cmds).toEqual(Float32Array.of( 173*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.MOVE_VERB, 1, 2, 174*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 3, 4 175*c8dee2aaSAndroid Build Coastguard Worker )); 176*c8dee2aaSAndroid Build Coastguard Worker 177*c8dee2aaSAndroid Build Coastguard Worker path.addVerbsPointsWeights( 178*c8dee2aaSAndroid Build Coastguard Worker [CanvasKit.QUAD_VERB, CanvasKit.CLOSE_VERB], 179*c8dee2aaSAndroid Build Coastguard Worker [5,6,7,8], 180*c8dee2aaSAndroid Build Coastguard Worker ); 181*c8dee2aaSAndroid Build Coastguard Worker 182*c8dee2aaSAndroid Build Coastguard Worker cmds = path.toCmds(); 183*c8dee2aaSAndroid Build Coastguard Worker expect(cmds).toEqual(Float32Array.of( 184*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.MOVE_VERB, 1, 2, 185*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 3, 4, 186*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.QUAD_VERB, 5, 6, 7, 8, 187*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.CLOSE_VERB 188*c8dee2aaSAndroid Build Coastguard Worker )); 189*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 190*c8dee2aaSAndroid Build Coastguard Worker }); 191*c8dee2aaSAndroid Build Coastguard Worker 192*c8dee2aaSAndroid Build Coastguard Worker 193*c8dee2aaSAndroid Build Coastguard Worker it('can add points to a path in bulk', () => { 194*c8dee2aaSAndroid Build Coastguard Worker const mVerbs = CanvasKit.Malloc(Uint8Array, 6); 195*c8dee2aaSAndroid Build Coastguard Worker const mPoints = CanvasKit.Malloc(Float32Array, 18); 196*c8dee2aaSAndroid Build Coastguard Worker const mWeights = CanvasKit.Malloc(Float32Array, 1); 197*c8dee2aaSAndroid Build Coastguard Worker mVerbs.toTypedArray().set([CanvasKit.MOVE_VERB, CanvasKit.LINE_VERB, 198*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.QUAD_VERB, CanvasKit.CONIC_VERB, CanvasKit.CUBIC_VERB, CanvasKit.CLOSE_VERB 199*c8dee2aaSAndroid Build Coastguard Worker ]); 200*c8dee2aaSAndroid Build Coastguard Worker 201*c8dee2aaSAndroid Build Coastguard Worker mPoints.toTypedArray().set([ 202*c8dee2aaSAndroid Build Coastguard Worker 1,2, // moveTo 203*c8dee2aaSAndroid Build Coastguard Worker 3,4, // lineTo 204*c8dee2aaSAndroid Build Coastguard Worker 5,6,7,8, // quadTo 205*c8dee2aaSAndroid Build Coastguard Worker 9,10,11,12, // conicTo 206*c8dee2aaSAndroid Build Coastguard Worker 13,14,15,16,17,18, // cubicTo 207*c8dee2aaSAndroid Build Coastguard Worker ]); 208*c8dee2aaSAndroid Build Coastguard Worker 209*c8dee2aaSAndroid Build Coastguard Worker mWeights.toTypedArray().set([117]); 210*c8dee2aaSAndroid Build Coastguard Worker 211*c8dee2aaSAndroid Build Coastguard Worker const path = new CanvasKit.Path(); 212*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(77, 88); 213*c8dee2aaSAndroid Build Coastguard Worker path.addVerbsPointsWeights(mVerbs, mPoints, mWeights); 214*c8dee2aaSAndroid Build Coastguard Worker 215*c8dee2aaSAndroid Build Coastguard Worker let cmds = path.toCmds(); 216*c8dee2aaSAndroid Build Coastguard Worker expect(cmds).toEqual(Float32Array.of( 217*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.MOVE_VERB, 0, 0, 218*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 77, 88, 219*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.MOVE_VERB, 1, 2, 220*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 3, 4, 221*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.QUAD_VERB, 5, 6, 7, 8, 222*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.CONIC_VERB, 9, 10, 11, 12, 117, 223*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.CUBIC_VERB, 13, 14, 15, 16, 17, 18, 224*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.CLOSE_VERB, 225*c8dee2aaSAndroid Build Coastguard Worker )); 226*c8dee2aaSAndroid Build Coastguard Worker 227*c8dee2aaSAndroid Build Coastguard Worker path.rewind(); 228*c8dee2aaSAndroid Build Coastguard Worker cmds = path.toCmds(); 229*c8dee2aaSAndroid Build Coastguard Worker expect(cmds).toEqual(new Float32Array(0)); 230*c8dee2aaSAndroid Build Coastguard Worker 231*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 232*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Free(mVerbs); 233*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Free(mPoints); 234*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Free(mWeights); 235*c8dee2aaSAndroid Build Coastguard Worker }); 236*c8dee2aaSAndroid Build Coastguard Worker 237*c8dee2aaSAndroid Build Coastguard Worker it('can retrieve points from a path', () => { 238*c8dee2aaSAndroid Build Coastguard Worker const path = new CanvasKit.Path(); 239*c8dee2aaSAndroid Build Coastguard Worker path.addRect([10, 15, 20, 25]); 240*c8dee2aaSAndroid Build Coastguard Worker 241*c8dee2aaSAndroid Build Coastguard Worker let pt = path.getPoint(0); 242*c8dee2aaSAndroid Build Coastguard Worker expect(pt[0]).toEqual(10); 243*c8dee2aaSAndroid Build Coastguard Worker expect(pt[1]).toEqual(15); 244*c8dee2aaSAndroid Build Coastguard Worker 245*c8dee2aaSAndroid Build Coastguard Worker path.getPoint(2, pt); 246*c8dee2aaSAndroid Build Coastguard Worker expect(pt[0]).toEqual(20); 247*c8dee2aaSAndroid Build Coastguard Worker expect(pt[1]).toEqual(25); 248*c8dee2aaSAndroid Build Coastguard Worker 249*c8dee2aaSAndroid Build Coastguard Worker path.getPoint(1000, pt); // off the end returns (0, 0) as per the docs. 250*c8dee2aaSAndroid Build Coastguard Worker expect(pt[0]).toEqual(0); 251*c8dee2aaSAndroid Build Coastguard Worker expect(pt[1]).toEqual(0); 252*c8dee2aaSAndroid Build Coastguard Worker 253*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 254*c8dee2aaSAndroid Build Coastguard Worker }); 255*c8dee2aaSAndroid Build Coastguard Worker 256*c8dee2aaSAndroid Build Coastguard Worker gm('offset_path', (canvas) => { 257*c8dee2aaSAndroid Build Coastguard Worker const path = starPath(CanvasKit); 258*c8dee2aaSAndroid Build Coastguard Worker 259*c8dee2aaSAndroid Build Coastguard Worker const paint = new CanvasKit.Paint(); 260*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(CanvasKit.PaintStyle.Stroke); 261*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(5.0); 262*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 263*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(CanvasKit.BLACK); 264*c8dee2aaSAndroid Build Coastguard Worker 265*c8dee2aaSAndroid Build Coastguard Worker canvas.drawPath(path, paint); 266*c8dee2aaSAndroid Build Coastguard Worker path.offset(80, 40); 267*c8dee2aaSAndroid Build Coastguard Worker canvas.drawPath(path, paint); 268*c8dee2aaSAndroid Build Coastguard Worker 269*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 270*c8dee2aaSAndroid Build Coastguard Worker paint.delete(); 271*c8dee2aaSAndroid Build Coastguard Worker }); 272*c8dee2aaSAndroid Build Coastguard Worker 273*c8dee2aaSAndroid Build Coastguard Worker gm('oval_path', (canvas) => { 274*c8dee2aaSAndroid Build Coastguard Worker const paint = new CanvasKit.Paint(); 275*c8dee2aaSAndroid Build Coastguard Worker 276*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(CanvasKit.PaintStyle.Stroke); 277*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(5.0); 278*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 279*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(CanvasKit.BLACK); 280*c8dee2aaSAndroid Build Coastguard Worker 281*c8dee2aaSAndroid Build Coastguard Worker const path = new CanvasKit.Path(); 282*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(5, 5); 283*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(10, 120); 284*c8dee2aaSAndroid Build Coastguard Worker path.addOval(CanvasKit.LTRBRect(10, 20, 100, 200), false, 3); 285*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(300, 300); 286*c8dee2aaSAndroid Build Coastguard Worker 287*c8dee2aaSAndroid Build Coastguard Worker canvas.drawPath(path, paint); 288*c8dee2aaSAndroid Build Coastguard Worker 289*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 290*c8dee2aaSAndroid Build Coastguard Worker paint.delete(); 291*c8dee2aaSAndroid Build Coastguard Worker }); 292*c8dee2aaSAndroid Build Coastguard Worker 293*c8dee2aaSAndroid Build Coastguard Worker gm('bounds_path', (canvas) => { 294*c8dee2aaSAndroid Build Coastguard Worker const paint = new CanvasKit.Paint(); 295*c8dee2aaSAndroid Build Coastguard Worker 296*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(CanvasKit.PaintStyle.Stroke); 297*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(5.0); 298*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 299*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(CanvasKit.BLACK); 300*c8dee2aaSAndroid Build Coastguard Worker 301*c8dee2aaSAndroid Build Coastguard Worker const path = new CanvasKit.Path(); 302*c8dee2aaSAndroid Build Coastguard Worker // Arbitrary points to make an interesting curve. 303*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(97, 225); 304*c8dee2aaSAndroid Build Coastguard Worker path.cubicTo(20, 400, 404, 75, 243, 271); 305*c8dee2aaSAndroid Build Coastguard Worker 306*c8dee2aaSAndroid Build Coastguard Worker canvas.drawPath(path, paint); 307*c8dee2aaSAndroid Build Coastguard Worker 308*c8dee2aaSAndroid Build Coastguard Worker const bounds = new Float32Array(4); 309*c8dee2aaSAndroid Build Coastguard Worker path.getBounds(bounds); 310*c8dee2aaSAndroid Build Coastguard Worker 311*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(CanvasKit.BLUE); 312*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(3.0); 313*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRect(bounds, paint); 314*c8dee2aaSAndroid Build Coastguard Worker 315*c8dee2aaSAndroid Build Coastguard Worker path.computeTightBounds(bounds); 316*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(CanvasKit.RED); 317*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(3.0); 318*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRect(bounds, paint); 319*c8dee2aaSAndroid Build Coastguard Worker 320*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 321*c8dee2aaSAndroid Build Coastguard Worker paint.delete(); 322*c8dee2aaSAndroid Build Coastguard Worker }); 323*c8dee2aaSAndroid Build Coastguard Worker 324*c8dee2aaSAndroid Build Coastguard Worker gm('arcto_path', (canvas) => { 325*c8dee2aaSAndroid Build Coastguard Worker const paint = new CanvasKit.Paint(); 326*c8dee2aaSAndroid Build Coastguard Worker 327*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(CanvasKit.PaintStyle.Stroke); 328*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(5.0); 329*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 330*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(CanvasKit.BLACK); 331*c8dee2aaSAndroid Build Coastguard Worker 332*c8dee2aaSAndroid Build Coastguard Worker const path = new CanvasKit.Path(); 333*c8dee2aaSAndroid Build Coastguard Worker 334*c8dee2aaSAndroid Build Coastguard Worker // - x1, y1, x2, y2, radius 335*c8dee2aaSAndroid Build Coastguard Worker path.arcToTangent(40, 0, 40, 40, 40); 336*c8dee2aaSAndroid Build Coastguard Worker // - oval (as Rect), startAngle, sweepAngle, forceMoveTo 337*c8dee2aaSAndroid Build Coastguard Worker path.arcToOval(CanvasKit.LTRBRect(90, 10, 120, 200), 30, 300, true); 338*c8dee2aaSAndroid Build Coastguard Worker // - rx, ry, xAxisRotate, useSmallArc, isCCW, x, y 339*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(5, 105); 340*c8dee2aaSAndroid Build Coastguard Worker path.arcToRotated(24, 24, 45, true, false, 82, 156); 341*c8dee2aaSAndroid Build Coastguard Worker 342*c8dee2aaSAndroid Build Coastguard Worker canvas.drawPath(path, paint); 343*c8dee2aaSAndroid Build Coastguard Worker 344*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 345*c8dee2aaSAndroid Build Coastguard Worker paint.delete(); 346*c8dee2aaSAndroid Build Coastguard Worker }); 347*c8dee2aaSAndroid Build Coastguard Worker 348*c8dee2aaSAndroid Build Coastguard Worker gm('path_relative', (canvas) => { 349*c8dee2aaSAndroid Build Coastguard Worker const paint = new CanvasKit.Paint(); 350*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(1.0); 351*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 352*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(CanvasKit.Color(0, 0, 0, 1.0)); 353*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(CanvasKit.PaintStyle.Stroke); 354*c8dee2aaSAndroid Build Coastguard Worker 355*c8dee2aaSAndroid Build Coastguard Worker const path = new CanvasKit.Path(); 356*c8dee2aaSAndroid Build Coastguard Worker path.rMoveTo(20, 5) 357*c8dee2aaSAndroid Build Coastguard Worker .rLineTo(10, 15) // 30, 20 358*c8dee2aaSAndroid Build Coastguard Worker .rLineTo(10, -5); // 40, 10 359*c8dee2aaSAndroid Build Coastguard Worker path.rLineTo(10, 10); // 50, 20 360*c8dee2aaSAndroid Build Coastguard Worker path.rLineTo(10, -20); // 60, 0 361*c8dee2aaSAndroid Build Coastguard Worker path.rLineTo(-40, 5); // 20, 5 362*c8dee2aaSAndroid Build Coastguard Worker 363*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(20, 80) 364*c8dee2aaSAndroid Build Coastguard Worker .rCubicTo(70, -70, 140, 70, 170, -70); // 90, 10, 160, 150, 190, 10 365*c8dee2aaSAndroid Build Coastguard Worker 366*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(36, 148) 367*c8dee2aaSAndroid Build Coastguard Worker .rQuadTo(30, 40, 84, -12) // 66, 188, 120, 136 368*c8dee2aaSAndroid Build Coastguard Worker .lineTo(36, 148); 369*c8dee2aaSAndroid Build Coastguard Worker 370*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(150, 180) 371*c8dee2aaSAndroid Build Coastguard Worker .rArcTo(24, 24, 45, true, false, -68, -24); // 82, 156 372*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(160, 160); 373*c8dee2aaSAndroid Build Coastguard Worker 374*c8dee2aaSAndroid Build Coastguard Worker canvas.drawPath(path, paint); 375*c8dee2aaSAndroid Build Coastguard Worker 376*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 377*c8dee2aaSAndroid Build Coastguard Worker paint.delete(); 378*c8dee2aaSAndroid Build Coastguard Worker }); 379*c8dee2aaSAndroid Build Coastguard Worker 380*c8dee2aaSAndroid Build Coastguard Worker it('can measure the contours of a path', () => { 381*c8dee2aaSAndroid Build Coastguard Worker const path = new CanvasKit.Path(); 382*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(10, 10) 383*c8dee2aaSAndroid Build Coastguard Worker .lineTo(40, 50); // should be length 50 because of the 3/4/5 triangle rule 384*c8dee2aaSAndroid Build Coastguard Worker 385*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(80, 0) 386*c8dee2aaSAndroid Build Coastguard Worker .lineTo(80, 10) 387*c8dee2aaSAndroid Build Coastguard Worker .lineTo(100, 5) 388*c8dee2aaSAndroid Build Coastguard Worker .lineTo(80, 0); 389*c8dee2aaSAndroid Build Coastguard Worker 390*c8dee2aaSAndroid Build Coastguard Worker const meas = new CanvasKit.ContourMeasureIter(path, false, 1); 391*c8dee2aaSAndroid Build Coastguard Worker let cont = meas.next(); 392*c8dee2aaSAndroid Build Coastguard Worker expect(cont).toBeTruthy(); 393*c8dee2aaSAndroid Build Coastguard Worker 394*c8dee2aaSAndroid Build Coastguard Worker expect(cont.length()).toBeCloseTo(50.0, 3); 395*c8dee2aaSAndroid Build Coastguard Worker const pt = cont.getPosTan(28.7); // arbitrary point 396*c8dee2aaSAndroid Build Coastguard Worker expect(pt[0]).toBeCloseTo(27.22, 3); // x 397*c8dee2aaSAndroid Build Coastguard Worker expect(pt[1]).toBeCloseTo(32.96, 3); // y 398*c8dee2aaSAndroid Build Coastguard Worker expect(pt[2]).toBeCloseTo(0.6, 3); // dy 399*c8dee2aaSAndroid Build Coastguard Worker expect(pt[3]).toBeCloseTo(0.8, 3); // dy 400*c8dee2aaSAndroid Build Coastguard Worker 401*c8dee2aaSAndroid Build Coastguard Worker pt.set([-1, -1, -1, -1]); // fill with sentinel values. 402*c8dee2aaSAndroid Build Coastguard Worker cont.getPosTan(28.7, pt); // arbitrary point again, passing in an array to copy into. 403*c8dee2aaSAndroid Build Coastguard Worker expect(pt[0]).toBeCloseTo(27.22, 3); // x 404*c8dee2aaSAndroid Build Coastguard Worker expect(pt[1]).toBeCloseTo(32.96, 3); // y 405*c8dee2aaSAndroid Build Coastguard Worker expect(pt[2]).toBeCloseTo(0.6, 3); // dy 406*c8dee2aaSAndroid Build Coastguard Worker expect(pt[3]).toBeCloseTo(0.8, 3); // dy 407*c8dee2aaSAndroid Build Coastguard Worker 408*c8dee2aaSAndroid Build Coastguard Worker const subpath = cont.getSegment(20, 40, true); // make sure this doesn't crash 409*c8dee2aaSAndroid Build Coastguard Worker 410*c8dee2aaSAndroid Build Coastguard Worker cont.delete(); 411*c8dee2aaSAndroid Build Coastguard Worker cont = meas.next(); 412*c8dee2aaSAndroid Build Coastguard Worker expect(cont).toBeTruthy(); 413*c8dee2aaSAndroid Build Coastguard Worker expect(cont.length()).toBeCloseTo(51.231, 3); 414*c8dee2aaSAndroid Build Coastguard Worker 415*c8dee2aaSAndroid Build Coastguard Worker cont.delete(); 416*c8dee2aaSAndroid Build Coastguard Worker expect(meas.next()).toBeFalsy(); 417*c8dee2aaSAndroid Build Coastguard Worker 418*c8dee2aaSAndroid Build Coastguard Worker meas.delete(); 419*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 420*c8dee2aaSAndroid Build Coastguard Worker }); 421*c8dee2aaSAndroid Build Coastguard Worker 422*c8dee2aaSAndroid Build Coastguard Worker gm('drawpoly_path', (canvas) => { 423*c8dee2aaSAndroid Build Coastguard Worker const paint = new CanvasKit.Paint(); 424*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(1.0); 425*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 426*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(CanvasKit.Color(0, 0, 0, 1.0)); 427*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(CanvasKit.PaintStyle.Stroke); 428*c8dee2aaSAndroid Build Coastguard Worker 429*c8dee2aaSAndroid Build Coastguard Worker const points = [5, 5, 30, 20, 55, 5, 55, 50, 30, 30, 5, 50]; 430*c8dee2aaSAndroid Build Coastguard Worker 431*c8dee2aaSAndroid Build Coastguard Worker const pointsObj = CanvasKit.Malloc(Float32Array, 6 * 2); 432*c8dee2aaSAndroid Build Coastguard Worker const mPoints = pointsObj.toTypedArray(); 433*c8dee2aaSAndroid Build Coastguard Worker mPoints.set([105, 105, 130, 120, 155, 105, 155, 150, 130, 130, 105, 150]); 434*c8dee2aaSAndroid Build Coastguard Worker 435*c8dee2aaSAndroid Build Coastguard Worker const path = new CanvasKit.Path(); 436*c8dee2aaSAndroid Build Coastguard Worker path.addPoly(points, true) 437*c8dee2aaSAndroid Build Coastguard Worker .moveTo(100, 0) 438*c8dee2aaSAndroid Build Coastguard Worker .addPoly(mPoints, true); 439*c8dee2aaSAndroid Build Coastguard Worker 440*c8dee2aaSAndroid Build Coastguard Worker canvas.drawPath(path, paint); 441*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Free(pointsObj); 442*c8dee2aaSAndroid Build Coastguard Worker 443*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 444*c8dee2aaSAndroid Build Coastguard Worker paint.delete(); 445*c8dee2aaSAndroid Build Coastguard Worker }); 446*c8dee2aaSAndroid Build Coastguard Worker 447*c8dee2aaSAndroid Build Coastguard Worker // Test trim, adding paths to paths, and a bunch of other path methods. 448*c8dee2aaSAndroid Build Coastguard Worker gm('trim_path', (canvas) => { 449*c8dee2aaSAndroid Build Coastguard Worker 450*c8dee2aaSAndroid Build Coastguard Worker const paint = new CanvasKit.Paint(); 451*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(1.0); 452*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 453*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(CanvasKit.Color(0, 0, 0, 1.0)); 454*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(CanvasKit.PaintStyle.Stroke); 455*c8dee2aaSAndroid Build Coastguard Worker 456*c8dee2aaSAndroid Build Coastguard Worker const arcpath = new CanvasKit.Path(); 457*c8dee2aaSAndroid Build Coastguard Worker arcpath.arc(400, 400, 100, 0, -90, false) // x, y, radius, startAngle, endAngle, ccw 458*c8dee2aaSAndroid Build Coastguard Worker .dash(3, 1, 0) 459*c8dee2aaSAndroid Build Coastguard Worker .conicTo(10, 20, 30, 40, 5) 460*c8dee2aaSAndroid Build Coastguard Worker .rConicTo(60, 70, 80, 90, 5) 461*c8dee2aaSAndroid Build Coastguard Worker .trim(0.2, 1, false); 462*c8dee2aaSAndroid Build Coastguard Worker 463*c8dee2aaSAndroid Build Coastguard Worker const path = new CanvasKit.Path(); 464*c8dee2aaSAndroid Build Coastguard Worker path.addArc(CanvasKit.LTRBRect(10, 20, 100, 200), 30, 300) 465*c8dee2aaSAndroid Build Coastguard Worker .addRect(CanvasKit.LTRBRect(200, 200, 300, 300)) // test single arg, default cw 466*c8dee2aaSAndroid Build Coastguard Worker .addRect(CanvasKit.LTRBRect(240, 240, 260, 260), true) // test two arg, true means ccw 467*c8dee2aaSAndroid Build Coastguard Worker .addRect([260, 260, 290, 290], true) // test five arg, true means ccw 468*c8dee2aaSAndroid Build Coastguard Worker .addRRect([300, 10, 500, 290, // Rect in LTRB order 469*c8dee2aaSAndroid Build Coastguard Worker 60, 60, 60, 60, 60, 60, 60, 60], // all radii are the same 470*c8dee2aaSAndroid Build Coastguard Worker false) // ccw 471*c8dee2aaSAndroid Build Coastguard Worker .addRRect(CanvasKit.RRectXY([350, 60, 450, 240], 20, 80), true) // Rect, rx, ry, ccw 472*c8dee2aaSAndroid Build Coastguard Worker .addPath(arcpath) 473*c8dee2aaSAndroid Build Coastguard Worker .transform(0.54, -0.84, 390.35, 474*c8dee2aaSAndroid Build Coastguard Worker 0.84, 0.54, -114.53, 475*c8dee2aaSAndroid Build Coastguard Worker 0, 0, 1); 476*c8dee2aaSAndroid Build Coastguard Worker 477*c8dee2aaSAndroid Build Coastguard Worker canvas.drawPath(path, paint); 478*c8dee2aaSAndroid Build Coastguard Worker 479*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 480*c8dee2aaSAndroid Build Coastguard Worker paint.delete(); 481*c8dee2aaSAndroid Build Coastguard Worker }); 482*c8dee2aaSAndroid Build Coastguard Worker 483*c8dee2aaSAndroid Build Coastguard Worker gm('winding_example', (canvas) => { 484*c8dee2aaSAndroid Build Coastguard Worker // Inspired by https://fiddle.skia.org/c/@Path_FillType_a 485*c8dee2aaSAndroid Build Coastguard Worker const path = new CanvasKit.Path(); 486*c8dee2aaSAndroid Build Coastguard Worker // Draw overlapping rects on top 487*c8dee2aaSAndroid Build Coastguard Worker path.addRect(CanvasKit.LTRBRect(10, 10, 30, 30), false); 488*c8dee2aaSAndroid Build Coastguard Worker path.addRect(CanvasKit.LTRBRect(20, 20, 40, 40), false); 489*c8dee2aaSAndroid Build Coastguard Worker // Draw overlapping rects on bottom, with different direction lines. 490*c8dee2aaSAndroid Build Coastguard Worker path.addRect(CanvasKit.LTRBRect(10, 60, 30, 80), false); 491*c8dee2aaSAndroid Build Coastguard Worker path.addRect(CanvasKit.LTRBRect(20, 70, 40, 90), true); 492*c8dee2aaSAndroid Build Coastguard Worker 493*c8dee2aaSAndroid Build Coastguard Worker expect(path.getFillType()).toEqual(CanvasKit.FillType.Winding); 494*c8dee2aaSAndroid Build Coastguard Worker 495*c8dee2aaSAndroid Build Coastguard Worker // Draw the two rectangles on the left side. 496*c8dee2aaSAndroid Build Coastguard Worker const paint = new CanvasKit.Paint(); 497*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(CanvasKit.PaintStyle.Stroke); 498*c8dee2aaSAndroid Build Coastguard Worker canvas.drawPath(path, paint); 499*c8dee2aaSAndroid Build Coastguard Worker 500*c8dee2aaSAndroid Build Coastguard Worker const clipRect = CanvasKit.LTRBRect(0, 0, 51, 100); 501*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(CanvasKit.PaintStyle.Fill); 502*c8dee2aaSAndroid Build Coastguard Worker 503*c8dee2aaSAndroid Build Coastguard Worker for (const fillType of [CanvasKit.FillType.Winding, CanvasKit.FillType.EvenOdd]) { 504*c8dee2aaSAndroid Build Coastguard Worker canvas.translate(51, 0); 505*c8dee2aaSAndroid Build Coastguard Worker canvas.save(); 506*c8dee2aaSAndroid Build Coastguard Worker canvas.clipRect(clipRect, CanvasKit.ClipOp.Intersect, false); 507*c8dee2aaSAndroid Build Coastguard Worker path.setFillType(fillType); 508*c8dee2aaSAndroid Build Coastguard Worker canvas.drawPath(path, paint); 509*c8dee2aaSAndroid Build Coastguard Worker canvas.restore(); 510*c8dee2aaSAndroid Build Coastguard Worker } 511*c8dee2aaSAndroid Build Coastguard Worker 512*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 513*c8dee2aaSAndroid Build Coastguard Worker paint.delete(); 514*c8dee2aaSAndroid Build Coastguard Worker }); 515*c8dee2aaSAndroid Build Coastguard Worker 516*c8dee2aaSAndroid Build Coastguard Worker gm('as_winding', (canvas) => { 517*c8dee2aaSAndroid Build Coastguard Worker const evenOddPath = new CanvasKit.Path(); 518*c8dee2aaSAndroid Build Coastguard Worker // Draw overlapping rects 519*c8dee2aaSAndroid Build Coastguard Worker evenOddPath.addRect(CanvasKit.LTRBRect(10, 10, 70, 70), false); 520*c8dee2aaSAndroid Build Coastguard Worker evenOddPath.addRect(CanvasKit.LTRBRect(30, 30, 50, 50), false); 521*c8dee2aaSAndroid Build Coastguard Worker evenOddPath.setFillType(CanvasKit.FillType.EvenOdd); 522*c8dee2aaSAndroid Build Coastguard Worker 523*c8dee2aaSAndroid Build Coastguard Worker const evenOddCmds = evenOddPath.toCmds(); 524*c8dee2aaSAndroid Build Coastguard Worker expect(evenOddCmds).toEqual(Float32Array.of( 525*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.MOVE_VERB, 10, 10, 526*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 70, 10, 527*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 70, 70, 528*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 10, 70, 529*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.CLOSE_VERB, 530*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.MOVE_VERB, 30, 30, // This contour is drawn 531*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 50, 30, // clockwise, as specified. 532*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 50, 50, 533*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 30, 50, 534*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.CLOSE_VERB 535*c8dee2aaSAndroid Build Coastguard Worker )); 536*c8dee2aaSAndroid Build Coastguard Worker 537*c8dee2aaSAndroid Build Coastguard Worker const windingPath = evenOddPath.makeAsWinding(); 538*c8dee2aaSAndroid Build Coastguard Worker 539*c8dee2aaSAndroid Build Coastguard Worker expect(windingPath.getFillType()).toBe(CanvasKit.FillType.Winding); 540*c8dee2aaSAndroid Build Coastguard Worker const windingCmds = windingPath.toCmds(); 541*c8dee2aaSAndroid Build Coastguard Worker expect(windingCmds).toEqual(Float32Array.of( 542*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.MOVE_VERB, 10, 10, 543*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 70, 10, 544*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 70, 70, 545*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 10, 70, 546*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.CLOSE_VERB, 547*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.MOVE_VERB, 30, 50, // This contour has been 548*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 50, 50, // re-drawn counter-clockwise 549*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 50, 30, // so that it covers the same 550*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.LINE_VERB, 30, 30, // area, but with the winding fill type. 551*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.CLOSE_VERB 552*c8dee2aaSAndroid Build Coastguard Worker )); 553*c8dee2aaSAndroid Build Coastguard Worker 554*c8dee2aaSAndroid Build Coastguard Worker const paint = new CanvasKit.Paint(); 555*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(CanvasKit.PaintStyle.Fill); 556*c8dee2aaSAndroid Build Coastguard Worker const font = new CanvasKit.Font(CanvasKit.Typeface.GetDefault(), 20); 557*c8dee2aaSAndroid Build Coastguard Worker 558*c8dee2aaSAndroid Build Coastguard Worker canvas.drawText('Original path (even odd)', 5, 20, paint, font); 559*c8dee2aaSAndroid Build Coastguard Worker canvas.translate(0, 50); 560*c8dee2aaSAndroid Build Coastguard Worker canvas.drawPath(evenOddPath, paint); 561*c8dee2aaSAndroid Build Coastguard Worker 562*c8dee2aaSAndroid Build Coastguard Worker canvas.translate(300, 0); 563*c8dee2aaSAndroid Build Coastguard Worker canvas.drawPath(windingPath, paint); 564*c8dee2aaSAndroid Build Coastguard Worker 565*c8dee2aaSAndroid Build Coastguard Worker canvas.translate(0, -50); 566*c8dee2aaSAndroid Build Coastguard Worker canvas.drawText('makeAsWinding path', 5, 20, paint, font); 567*c8dee2aaSAndroid Build Coastguard Worker 568*c8dee2aaSAndroid Build Coastguard Worker evenOddPath.delete(); 569*c8dee2aaSAndroid Build Coastguard Worker windingPath.delete(); 570*c8dee2aaSAndroid Build Coastguard Worker }); 571*c8dee2aaSAndroid Build Coastguard Worker}); 572