blob: aa674ba17c33a4440f9c930c4ccea3011bad033f [file] [log] [blame]
Kevin Lubick644d8e72018-08-09 13:58:04 -04001describe('PathKit\'s Path Behavior', function() {
Kevin Lubick644d8e72018-08-09 13:58:04 -04002
Kevin Lubick11194ab2018-08-17 13:52:56 -04003 describe('Basic Path Features', function() {
4 function drawSimplePath() {
Kevin Lubick644d8e72018-08-09 13:58:04 -04005 let path = PathKit.NewPath();
Kevin Lubick11194ab2018-08-17 13:52:56 -04006 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) {
Kevin Lubicke71e9ef2018-11-05 07:51:40 -050014 LoadPathKit.then(catchException(done, () => {
Kevin Lubick11194ab2018-08-17 13:52:56 -040015 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();
Kevin Lubicke71e9ef2018-11-05 07:51:40 -050032 }));
Kevin Lubick11194ab2018-08-17 13:52:56 -040033 });
34
35 it('has a copy constructor', function(done) {
Kevin Lubicke71e9ef2018-11-05 07:51:40 -050036 LoadPathKit.then(catchException(done, () => {
Kevin Lubick11194ab2018-08-17 13:52:56 -040037 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();
Kevin Lubicke71e9ef2018-11-05 07:51:40 -050046 }));
Kevin Lubick11194ab2018-08-17 13:52:56 -040047 });
48
49 it('has a copy method', function(done) {
Kevin Lubicke71e9ef2018-11-05 07:51:40 -050050 LoadPathKit.then(catchException(done, () => {
Kevin Lubick11194ab2018-08-17 13:52:56 -040051 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();
Kevin Lubicke71e9ef2018-11-05 07:51:40 -050060 }));
Kevin Lubick11194ab2018-08-17 13:52:56 -040061 });
62
63 it('can create a copy with MakePath', function(done) {
Kevin Lubicke71e9ef2018-11-05 07:51:40 -050064 LoadPathKit.then(catchException(done, () => {
Kevin Lubick11194ab2018-08-17 13:52:56 -040065 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();
Kevin Lubicke71e9ef2018-11-05 07:51:40 -050074 }));
Kevin Lubick644d8e72018-08-09 13:58:04 -040075 });
76 });
77
Kevin Lubickf14a3c02018-08-22 09:35:32 -040078 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 }
Kevin Lubick11194ab2018-08-17 13:52:56 -040090
Kevin Lubick97d6d982018-08-10 15:53:16 -040091 function bits2float(str) {
92 return PathKit.SkBits2FloatUnsigned(parseInt(str))
93 }
94
Kevin Lubick11194ab2018-08-17 13:52:56 -040095 describe('bounds and rect', function(){
96 it('dynamically updates getBounds()', function(done){
Kevin Lubicke71e9ef2018-11-05 07:51:40 -050097 LoadPathKit.then(catchException(done, () => {
Kevin Lubick11194ab2018-08-17 13:52:56 -040098 // Based on test_bounds_crbug_513799
99 let path = PathKit.NewPath();
Kevin Lubickd9936482018-08-24 10:44:16 -0400100 expect(path.getBounds()).toEqual(PathKit.LTRBRect(0, 0, 0, 0));
Kevin Lubick11194ab2018-08-17 13:52:56 -0400101 path.moveTo(-5, -8);
Kevin Lubickd9936482018-08-24 10:44:16 -0400102 expect(path.getBounds()).toEqual(PathKit.LTRBRect(-5, -8, -5, -8));
Kevin Lubick11194ab2018-08-17 13:52:56 -0400103 path.rect(1, 2, 2, 2);
Kevin Lubickd9936482018-08-24 10:44:16 -0400104 expect(path.getBounds()).toEqual(PathKit.LTRBRect(-5, -8, 3, 4));
Kevin Lubick11194ab2018-08-17 13:52:56 -0400105 path.moveTo(1, 2);
Kevin Lubickd9936482018-08-24 10:44:16 -0400106 expect(path.getBounds()).toEqual(PathKit.LTRBRect(-5, -8, 3, 4));
Kevin Lubick11194ab2018-08-17 13:52:56 -0400107 path.delete();
108 done();
Kevin Lubicke71e9ef2018-11-05 07:51:40 -0500109 }));
Kevin Lubick11194ab2018-08-17 13:52:56 -0400110 });
Kevin Lubick644d8e72018-08-09 13:58:04 -0400111
Kevin Lubick11194ab2018-08-17 13:52:56 -0400112 it('has getBounds() and computeTightBounds()', function(done){
Kevin Lubicke71e9ef2018-11-05 07:51:40 -0500113 LoadPathKit.then(catchException(done, () => {
Kevin Lubick11194ab2018-08-17 13:52:56 -0400114 // Based on PathOpsTightBoundsIllBehaved
115 let path = PathKit.NewPath();
116 path.moveTo(1, 1);
117 path.quadraticCurveTo(4, 3, 2, 2);
Kevin Lubickd9936482018-08-24 10:44:16 -0400118 expect(path.getBounds()).toEqual(PathKit.LTRBRect(1, 1, 4, 3));
Kevin Lubickf14a3c02018-08-22 09:35:32 -0400119 ExpectRectsToBeEqual(path.computeTightBounds(),
Kevin Lubickd9936482018-08-24 10:44:16 -0400120 PathKit.LTRBRect(1, 1,
Kevin Lubickf14a3c02018-08-22 09:35:32 -0400121 bits2float("0x40333334"), // 2.8
122 bits2float("0x40155556"))); // 2.3333333
Kevin Lubick11194ab2018-08-17 13:52:56 -0400123 path.delete();
124
125 done();
Kevin Lubicke71e9ef2018-11-05 07:51:40 -0500126 }));
Kevin Lubick644d8e72018-08-09 13:58:04 -0400127 });
128 });
129
Kevin Lubickf14a3c02018-08-22 09:35:32 -0400130 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
Kevin Lubick11194ab2018-08-17 13:52:56 -0400145 describe('Command arrays', function(){
Kevin Lubickda3d8ac2019-01-07 11:08:55 -0500146 it('does NOT approximates conics when dumping as toCmds', function(done) {
Kevin Lubicke71e9ef2018-11-05 07:51:40 -0500147 LoadPathKit.then(catchException(done, () => {
Kevin Lubick11194ab2018-08-17 13:52:56 -0400148 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);
Kevin Lubick97d6d982018-08-10 15:53:16 -0400152
Kevin Lubick11194ab2018-08-17 13:52:56 -0400153 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 ];
Kevin Lubickf14a3c02018-08-22 09:35:32 -0400162 ExpectCmdsToBeEqual(path.toCmds(), expectedCmds);
Kevin Lubick97d6d982018-08-10 15:53:16 -0400163
Kevin Lubick11194ab2018-08-17 13:52:56 -0400164 path.delete();
165 done();
Kevin Lubicke71e9ef2018-11-05 07:51:40 -0500166 }));
Kevin Lubick97d6d982018-08-10 15:53:16 -0400167 });
168 });
169
Kevin Lubick644d8e72018-08-09 13:58:04 -0400170});