1*c8dee2aaSAndroid Build Coastguard Workerdescribe('PathKit\'s Path Behavior', function() { 2*c8dee2aaSAndroid Build Coastguard Worker 3*c8dee2aaSAndroid Build Coastguard Worker describe('Basic Path Features', function() { 4*c8dee2aaSAndroid Build Coastguard Worker function drawSimplePath() { 5*c8dee2aaSAndroid Build Coastguard Worker let path = PathKit.NewPath(); 6*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(0, 0); 7*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(10, 0); 8*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(10, 10); 9*c8dee2aaSAndroid Build Coastguard Worker path.close(); 10*c8dee2aaSAndroid Build Coastguard Worker return path; 11*c8dee2aaSAndroid Build Coastguard Worker } 12*c8dee2aaSAndroid Build Coastguard Worker 13*c8dee2aaSAndroid Build Coastguard Worker it('supports.equals()', function(done) { 14*c8dee2aaSAndroid Build Coastguard Worker LoadPathKit.then(catchException(done, () => { 15*c8dee2aaSAndroid Build Coastguard Worker let path = drawSimplePath(); 16*c8dee2aaSAndroid Build Coastguard Worker let otherPath = drawSimplePath(); 17*c8dee2aaSAndroid Build Coastguard Worker let blank = PathKit.NewPath(); 18*c8dee2aaSAndroid Build Coastguard Worker 19*c8dee2aaSAndroid Build Coastguard Worker expect(path.equals(path)).toBe(true); 20*c8dee2aaSAndroid Build Coastguard Worker expect(otherPath.equals(path)).toBe(true); 21*c8dee2aaSAndroid Build Coastguard Worker expect(path.equals(otherPath)).toBe(true); 22*c8dee2aaSAndroid Build Coastguard Worker 23*c8dee2aaSAndroid Build Coastguard Worker expect(path.equals(blank)).toBe(false); 24*c8dee2aaSAndroid Build Coastguard Worker expect(otherPath.equals(blank)).toBe(false); 25*c8dee2aaSAndroid Build Coastguard Worker expect(blank.equals(path)).toBe(false); 26*c8dee2aaSAndroid Build Coastguard Worker expect(blank.equals(otherPath)).toBe(false); 27*c8dee2aaSAndroid Build Coastguard Worker 28*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 29*c8dee2aaSAndroid Build Coastguard Worker otherPath.delete(); 30*c8dee2aaSAndroid Build Coastguard Worker blank.delete(); 31*c8dee2aaSAndroid Build Coastguard Worker done(); 32*c8dee2aaSAndroid Build Coastguard Worker })); 33*c8dee2aaSAndroid Build Coastguard Worker }); 34*c8dee2aaSAndroid Build Coastguard Worker 35*c8dee2aaSAndroid Build Coastguard Worker it('has a copy constructor', function(done) { 36*c8dee2aaSAndroid Build Coastguard Worker LoadPathKit.then(catchException(done, () => { 37*c8dee2aaSAndroid Build Coastguard Worker let orig = drawSimplePath(); 38*c8dee2aaSAndroid Build Coastguard Worker let copy = new PathKit.SkPath(orig); 39*c8dee2aaSAndroid Build Coastguard Worker 40*c8dee2aaSAndroid Build Coastguard Worker expect(orig.toSVGString()).toEqual(copy.toSVGString()); 41*c8dee2aaSAndroid Build Coastguard Worker expect(orig.equals(copy)).toBe(true); 42*c8dee2aaSAndroid Build Coastguard Worker 43*c8dee2aaSAndroid Build Coastguard Worker orig.delete(); 44*c8dee2aaSAndroid Build Coastguard Worker copy.delete(); 45*c8dee2aaSAndroid Build Coastguard Worker done(); 46*c8dee2aaSAndroid Build Coastguard Worker })); 47*c8dee2aaSAndroid Build Coastguard Worker }); 48*c8dee2aaSAndroid Build Coastguard Worker 49*c8dee2aaSAndroid Build Coastguard Worker it('has a copy method', function(done) { 50*c8dee2aaSAndroid Build Coastguard Worker LoadPathKit.then(catchException(done, () => { 51*c8dee2aaSAndroid Build Coastguard Worker let orig = drawSimplePath(); 52*c8dee2aaSAndroid Build Coastguard Worker let copy = orig.copy(); 53*c8dee2aaSAndroid Build Coastguard Worker 54*c8dee2aaSAndroid Build Coastguard Worker expect(orig.toSVGString()).toEqual(copy.toSVGString()); 55*c8dee2aaSAndroid Build Coastguard Worker expect(orig.equals(copy)).toBe(true); 56*c8dee2aaSAndroid Build Coastguard Worker 57*c8dee2aaSAndroid Build Coastguard Worker orig.delete(); 58*c8dee2aaSAndroid Build Coastguard Worker copy.delete(); 59*c8dee2aaSAndroid Build Coastguard Worker done(); 60*c8dee2aaSAndroid Build Coastguard Worker })); 61*c8dee2aaSAndroid Build Coastguard Worker }); 62*c8dee2aaSAndroid Build Coastguard Worker 63*c8dee2aaSAndroid Build Coastguard Worker it('can create a copy with MakePath', function(done) { 64*c8dee2aaSAndroid Build Coastguard Worker LoadPathKit.then(catchException(done, () => { 65*c8dee2aaSAndroid Build Coastguard Worker let orig = drawSimplePath(); 66*c8dee2aaSAndroid Build Coastguard Worker let copy = PathKit.NewPath(orig); 67*c8dee2aaSAndroid Build Coastguard Worker 68*c8dee2aaSAndroid Build Coastguard Worker expect(orig.toSVGString()).toEqual(copy.toSVGString()); 69*c8dee2aaSAndroid Build Coastguard Worker expect(orig.equals(copy)).toBe(true); 70*c8dee2aaSAndroid Build Coastguard Worker 71*c8dee2aaSAndroid Build Coastguard Worker orig.delete(); 72*c8dee2aaSAndroid Build Coastguard Worker copy.delete(); 73*c8dee2aaSAndroid Build Coastguard Worker done(); 74*c8dee2aaSAndroid Build Coastguard Worker })); 75*c8dee2aaSAndroid Build Coastguard Worker }); 76*c8dee2aaSAndroid Build Coastguard Worker }); 77*c8dee2aaSAndroid Build Coastguard Worker 78*c8dee2aaSAndroid Build Coastguard Worker function ExpectRectsToBeEqual(actual, expected) { 79*c8dee2aaSAndroid Build Coastguard Worker if (PathKit.usingWasm) { 80*c8dee2aaSAndroid Build Coastguard Worker // exact match 81*c8dee2aaSAndroid Build Coastguard Worker expect(actual).toEqual(expected); 82*c8dee2aaSAndroid Build Coastguard Worker } else { 83*c8dee2aaSAndroid Build Coastguard Worker // floats get rounded a little bit 84*c8dee2aaSAndroid Build Coastguard Worker expect(actual.fLeft).toBeCloseTo(expected.fLeft, 4); 85*c8dee2aaSAndroid Build Coastguard Worker expect(actual.fTop).toBeCloseTo(expected.fTop, 4); 86*c8dee2aaSAndroid Build Coastguard Worker expect(actual.fRight).toBeCloseTo(expected.fRight, 4); 87*c8dee2aaSAndroid Build Coastguard Worker expect(actual.fBottom).toBeCloseTo(expected.fBottom, 4); 88*c8dee2aaSAndroid Build Coastguard Worker } 89*c8dee2aaSAndroid Build Coastguard Worker } 90*c8dee2aaSAndroid Build Coastguard Worker 91*c8dee2aaSAndroid Build Coastguard Worker function bits2float(str) { 92*c8dee2aaSAndroid Build Coastguard Worker return PathKit.SkBits2FloatUnsigned(parseInt(str)) 93*c8dee2aaSAndroid Build Coastguard Worker } 94*c8dee2aaSAndroid Build Coastguard Worker 95*c8dee2aaSAndroid Build Coastguard Worker describe('bounds and rect', function(){ 96*c8dee2aaSAndroid Build Coastguard Worker it('dynamically updates getBounds()', function(done){ 97*c8dee2aaSAndroid Build Coastguard Worker LoadPathKit.then(catchException(done, () => { 98*c8dee2aaSAndroid Build Coastguard Worker // Based on test_bounds_crbug_513799 99*c8dee2aaSAndroid Build Coastguard Worker let path = PathKit.NewPath(); 100*c8dee2aaSAndroid Build Coastguard Worker expect(path.getBounds()).toEqual(PathKit.LTRBRect(0, 0, 0, 0)); 101*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(-5, -8); 102*c8dee2aaSAndroid Build Coastguard Worker expect(path.getBounds()).toEqual(PathKit.LTRBRect(-5, -8, -5, -8)); 103*c8dee2aaSAndroid Build Coastguard Worker path.rect(1, 2, 2, 2); 104*c8dee2aaSAndroid Build Coastguard Worker expect(path.getBounds()).toEqual(PathKit.LTRBRect(-5, -8, 3, 4)); 105*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(1, 2); 106*c8dee2aaSAndroid Build Coastguard Worker expect(path.getBounds()).toEqual(PathKit.LTRBRect(-5, -8, 3, 4)); 107*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 108*c8dee2aaSAndroid Build Coastguard Worker done(); 109*c8dee2aaSAndroid Build Coastguard Worker })); 110*c8dee2aaSAndroid Build Coastguard Worker }); 111*c8dee2aaSAndroid Build Coastguard Worker 112*c8dee2aaSAndroid Build Coastguard Worker it('has getBounds() and computeTightBounds()', function(done){ 113*c8dee2aaSAndroid Build Coastguard Worker LoadPathKit.then(catchException(done, () => { 114*c8dee2aaSAndroid Build Coastguard Worker // Based on PathOpsTightBoundsIllBehaved 115*c8dee2aaSAndroid Build Coastguard Worker let path = PathKit.NewPath(); 116*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(1, 1); 117*c8dee2aaSAndroid Build Coastguard Worker path.quadraticCurveTo(4, 3, 2, 2); 118*c8dee2aaSAndroid Build Coastguard Worker expect(path.getBounds()).toEqual(PathKit.LTRBRect(1, 1, 4, 3)); 119*c8dee2aaSAndroid Build Coastguard Worker ExpectRectsToBeEqual(path.computeTightBounds(), 120*c8dee2aaSAndroid Build Coastguard Worker PathKit.LTRBRect(1, 1, 121*c8dee2aaSAndroid Build Coastguard Worker bits2float("0x40333334"), // 2.8 122*c8dee2aaSAndroid Build Coastguard Worker bits2float("0x40155556"))); // 2.3333333 123*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 124*c8dee2aaSAndroid Build Coastguard Worker 125*c8dee2aaSAndroid Build Coastguard Worker done(); 126*c8dee2aaSAndroid Build Coastguard Worker })); 127*c8dee2aaSAndroid Build Coastguard Worker }); 128*c8dee2aaSAndroid Build Coastguard Worker }); 129*c8dee2aaSAndroid Build Coastguard Worker 130*c8dee2aaSAndroid Build Coastguard Worker function ExpectCmdsToBeEqual(actual, expected) { 131*c8dee2aaSAndroid Build Coastguard Worker if (PathKit.usingWasm) { 132*c8dee2aaSAndroid Build Coastguard Worker // exact match 133*c8dee2aaSAndroid Build Coastguard Worker expect(actual).toEqual(expected); 134*c8dee2aaSAndroid Build Coastguard Worker } else { 135*c8dee2aaSAndroid Build Coastguard Worker // lossy match 136*c8dee2aaSAndroid Build Coastguard Worker actual.every((cmd, cmdIdx) => { 137*c8dee2aaSAndroid Build Coastguard Worker cmd.every((arg, argIdx) => { 138*c8dee2aaSAndroid Build Coastguard Worker // The asm.js code is close to the wasm/c++ output, but not quite. 139*c8dee2aaSAndroid Build Coastguard Worker expect(arg).toBeCloseTo(expected[cmdIdx][argIdx], 4) 140*c8dee2aaSAndroid Build Coastguard Worker }); 141*c8dee2aaSAndroid Build Coastguard Worker }); 142*c8dee2aaSAndroid Build Coastguard Worker } 143*c8dee2aaSAndroid Build Coastguard Worker } 144*c8dee2aaSAndroid Build Coastguard Worker 145*c8dee2aaSAndroid Build Coastguard Worker describe('Command arrays', function(){ 146*c8dee2aaSAndroid Build Coastguard Worker it('does NOT approximates conics when dumping as toCmds', function(done) { 147*c8dee2aaSAndroid Build Coastguard Worker LoadPathKit.then(catchException(done, () => { 148*c8dee2aaSAndroid Build Coastguard Worker let path = PathKit.NewPath(); 149*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(20, 120); 150*c8dee2aaSAndroid Build Coastguard Worker path.arc(20, 120, 18, 0, 1.75 * Math.PI); 151*c8dee2aaSAndroid Build Coastguard Worker path.lineTo(20, 120); 152*c8dee2aaSAndroid Build Coastguard Worker 153*c8dee2aaSAndroid Build Coastguard Worker let expectedCmds = [ 154*c8dee2aaSAndroid Build Coastguard Worker [PathKit.MOVE_VERB, 20, 120], 155*c8dee2aaSAndroid Build Coastguard Worker [PathKit.LINE_VERB, 38, 120], 156*c8dee2aaSAndroid Build Coastguard Worker [PathKit.CONIC_VERB, 38, 138, 20, 138, bits2float("0x3f3504f3)")], // 0.707107f 157*c8dee2aaSAndroid Build Coastguard Worker [PathKit.CONIC_VERB, 2, 138, 2, 120, bits2float("0x3f3504f3)")], // 0.707107f 158*c8dee2aaSAndroid Build Coastguard Worker [PathKit.CONIC_VERB, 2, 102, 20, 102, bits2float("0x3f3504f3)")], // 0.707107f 159*c8dee2aaSAndroid Build Coastguard Worker [PathKit.CONIC_VERB, bits2float("0x41dba58e"), 102, bits2float("0x4202e962"), bits2float("0x42d68b4d"), bits2float("0x3f6c8361")], // 27.4558, 102, 32.7279, 107.272, 0.92388 160*c8dee2aaSAndroid Build Coastguard Worker [PathKit.LINE_VERB, 20, 120], 161*c8dee2aaSAndroid Build Coastguard Worker ]; 162*c8dee2aaSAndroid Build Coastguard Worker ExpectCmdsToBeEqual(path.toCmds(), expectedCmds); 163*c8dee2aaSAndroid Build Coastguard Worker 164*c8dee2aaSAndroid Build Coastguard Worker path.delete(); 165*c8dee2aaSAndroid Build Coastguard Worker done(); 166*c8dee2aaSAndroid Build Coastguard Worker })); 167*c8dee2aaSAndroid Build Coastguard Worker }); 168*c8dee2aaSAndroid Build Coastguard Worker }); 169*c8dee2aaSAndroid Build Coastguard Worker 170*c8dee2aaSAndroid Build Coastguard Worker}); 171