Bug 1935611 - Fix libyuv/libpng link failed for loongarch64. r=glandium,tnikkel,ng
[gecko.git] / dom / canvas / test / test_canvas_path.html
blobbd10376bbb5d079d0679406a2cb487765f56f3fc
1 <!DOCTYPE HTML>
2 <title>Canvas Tests</title>
3 <script src="/tests/SimpleTest/SimpleTest.js"></script>
4 <link rel="stylesheet" href="/tests/SimpleTest/test.css">
5 <body>
6 <script>
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],
17 pg = pixel.data[1],
18 pb = pixel.data[2],
19 pa = pixel.data[3];
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);
26 </script>
28 <p>Canvas test: test_drawClipPath_canvas</p>
29 <canvas id="c1" class="output" width="100" height="100">+
30 </canvas>
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)';
41 ctx.beginPath();
42 ctx.fillRect(0, 0, 100, 100);
43 ctx.fillStyle = 'rgb(0,255,0)';
44 ctx.save();
45 ctx.clip(path);
47 ctx.fillRect(0, 0, 100, 100);
48 isPixel(ctx, 50, 50, [0, 255, 0, 255], 5);
49 ctx.restore();
51 ctx.fillStyle = 'rgb(255,0,0)';
52 ctx.beginPath();
53 ctx.fillRect(0, 0, 100, 100);
54 ctx.fillStyle = 'rgb(0,255,0)';
55 ctx.save();
56 ctx.clip(path, 'nonzero');
58 ctx.fillRect(0, 0, 100, 100);
59 isPixel(ctx, 50, 50, [0, 255, 0, 255], 5);
60 ctx.restore();
62 ctx.fillStyle = 'rgb(255,0,0)';
63 ctx.beginPath();
64 ctx.fillRect(0, 0, 100, 100);
65 ctx.fillStyle = 'rgb(0,255,0)';
66 ctx.save();
67 ctx.clip(path, 'evenodd');
69 ctx.fillRect(0, 0, 100, 100);
70 isPixel(ctx, 50, 50, [255, 0, 0, 255], 5);
71 ctx.restore();
73 </script>
75 <p>Canvas test: test_drawFillPath_canvas</p>
76 <canvas id="c2" class="output" width="100" height="100">+
77 </canvas>
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)';
90 ctx.fill(path);
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);
105 </script>
107 <p>Canvas test: test_drawStrokePath_canvas</p>
108 <canvas id="c3" class="output" width="100" height="100">+
109 </canvas>
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)';
122 ctx.lineWidth = 5;
123 ctx.stroke(path);
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);
128 </script>
130 <p>Canvas test: test_large_canvas</p>
131 <canvas id="c4" class="output" width="10000" height="100">+
132 </canvas>
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)';
147 ctx.fill(path);
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);
162 </script>
164 <p>Canvas test: test_isPointInPath_canvas</p>
165 <canvas id="c5" class="output" width="100" height="100">+
166 </canvas>
167 <script type="text/javascript">
169 function shouldThrow(ctx, s) {
170 var _ok = false;
171 try {
172 // eslint-disable-next-line no-eval
173 eval(s);
174 } catch(e) {
175 _ok = true;
177 ok(_ok, s);
180 function shouldBeTrue(ctx, path, s) {
181 // eslint-disable-next-line no-eval
182 var _ok = eval(s);
183 ok(_ok, s);
185 function shouldBeFalse(ctx, path, s) {
186 // eslint-disable-next-line no-eval
187 var _ok = !eval(s);
188 ok(_ok, s);
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)");
202 path = new Path2D();
203 path.rect(0, 0, 100, 100);
204 path.rect(25, 25, 50, 50);
205 shouldBeTrue(ctx, path, "ctx.isPointInPath(path, 50, 50, 'nonzero')");
207 path = new Path2D();
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')");
226 </script>
228 <p>Canvas test: test_isPointInStroke_canvas</p>
229 <canvas id="c6" class="output" width="100" height="100">+
230 </canvas>
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)");
265 ctx.lineWidth = 10;
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)");
279 path = new Path2D();
280 path.moveTo(10,10);
281 path.lineTo(110,20);
282 path.lineTo(10,30);
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)");
293 path = new Path2D();
294 path.moveTo(10,10);
295 path.lineTo(110,10);
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)");
318 </script>
320 <p>Canvas test: test_pathconstructor_canvas</p>
321 <canvas id="c7" class="output" width="200" height="100">+
322 </canvas>
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';
331 ctx.fill(p);
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);
340 </script>
342 <p>Canvas test: test_addpath_canvas</p>
343 <canvas id="c8" class="output" width="200" height="200">+
344 </canvas>
345 <script type="text/javascript">
347 function test_addpath_canvas() {
348 var c = document.getElementById("c8");
349 var ctx = c.getContext("2d");
350 ctx.beginPath();
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;
356 p1.addPath(p2, m);
357 ctx.fillStyle = 'yellow';
358 ctx.fill(p1);
359 isPixel(ctx, 0, 100, [255, 255, 0, 255], 0);
361 ctx.clearRect(0,0,200,200);
363 ctx.beginPath();
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();
369 m.a = 1; m.b = 0;
370 m.c = 0; m.d = 1;
371 m.e = 100; m.f = -100;
372 p3.addPath(p4, m);
373 ctx.fillStyle = 'yellow';
374 ctx.fill(p3);
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)");
384 p5 = p5.addPath(p5);
386 </script>
388 <script>
390 function runTests() {
391 try {
392 test_drawClipPath_canvas();
393 } catch(e) {
394 ok(false, "unexpected exception thrown in: test_drawClipPath_canvas");
395 throw e;
397 try {
398 test_drawFillPath_canvas();
399 } catch(e) {
400 ok(false, "unexpected exception thrown in: test_drawFillPath_canvas");
401 throw e;
403 try {
404 test_drawStrokePath_canvas();
405 } catch(e) {
406 ok(false, "unexpected exception thrown in: test_drawStrokePath_canvas");
407 throw e;
409 try {
410 test_large_canvas();
411 } catch(e) {
412 ok(false, "unexpected exception thrown in: test_large_canvas");
413 throw e;
415 try {
416 test_isPointInPath_canvas();
417 } catch(e) {
418 ok(false, "unexpected exception thrown in: test_isPointInPath_canvas");
419 throw e;
421 try {
422 test_isPointInStroke_canvas();
423 } catch(e) {
424 ok(false, "unexpected exception thrown in: test_isPointInStroke_canvas");
425 throw e;
427 try {
428 test_pathconstructor_canvas();
429 } catch(e) {
430 ok(false, "unexpected exception thrown in: test_pathconstructor_canvas");
431 throw e;
433 try {
434 test_addpath_canvas();
435 } catch(e) {
436 ok(false, "unexpected exception thrown in: test_addpath_canvas");
437 throw e;
439 SimpleTest.finish();
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.
447 document.all;
448 window.p = new Path2D();
450 </script>