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