Bug 1773348 [wpt PR 34351] - Fix 'colour' -> 'color' spelling in WPT Canvas tests...
[gecko.git] / testing / web-platform / tests / html / canvas / tools / yaml / element / fill-and-stroke-styles.yaml
blob88a36119d4127907a3f4dc494e9b28349b1a1929
1 - name: 2d.fillStyle.parse.current.basic
2   desc: currentColor is computed from the canvas element
3   testing:
4   - 2d.colors.parse
5   - 2d.currentColor.onset
6   code: |
7     canvas.setAttribute('style', 'color: #0f0');
8     ctx.fillStyle = '#f00';
9     ctx.fillStyle = 'currentColor';
10     ctx.fillRect(0, 0, 100, 50);
11     @assert pixel 50,25 == 0,255,0,255;
12   expected: green
14 - name: 2d.fillStyle.parse.current.changed
15   desc: currentColor is computed when the attribute is set, not when it is painted
16   testing:
17   - 2d.colors.parse
18   - 2d.currentColor.onset
19   code: |
20     canvas.setAttribute('style', 'color: #0f0');
21     ctx.fillStyle = '#f00';
22     ctx.fillStyle = 'currentColor';
23     canvas.setAttribute('style', 'color: #f00');
24     ctx.fillRect(0, 0, 100, 50);
25     @assert pixel 50,25 == 0,255,0,255;
26   expected: green
28 - name: 2d.fillStyle.parse.current.removed
29   desc: currentColor is solid black when the canvas element is not in a document
30   testing:
31   - 2d.colors.parse
32   - 2d.currentColor.outofdoc
33   code: |
34     // Try not to let it undetectably incorrectly pick up opaque-black
35     // from other parts of the document:
36     document.body.parentNode.setAttribute('style', 'color: #f00');
37     document.body.setAttribute('style', 'color: #f00');
38     canvas.setAttribute('style', 'color: #f00');
40     var canvas2 = document.createElement('canvas');
41     var ctx2 = canvas2.getContext('2d');
42     ctx2.fillStyle = '#f00';
43     ctx2.fillStyle = 'currentColor';
44     ctx2.fillRect(0, 0, 100, 50);
45     ctx.drawImage(canvas2, 0, 0);
47     document.body.parentNode.removeAttribute('style');
48     document.body.removeAttribute('style');
50     @assert pixel 50,25 == 0,0,0,255;
51   expected: |
52     size 100 50
53     cr.set_source_rgb(0, 0, 0)
54     cr.rectangle(0, 0, 100, 50)
55     cr.fill()
57 - name: 2d.fillStyle.invalidstring
58   testing:
59   - 2d.colors.invalidstring
60   code: |
61     ctx.fillStyle = '#f00';
62     ctx.fillRect(0, 0, 100, 50);
63     ctx.fillStyle = '#0f0';
64     ctx.fillStyle = 'invalid';
65     ctx.fillRect(0, 0, 100, 50);
66     @assert pixel 50,25 == 0,255,0,255;
67   expected: green
69 - name: 2d.fillStyle.invalidtype
70   testing:
71   - 2d.colors.invalidtype
72   code: |
73     ctx.fillStyle = '#f00';
74     ctx.fillRect(0, 0, 100, 50);
75     ctx.fillStyle = '#0f0';
76     ctx.fillStyle = null;
77     ctx.fillRect(0, 0, 100, 50);
78     @assert pixel 50,25 == 0,255,0,255;
79   expected: green
81 - name: 2d.fillStyle.get.solid
82   testing:
83   - 2d.colors.getcolor
84   - 2d.serializecolor.solid
85   code: |
86     ctx.fillStyle = '#fa0';
87     @assert ctx.fillStyle === '#ffaa00';
89 - name: 2d.fillStyle.get.semitransparent
90   testing:
91   - 2d.colors.getcolor
92   - 2d.serializecolor.transparent
93   code: |
94     ctx.fillStyle = 'rgba(255,255,255,0.45)';
95     @assert ctx.fillStyle =~ /^rgba\(255, 255, 255, 0\.4\d+\)$/;
97 - name: 2d.fillStyle.get.halftransparent
98   testing:
99   - 2d.colors.getcolor
100   - 2d.serializecolor.transparent
101   code: |
102     ctx.fillStyle = 'rgba(255,255,255,0.5)';
103     @assert ctx.fillStyle === 'rgba(255, 255, 255, 0.5)';
105 - name: 2d.fillStyle.get.transparent
106   testing:
107   - 2d.colors.getcolor
108   - 2d.serializecolor.transparent
109   code: |
110     ctx.fillStyle = 'rgba(0,0,0,0)';
111     @assert ctx.fillStyle === 'rgba(0, 0, 0, 0)';
113 - name: 2d.fillStyle.default
114   testing:
115   - 2d.colors.default
116   code: |
117     @assert ctx.fillStyle === '#000000';
119 - name: 2d.fillStyle.toStringFunctionCallback
120   desc: Passing a function in to ctx.fillStyle or ctx.strokeStyle with a toString callback works as specified
121   testing:
122     2d.colors.toStringFunctionCallback
123   code: |
124     ctx.fillStyle = { toString: function() { return "#008000"; } };
125     @assert ctx.fillStyle === "#008000";
126     ctx.fillStyle = {};
127     @assert ctx.fillStyle === "#008000";
128     ctx.fillStyle = 800000;
129     @assert ctx.fillStyle === "#008000";
130     @assert throws TypeError ctx.fillStyle = { toString: function() { throw new TypeError; } };
131     ctx.strokeStyle = { toString: function() { return "#008000"; } };
132     @assert ctx.strokeStyle === "#008000";
133     ctx.strokeStyle = {};
134     @assert ctx.strokeStyle === "#008000";
135     ctx.strokeStyle = 800000;
136     @assert ctx.strokeStyle === "#008000";
137     @assert throws TypeError ctx.strokeStyle = { toString: function() { throw new TypeError; } };
139 - name: 2d.strokeStyle.default
140   testing:
141   - 2d.colors.default
142   code: |
143     @assert ctx.strokeStyle === '#000000';
146 - name: 2d.gradient.object.type
147   desc: window.CanvasGradient exists and has the right properties
148   testing:
149   - 2d.canvasGradient.type
150   notes: &bindings Defined in "Web IDL" (draft)
151   code: |
152     @assert window.CanvasGradient !== undefined;
153     @assert window.CanvasGradient.prototype.addColorStop !== undefined;
155 - name: 2d.gradient.object.return
156   desc: createLinearGradient() and createRadialGradient() returns objects implementing
157     CanvasGradient
158   testing:
159   - 2d.gradient.linear.return
160   - 2d.gradient.radial.return
161   code: |
162     window.CanvasGradient.prototype.thisImplementsCanvasGradient = true;
164     var g1 = ctx.createLinearGradient(0, 0, 100, 0);
165     @assert g1.addColorStop !== undefined;
166     @assert g1.thisImplementsCanvasGradient === true;
168     var g2 = ctx.createRadialGradient(0, 0, 10, 0, 0, 20);
169     @assert g2.addColorStop !== undefined;
170     @assert g2.thisImplementsCanvasGradient === true;
172 - name: 2d.gradient.interpolate.solid
173   testing:
174   - 2d.gradient.interpolate.linear
175   code: |
176     var g = ctx.createLinearGradient(0, 0, 100, 0);
177     g.addColorStop(0, '#0f0');
178     g.addColorStop(1, '#0f0');
179     ctx.fillStyle = g;
180     ctx.fillRect(0, 0, 100, 50);
181     @assert pixel 50,25 == 0,255,0,255;
182   expected: green
184 - name: 2d.gradient.interpolate.color
185   testing:
186   - 2d.gradient.interpolate.linear
187   code: |
188     var g = ctx.createLinearGradient(0, 0, 100, 0);
189     g.addColorStop(0, '#ff0');
190     g.addColorStop(1, '#00f');
191     ctx.fillStyle = g;
192     ctx.fillRect(0, 0, 100, 50);
193     @assert pixel 25,25 ==~ 191,191,63,255 +/- 3;
194     @assert pixel 50,25 ==~ 127,127,127,255 +/- 3;
195     @assert pixel 75,25 ==~ 63,63,191,255 +/- 3;
196   expected: |
197     size 100 50
198     g = cairo.LinearGradient(0, 0, 100, 0)
199     g.add_color_stop_rgb(0, 1,1,0)
200     g.add_color_stop_rgb(1, 0,0,1)
201     cr.set_source(g)
202     cr.rectangle(0, 0, 100, 50)
203     cr.fill()
205 - name: 2d.gradient.interpolate.alpha
206   testing:
207   - 2d.gradient.interpolate.linear
208   code: |
209     ctx.fillStyle = '#ff0';
210     ctx.fillRect(0, 0, 100, 50);
211     var g = ctx.createLinearGradient(0, 0, 100, 0);
212     g.addColorStop(0, 'rgba(0,0,255, 0)');
213     g.addColorStop(1, 'rgba(0,0,255, 1)');
214     ctx.fillStyle = g;
215     ctx.fillRect(0, 0, 100, 50);
216     @assert pixel 25,25 ==~ 191,191,63,255 +/- 3;
217     @assert pixel 50,25 ==~ 127,127,127,255 +/- 3;
218     @assert pixel 75,25 ==~ 63,63,191,255 +/- 3;
219   expected: |
220     size 100 50
221     g = cairo.LinearGradient(0, 0, 100, 0)
222     g.add_color_stop_rgb(0, 1,1,0)
223     g.add_color_stop_rgb(1, 0,0,1)
224     cr.set_source(g)
225     cr.rectangle(0, 0, 100, 50)
226     cr.fill()
228 - name: 2d.gradient.interpolate.coloralpha
229   testing:
230   - 2d.gradient.interpolate.alpha
231   code: |
232     var g = ctx.createLinearGradient(0, 0, 100, 0);
233     g.addColorStop(0, 'rgba(255,255,0, 0)');
234     g.addColorStop(1, 'rgba(0,0,255, 1)');
235     ctx.fillStyle = g;
236     ctx.fillRect(0, 0, 100, 50);
237     @assert pixel 25,25 ==~ 190,190,65,65 +/- 3;
238     @assert pixel 50,25 ==~ 126,126,128,128 +/- 3;
239     @assert pixel 75,25 ==~ 62,62,192,192 +/- 3;
240   expected: |
241     size 100 50
242     g = cairo.LinearGradient(0, 0, 100, 0)
243     g.add_color_stop_rgba(0, 1,1,0, 0)
244     g.add_color_stop_rgba(1, 0,0,1, 1)
245     cr.set_source(g)
246     cr.rectangle(0, 0, 100, 50)
247     cr.fill()
249 - name: 2d.gradient.interpolate.outside
250   testing:
251   - 2d.gradient.outside.first
252   - 2d.gradient.outside.last
253   code: |
254     ctx.fillStyle = '#f00';
255     ctx.fillRect(0, 0, 100, 50);
257     var g = ctx.createLinearGradient(25, 0, 75, 0);
258     g.addColorStop(0.4, '#0f0');
259     g.addColorStop(0.6, '#0f0');
261     ctx.fillStyle = g;
262     ctx.fillRect(0, 0, 100, 50);
263     @assert pixel 20,25 ==~ 0,255,0,255;
264     @assert pixel 50,25 ==~ 0,255,0,255;
265     @assert pixel 80,25 ==~ 0,255,0,255;
266   expected: green
268 - name: 2d.gradient.interpolate.zerosize.fill
269   testing:
270   - 2d.gradient.linear.zerosize
271   code: |
272     ctx.fillStyle = '#0f0';
273     ctx.fillRect(0, 0, 100, 50);
275     var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
276     g.addColorStop(0, '#f00');
277     g.addColorStop(1, '#f00');
278     ctx.fillStyle = g;
279     ctx.rect(0, 0, 100, 50);
280     ctx.fill();
281     @assert pixel 40,20 == 0,255,0,255;
282   expected: green
284 - name: 2d.gradient.interpolate.zerosize.stroke
285   testing:
286   - 2d.gradient.linear.zerosize
287   code: |
288     ctx.fillStyle = '#0f0';
289     ctx.fillRect(0, 0, 100, 50);
291     var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
292     g.addColorStop(0, '#f00');
293     g.addColorStop(1, '#f00');
294     ctx.strokeStyle = g;
295     ctx.rect(20, 20, 60, 10);
296     ctx.stroke();
297     @assert pixel 19,19 == 0,255,0,255;
298     @assert pixel 20,19 == 0,255,0,255;
299     @assert pixel 21,19 == 0,255,0,255;
300     @assert pixel 19,20 == 0,255,0,255;
301     @assert pixel 20,20 == 0,255,0,255;
302     @assert pixel 21,20 == 0,255,0,255;
303     @assert pixel 19,21 == 0,255,0,255;
304     @assert pixel 20,21 == 0,255,0,255;
305     @assert pixel 21,21 == 0,255,0,255;
306   expected: green
308 - name: 2d.gradient.interpolate.zerosize.fillRect
309   testing:
310   - 2d.gradient.linear.zerosize
311   code: |
312     ctx.fillStyle = '#0f0';
313     ctx.fillRect(0, 0, 100, 50);
315     var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
316     g.addColorStop(0, '#f00');
317     g.addColorStop(1, '#f00');
318     ctx.fillStyle = g;
319     ctx.fillRect(0, 0, 100, 50);
320     @assert pixel 40,20 == 0,255,0,255; @moz-todo
321   expected: green
323 - name: 2d.gradient.interpolate.zerosize.strokeRect
324   testing:
325   - 2d.gradient.linear.zerosize
326   code: |
327     ctx.fillStyle = '#0f0';
328     ctx.fillRect(0, 0, 100, 50);
330     var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
331     g.addColorStop(0, '#f00');
332     g.addColorStop(1, '#f00');
333     ctx.strokeStyle = g;
334     ctx.strokeRect(20, 20, 60, 10);
335     @assert pixel 19,19 == 0,255,0,255;
336     @assert pixel 20,19 == 0,255,0,255;
337     @assert pixel 21,19 == 0,255,0,255;
338     @assert pixel 19,20 == 0,255,0,255;
339     @assert pixel 20,20 == 0,255,0,255;
340     @assert pixel 21,20 == 0,255,0,255;
341     @assert pixel 19,21 == 0,255,0,255;
342     @assert pixel 20,21 == 0,255,0,255;
343     @assert pixel 21,21 == 0,255,0,255;
344   expected: green
346 - name: 2d.gradient.interpolate.zerosize.fillText
347   testing:
348   - 2d.gradient.linear.zerosize
349   code: |
350     ctx.fillStyle = '#0f0';
351     ctx.fillRect(0, 0, 100, 50);
353     var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
354     g.addColorStop(0, '#f00');
355     g.addColorStop(1, '#f00');
356     ctx.fillStyle = g;
357     ctx.font = '100px sans-serif';
358     ctx.fillText("AA", 0, 50);
359     _assertGreen(ctx, 100, 50);
360   expected: green
362 - name: 2d.gradient.interpolate.zerosize.strokeText
363   testing:
364   - 2d.gradient.linear.zerosize
365   code: |
366     ctx.fillStyle = '#0f0';
367     ctx.fillRect(0, 0, 100, 50);
369     var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
370     g.addColorStop(0, '#f00');
371     g.addColorStop(1, '#f00');
372     ctx.strokeStyle = g;
373     ctx.font = '100px sans-serif';
374     ctx.strokeText("AA", 0, 50);
375     _assertGreen(ctx, 100, 50);
376   expected: green
379 - name: 2d.gradient.interpolate.vertical
380   testing:
381   - 2d.gradient.interpolate.linear
382   code: |
383     var g = ctx.createLinearGradient(0, 0, 0, 50);
384     g.addColorStop(0, '#ff0');
385     g.addColorStop(1, '#00f');
386     ctx.fillStyle = g;
387     ctx.fillRect(0, 0, 100, 50);
388     @assert pixel 50,12 ==~ 191,191,63,255 +/- 10;
389     @assert pixel 50,25 ==~ 127,127,127,255 +/- 5;
390     @assert pixel 50,37 ==~ 63,63,191,255 +/- 10;
391   expected: |
392     size 100 50
393     g = cairo.LinearGradient(0, 0, 0, 50)
394     g.add_color_stop_rgb(0, 1,1,0)
395     g.add_color_stop_rgb(1, 0,0,1)
396     cr.set_source(g)
397     cr.rectangle(0, 0, 100, 50)
398     cr.fill()
400 - name: 2d.gradient.interpolate.multiple
401   testing:
402   - 2d.gradient.interpolate.linear
403   code: |
404     canvas.width = 200;
405     var g = ctx.createLinearGradient(0, 0, 200, 0);
406     g.addColorStop(0, '#ff0');
407     g.addColorStop(0.5, '#0ff');
408     g.addColorStop(1, '#f0f');
409     ctx.fillStyle = g;
410     ctx.fillRect(0, 0, 200, 50);
411     @assert pixel 50,25 ==~ 127,255,127,255 +/- 3;
412     @assert pixel 100,25 ==~ 0,255,255,255 +/- 3;
413     @assert pixel 150,25 ==~ 127,127,255,255 +/- 3;
414   expected: |
415     size 200 50
416     g = cairo.LinearGradient(0, 0, 200, 0)
417     g.add_color_stop_rgb(0.0, 1,1,0)
418     g.add_color_stop_rgb(0.5, 0,1,1)
419     g.add_color_stop_rgb(1.0, 1,0,1)
420     cr.set_source(g)
421     cr.rectangle(0, 0, 200, 50)
422     cr.fill()
424 - name: 2d.gradient.interpolate.overlap
425   testing:
426   - 2d.gradient.interpolate.overlap
427   code: |
428     canvas.width = 200;
429     var g = ctx.createLinearGradient(0, 0, 200, 0);
430     g.addColorStop(0, '#f00');
431     g.addColorStop(0, '#ff0');
432     g.addColorStop(0.25, '#00f');
433     g.addColorStop(0.25, '#0f0');
434     g.addColorStop(0.25, '#0f0');
435     g.addColorStop(0.25, '#0f0');
436     g.addColorStop(0.25, '#ff0');
437     g.addColorStop(0.5, '#00f');
438     g.addColorStop(0.5, '#0f0');
439     g.addColorStop(0.75, '#00f');
440     g.addColorStop(0.75, '#f00');
441     g.addColorStop(0.75, '#ff0');
442     g.addColorStop(0.5, '#0f0');
443     g.addColorStop(0.5, '#0f0');
444     g.addColorStop(0.5, '#ff0');
445     g.addColorStop(1, '#00f');
446     ctx.fillStyle = g;
447     ctx.fillRect(0, 0, 200, 50);
448     @assert pixel 49,25 ==~ 0,0,255,255 +/- 16;
449     @assert pixel 51,25 ==~ 255,255,0,255 +/- 16;
450     @assert pixel 99,25 ==~ 0,0,255,255 +/- 16;
451     @assert pixel 101,25 ==~ 255,255,0,255 +/- 16;
452     @assert pixel 149,25 ==~ 0,0,255,255 +/- 16;
453     @assert pixel 151,25 ==~ 255,255,0,255 +/- 16;
454   expected: |
455     size 200 50
456     g = cairo.LinearGradient(0, 0, 50, 0)
457     g.add_color_stop_rgb(0, 1,1,0)
458     g.add_color_stop_rgb(1, 0,0,1)
459     cr.set_source(g)
460     cr.rectangle(0, 0, 50, 50)
461     cr.fill()
463     g = cairo.LinearGradient(50, 0, 100, 0)
464     g.add_color_stop_rgb(0, 1,1,0)
465     g.add_color_stop_rgb(1, 0,0,1)
466     cr.set_source(g)
467     cr.rectangle(50, 0, 50, 50)
468     cr.fill()
470     g = cairo.LinearGradient(100, 0, 150, 0)
471     g.add_color_stop_rgb(0, 1,1,0)
472     g.add_color_stop_rgb(1, 0,0,1)
473     cr.set_source(g)
474     cr.rectangle(100, 0, 50, 50)
475     cr.fill()
477     g = cairo.LinearGradient(150, 0, 200, 0)
478     g.add_color_stop_rgb(0, 1,1,0)
479     g.add_color_stop_rgb(1, 0,0,1)
480     cr.set_source(g)
481     cr.rectangle(150, 0, 50, 50)
482     cr.fill()
484 - name: 2d.gradient.interpolate.overlap2
485   testing:
486   - 2d.gradient.interpolate.overlap
487   code: |
488     var g = ctx.createLinearGradient(0, 0, 100, 0);
489     var ps = [ 0, 1/10, 1/4, 1/3, 1/2, 3/4, 1 ];
490     for (var p = 0; p < ps.length; ++p)
491     {
492             g.addColorStop(ps[p], '#0f0');
493             for (var i = 0; i < 15; ++i)
494                     g.addColorStop(ps[p], '#f00');
495             g.addColorStop(ps[p], '#0f0');
496     }
497     ctx.fillStyle = g;
498     ctx.fillRect(0, 0, 100, 50);
499     @assert pixel 1,25 == 0,255,0,255;
500     @assert pixel 30,25 == 0,255,0,255;
501     @assert pixel 40,25 == 0,255,0,255;
502     @assert pixel 60,25 == 0,255,0,255;
503     @assert pixel 80,25 == 0,255,0,255;
504   expected: green
506 - name: 2d.gradient.empty
507   testing:
508   - 2d.gradient.empty
509   code: |
510     ctx.fillStyle = '#0f0';
511     ctx.fillRect(0, 0, 100, 50);
512     var g = ctx.createLinearGradient(0, 0, 0, 50);
513     ctx.fillStyle = g;
514     ctx.fillRect(0, 0, 100, 50);
515     @assert pixel 50,25 ==~ 0,255,0,255;
516   expected: green
518 - name: 2d.gradient.object.update
519   testing:
520   - 2d.gradient.update
521   code: |
522     var g = ctx.createLinearGradient(-100, 0, 200, 0);
523     g.addColorStop(0, '#f00');
524     g.addColorStop(1, '#f00');
525     ctx.fillStyle = g;
526     g.addColorStop(0.1, '#0f0');
527     g.addColorStop(0.9, '#0f0');
528     ctx.fillRect(0, 0, 100, 50);
529     @assert pixel 50,25 ==~ 0,255,0,255;
530   expected: green
532 - name: 2d.gradient.object.compare
533   testing:
534   - 2d.gradient.object
535   code: |
536     var g1 = ctx.createLinearGradient(0, 0, 100, 0);
537     var g2 = ctx.createLinearGradient(0, 0, 100, 0);
538     @assert g1 !== g2;
539     ctx.fillStyle = g1;
540     @assert ctx.fillStyle === g1;
542 - name: 2d.gradient.object.crosscanvas
543   code: |
544     ctx.fillStyle = '#f00';
545     ctx.fillRect(0, 0, 100, 50);
546     var g = document.createElement('canvas').getContext('2d').createLinearGradient(0, 0, 100, 0);
547     g.addColorStop(0, '#0f0');
548     g.addColorStop(1, '#0f0');
549     ctx.fillStyle = g;
550     ctx.fillRect(0, 0, 100, 50);
551     @assert pixel 50,25 ==~ 0,255,0,255;
552   expected: green
554 - name: 2d.gradient.object.current
555   testing:
556   - 2d.currentColor.gradient
557   code: |
558     canvas.setAttribute('style', 'color: #f00');
560     ctx.fillStyle = '#f00';
561     ctx.fillRect(0, 0, 100, 50);
563     var g = ctx.createLinearGradient(0, 0, 100, 0);
564     g.addColorStop(0, 'currentColor');
565     g.addColorStop(1, 'currentColor');
566     ctx.fillStyle = g;
567     ctx.fillRect(0, 0, 100, 50);
568     @assert pixel 50,25 ==~ 0,0,0,255;
569   expected: |
570     size 100 50
571     cr.set_source_rgb(0, 0, 0)
572     cr.rectangle(0, 0, 100, 50)
573     cr.fill()
575 - name: 2d.gradient.object.invalidoffset
576   testing:
577   - 2d.gradient.invalidoffset
578   code: |
579     var g = ctx.createLinearGradient(0, 0, 100, 0);
580     @assert throws INDEX_SIZE_ERR g.addColorStop(-1, '#000');
581     @assert throws INDEX_SIZE_ERR g.addColorStop(2, '#000');
582     @assert throws TypeError g.addColorStop(Infinity, '#000');
583     @assert throws TypeError g.addColorStop(-Infinity, '#000');
584     @assert throws TypeError g.addColorStop(NaN, '#000');
586 - name: 2d.gradient.object.invalidcolor
587   testing:
588   - 2d.gradient.invalidcolor
589   code: |
590     var g = ctx.createLinearGradient(0, 0, 100, 0);
591     @assert throws SYNTAX_ERR g.addColorStop(0, "");
592     @assert throws SYNTAX_ERR g.addColorStop(0, 'rgb(NaN%, NaN%, NaN%)');
593     @assert throws SYNTAX_ERR g.addColorStop(0, 'null');
594     @assert throws SYNTAX_ERR g.addColorStop(0, 'undefined');
595     @assert throws SYNTAX_ERR g.addColorStop(0, null);
596     @assert throws SYNTAX_ERR g.addColorStop(0, undefined);
598     var g = ctx.createRadialGradient(0, 0, 0, 100, 0, 0);
599     @assert throws SYNTAX_ERR g.addColorStop(0, "");
600     @assert throws SYNTAX_ERR g.addColorStop(0, 'rgb(NaN%, NaN%, NaN%)');
601     @assert throws SYNTAX_ERR g.addColorStop(0, 'null');
602     @assert throws SYNTAX_ERR g.addColorStop(0, 'undefined');
603     @assert throws SYNTAX_ERR g.addColorStop(0, null);
604     @assert throws SYNTAX_ERR g.addColorStop(0, undefined);
607 - name: 2d.gradient.linear.nonfinite
608   desc: createLinearGradient() throws TypeError if arguments are not finite
609   notes: *bindings
610   testing:
611   - 2d.gradient.linear.nonfinite
612   code: |
613     @nonfinite @assert throws TypeError ctx.createLinearGradient(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>);
615 - name: 2d.gradient.linear.transform.1
616   desc: Linear gradient coordinates are relative to the coordinate space at the time
617     of filling
618   testing:
619   - 2d.gradient.linear.transform
620   code: |
621     var g = ctx.createLinearGradient(0, 0, 200, 0);
622     g.addColorStop(0, '#f00');
623     g.addColorStop(0.25, '#0f0');
624     g.addColorStop(0.75, '#0f0');
625     g.addColorStop(1, '#f00');
626     ctx.fillStyle = g;
627     ctx.translate(-50, 0);
628     ctx.fillRect(50, 0, 100, 50);
629     @assert pixel 25,25 == 0,255,0,255;
630     @assert pixel 50,25 == 0,255,0,255;
631     @assert pixel 75,25 == 0,255,0,255;
632   expected: green
634 - name: 2d.gradient.linear.transform.2
635   desc: Linear gradient coordinates are relative to the coordinate space at the time
636     of filling
637   testing:
638   - 2d.gradient.linear.transform
639   code: |
640     ctx.translate(100, 0);
641     var g = ctx.createLinearGradient(0, 0, 200, 0);
642     g.addColorStop(0, '#f00');
643     g.addColorStop(0.25, '#0f0');
644     g.addColorStop(0.75, '#0f0');
645     g.addColorStop(1, '#f00');
646     ctx.fillStyle = g;
647     ctx.translate(-150, 0);
648     ctx.fillRect(50, 0, 100, 50);
649     @assert pixel 25,25 == 0,255,0,255;
650     @assert pixel 50,25 == 0,255,0,255;
651     @assert pixel 75,25 == 0,255,0,255;
652   expected: green
654 - name: 2d.gradient.linear.transform.3
655   desc: Linear gradient transforms do not experience broken caching effects
656   testing:
657   - 2d.gradient.linear.transform
658   code: |
659     var g = ctx.createLinearGradient(0, 0, 200, 0);
660     g.addColorStop(0, '#f00');
661     g.addColorStop(0.25, '#0f0');
662     g.addColorStop(0.75, '#0f0');
663     g.addColorStop(1, '#f00');
664     ctx.fillStyle = g;
665     ctx.fillRect(0, 0, 100, 50);
666     ctx.translate(-50, 0);
667     ctx.fillRect(50, 0, 100, 50);
668     @assert pixel 25,25 == 0,255,0,255;
669     @assert pixel 50,25 == 0,255,0,255;
670     @assert pixel 75,25 == 0,255,0,255;
671   expected: green
673 - name: 2d.gradient.radial.negative
674   desc: createRadialGradient() throws INDEX_SIZE_ERR if either radius is negative
675   testing:
676   - 2d.gradient.radial.negative
677   code: |
678     @assert throws INDEX_SIZE_ERR ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1);
679     @assert throws INDEX_SIZE_ERR ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1);
680     @assert throws INDEX_SIZE_ERR ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1);
682 - name: 2d.gradient.radial.nonfinite
683   desc: createRadialGradient() throws TypeError if arguments are not finite
684   notes: *bindings
685   testing:
686   - 2d.gradient.radial.nonfinite
687   code: |
688     @nonfinite @assert throws TypeError ctx.createRadialGradient(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>);
690 - name: 2d.gradient.radial.inside1
691   testing:
692   - 2d.gradient.radial.rendering
693   code: |
694     ctx.fillStyle = '#f00';
695     ctx.fillRect(0, 0, 100, 50);
697     var g = ctx.createRadialGradient(50, 25, 100, 50, 25, 200);
698     g.addColorStop(0, '#0f0');
699     g.addColorStop(1, '#f00');
700     ctx.fillStyle = g;
701     ctx.fillRect(0, 0, 100, 50);
703     @assert pixel 1,1 == 0,255,0,255;
704     @assert pixel 50,1 == 0,255,0,255;
705     @assert pixel 98,1 == 0,255,0,255;
706     @assert pixel 1,25 == 0,255,0,255;
707     @assert pixel 50,25 == 0,255,0,255;
708     @assert pixel 98,25 == 0,255,0,255;
709     @assert pixel 1,48 == 0,255,0,255;
710     @assert pixel 50,48 == 0,255,0,255;
711     @assert pixel 98,48 == 0,255,0,255;
712   expected: green
714 - name: 2d.gradient.radial.inside2
715   testing:
716   - 2d.gradient.radial.rendering
717   code: |
718     ctx.fillStyle = '#f00';
719     ctx.fillRect(0, 0, 100, 50);
721     var g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100);
722     g.addColorStop(0, '#f00');
723     g.addColorStop(1, '#0f0');
724     ctx.fillStyle = g;
725     ctx.fillRect(0, 0, 100, 50);
727     @assert pixel 1,1 == 0,255,0,255;
728     @assert pixel 50,1 == 0,255,0,255;
729     @assert pixel 98,1 == 0,255,0,255;
730     @assert pixel 1,25 == 0,255,0,255;
731     @assert pixel 50,25 == 0,255,0,255;
732     @assert pixel 98,25 == 0,255,0,255;
733     @assert pixel 1,48 == 0,255,0,255;
734     @assert pixel 50,48 == 0,255,0,255;
735     @assert pixel 98,48 == 0,255,0,255;
736   expected: green
738 - name: 2d.gradient.radial.inside3
739   testing:
740   - 2d.gradient.radial.rendering
741   code: |
742     ctx.fillStyle = '#f00';
743     ctx.fillRect(0, 0, 100, 50);
745     var g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100);
746     g.addColorStop(0, '#f00');
747     g.addColorStop(0.993, '#f00');
748     g.addColorStop(1, '#0f0');
749     ctx.fillStyle = g;
750     ctx.fillRect(0, 0, 100, 50);
752     @assert pixel 1,1 == 0,255,0,255;
753     @assert pixel 50,1 == 0,255,0,255;
754     @assert pixel 98,1 == 0,255,0,255;
755     @assert pixel 1,25 == 0,255,0,255;
756     @assert pixel 50,25 == 0,255,0,255;
757     @assert pixel 98,25 == 0,255,0,255;
758     @assert pixel 1,48 == 0,255,0,255;
759     @assert pixel 50,48 == 0,255,0,255;
760     @assert pixel 98,48 == 0,255,0,255;
761   expected: green
763 - name: 2d.gradient.radial.outside1
764   testing:
765   - 2d.gradient.radial.rendering
766   code: |
767     ctx.fillStyle = '#f00';
768     ctx.fillRect(0, 0, 100, 50);
770     var g = ctx.createRadialGradient(200, 25, 10, 200, 25, 20);
771     g.addColorStop(0, '#f00');
772     g.addColorStop(1, '#0f0');
773     ctx.fillStyle = g;
774     ctx.fillRect(0, 0, 100, 50);
776     @assert pixel 1,1 == 0,255,0,255;
777     @assert pixel 50,1 == 0,255,0,255;
778     @assert pixel 98,1 == 0,255,0,255;
779     @assert pixel 1,25 == 0,255,0,255;
780     @assert pixel 50,25 == 0,255,0,255;
781     @assert pixel 98,25 == 0,255,0,255;
782     @assert pixel 1,48 == 0,255,0,255;
783     @assert pixel 50,48 == 0,255,0,255;
784     @assert pixel 98,48 == 0,255,0,255;
785   expected: green
787 - name: 2d.gradient.radial.outside2
788   testing:
789   - 2d.gradient.radial.rendering
790   code: |
791     ctx.fillStyle = '#f00';
792     ctx.fillRect(0, 0, 100, 50);
794     var g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
795     g.addColorStop(0, '#0f0');
796     g.addColorStop(1, '#f00');
797     ctx.fillStyle = g;
798     ctx.fillRect(0, 0, 100, 50);
800     @assert pixel 1,1 == 0,255,0,255;
801     @assert pixel 50,1 == 0,255,0,255;
802     @assert pixel 98,1 == 0,255,0,255;
803     @assert pixel 1,25 == 0,255,0,255;
804     @assert pixel 50,25 == 0,255,0,255;
805     @assert pixel 98,25 == 0,255,0,255;
806     @assert pixel 1,48 == 0,255,0,255;
807     @assert pixel 50,48 == 0,255,0,255;
808     @assert pixel 98,48 == 0,255,0,255;
809   expected: green
811 - name: 2d.gradient.radial.outside3
812   testing:
813   - 2d.gradient.radial.rendering
814   code: |
815     ctx.fillStyle = '#f00';
816     ctx.fillRect(0, 0, 100, 50);
818     var g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
819     g.addColorStop(0, '#0f0');
820     g.addColorStop(0.001, '#f00');
821     g.addColorStop(1, '#f00');
822     ctx.fillStyle = g;
823     ctx.fillRect(0, 0, 100, 50);
825     @assert pixel 1,1 == 0,255,0,255;
826     @assert pixel 50,1 == 0,255,0,255;
827     @assert pixel 98,1 == 0,255,0,255;
828     @assert pixel 1,25 == 0,255,0,255;
829     @assert pixel 50,25 == 0,255,0,255;
830     @assert pixel 98,25 == 0,255,0,255;
831     @assert pixel 1,48 == 0,255,0,255;
832     @assert pixel 50,48 == 0,255,0,255;
833     @assert pixel 98,48 == 0,255,0,255;
834   expected: green
836 - name: 2d.gradient.radial.touch1
837   testing:
838   - 2d.gradient.radial.rendering
839   code: |
840     ctx.fillStyle = '#0f0';
841     ctx.fillRect(0, 0, 100, 50);
843     var g = ctx.createRadialGradient(150, 25, 50, 200, 25, 100);
844     g.addColorStop(0, '#f00');
845     g.addColorStop(1, '#f00');
846     ctx.fillStyle = g;
847     ctx.fillRect(0, 0, 100, 50);
849     @assert pixel 1,1 == 0,255,0,255; @moz-todo
850     @assert pixel 50,1 == 0,255,0,255; @moz-todo
851     @assert pixel 98,1 == 0,255,0,255; @moz-todo
852     @assert pixel 1,25 == 0,255,0,255; @moz-todo
853     @assert pixel 50,25 == 0,255,0,255; @moz-todo
854     @assert pixel 98,25 == 0,255,0,255; @moz-todo
855     @assert pixel 1,48 == 0,255,0,255; @moz-todo
856     @assert pixel 50,48 == 0,255,0,255; @moz-todo
857     @assert pixel 98,48 == 0,255,0,255; @moz-todo
858   expected: green
860 - name: 2d.gradient.radial.touch2
861   testing:
862   - 2d.gradient.radial.rendering
863   code: |
864     ctx.fillStyle = '#f00';
865     ctx.fillRect(0, 0, 100, 50);
867     var g = ctx.createRadialGradient(-80, 25, 70, 0, 25, 150);
868     g.addColorStop(0, '#f00');
869     g.addColorStop(0.01, '#0f0');
870     g.addColorStop(0.99, '#0f0');
871     g.addColorStop(1, '#f00');
872     ctx.fillStyle = g;
873     ctx.fillRect(0, 0, 100, 50);
875     @assert pixel 1,1 == 0,255,0,255;
876     @assert pixel 50,1 == 0,255,0,255;
877     @assert pixel 98,1 == 0,255,0,255;
878     @assert pixel 1,25 == 0,255,0,255;
879     @assert pixel 50,25 == 0,255,0,255;
880     @assert pixel 98,25 == 0,255,0,255;
881     @assert pixel 1,48 == 0,255,0,255;
882     @assert pixel 50,48 == 0,255,0,255;
883     @assert pixel 98,48 == 0,255,0,255;
884   expected: green
886 - name: 2d.gradient.radial.touch3
887   testing:
888   - 2d.gradient.radial.rendering
889   code: |
890     ctx.fillStyle = '#0f0';
891     ctx.fillRect(0, 0, 100, 50);
893     var g = ctx.createRadialGradient(120, -15, 25, 140, -30, 50);
894     g.addColorStop(0, '#f00');
895     g.addColorStop(1, '#f00');
896     ctx.fillStyle = g;
897     ctx.fillRect(0, 0, 100, 50);
899     @assert pixel 1,1 == 0,255,0,255; @moz-todo
900     @assert pixel 50,1 == 0,255,0,255; @moz-todo
901     @assert pixel 98,1 == 0,255,0,255; @moz-todo
902     @assert pixel 1,25 == 0,255,0,255; @moz-todo
903     @assert pixel 50,25 == 0,255,0,255; @moz-todo
904     @assert pixel 98,25 == 0,255,0,255; @moz-todo
905     @assert pixel 1,48 == 0,255,0,255; @moz-todo
906     @assert pixel 50,48 == 0,255,0,255; @moz-todo
907     @assert pixel 98,48 == 0,255,0,255; @moz-todo
908   expected: green
910 - name: 2d.gradient.radial.equal
911   testing:
912   - 2d.gradient.radial.equal
913   code: |
914     ctx.fillStyle = '#0f0';
915     ctx.fillRect(0, 0, 100, 50);
917     var g = ctx.createRadialGradient(50, 25, 20, 50, 25, 20);
918     g.addColorStop(0, '#f00');
919     g.addColorStop(1, '#f00');
920     ctx.fillStyle = g;
921     ctx.fillRect(0, 0, 100, 50);
923     @assert pixel 1,1 == 0,255,0,255; @moz-todo
924     @assert pixel 50,1 == 0,255,0,255; @moz-todo
925     @assert pixel 98,1 == 0,255,0,255; @moz-todo
926     @assert pixel 1,25 == 0,255,0,255; @moz-todo
927     @assert pixel 50,25 == 0,255,0,255; @moz-todo
928     @assert pixel 98,25 == 0,255,0,255; @moz-todo
929     @assert pixel 1,48 == 0,255,0,255; @moz-todo
930     @assert pixel 50,48 == 0,255,0,255; @moz-todo
931     @assert pixel 98,48 == 0,255,0,255; @moz-todo
932   expected: green
934 - name: 2d.gradient.radial.cone.behind
935   testing:
936   - 2d.gradient.radial.rendering
937   code: |
938     ctx.fillStyle = '#0f0';
939     ctx.fillRect(0, 0, 100, 50);
941     var g = ctx.createRadialGradient(120, 25, 10, 211, 25, 100);
942     g.addColorStop(0, '#f00');
943     g.addColorStop(1, '#f00');
944     ctx.fillStyle = g;
945     ctx.fillRect(0, 0, 100, 50);
947     @assert pixel 1,1 == 0,255,0,255; @moz-todo
948     @assert pixel 50,1 == 0,255,0,255; @moz-todo
949     @assert pixel 98,1 == 0,255,0,255; @moz-todo
950     @assert pixel 1,25 == 0,255,0,255; @moz-todo
951     @assert pixel 50,25 == 0,255,0,255; @moz-todo
952     @assert pixel 98,25 == 0,255,0,255; @moz-todo
953     @assert pixel 1,48 == 0,255,0,255; @moz-todo
954     @assert pixel 50,48 == 0,255,0,255; @moz-todo
955     @assert pixel 98,48 == 0,255,0,255; @moz-todo
956   expected: green
958 - name: 2d.gradient.radial.cone.front
959   testing:
960   - 2d.gradient.radial.rendering
961   code: |
962     ctx.fillStyle = '#f00';
963     ctx.fillRect(0, 0, 100, 50);
965     var g = ctx.createRadialGradient(311, 25, 10, 210, 25, 100);
966     g.addColorStop(0, '#f00');
967     g.addColorStop(1, '#0f0');
968     ctx.fillStyle = g;
969     ctx.fillRect(0, 0, 100, 50);
971     @assert pixel 1,1 == 0,255,0,255;
972     @assert pixel 50,1 == 0,255,0,255;
973     @assert pixel 98,1 == 0,255,0,255;
974     @assert pixel 1,25 == 0,255,0,255;
975     @assert pixel 50,25 == 0,255,0,255;
976     @assert pixel 98,25 == 0,255,0,255;
977     @assert pixel 1,48 == 0,255,0,255;
978     @assert pixel 50,48 == 0,255,0,255;
979     @assert pixel 98,48 == 0,255,0,255;
980   expected: green
982 - name: 2d.gradient.radial.cone.bottom
983   testing:
984   - 2d.gradient.radial.rendering
985   code: |
986     ctx.fillStyle = '#f00';
987     ctx.fillRect(0, 0, 100, 50);
989     var g = ctx.createRadialGradient(210, 25, 100, 230, 25, 101);
990     g.addColorStop(0, '#0f0');
991     g.addColorStop(1, '#f00');
992     ctx.fillStyle = g;
993     ctx.fillRect(0, 0, 100, 50);
995     @assert pixel 1,1 == 0,255,0,255;
996     @assert pixel 50,1 == 0,255,0,255;
997     @assert pixel 98,1 == 0,255,0,255;
998     @assert pixel 1,25 == 0,255,0,255;
999     @assert pixel 50,25 == 0,255,0,255;
1000     @assert pixel 98,25 == 0,255,0,255;
1001     @assert pixel 1,48 == 0,255,0,255;
1002     @assert pixel 50,48 == 0,255,0,255;
1003     @assert pixel 98,48 == 0,255,0,255;
1004   expected: green
1006 - name: 2d.gradient.radial.cone.top
1007   testing:
1008   - 2d.gradient.radial.rendering
1009   code: |
1010     ctx.fillStyle = '#f00';
1011     ctx.fillRect(0, 0, 100, 50);
1013     var g = ctx.createRadialGradient(230, 25, 100, 100, 25, 101);
1014     g.addColorStop(0, '#f00');
1015     g.addColorStop(1, '#0f0');
1016     ctx.fillStyle = g;
1017     ctx.fillRect(0, 0, 100, 50);
1019     @assert pixel 1,1 == 0,255,0,255;
1020     @assert pixel 50,1 == 0,255,0,255;
1021     @assert pixel 98,1 == 0,255,0,255;
1022     @assert pixel 1,25 == 0,255,0,255;
1023     @assert pixel 50,25 == 0,255,0,255;
1024     @assert pixel 98,25 == 0,255,0,255;
1025     @assert pixel 1,48 == 0,255,0,255;
1026     @assert pixel 50,48 == 0,255,0,255;
1027     @assert pixel 98,48 == 0,255,0,255;
1028   expected: green
1030 - name: 2d.gradient.radial.cone.beside
1031   testing:
1032   - 2d.gradient.radial.rendering
1033   code: |
1034     ctx.fillStyle = '#0f0';
1035     ctx.fillRect(0, 0, 100, 50);
1037     var g = ctx.createRadialGradient(0, 100, 40, 100, 100, 50);
1038     g.addColorStop(0, '#f00');
1039     g.addColorStop(1, '#f00');
1040     ctx.fillStyle = g;
1041     ctx.fillRect(0, 0, 100, 50);
1043     @assert pixel 1,1 == 0,255,0,255; @moz-todo
1044     @assert pixel 50,1 == 0,255,0,255; @moz-todo
1045     @assert pixel 98,1 == 0,255,0,255; @moz-todo
1046     @assert pixel 1,25 == 0,255,0,255; @moz-todo
1047     @assert pixel 50,25 == 0,255,0,255; @moz-todo
1048     @assert pixel 98,25 == 0,255,0,255; @moz-todo
1049     @assert pixel 1,48 == 0,255,0,255; @moz-todo
1050     @assert pixel 50,48 == 0,255,0,255; @moz-todo
1051     @assert pixel 98,48 == 0,255,0,255; @moz-todo
1052   expected: green
1054 - name: 2d.gradient.radial.cone.cylinder
1055   testing:
1056   - 2d.gradient.radial.rendering
1057   code: |
1058     ctx.fillStyle = '#f00';
1059     ctx.fillRect(0, 0, 100, 50);
1061     var g = ctx.createRadialGradient(210, 25, 100, 230, 25, 100);
1062     g.addColorStop(0, '#0f0');
1063     g.addColorStop(1, '#f00');
1064     ctx.fillStyle = g;
1065     ctx.fillRect(0, 0, 100, 50);
1067     @assert pixel 1,1 == 0,255,0,255;
1068     @assert pixel 50,1 == 0,255,0,255;
1069     @assert pixel 98,1 == 0,255,0,255;
1070     @assert pixel 1,25 == 0,255,0,255;
1071     @assert pixel 50,25 == 0,255,0,255;
1072     @assert pixel 98,25 == 0,255,0,255;
1073     @assert pixel 1,48 == 0,255,0,255;
1074     @assert pixel 50,48 == 0,255,0,255;
1075     @assert pixel 98,48 == 0,255,0,255;
1076   expected: green
1078 - name: 2d.gradient.radial.cone.shape1
1079   testing:
1080   - 2d.gradient.radial.rendering
1081   code: |
1082     var tol = 1; // tolerance to avoid antialiasing artifacts
1084     ctx.fillStyle = '#0f0';
1085     ctx.fillRect(0, 0, 100, 50);
1087     ctx.fillStyle = '#f00';
1088     ctx.beginPath();
1089     ctx.moveTo(30+tol, 40);
1090     ctx.lineTo(110, -20+tol);
1091     ctx.lineTo(110, 100-tol);
1092     ctx.fill();
1094     var g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4);
1095     g.addColorStop(0, '#0f0');
1096     g.addColorStop(1, '#0f0');
1097     ctx.fillStyle = g;
1098     ctx.fillRect(0, 0, 100, 50);
1100     @assert pixel 1,1 == 0,255,0,255;
1101     @assert pixel 50,1 == 0,255,0,255;
1102     @assert pixel 98,1 == 0,255,0,255;
1103     @assert pixel 1,25 == 0,255,0,255;
1104     @assert pixel 50,25 == 0,255,0,255;
1105     @assert pixel 98,25 == 0,255,0,255;
1106     @assert pixel 1,48 == 0,255,0,255;
1107     @assert pixel 50,48 == 0,255,0,255;
1108     @assert pixel 98,48 == 0,255,0,255;
1109   expected: green
1111 - name: 2d.gradient.radial.cone.shape2
1112   testing:
1113   - 2d.gradient.radial.rendering
1114   code: |
1115     var tol = 1; // tolerance to avoid antialiasing artifacts
1117     ctx.fillStyle = '#0f0';
1118     ctx.fillRect(0, 0, 100, 50);
1120     var g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4);
1121     g.addColorStop(0, '#f00');
1122     g.addColorStop(1, '#f00');
1123     ctx.fillStyle = g;
1124     ctx.fillRect(0, 0, 100, 50);
1126     ctx.fillStyle = '#0f0';
1127     ctx.beginPath();
1128     ctx.moveTo(30-tol, 40);
1129     ctx.lineTo(110, -20-tol);
1130     ctx.lineTo(110, 100+tol);
1131     ctx.fill();
1133     @assert pixel 1,1 == 0,255,0,255; @moz-todo
1134     @assert pixel 50,1 == 0,255,0,255; @moz-todo
1135     @assert pixel 98,1 == 0,255,0,255;
1136     @assert pixel 1,25 == 0,255,0,255; @moz-todo
1137     @assert pixel 50,25 == 0,255,0,255;
1138     @assert pixel 98,25 == 0,255,0,255;
1139     @assert pixel 1,48 == 0,255,0,255; @moz-todo
1140     @assert pixel 50,48 == 0,255,0,255;
1141     @assert pixel 98,48 == 0,255,0,255;
1142   expected: green
1144 - name: 2d.gradient.radial.transform.1
1145   desc: Radial gradient coordinates are relative to the coordinate space at the time
1146     of filling
1147   testing:
1148   - 2d.gradient.radial.transform
1149   code: |
1150     var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
1151     g.addColorStop(0, '#0f0');
1152     g.addColorStop(0.5, '#0f0');
1153     g.addColorStop(0.51, '#f00');
1154     g.addColorStop(1, '#f00');
1155     ctx.fillStyle = g;
1156     ctx.translate(50, 25);
1157     ctx.scale(10, 10);
1158     ctx.fillRect(-5, -2.5, 10, 5);
1159     @assert pixel 25,25 == 0,255,0,255;
1160     @assert pixel 50,25 == 0,255,0,255;
1161     @assert pixel 75,25 == 0,255,0,255;
1162   expected: green
1164 - name: 2d.gradient.radial.transform.2
1165   desc: Radial gradient coordinates are relative to the coordinate space at the time
1166     of filling
1167   testing:
1168   - 2d.gradient.radial.transform
1169   code: |
1170     ctx.translate(100, 0);
1171     var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
1172     g.addColorStop(0, '#0f0');
1173     g.addColorStop(0.5, '#0f0');
1174     g.addColorStop(0.51, '#f00');
1175     g.addColorStop(1, '#f00');
1176     ctx.fillStyle = g;
1177     ctx.translate(-50, 25);
1178     ctx.scale(10, 10);
1179     ctx.fillRect(-5, -2.5, 10, 5);
1180     @assert pixel 25,25 == 0,255,0,255;
1181     @assert pixel 50,25 == 0,255,0,255;
1182     @assert pixel 75,25 == 0,255,0,255;
1183   expected: green
1185 - name: 2d.gradient.radial.transform.3
1186   desc: Radial gradient transforms do not experience broken caching effects
1187   testing:
1188   - 2d.gradient.radial.transform
1189   code: |
1190     var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
1191     g.addColorStop(0, '#0f0');
1192     g.addColorStop(0.5, '#0f0');
1193     g.addColorStop(0.51, '#f00');
1194     g.addColorStop(1, '#f00');
1195     ctx.fillStyle = g;
1196     ctx.fillRect(0, 0, 100, 50);
1197     ctx.translate(50, 25);
1198     ctx.scale(10, 10);
1199     ctx.fillRect(-5, -2.5, 10, 5);
1200     @assert pixel 25,25 == 0,255,0,255;
1201     @assert pixel 50,25 == 0,255,0,255;
1202     @assert pixel 75,25 == 0,255,0,255;
1203   expected: green
1205 - name: 2d.gradient.conic.positive.rotation
1206   desc: Conic gradient with positive rotation
1207   code: |
1208     const g = ctx.createConicGradient(3*Math.PI/2, 50, 25);
1209     // It's red in the upper right region and green on the lower left region
1210     g.addColorStop(0, "#f00");
1211     g.addColorStop(0.25, "#0f0");
1212     g.addColorStop(0.50, "#0f0");
1213     g.addColorStop(0.75, "#f00");
1214     ctx.fillStyle = g;
1215     ctx.fillRect(0, 0, 100, 50);
1216     @assert pixel 25,15 == 255,0,0,255;
1217     @assert pixel 75,40 == 0,255,0,255;
1218   expected: green
1220 - name: 2d.gradient.conic.negative.rotation
1221   desc: Conic gradient with negative rotation
1222   code: |
1223     const g = ctx.createConicGradient(-Math.PI/2, 50, 25);
1224     // It's red in the upper right region and green on the lower left region
1225     g.addColorStop(0, "#f00");
1226     g.addColorStop(0.25, "#0f0");
1227     g.addColorStop(0.50, "#0f0");
1228     g.addColorStop(0.75, "#f00");
1229     ctx.fillStyle = g;
1230     ctx.fillRect(0, 0, 100, 50);
1231     @assert pixel 25,15 == 255,0,0,255;
1232     @assert pixel 75,40 == 0,255,0,255;
1233   expected: green
1235 - name: 2d.gradient.conic.invalid.inputs
1236   desc: Conic gradient function with invalid inputs
1237   code: |
1238     @nonfinite @assert throws TypeError ctx.createConicGradient(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>);
1240     const g = ctx.createConicGradient(0, 0, 25);
1241     @nonfinite @assert throws TypeError g.addColorStop(<Infinity -Infinity NaN>, <'#f00'>);
1242     @nonfinite @assert throws SYNTAX_ERR g.addColorStop(<0>, <Infinity -Infinity NaN>);
1244 - name: 2d.pattern.basic.type
1245   testing:
1246   - 2d.pattern.return
1247   images:
1248   - green.png
1249   code: |
1250     @assert window.CanvasPattern !== undefined;
1252     window.CanvasPattern.prototype.thisImplementsCanvasPattern = true;
1254     var img = document.getElementById('green.png');
1255     var pattern = ctx.createPattern(img, 'no-repeat');
1256     @assert pattern.thisImplementsCanvasPattern;
1258 - name: 2d.pattern.basic.image
1259   testing:
1260   - 2d.pattern.painting
1261   images:
1262   - green.png
1263   code: |
1264     ctx.fillStyle = '#f00';
1265     ctx.fillRect(0, 0, 100, 50);
1266     var img = document.getElementById('green.png');
1267     var pattern = ctx.createPattern(img, 'no-repeat');
1268     ctx.fillStyle = pattern;
1269     ctx.fillRect(0, 0, 100, 50);
1271     @assert pixel 1,1 == 0,255,0,255;
1272     @assert pixel 98,1 == 0,255,0,255;
1273     @assert pixel 1,48 == 0,255,0,255;
1274     @assert pixel 98,48 == 0,255,0,255;
1275   expected: green
1277 - name: 2d.pattern.basic.canvas
1278   testing:
1279   - 2d.pattern.painting
1280   code: |
1281     ctx.fillStyle = '#f00';
1282     ctx.fillRect(0, 0, 100, 50);
1284     var canvas2 = document.createElement('canvas');
1285     canvas2.width = 100;
1286     canvas2.height = 50;
1287     var ctx2 = canvas2.getContext('2d');
1288     ctx2.fillStyle = '#0f0';
1289     ctx2.fillRect(0, 0, 100, 50);
1291     var pattern = ctx.createPattern(canvas2, 'no-repeat');
1292     ctx.fillStyle = pattern;
1293     ctx.fillRect(0, 0, 100, 50);
1295     @assert pixel 1,1 == 0,255,0,255;
1296     @assert pixel 50,1 == 0,255,0,255;
1297     @assert pixel 98,1 == 0,255,0,255;
1298     @assert pixel 1,25 == 0,255,0,255;
1299     @assert pixel 50,25 == 0,255,0,255;
1300     @assert pixel 98,25 == 0,255,0,255;
1301     @assert pixel 1,48 == 0,255,0,255;
1302     @assert pixel 50,48 == 0,255,0,255;
1303     @assert pixel 98,48 == 0,255,0,255;
1304   expected: green
1306 - name: 2d.pattern.basic.zerocanvas
1307   testing:
1308   - 2d.pattern.zerocanvas
1309   code: |
1310     canvas.width = 0;
1311     canvas.height = 10;
1312     @assert canvas.width === 0;
1313     @assert canvas.height === 10;
1314     @assert throws INVALID_STATE_ERR ctx.createPattern(canvas, 'repeat');
1316     canvas.width = 10;
1317     canvas.height = 0;
1318     @assert canvas.width === 10;
1319     @assert canvas.height === 0;
1320     @assert throws INVALID_STATE_ERR ctx.createPattern(canvas, 'repeat');
1322     canvas.width = 0;
1323     canvas.height = 0;
1324     @assert canvas.width === 0;
1325     @assert canvas.height === 0;
1326     @assert throws INVALID_STATE_ERR ctx.createPattern(canvas, 'repeat');
1328 - name: 2d.pattern.basic.nocontext
1329   testing:
1330   - 2d.pattern.painting
1331   code: |
1332     var canvas2 = document.createElement('canvas');
1333     canvas2.width = 100;
1334     canvas2.height = 50;
1335     var pattern = ctx.createPattern(canvas2, 'no-repeat');
1337     ctx.fillStyle = '#0f0';
1338     ctx.fillRect(0, 0, 100, 50);
1339     ctx.fillStyle = '#f00';
1340     ctx.fillStyle = pattern;
1341     ctx.fillRect(0, 0, 100, 50);
1343     @assert pixel 1,1 == 0,255,0,255;
1344     @assert pixel 98,1 == 0,255,0,255;
1345     @assert pixel 1,48 == 0,255,0,255;
1346     @assert pixel 98,48 == 0,255,0,255;
1347   expected: green
1349 - name: 2d.pattern.transform.identity
1350   testing:
1351   - 2d.pattern.transform
1352   code: |
1353     var canvas2 = document.createElement('canvas');
1354     canvas2.width = 100;
1355     canvas2.height = 50;
1356     var pattern = ctx.createPattern(canvas2, 'no-repeat');
1357     pattern.setTransform(new DOMMatrix());
1359     ctx.fillStyle = '#0f0';
1360     ctx.fillRect(0, 0, 100, 50);
1361     ctx.fillStyle = '#f00';
1362     ctx.fillStyle = pattern;
1363     ctx.fillRect(0, 0, 100, 50);
1365     @assert pixel 1,1 == 0,255,0,255;
1366     @assert pixel 98,1 == 0,255,0,255;
1367     @assert pixel 1,48 == 0,255,0,255;
1368     @assert pixel 98,48 == 0,255,0,255;
1369   expected: green
1371 - name: 2d.pattern.transform.infinity
1372   testing:
1373   - 2d.pattern.transform
1374   code: |
1375     var canvas2 = document.createElement('canvas');
1376     canvas2.width = 100;
1377     canvas2.height = 50;
1378     var pattern = ctx.createPattern(canvas2, 'no-repeat');
1379     pattern.setTransform({a: Infinity});
1381     ctx.fillStyle = '#0f0';
1382     ctx.fillRect(0, 0, 100, 50);
1383     ctx.fillStyle = '#f00';
1384     ctx.fillStyle = pattern;
1385     ctx.fillRect(0, 0, 100, 50);
1387     @assert pixel 1,1 == 0,255,0,255;
1388     @assert pixel 98,1 == 0,255,0,255;
1389     @assert pixel 1,48 == 0,255,0,255;
1390     @assert pixel 98,48 == 0,255,0,255;
1391   expected: green
1393 - name: 2d.pattern.transform.invalid
1394   testing:
1395   - 2d.pattern.transform
1396   code: |
1397     var canvas2 = document.createElement('canvas');
1398     canvas2.width = 100;
1399     canvas2.height = 50;
1400     var pattern = ctx.createPattern(canvas2, 'no-repeat');
1401     @assert throws TypeError pattern.setTransform({a: 1, m11: 2});
1403 - name: 2d.pattern.image.undefined
1404   testing:
1405   - 2d.pattern.IDL
1406   notes: *bindings
1407   code: |
1408     @assert throws TypeError ctx.createPattern(undefined, 'repeat');
1410 - name: 2d.pattern.image.null
1411   testing:
1412   - 2d.pattern.IDL
1413   notes: *bindings
1414   code: |
1415     @assert throws TypeError ctx.createPattern(null, 'repeat');
1417 - name: 2d.pattern.image.string
1418   testing:
1419   - 2d.pattern.IDL
1420   notes: *bindings
1421   code: |
1422     @assert throws TypeError ctx.createPattern('../images/red.png', 'repeat');
1424 - name: 2d.pattern.image.incomplete.nosrc
1425   testing:
1426   - 2d.pattern.incomplete.image
1427   code: |
1428     var img = new Image();
1429     @assert ctx.createPattern(img, 'repeat') === null;
1431 - name: 2d.pattern.image.incomplete.immediate
1432   testing:
1433   - 2d.pattern.incomplete.image
1434   images:
1435   - red.png
1436   code: |
1437     var img = new Image();
1438     img.src = '../images/red.png';
1439     // This triggers the "update the image data" algorithm.
1440     // The image will not go to the "completely available" state
1441     // until a fetch task in the networking task source is processed,
1442     // so the image must not be fully decodable yet:
1443     @assert ctx.createPattern(img, 'repeat') === null; @moz-todo
1445 - name: 2d.pattern.image.incomplete.reload
1446   testing:
1447   - 2d.pattern.incomplete.image
1448   images:
1449   - yellow.png
1450   - red.png
1451   code: |
1452     var img = document.getElementById('yellow.png');
1453     img.src = '../images/red.png';
1454     // This triggers the "update the image data" algorithm,
1455     // and resets the image to the "unavailable" state.
1456     // The image will not go to the "completely available" state
1457     // until a fetch task in the networking task source is processed,
1458     // so the image must not be fully decodable yet:
1459     @assert ctx.createPattern(img, 'repeat') === null; @moz-todo
1461 - name: 2d.pattern.image.incomplete.emptysrc
1462   testing:
1463   - 2d.pattern.incomplete.image
1464   images:
1465   - red.png
1466   mozilla: {throws: !!null ''}
1467   code: |
1468     var img = document.getElementById('red.png');
1469     img.src = "";
1470     @assert ctx.createPattern(img, 'repeat') === null;
1472 - name: 2d.pattern.image.incomplete.removedsrc
1473   testing:
1474   - 2d.pattern.incomplete.image
1475   images:
1476   - red.png
1477   mozilla: {throws: !!null ''}
1478   code: |
1479     var img = document.getElementById('red.png');
1480     img.removeAttribute('src');
1481     @assert ctx.createPattern(img, 'repeat') === null;
1483 - name: 2d.pattern.image.broken
1484   testing:
1485   - 2d.pattern.broken.image
1486   images:
1487   - broken.png
1488   code: |
1489     var img = document.getElementById('broken.png');
1490     @assert ctx.createPattern(img, 'repeat') === null;
1492 - name: 2d.pattern.image.nonexistent
1493   testing:
1494   - 2d.pattern.nonexistent.image
1495   images:
1496   - no-such-image-really.png
1497   code: |
1498     var img = document.getElementById('no-such-image-really.png');
1499     @assert throws INVALID_STATE_ERR ctx.createPattern(img, 'repeat');
1501 - name: 2d.pattern.svgimage.nonexistent
1502   testing:
1503   - 2d.pattern.nonexistent.svgimage
1504   svgimages:
1505   - no-such-image-really.png
1506   code: |
1507     var img = document.getElementById('no-such-image-really.png');
1508     @assert throws INVALID_STATE_ERR ctx.createPattern(img, 'repeat');
1510 - name: 2d.pattern.image.nonexistent-but-loading
1511   testing:
1512   - 2d.pattern.nonexistent-but-loading.image
1513   code: |
1514     var img = document.createElement("img");
1515     img.src = "/images/no-such-image-really.png";
1516     @assert ctx.createPattern(img, 'repeat') === null;
1517     var img = document.createElementNS("http://www.w3.org/2000/svg", "image");
1518     img.src = "/images/no-such-image-really.png";
1519     @assert ctx.createPattern(img, 'repeat') === null;
1521 - name: 2d.pattern.image.nosrc
1522   testing:
1523   - 2d.pattern.nosrc.image
1524   code: |
1525     var img = document.createElement("img");
1526     @assert ctx.createPattern(img, 'repeat') === null;
1527     var img = document.createElementNS("http://www.w3.org/2000/svg", "image");
1528     @assert ctx.createPattern(img, 'repeat') === null;
1530 - name: 2d.pattern.image.zerowidth
1531   testing:
1532   - 2d.pattern.zerowidth.image
1533   images:
1534   - red-zerowidth.svg
1535   code: |
1536     var img = document.getElementById('red-zerowidth.svg');
1537     @assert ctx.createPattern(img, 'repeat') === null;
1539 - name: 2d.pattern.image.zeroheight
1540   testing:
1541   - 2d.pattern.zeroheight.image
1542   images:
1543   - red-zeroheight.svg
1544   code: |
1545     var img = document.getElementById('red-zeroheight.svg');
1546     @assert ctx.createPattern(img, 'repeat') === null;
1548 - name: 2d.pattern.svgimage.zerowidth
1549   testing:
1550   - 2d.pattern.zerowidth.svgimage
1551   svgimages:
1552   - red-zerowidth.svg
1553   code: |
1554     var img = document.getElementById('red-zerowidth.svg');
1555     @assert ctx.createPattern(img, 'repeat') === null;
1557 - name: 2d.pattern.svgimage.zeroheight
1558   testing:
1559   - 2d.pattern.zeroheight.svgimage
1560   svgimages:
1561   - red-zeroheight.svg
1562   code: |
1563     var img = document.getElementById('red-zeroheight.svg');
1564     @assert ctx.createPattern(img, 'repeat') === null;
1566 - name: 2d.pattern.repeat.empty
1567   testing:
1568   - 2d.pattern.missing
1569   images:
1570   - green-1x1.png
1571   code: |
1572     ctx.fillStyle = '#f00';
1573     ctx.fillRect(0, 0, 100, 50);
1574     var img = document.getElementById('green-1x1.png');
1575     var pattern = ctx.createPattern(img, "");
1576     ctx.fillStyle = pattern;
1577     ctx.fillRect(0, 0, 200, 50);
1579     @assert pixel 1,1 == 0,255,0,255;
1580     @assert pixel 98,1 == 0,255,0,255;
1581     @assert pixel 1,48 == 0,255,0,255;
1582     @assert pixel 98,48 == 0,255,0,255;
1583   expected: green
1585 - name: 2d.pattern.repeat.null
1586   testing:
1587   - 2d.pattern.unrecognised
1588   code: |
1589     @assert ctx.createPattern(canvas, null) != null;
1591 - name: 2d.pattern.repeat.undefined
1592   testing:
1593   - 2d.pattern.unrecognised
1594   code: |
1595     @assert throws SYNTAX_ERR ctx.createPattern(canvas, undefined);
1597 - name: 2d.pattern.repeat.unrecognised
1598   testing:
1599   - 2d.pattern.unrecognised
1600   code: |
1601     @assert throws SYNTAX_ERR ctx.createPattern(canvas, "invalid");
1603 - name: 2d.pattern.repeat.unrecognisednull
1604   testing:
1605   - 2d.pattern.unrecognised
1606   code: |
1607     @assert throws SYNTAX_ERR ctx.createPattern(canvas, "null");
1609 - name: 2d.pattern.repeat.case
1610   testing:
1611   - 2d.pattern.exact
1612   code: |
1613     @assert throws SYNTAX_ERR ctx.createPattern(canvas, "Repeat");
1615 - name: 2d.pattern.repeat.nullsuffix
1616   testing:
1617   - 2d.pattern.exact
1618   code: |
1619     @assert throws SYNTAX_ERR ctx.createPattern(canvas, "repeat\0");
1621 - name: 2d.pattern.modify.image1
1622   testing:
1623   - 2d.pattern.modify
1624   images:
1625   - green.png
1626   code: |
1627     var img = document.getElementById('green.png');
1628     var pattern = ctx.createPattern(img, 'no-repeat');
1629     deferTest();
1630     img.onload = t.step_func_done(function ()
1631     {
1632         ctx.fillStyle = pattern;
1633         ctx.fillRect(0, 0, 100, 50);
1635         @assert pixel 1,1 == 0,255,0,255;
1636         @assert pixel 98,1 == 0,255,0,255;
1637         @assert pixel 1,48 == 0,255,0,255;
1638         @assert pixel 98,48 == 0,255,0,255;
1639     });
1640     img.src = '/images/red.png';
1641   expected: green
1643 - name: 2d.pattern.modify.image2
1644   testing:
1645   - 2d.pattern.modify
1646   images:
1647   - green.png
1648   code: |
1649     var img = document.getElementById('green.png');
1650     var pattern = ctx.createPattern(img, 'no-repeat');
1651     ctx.fillStyle = pattern;
1652     ctx.fillRect(0, 0, 100, 50);
1653     ctx.fillStyle = '#00f';
1654     ctx.fillRect(0, 0, 100, 50);
1655     deferTest();
1656     img.onload = t.step_func_done(function ()
1657     {
1658         ctx.fillStyle = pattern;
1659         ctx.fillRect(0, 0, 100, 50);
1661         @assert pixel 1,1 == 0,255,0,255;
1662         @assert pixel 98,1 == 0,255,0,255;
1663         @assert pixel 1,48 == 0,255,0,255;
1664         @assert pixel 98,48 == 0,255,0,255;
1665     });
1666     img.src = '/images/red.png';
1667   expected: green
1669 - name: 2d.pattern.modify.canvas1
1670   testing:
1671   - 2d.pattern.modify
1672   code: |
1673     var canvas2 = document.createElement('canvas');
1674     canvas2.width = 100;
1675     canvas2.height = 50;
1676     var ctx2 = canvas2.getContext('2d');
1677     ctx2.fillStyle = '#0f0';
1678     ctx2.fillRect(0, 0, 100, 50);
1680     var pattern = ctx.createPattern(canvas2, 'no-repeat');
1682     ctx2.fillStyle = '#f00';
1683     ctx2.fillRect(0, 0, 100, 50);
1685     ctx.fillStyle = pattern;
1686     ctx.fillRect(0, 0, 100, 50);
1688     @assert pixel 1,1 == 0,255,0,255;
1689     @assert pixel 98,1 == 0,255,0,255;
1690     @assert pixel 1,48 == 0,255,0,255;
1691     @assert pixel 98,48 == 0,255,0,255;
1692   expected: green
1694 - name: 2d.pattern.modify.canvas2
1695   testing:
1696   - 2d.pattern.modify
1697   code: |
1698     var canvas2 = document.createElement('canvas');
1699     canvas2.width = 100;
1700     canvas2.height = 50;
1701     var ctx2 = canvas2.getContext('2d');
1702     ctx2.fillStyle = '#0f0';
1703     ctx2.fillRect(0, 0, 100, 50);
1705     var pattern = ctx.createPattern(canvas2, 'no-repeat');
1706     ctx.fillStyle = pattern;
1707     ctx.fillRect(0, 0, 100, 50);
1708     ctx.fillStyle = '#f00';
1709     ctx.fillRect(0, 0, 100, 50);
1711     ctx2.fillStyle = '#f00';
1712     ctx2.fillRect(0, 0, 100, 50);
1714     ctx.fillStyle = pattern;
1715     ctx.fillRect(0, 0, 100, 50);
1717     @assert pixel 1,1 == 0,255,0,255;
1718     @assert pixel 98,1 == 0,255,0,255;
1719     @assert pixel 1,48 == 0,255,0,255;
1720     @assert pixel 98,48 == 0,255,0,255;
1721   expected: green
1723 - name: 2d.pattern.crosscanvas
1724   images:
1725   - green.png
1726   code: |
1727     var img = document.getElementById('green.png');
1729     var pattern = document.createElement('canvas').getContext('2d').createPattern(img, 'no-repeat');
1730     ctx.fillStyle = '#f00';
1731     ctx.fillRect(0, 0, 100, 50);
1732     ctx.fillStyle = pattern;
1733     ctx.fillRect(0, 0, 100, 50);
1735     @assert pixel 50,25 == 0,255,0,255;
1736   expected: green
1738 - name: 2d.pattern.paint.norepeat.basic
1739   testing:
1740   - 2d.pattern.painting
1741   images:
1742   - green.png
1743   code: |
1744     ctx.fillStyle = '#f00';
1745     ctx.fillRect(0, 0, 100, 50);
1747     var img = document.getElementById('green.png');
1748     var pattern = ctx.createPattern(img, 'no-repeat');
1749     ctx.fillStyle = pattern;
1750     ctx.fillRect(0, 0, 100, 50);
1752     @assert pixel 1,1 == 0,255,0,255;
1753     @assert pixel 98,1 == 0,255,0,255;
1754     @assert pixel 1,48 == 0,255,0,255;
1755     @assert pixel 98,48 == 0,255,0,255;
1756   expected: green
1758 - name: 2d.pattern.paint.norepeat.outside
1759   testing:
1760   - 2d.pattern.painting
1761   images:
1762   - red.png
1763   code: |
1764     ctx.fillStyle = '#f00';
1765     ctx.fillRect(0, 0, 100, 50);
1767     var img = document.getElementById('red.png');
1768     var pattern = ctx.createPattern(img, 'no-repeat');
1769     ctx.fillStyle = '#0f0';
1770     ctx.fillRect(0, 0, 100, 50);
1772     ctx.fillStyle = pattern;
1773     ctx.fillRect(0, -50, 100, 50);
1774     ctx.fillRect(-100, 0, 100, 50);
1775     ctx.fillRect(0, 50, 100, 50);
1776     ctx.fillRect(100, 0, 100, 50);
1778     @assert pixel 1,1 == 0,255,0,255;
1779     @assert pixel 98,1 == 0,255,0,255;
1780     @assert pixel 1,48 == 0,255,0,255;
1781     @assert pixel 98,48 == 0,255,0,255;
1782   expected: green
1784 - name: 2d.pattern.paint.norepeat.coord1
1785   testing:
1786   - 2d.pattern.painting
1787   images:
1788   - green.png
1789   code: |
1790     ctx.fillStyle = '#0f0';
1791     ctx.fillRect(0, 0, 50, 50);
1792     ctx.fillStyle = '#f00';
1793     ctx.fillRect(50, 0, 50, 50);
1795     var img = document.getElementById('green.png');
1796     var pattern = ctx.createPattern(img, 'no-repeat');
1797     ctx.fillStyle = pattern;
1798     ctx.translate(50, 0);
1799     ctx.fillRect(-50, 0, 100, 50);
1801     @assert pixel 1,1 == 0,255,0,255;
1802     @assert pixel 98,1 == 0,255,0,255;
1803     @assert pixel 1,48 == 0,255,0,255;
1804     @assert pixel 98,48 == 0,255,0,255;
1805   expected: green
1807 - name: 2d.pattern.paint.norepeat.coord2
1808   testing:
1809   - 2d.pattern.painting
1810   images:
1811   - green.png
1812   code: |
1813     var img = document.getElementById('green.png');
1814     var pattern = ctx.createPattern(img, 'no-repeat');
1815     ctx.fillStyle = pattern;
1816     ctx.fillRect(0, 0, 50, 50);
1818     ctx.fillStyle = '#f00';
1819     ctx.fillRect(50, 0, 50, 50);
1821     ctx.fillStyle = pattern;
1822     ctx.translate(50, 0);
1823     ctx.fillRect(-50, 0, 100, 50);
1825     @assert pixel 1,1 == 0,255,0,255;
1826     @assert pixel 98,1 == 0,255,0,255;
1827     @assert pixel 1,48 == 0,255,0,255;
1828     @assert pixel 98,48 == 0,255,0,255;
1829   expected: green
1831 - name: 2d.pattern.paint.norepeat.coord3
1832   testing:
1833   - 2d.pattern.painting
1834   images:
1835   - red.png
1836   code: |
1837     ctx.fillStyle = '#0f0';
1838     ctx.fillRect(0, 0, 100, 50);
1840     var img = document.getElementById('red.png');
1841     var pattern = ctx.createPattern(img, 'no-repeat');
1842     ctx.fillStyle = pattern;
1843     ctx.translate(50, 25);
1844     ctx.fillRect(-50, -25, 100, 50);
1846     ctx.fillStyle = '#0f0';
1847     ctx.fillRect(0, 0, 50, 25);
1849     @assert pixel 1,1 == 0,255,0,255;
1850     @assert pixel 98,1 == 0,255,0,255;
1851     @assert pixel 1,48 == 0,255,0,255;
1852     @assert pixel 98,48 == 0,255,0,255;
1853   expected: green
1855 - name: 2d.pattern.paint.repeat.basic
1856   testing:
1857   - 2d.pattern.painting
1858   images:
1859   - green-16x16.png
1860   code: |
1861     ctx.fillStyle = '#f00';
1862     ctx.fillRect(0, 0, 100, 50);
1864     var img = document.getElementById('green-16x16.png');
1865     var pattern = ctx.createPattern(img, 'repeat');
1866     ctx.fillStyle = pattern;
1867     ctx.fillRect(0, 0, 100, 50);
1869     @assert pixel 1,1 == 0,255,0,255;
1870     @assert pixel 98,1 == 0,255,0,255;
1871     @assert pixel 1,48 == 0,255,0,255;
1872     @assert pixel 98,48 == 0,255,0,255;
1873   expected: green
1875 - name: 2d.pattern.paint.repeat.outside
1876   testing:
1877   - 2d.pattern.painting
1878   images:
1879   - green-16x16.png
1880   code: |
1881     ctx.fillStyle = '#f00';
1882     ctx.fillRect(0, 0, 100, 50);
1884     var img = document.getElementById('green-16x16.png');
1885     var pattern = ctx.createPattern(img, 'repeat');
1886     ctx.fillStyle = pattern;
1887     ctx.translate(50, 25);
1888     ctx.fillRect(-50, -25, 100, 50);
1890     @assert pixel 1,1 == 0,255,0,255;
1891     @assert pixel 98,1 == 0,255,0,255;
1892     @assert pixel 1,48 == 0,255,0,255;
1893     @assert pixel 98,48 == 0,255,0,255;
1894   expected: green
1896 - name: 2d.pattern.paint.repeat.coord1
1897   testing:
1898   - 2d.pattern.painting
1899   images:
1900   - rgrg-256x256.png
1901   code: |
1902     ctx.fillStyle = '#f00';
1903     ctx.fillRect(0, 0, 100, 50);
1905     var img = document.getElementById('rgrg-256x256.png');
1906     var pattern = ctx.createPattern(img, 'repeat');
1907     ctx.fillStyle = pattern;
1908     ctx.translate(-128, -78);
1909     ctx.fillRect(128, 78, 100, 50);
1911     @assert pixel 1,1 == 0,255,0,255;
1912     @assert pixel 98,1 == 0,255,0,255;
1913     @assert pixel 1,48 == 0,255,0,255;
1914     @assert pixel 98,48 == 0,255,0,255;
1915   expected: green
1917 - name: 2d.pattern.paint.repeat.coord2
1918   testing:
1919   - 2d.pattern.painting
1920   images:
1921   - ggrr-256x256.png
1922   code: |
1923     var img = document.getElementById('ggrr-256x256.png');
1924     var pattern = ctx.createPattern(img, 'repeat');
1925     ctx.fillStyle = pattern;
1926     ctx.fillRect(0, 0, 100, 50);
1928     @assert pixel 1,1 == 0,255,0,255;
1929     @assert pixel 98,1 == 0,255,0,255;
1930     @assert pixel 1,48 == 0,255,0,255;
1931     @assert pixel 98,48 == 0,255,0,255;
1932   expected: green
1934 - name: 2d.pattern.paint.repeat.coord3
1935   testing:
1936   - 2d.pattern.painting
1937   images:
1938   - rgrg-256x256.png
1939   code: |
1940     var img = document.getElementById('rgrg-256x256.png');
1941     var pattern = ctx.createPattern(img, 'repeat');
1942     ctx.fillStyle = pattern;
1943     ctx.fillRect(0, 0, 100, 50);
1945     ctx.translate(-128, -78);
1946     ctx.fillRect(128, 78, 100, 50);
1948     @assert pixel 1,1 == 0,255,0,255;
1949     @assert pixel 98,1 == 0,255,0,255;
1950     @assert pixel 1,48 == 0,255,0,255;
1951     @assert pixel 98,48 == 0,255,0,255;
1952   expected: green
1954 - name: 2d.pattern.paint.repeatx.basic
1955   testing:
1956   - 2d.pattern.painting
1957   images:
1958   - green-16x16.png
1959   code: |
1960     ctx.fillStyle = '#0f0';
1961     ctx.fillRect(0, 0, 100, 50);
1962     ctx.fillStyle = '#f00';
1963     ctx.fillRect(0, 0, 100, 16);
1965     var img = document.getElementById('green-16x16.png');
1966     var pattern = ctx.createPattern(img, 'repeat-x');
1967     ctx.fillStyle = pattern;
1968     ctx.fillRect(0, 0, 100, 50);
1970     @assert pixel 1,1 == 0,255,0,255;
1971     @assert pixel 98,1 == 0,255,0,255;
1972     @assert pixel 1,48 == 0,255,0,255;
1973     @assert pixel 98,48 == 0,255,0,255;
1974   expected: green
1976 - name: 2d.pattern.paint.repeatx.outside
1977   testing:
1978   - 2d.pattern.painting
1979   images:
1980   - red-16x16.png
1981   code: |
1982     ctx.fillStyle = '#0f0';
1983     ctx.fillRect(0, 0, 100, 50);
1985     var img = document.getElementById('red-16x16.png');
1986     var pattern = ctx.createPattern(img, 'repeat-x');
1987     ctx.fillStyle = pattern;
1988     ctx.fillRect(0, 0, 100, 50);
1990     ctx.fillStyle = '#0f0';
1991     ctx.fillRect(0, 0, 100, 16);
1993     @assert pixel 1,1 == 0,255,0,255;
1994     @assert pixel 98,1 == 0,255,0,255;
1995     @assert pixel 1,48 == 0,255,0,255;
1996     @assert pixel 98,48 == 0,255,0,255;
1997   expected: green
1999 - name: 2d.pattern.paint.repeatx.coord1
2000   testing:
2001   - 2d.pattern.painting
2002   images:
2003   - red-16x16.png
2004   code: |
2005     ctx.fillStyle = '#0f0';
2006     ctx.fillRect(0, 0, 100, 50);
2008     var img = document.getElementById('red-16x16.png');
2009     var pattern = ctx.createPattern(img, 'repeat-x');
2010     ctx.fillStyle = pattern;
2011     ctx.translate(0, 16);
2012     ctx.fillRect(0, -16, 100, 50);
2014     ctx.fillStyle = '#0f0';
2015     ctx.fillRect(0, 0, 100, 16);
2017     @assert pixel 1,1 == 0,255,0,255;
2018     @assert pixel 98,1 == 0,255,0,255;
2019     @assert pixel 1,25 == 0,255,0,255;
2020     @assert pixel 98,25 == 0,255,0,255;
2021     @assert pixel 1,48 == 0,255,0,255;
2022     @assert pixel 98,48 == 0,255,0,255;
2023   expected: green
2025 - name: 2d.pattern.paint.repeaty.basic
2026   testing:
2027   - 2d.pattern.painting
2028   images:
2029   - green-16x16.png
2030   code: |
2031     ctx.fillStyle = '#0f0';
2032     ctx.fillRect(0, 0, 100, 50);
2033     ctx.fillStyle = '#f00';
2034     ctx.fillRect(0, 0, 16, 50);
2036     var img = document.getElementById('green-16x16.png');
2037     var pattern = ctx.createPattern(img, 'repeat-y');
2038     ctx.fillStyle = pattern;
2039     ctx.fillRect(0, 0, 100, 50);
2041     @assert pixel 1,1 == 0,255,0,255;
2042     @assert pixel 98,1 == 0,255,0,255;
2043     @assert pixel 1,48 == 0,255,0,255;
2044     @assert pixel 98,48 == 0,255,0,255;
2045   expected: green
2047 - name: 2d.pattern.paint.repeaty.outside
2048   testing:
2049   - 2d.pattern.painting
2050   images:
2051   - red-16x16.png
2052   code: |
2053     ctx.fillStyle = '#0f0';
2054     ctx.fillRect(0, 0, 100, 50);
2056     var img = document.getElementById('red-16x16.png');
2057     var pattern = ctx.createPattern(img, 'repeat-y');
2058     ctx.fillStyle = pattern;
2059     ctx.fillRect(0, 0, 100, 50);
2061     ctx.fillStyle = '#0f0';
2062     ctx.fillRect(0, 0, 16, 50);
2064     @assert pixel 1,1 == 0,255,0,255;
2065     @assert pixel 98,1 == 0,255,0,255;
2066     @assert pixel 1,48 == 0,255,0,255;
2067     @assert pixel 98,48 == 0,255,0,255;
2068   expected: green
2070 - name: 2d.pattern.paint.repeaty.coord1
2071   testing:
2072   - 2d.pattern.painting
2073   images:
2074   - red-16x16.png
2075   code: |
2076     ctx.fillStyle = '#0f0';
2077     ctx.fillRect(0, 0, 100, 50);
2079     var img = document.getElementById('red-16x16.png');
2080     var pattern = ctx.createPattern(img, 'repeat-y');
2081     ctx.fillStyle = pattern;
2082     ctx.translate(48, 0);
2083     ctx.fillRect(-48, 0, 100, 50);
2085     ctx.fillStyle = '#0f0';
2086     ctx.fillRect(0, 0, 16, 50);
2088     @assert pixel 1,1 == 0,255,0,255;
2089     @assert pixel 50,1 == 0,255,0,255;
2090     @assert pixel 98,1 == 0,255,0,255;
2091     @assert pixel 1,48 == 0,255,0,255;
2092     @assert pixel 50,48 == 0,255,0,255;
2093     @assert pixel 98,48 == 0,255,0,255;
2094   expected: green
2096 - name: 2d.pattern.paint.orientation.image
2097   desc: Image patterns do not get flipped when painted
2098   testing:
2099   - 2d.pattern.painting
2100   images:
2101   - rrgg-256x256.png
2102   code: |
2103     ctx.fillStyle = '#f00';
2104     ctx.fillRect(0, 0, 100, 50);
2106     var img = document.getElementById('rrgg-256x256.png');
2107     var pattern = ctx.createPattern(img, 'no-repeat');
2108     ctx.fillStyle = pattern;
2109     ctx.save();
2110     ctx.translate(0, -103);
2111     ctx.fillRect(0, 103, 100, 50);
2112     ctx.restore();
2114     ctx.fillStyle = '#0f0';
2115     ctx.fillRect(0, 0, 100, 25);
2117     @assert pixel 1,1 == 0,255,0,255;
2118     @assert pixel 98,1 == 0,255,0,255;
2119     @assert pixel 1,48 == 0,255,0,255;
2120     @assert pixel 98,48 == 0,255,0,255;
2121   expected: green
2123 - name: 2d.pattern.paint.orientation.canvas
2124   desc: Canvas patterns do not get flipped when painted
2125   testing:
2126   - 2d.pattern.painting
2127   code: |
2128     ctx.fillStyle = '#f00';
2129     ctx.fillRect(0, 0, 100, 50);
2131     var canvas2 = document.createElement('canvas');
2132     canvas2.width = 100;
2133     canvas2.height = 50;
2134     var ctx2 = canvas2.getContext('2d');
2135     ctx2.fillStyle = '#f00';
2136     ctx2.fillRect(0, 0, 100, 25);
2137     ctx2.fillStyle = '#0f0';
2138     ctx2.fillRect(0, 25, 100, 25);
2140     var pattern = ctx.createPattern(canvas2, 'no-repeat');
2141     ctx.fillStyle = pattern;
2142     ctx.fillRect(0, 0, 100, 50);
2143     ctx.fillStyle = '#0f0';
2144     ctx.fillRect(0, 0, 100, 25);
2146     @assert pixel 1,1 == 0,255,0,255;
2147     @assert pixel 98,1 == 0,255,0,255;
2148     @assert pixel 1,48 == 0,255,0,255;
2149     @assert pixel 98,48 == 0,255,0,255;
2150   expected: green
2153 - name: 2d.pattern.animated.gif
2154   desc: createPattern() of an animated GIF draws the first frame
2155   testing:
2156   - 2d.pattern.animated.image
2157   images:
2158   - anim-gr.gif
2159   code: |
2160     deferTest();
2161     step_timeout(function () {
2162         var pattern = ctx.createPattern(document.getElementById('anim-gr.gif'), 'repeat');
2163         ctx.fillStyle = pattern;
2164         ctx.fillRect(0, 0, 50, 50);
2165         step_timeout(t.step_func_done(function () {
2166             ctx.fillRect(50, 0, 50, 50);
2167             @assert pixel 25,25 ==~ 0,255,0,255;
2168             @assert pixel 75,25 ==~ 0,255,0,255;
2169         }), 250);
2170     }, 250);
2171   expected: green
2173 - name: 2d.fillStyle.CSSRGB
2174   desc: CSSRGB works as color input
2175   testing:
2176   - 2d.colors.CSSRGB
2177   code: |
2178     ctx.fillStyle = new CSSRGB(1, 0, 1);
2179     @assert ctx.fillStyle === '#ff00ff';
2180     ctx.fillRect(0, 0, 100, 50);
2181     @assert pixel 50,25 == 255,0,255,255;
2183     const color = new CSSRGB(0, CSS.percent(50), 0);
2184     ctx.fillStyle = color;
2185     @assert ctx.fillStyle === '#008000';
2186     ctx.fillRect(0, 0, 100, 50);
2187     @assert pixel 50,25 == 0,128,0,255;
2188     color.g = 0;
2189     ctx.fillStyle = color;
2190     @assert ctx.fillStyle === '#000000';
2191     ctx.fillRect(0, 0, 100, 50);
2192     @assert pixel 50,25 == 0,0,0,255;
2194     color.alpha = 0;
2195     ctx.fillStyle = color;
2196     @assert ctx.fillStyle === 'rgba(0, 0, 0, 0)';
2197     ctx.reset();
2198     color.alpha = 0.5;
2199     ctx.fillStyle = color;
2200     ctx.fillRect(0, 0, 100, 50);
2201     @assert pixel 50,25 == 0,0,0,128;
2203     ctx.fillStyle = new CSSHSL(CSS.deg(0), 1, 1).toRGB();
2204     @assert ctx.fillStyle === '#ffffff';
2205     ctx.fillRect(0, 0, 100, 50);
2206     @assert pixel 50,25 == 255,255,255,255;
2208     color.alpha = 1;
2209     color.g = 1;
2210     ctx.fillStyle = color;
2211     ctx.fillRect(0, 0, 100, 50);
2212   expected: green
2214 - name: 2d.fillStyle.CSSHSL
2215   desc: CSSHSL works as color input
2216   testing:
2217   - 2d.colors.CSSHSL
2218   code: |
2219     ctx.fillStyle = new CSSHSL(CSS.deg(180), 0.5, 0.5);
2220     ctx.fillRect(0, 0, 100, 50);
2221     @assert pixel 50,25 ==~ 64,191,191,255 +/- 3;
2223     const color = new CSSHSL(CSS.deg(180), 1, 1);
2224     ctx.fillStyle = color;
2225     @assert ctx.fillStyle === '#ffffff';
2226     ctx.fillRect(0, 0, 100, 50);
2227     @assert pixel 50,25 == 255,255,255,255;
2228     color.l = 0.5;
2229     ctx.fillStyle = color;
2230     @assert ctx.fillStyle === '#00ffff';
2231     ctx.fillRect(0, 0, 100, 50);
2232     @assert pixel 50,25 == 0,255,255,255;
2234     ctx.fillStyle = new CSSRGB(1, 0, 1).toHSL();
2235     @assert ctx.fillStyle === '#ff00ff';
2236     ctx.fillRect(0, 0, 100, 50);
2237     @assert pixel 50,25 == 255,0,255,255;
2239     color.h = CSS.deg(120);
2240     color.s = 1;
2241     color.l = 0.5;
2242     ctx.fillStyle = color;
2243     ctx.fillRect(0, 0, 100, 50);
2244   expected: green