1 describe('PathKit\'s Path2D API', function() {
2 it('can do everything in the Path2D API w/o crashing', function(done) {
3 LoadPathKit.then(catchException(done, () => {
4 // This is taken from example.html
5 let path = PathKit.NewPath();
15 path.bezierCurveTo(90, 10, 160, 150, 190, 10);
18 path.quadraticCurveTo(66, 188, 120, 136);
21 path.rect(5, 170, 20, 20);
23 path.moveTo(150, 180);
24 path.arcTo(150, 100, 50, 200, 20);
25 path.lineTo(160, 160);
28 path.arc(20, 120, 18, 0, 1.75 * Math.PI);
31 let secondPath = PathKit.NewPath();
32 secondPath.ellipse(130, 25, 30, 10, -1*Math.PI/8, Math.PI/6, 1.5*Math.PI, false);
34 path.addPath(secondPath);
36 let m = document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGMatrix();
41 path.addPath(secondPath, m);
43 let canvas = document.createElement('canvas');
44 let canvasCtx = canvas.getContext('2d');
45 // Set canvas size and make it a bit bigger to zoom in on the lines
46 standardizedCanvasSize(canvasCtx);
47 canvasCtx.scale(3.0, 3.0);
48 canvasCtx.fillStyle = 'blue';
49 canvasCtx.stroke(path.toPath2D());
51 let svgPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
52 svgPath.setAttribute('stroke', 'black');
53 svgPath.setAttribute('fill', 'rgba(255,255,255,0.0)');
54 svgPath.setAttribute('transform', 'scale(3.0, 3.0)');
55 svgPath.setAttribute('d', path.toSVGString());
57 let newSVG = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
58 newSVG.appendChild(svgPath);
59 newSVG.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
60 newSVG.setAttribute('width', 600);
61 newSVG.setAttribute('height', 600);
66 reportCanvas(canvas, 'path2D_api_example').then(() => {
67 reportSVG(newSVG, 'path2D_api_example').then(() => {
69 }).catch(reportError(done));
70 }).catch(reportError(done));
74 it('can chain by returning the same object', function(done) {
75 LoadPathKit.then(catchException(done, () => {
76 let path = PathKit.NewPath();
78 let p1 = path.moveTo(20, 5)
80 .quadTo(66, 188, 120, 136)
83 // these should be the same object
84 expect(path === p1).toBe(true);
87 // This should throw an exception because
88 // the underlying path was already deleted.
90 expect('should not have gotten here').toBe(false);
98 it('does not leak path objects when chaining', function(done) {
99 LoadPathKit.then(catchException(done, () => {
100 // By default, we have 16 MB of memory assigned to our PathKit
101 // library. This can be configured by -S TOTAL_MEMORY=NN
102 // and defaults to 16MB (we likely don't need to touch this).
103 // If there's a leak in here, we should OOM pretty quick.
104 // Testing showed around 50k is enough to see one if we leak a path,
105 // so run 250k times just to be safe.
106 for(let i = 0; i < 250000; i++) {
107 let path = PathKit.NewPath()
110 .quadTo(66, 188, 120, 136)
118 function drawTriangle() {
119 let path = PathKit.NewPath();
127 it('has multiple overloads of addPath', function(done) {
128 LoadPathKit.then(catchException(done, () => {
129 let basePath = PathKit.NewPath();
130 let otherPath = drawTriangle();
131 // These add path call can be chained.
133 basePath.addPath(otherPath)
134 // providing the 6 params of an SVG matrix to make it appear 20.5 px down
135 .addPath(otherPath, 1, 0, 0, 1, 0, 20.5)
136 // provide the full 9 matrix params to make it appear 30 px to the right
137 // and be 3 times as big.
138 .addPath(otherPath, 3, 0, 30,
142 reportPath(basePath, 'add_path_3x', done);
148 it('approximates arcs (conics) with quads', function(done) {
149 LoadPathKit.then(catchException(done, () => {
150 let path = PathKit.NewPath();
151 path.moveTo(50, 120);
152 path.arc(50, 120, 45, 0, 1.75 * Math.PI);
153 path.lineTo(50, 120);
155 let canvas = document.createElement('canvas');
156 let canvasCtx = canvas.getContext('2d');
157 standardizedCanvasSize(canvasCtx);
158 // The and.callThrough is important to make it actually
159 // draw the quadratics
160 spyOn(canvasCtx, 'quadraticCurveTo').and.callThrough();
162 canvasCtx.beginPath();
163 path.toCanvas(canvasCtx);
165 // No need to check the whole path, as that's more what the
166 // gold correctness tests are for (can account for changes we make
167 // to the approximation algorithms).
168 expect(canvasCtx.quadraticCurveTo).toHaveBeenCalled();
170 reportCanvas(canvas, 'conics_quads_approx').then(() => {
172 }).catch(reportError(done));