2 <title>Canvas Tests
</title>
3 <script src=
"/tests/SimpleTest/SimpleTest.js"></script>
4 <link rel=
"stylesheet" href=
"/tests/SimpleTest/test.css">
8 SimpleTest
.waitForExplicitFinish();
9 const Cc
= SpecialPowers
.Cc
;
10 const Cr
= SpecialPowers
.Cr
;
12 function isPixel(ctx
, x
,y
, c
, d
) {
13 var pos
= x
+ "," + y
;
14 var color
= c
[0] + "," + c
[1] + "," + c
[2] + "," + c
[3];
15 var pixel
= ctx
.getImageData(x
, y
, 1, 1);
16 var pr
= pixel
.data
[0],
20 ok(c
[0]-d
<= pr
&& pr
<= c
[0]+d
&&
21 c
[1]-d
<= pg
&& pg
<= c
[1]+d
&&
22 c
[2]-d
<= pb
&& pb
<= c
[2]+d
&&
23 c
[3]-d
<= pa
&& pa
<= c
[3]+d
,
24 "pixel "+pos
+" of "+ctx
.canvas
.id
+" is "+pr
+","+pg
+","+pb
+","+pa
+"; expected "+color
+" +/- "+d
);
28 <p>Canvas test: test_drawClipPath_canvas
</p>
29 <canvas id=
"c1" class=
"output" width=
"100" height=
"100">+
31 <script type=
"text/javascript">
32 function test_drawClipPath_canvas() {
33 var c
= document
.getElementById("c1");
34 var ctx
= c
.getContext("2d");
36 var path
= new Path2D();
37 path
.rect(0, 0, 100, 100);
38 path
.rect(25, 25, 50, 50);
40 ctx
.fillStyle
= 'rgb(255,0,0)';
42 ctx
.fillRect(0, 0, 100, 100);
43 ctx
.fillStyle
= 'rgb(0,255,0)';
47 ctx
.fillRect(0, 0, 100, 100);
48 isPixel(ctx
, 50, 50, [0, 255, 0, 255], 5);
51 ctx
.fillStyle
= 'rgb(255,0,0)';
53 ctx
.fillRect(0, 0, 100, 100);
54 ctx
.fillStyle
= 'rgb(0,255,0)';
56 ctx
.clip(path
, 'nonzero');
58 ctx
.fillRect(0, 0, 100, 100);
59 isPixel(ctx
, 50, 50, [0, 255, 0, 255], 5);
62 ctx
.fillStyle
= 'rgb(255,0,0)';
64 ctx
.fillRect(0, 0, 100, 100);
65 ctx
.fillStyle
= 'rgb(0,255,0)';
67 ctx
.clip(path
, 'evenodd');
69 ctx
.fillRect(0, 0, 100, 100);
70 isPixel(ctx
, 50, 50, [255, 0, 0, 255], 5);
75 <p>Canvas test: test_drawFillPath_canvas
</p>
76 <canvas id=
"c2" class=
"output" width=
"100" height=
"100">+
78 <script type=
"text/javascript">
79 function test_drawFillPath_canvas() {
80 var c
= document
.getElementById("c2");
81 var ctx
= c
.getContext("2d");
83 var path
= new Path2D();
84 path
.rect(0, 0, 100, 100);
85 path
.rect(25, 25, 50, 50);
87 ctx
.fillStyle
= 'rgb(255,0,0)';
88 ctx
.fillRect(0, 0, 100, 100);
89 ctx
.fillStyle
= 'rgb(0,255,0)';
91 isPixel(ctx
, 50, 50, [0, 255, 0, 255], 5);
93 ctx
.fillStyle
= 'rgb(255,0,0)';
94 ctx
.fillRect(0, 0, 100, 100);
95 ctx
.fillStyle
= 'rgb(0,255,0)';
96 ctx
.fill(path
, 'nonzero');
97 isPixel(ctx
, 50, 50, [0, 255, 0, 255], 5);
99 ctx
.fillStyle
= 'rgb(255,0,0)';
100 ctx
.fillRect(0, 0, 100, 100);
101 ctx
.fillStyle
= 'rgb(0,255,0)';
102 ctx
.fill(path
, 'evenodd');
103 isPixel(ctx
, 50, 50, [255, 0, 0, 255], 5);
107 <p>Canvas test: test_drawStrokePath_canvas
</p>
108 <canvas id=
"c3" class=
"output" width=
"100" height=
"100">+
110 <script type=
"text/javascript">
111 function test_drawStrokePath_canvas() {
112 var c
= document
.getElementById("c3");
113 var ctx
= c
.getContext("2d");
115 var path
= new Path2D();
116 path
.rect(0, 0, 100, 100);
117 path
.rect(25, 25, 50, 50);
119 ctx
.fillStyle
= 'rgb(255,0,0)';
120 ctx
.fillRect(0, 0, 100, 100);
121 ctx
.strokeStyle
= 'rgb(0,255,0)';
124 isPixel(ctx
, 0, 0, [0, 255, 0, 255], 5);
125 isPixel(ctx
, 25, 25, [0, 255, 0, 255], 5);
126 isPixel(ctx
, 10, 10, [255, 0, 0, 255], 5);
130 <p>Canvas test: test_large_canvas
</p>
131 <canvas id=
"c4" class=
"output" width=
"10000" height=
"100">+
133 <script type=
"text/javascript">
134 function test_large_canvas() {
135 // test paths on large canvases. On certain platforms this will
136 // trigger retargeting of the backend
137 var c
= document
.getElementById("c4");
138 var ctx
= c
.getContext("2d");
140 var path
= new Path2D();
141 path
.rect(0, 0, 100, 100);
142 path
.rect(25, 25, 50, 50);
144 ctx
.fillStyle
= 'rgb(255,0,0)';
145 ctx
.fillRect(0, 0, 100, 100);
146 ctx
.fillStyle
= 'rgb(0,255,0)';
148 isPixel(ctx
, 50, 50, [0, 255, 0, 255], 5);
150 ctx
.fillStyle
= 'rgb(255,0,0)';
151 ctx
.fillRect(0, 0, 100, 100);
152 ctx
.fillStyle
= 'rgb(0,255,0)';
153 ctx
.fill(path
, 'nonzero');
154 isPixel(ctx
, 50, 50, [0, 255, 0, 255], 5);
156 ctx
.fillStyle
= 'rgb(255,0,0)';
157 ctx
.fillRect(0, 0, 100, 100);
158 ctx
.fillStyle
= 'rgb(0,255,0)';
159 ctx
.fill(path
, 'evenodd');
160 isPixel(ctx
, 50, 50, [255, 0, 0, 255], 5);
164 <p>Canvas test: test_isPointInPath_canvas
</p>
165 <canvas id=
"c5" class=
"output" width=
"100" height=
"100">+
167 <script type=
"text/javascript">
169 function shouldThrow(ctx
, s
) {
172 // eslint-disable-next-line no-eval
180 function shouldBeTrue(ctx
, path
, s
) {
181 // eslint-disable-next-line no-eval
185 function shouldBeFalse(ctx
, path
, s
) {
186 // eslint-disable-next-line no-eval
191 function test_isPointInPath_canvas() {
192 var c
= document
.getElementById("c5");
193 var ctx
= c
.getContext("2d");
195 var path
= new Path2D();
196 path
.rect(0, 0, 100, 100);
197 path
.rect(25, 25, 50, 50);
198 shouldBeTrue(ctx
, path
, "ctx.isPointInPath(path, 50, 50)");
199 shouldBeFalse(ctx
, path
, "ctx.isPointInPath(path, NaN, 50)");
200 shouldBeFalse(ctx
, path
, "ctx.isPointInPath(path, 50, NaN)");
203 path
.rect(0, 0, 100, 100);
204 path
.rect(25, 25, 50, 50);
205 shouldBeTrue(ctx
, path
, "ctx.isPointInPath(path, 50, 50, 'nonzero')");
208 path
.rect(0, 0, 100, 100);
209 path
.rect(25, 25, 50, 50);
210 shouldBeFalse(ctx
, path
, "ctx.isPointInPath(path, 50, 50, 'evenodd')");
212 shouldThrow(ctx
, "ctx.isPointInPath(null, 50, 50)");
213 shouldThrow(ctx
, "ctx.isPointInPath(null, 50, 50, 'nonzero')");
214 shouldThrow(ctx
, "ctx.isPointInPath(null, 50, 50, 'evenodd')");
215 shouldThrow(ctx
, "ctx.isPointInPath(path, 50, 50)");
216 shouldThrow(ctx
, "ctx.isPointInPath(path, 50, 50, 'nonzero')");
217 shouldThrow(ctx
, "ctx.isPointInPath(path, 50, 50, 'evenodd')");
219 shouldThrow(ctx
, "ctx.isPointInPath([], 50, 50)");
220 shouldThrow(ctx
, "ctx.isPointInPath([], 50, 50, 'nonzero')");
221 shouldThrow(ctx
, "ctx.isPointInPath([], 50, 50, 'evenodd')");
222 shouldThrow(ctx
, "ctx.isPointInPath({}, 50, 50)");
223 shouldThrow(ctx
, "ctx.isPointInPath({}, 50, 50, 'nonzero')");
224 shouldThrow(ctx
, "ctx.isPointInPath({}, 50, 50, 'evenodd')");
228 <p>Canvas test: test_isPointInStroke_canvas
</p>
229 <canvas id=
"c6" class=
"output" width=
"100" height=
"100">+
231 <script type=
"text/javascript">
233 function test_isPointInStroke_canvas() {
234 var c
= document
.getElementById("c6");
235 var ctx
= c
.getContext("2d");
237 ctx
.strokeStyle
= '#0ff';
239 var path
= new Path2D();
240 path
.rect(20,20,100,100);
242 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,20,20)");
243 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,120,20)");
244 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,20,120)");
245 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,120,120)");
246 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,70,20)");
247 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,20,70)");
248 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,120,70)");
249 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,70,120)");
250 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,22,22)");
251 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,118,22)");
252 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,22,118)");
253 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,118,118)");
254 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,70,18)");
255 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,122,70)");
256 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,70,122)");
257 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,18,70)");
258 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,NaN,122)");
259 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,18,NaN)");
261 shouldThrow(ctx
, "ctx.isPointInStroke(null,70,20)");
262 shouldThrow(ctx
, "ctx.isPointInStroke([],20,70)");
263 shouldThrow(ctx
, "ctx.isPointInStroke({},120,70)");
266 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,22,22)");
267 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,118,22)");
268 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,22,118)");
269 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,118,118)");
270 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,70,18)");
271 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,122,70)");
272 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,70,122)");
273 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,18,70)");
274 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,26,70)");
275 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,70,26)");
276 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,70,114)");
277 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,114,70)");
283 ctx
.lineJoin
= "bevel";
284 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,113,20)");
286 ctx
.miterLimit
= 40.0;
287 ctx
.lineJoin
= "miter";
288 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,113,20)");
290 ctx
.miterLimit
= 2.0;
291 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,113,20)");
296 ctx
.lineCap
= "butt";
297 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,112,10)");
299 ctx
.lineCap
= "round";
300 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,112,10)");
301 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,117,10)");
303 ctx
.lineCap
= "square";
304 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,112,10)");
305 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,117,10)");
307 ctx
.lineCap
= "butt";
308 ctx
.setLineDash([10,10]);
309 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,15,10)");
310 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,25,10)");
311 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,35,10)");
313 ctx
.lineDashOffset
= 10;
314 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,15,10)");
315 shouldBeTrue(ctx
, path
, "ctx.isPointInStroke(path,25,10)");
316 shouldBeFalse(ctx
, path
, "ctx.isPointInStroke(path,35,10)");
320 <p>Canvas test: test_pathconstructor_canvas
</p>
321 <canvas id=
"c7" class=
"output" width=
"200" height=
"100">+
323 <script type=
"text/javascript">
325 function test_pathconstructor_canvas() {
326 var c
= document
.getElementById("c7");
327 var ctx
= c
.getContext("2d");
329 var p
= new Path2D("M100,0L200,0L200,100L100,100z");
330 ctx
.fillStyle
= 'blue';
332 isPixel(ctx
, 105, 5, [0, 0, 255, 255], 0);
333 isPixel(ctx
, 5, 5, [0, 0, 0, 0], 0);
335 // copy constructor. This should not crash.
336 var p1
= new Path2D();
337 var _p2
= new Path2D(p1
);
338 p1
.arcTo(0, 0, 1, 1, 2);
342 <p>Canvas test: test_addpath_canvas
</p>
343 <canvas id=
"c8" class=
"output" width=
"200" height=
"200">+
345 <script type=
"text/javascript">
347 function test_addpath_canvas() {
348 var c
= document
.getElementById("c8");
349 var ctx
= c
.getContext("2d");
351 var p1
= new Path2D();
352 p1
.rect(0,0,100,100);
353 var p2
= new Path2D();
354 p2
.rect(0,100,100,100);
355 var m
= ctx
.currentTransform
;
357 ctx
.fillStyle
= 'yellow';
359 isPixel(ctx
, 0, 100, [255, 255, 0, 255], 0);
361 ctx
.clearRect(0,0,200,200);
364 var p3
= new Path2D();
365 p3
.rect(0,0,100,100);
366 var p4
= new Path2D();
367 p4
.rect(0,100,100,100);
368 var m
= document
.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGMatrix();
371 m
.e
= 100; m
.f
= -100;
373 ctx
.fillStyle
= 'yellow';
375 isPixel(ctx
, 50, 50, [255, 255, 0, 255], 0);
376 isPixel(ctx
, 150, 150, [0, 0, 0, 0], 0);
378 var p5
= new Path2D();
379 p5
.rect(0,0,100,100);
380 shouldThrow(ctx
, "p5.addPath(null, m)");
381 shouldThrow(ctx
, "p5.addPath([], m)");
382 shouldThrow(ctx
, "p5.addPath({}, m)");
390 function runTests() {
392 test_drawClipPath_canvas();
394 ok(false, "unexpected exception thrown in: test_drawClipPath_canvas");
398 test_drawFillPath_canvas();
400 ok(false, "unexpected exception thrown in: test_drawFillPath_canvas");
404 test_drawStrokePath_canvas();
406 ok(false, "unexpected exception thrown in: test_drawStrokePath_canvas");
412 ok(false, "unexpected exception thrown in: test_large_canvas");
416 test_isPointInPath_canvas();
418 ok(false, "unexpected exception thrown in: test_isPointInPath_canvas");
422 test_isPointInStroke_canvas();
424 ok(false, "unexpected exception thrown in: test_isPointInStroke_canvas");
428 test_pathconstructor_canvas();
430 ok(false, "unexpected exception thrown in: test_pathconstructor_canvas");
434 test_addpath_canvas();
436 ok(false, "unexpected exception thrown in: test_addpath_canvas");
442 addLoadEvent(function() {
443 SpecialPowers
.pushPrefEnv({"set":[["canvas.path.enabled", true]]}, runTests
);
446 // Don't leak the world via the Path2D reference to its window.
448 window
.p
= new Path2D();