summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/canvas/tools/yaml-new
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/html/canvas/tools/yaml-new
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/html/canvas/tools/yaml-new')
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/color_space.yaml329
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/compositing.yaml262
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/conformance_requirements.yaml178
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml1333
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-rectangles-to-the-canvas.yaml469
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/filters.yaml450
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/reset.yaml15
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/scroll.yaml76
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/video.yaml10
9 files changed, 3122 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/color_space.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/color_space.yaml
new file mode 100644
index 0000000000..ba5d93e0b0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/color_space.yaml
@@ -0,0 +1,329 @@
+- name: 2d.color.space.p3.to.p3
+ desc: test getImageData with display-p3 and uint8 from display p3 uint8 canvas
+ attributes: |
+ {colorSpace: "display-p3"}
+ code: |
+ var color_style = 'rgb(50, 100, 150)';
+ // [0.24304, 0.38818, 0.57227, 1.0] * 255 = [62, 99, 146, 255]
+ var pixel_expected = [62, 99, 146, 255];
+ var epsilon = 2;
+ ctx.fillStyle = color_style;
+ ctx.fillRect(0, 0, 10, 10);
+
+ var pixel = ctx.getImageData(5, 5, 1, 1, {colorSpace: "display-p3", storageFormat: "uint8"}).data;
+ @assert pixel.length === pixel_expected.length;
+ assert_approx_equals(pixel[0], pixel_expected[0], 2);
+ assert_approx_equals(pixel[1], pixel_expected[1], 2);
+ assert_approx_equals(pixel[2], pixel_expected[2], 2);
+ assert_approx_equals(pixel[3], pixel_expected[3], 2);
+
+- name: 2d.color.space.p3.to.srgb
+ desc: test getImageData with srsb and uint8 from display p3 uint8 canvas
+ attributes: |
+ {colorSpace: "display-p3"}
+ code: |
+ var color_style = 'rgb(50, 100, 150)';
+ var pixel_expected = [50, 100, 150, 255];
+ var epsilon = 2;
+ ctx.fillStyle = color_style;
+ ctx.fillRect(0, 0, 10, 10);
+
+ var pixel = ctx.getImageData(5, 5, 1, 1, {colorSpace: "srgb", storageFormat: "uint8"}).data;
+ @assert pixel.length === pixel_expected.length;
+ assert_approx_equals(pixel[0], pixel_expected[0], 2);
+ assert_approx_equals(pixel[1], pixel_expected[1], 2);
+ assert_approx_equals(pixel[2], pixel_expected[2], 2);
+ assert_approx_equals(pixel[3], pixel_expected[3], 2);
+
+- name: 2d.color.space.p3.toBlob.p3.canvas
+ desc: test if toblob returns p3 data from p3 color space canvas
+ attributes: |
+ {colorSpace: "display-p3"}
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ ctx.fillStyle = "rgba(155, 27, 27, 1)";
+ ctx.fillRect(0, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 155, 27, 0)";
+ ctx.fillRect(1, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 155, 0.5)";
+ ctx.fillRect(0, 1, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 27, 0.5)";
+ ctx.fillRect(1, 1, 1, 1);
+ expectedPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+
+ var image = new Image();
+ image.onload = t.step_func_done(function() {
+ var dstCanvas = document.createElement("canvas");
+ dstCanvas.width = 2;
+ dstCanvas.height = 2;
+ var ctx = dstCanvas.getContext('2d', {colorSpace: "display-p3"});
+ ctx.drawImage(image, 0, 0);
+ var actualPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+ assert_array_approx_equals(actualPixels, expectedPixels, 2);
+ });
+
+ canvas.toBlob(function(blob) {
+ var urlCreator = window.URL || window.webkitURL;
+ image.src = urlCreator.createObjectURL(blob);
+ }, 'image/png', 1);
+
+- name: 2d.color.space.p3.toDataURL.p3.canvas
+ desc: test if toDataURL returns p3 data from canvas with p3 color space
+ attributes: |
+ {colorSpace: "display-p3"}
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ ctx.fillStyle = "rgba(155, 27, 27, 1)";
+ ctx.fillRect(0, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 155, 27, 0)";
+ ctx.fillRect(1, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 155, 0.5)";
+ ctx.fillRect(0, 1, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 27, 0.5)";
+ ctx.fillRect(1, 1, 1, 1);
+ expectedPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+
+ var image = new Image();
+ image.onload = t.step_func_done(function() {
+ var dstCanvas = document.createElement("canvas");
+ dstCanvas.width = 2;
+ dstCanvas.height = 2;
+ var ctx = dstCanvas.getContext('2d', {colorSpace: "display-p3"});
+ ctx.drawImage(image, 0, 0);
+ var actualPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+ assert_array_approx_equals(actualPixels, expectedPixels, 2);
+ });
+ image.src = canvas.toDataURL();
+
+- name: 2d.color.space.p3.toDataURL.jpeg.p3.canvas
+ desc: test if toDataURL('image/jpeg') returns p3 data from canvas with p3 color space
+ attributes: |
+ {colorSpace: "display-p3"}
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ ctx.fillStyle = "rgba(155, 27, 27, 1)";
+ ctx.fillRect(0, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 155, 27, 0)";
+ ctx.fillRect(1, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 155, 0.5)";
+ ctx.fillRect(0, 1, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 27, 0.5)";
+ ctx.fillRect(1, 1, 1, 1);
+ expectedPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+
+ var image = new Image();
+ image.onload = t.step_func_done(function() {
+ var dstCanvas = document.createElement("canvas");
+ dstCanvas.width = 2;
+ dstCanvas.height = 2;
+ var ctx = dstCanvas.getContext('2d', {colorSpace: "display-p3"});
+ ctx.drawImage(image, 0, 0);
+ var actualPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+ assert_array_approx_equals(actualPixels, expectedPixels, 2);
+ });
+ image.src = canvas.toDataURL("image/jpeg");
+
+- name: 2d.color.space.p3.toBlob.with.putImageData
+ desc: Use putImageData to put some p3 data in canvas and test if toBlob returns the same data
+ attributes: |
+ {colorSpace: "display-p3"}
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ canvas.width = 2;
+ canvas.height = 2;
+
+ // Create an ImageData using createImageData and populate its data array.
+ var image_data = ctx.createImageData(canvas.width, canvas.height, {colorSpace: "display-p3"});
+ var color_data = [[255, 100, 150, 1.0], [255, 100, 150, 0.5],
+ [255, 100, 150, 0.5], [255, 100, 150, 0]];
+ var data = image_data.data;
+ for (var i = 0; i < data.length / 4; ++i) {
+ data[4*i + 0] = color_data[i][0];
+ data[4*i + 1] = color_data[i][1];
+ data[4*i + 2] = color_data[i][2];
+ data[4*i + 3] = color_data[i][3];
+ }
+ ctx.putImageData(image_data, 0, 0);
+ expectedPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+
+ var image = new Image();
+ image.onload = t.step_func_done(function() {
+ var dstCanvas = document.createElement("canvas");
+ dstCanvas.width = 2;
+ dstCanvas.height = 2;
+ var ctx = dstCanvas.getContext('2d', {colorSpace: "display-p3"});
+ ctx.drawImage(image, 0, 0);
+ var actualPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+ assert_array_approx_equals(actualPixels, expectedPixels, 2);
+ });
+ canvas.toBlob(function(blob) {
+ var urlCreator = window.URL || window.webkitURL;
+ image.src = urlCreator.createObjectURL(blob);
+ }, 'image/png', 1);
+
+- name: 2d.color.space.p3.toDataURL.with.putImageData
+ desc: Use putImageData to put some p3 data in canvas and test if toDataURL returns the same data
+ attributes: |
+ {colorSpace: "display-p3"}
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ canvas.width = 2;
+ canvas.height = 2;
+
+ // Create an ImageData using createImageData and populate its data array.
+ var image_data = ctx.createImageData(canvas.width, canvas.height, {colorSpace: "display-p3"});
+ var color_data = [[255, 100, 150, 1.0], [255, 100, 150, 0.5],
+ [255, 100, 150, 0.5], [255, 100, 150, 0]];
+ var data = image_data.data;
+ for (var i = 0; i < data.length / 4; ++i) {
+ data[4*i + 0] = color_data[i][0];
+ data[4*i + 1] = color_data[i][1];
+ data[4*i + 2] = color_data[i][2];
+ data[4*i + 3] = color_data[i][3];
+ }
+ ctx.putImageData(image_data, 0, 0);
+ expectedPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+
+ var image = new Image();
+ image.onload = t.step_func_done(function() {
+ var dstCanvas = document.createElement("canvas");
+ dstCanvas.width = 2;
+ dstCanvas.height = 2;
+ var ctx = dstCanvas.getContext('2d', {colorSpace: "display-p3"});
+ ctx.drawImage(image, 0, 0);
+ var actualPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+ assert_array_approx_equals(actualPixels, expectedPixels, 2);
+ });
+ image.src = canvas.toDataURL();
+
+- name: 2d.color.space.p3.fillText
+ desc: Test if fillText can be used with a solid display-p3 color
+ attributes: |
+ {colorSpace: "display-p3"}
+ canvasType: ['HTMLCanvas']
+ code: |
+ deferTest();
+
+ const fullRedInP3 = [255, 0, 0, 255];
+ const sRGBRedInP3 = [234, 51, 35, 255];
+
+ canvas.width = 100;
+ canvas.height = 100;
+
+ let f = new FontFace("Ahem", "url(/fonts/Ahem.ttf)");
+ document.fonts.add(f);
+ f.load().then(function() {
+ t.step(function() {
+ ctx.font = "40px Ahem";
+
+ ctx.fillStyle = "#f00";
+ ctx.fillText("A", 0, 50);
+
+ ctx.fillStyle = "black";
+ ctx.fillStyle = "color(display-p3 100% 0 0)";
+ ctx.fillText("A", 50, 50);
+
+ let pixels = ctx.getImageData(0, 0, canvas.width, canvas.height, { colorSpace: "display-p3" }).data;
+ let pixelAt = function(x, y) {
+ let offset = (y * canvas.width + x) * 4;
+ return [pixels[offset], pixels[offset + 1], pixels[offset + 2], pixels[offset + 3]];
+ };
+
+ assert_array_equals(pixelAt(25, 25), sRGBRedInP3);
+ assert_array_equals(pixelAt(75, 25), fullRedInP3);
+
+ t.done();
+ });
+ });
+
+- name: 2d.color.space.p3.strokeText
+ desc: Test if strokeText can be used with a solid display-p3 color
+ attributes: |
+ {colorSpace: "display-p3"}
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ deferTest();
+
+ const fullRedInP3 = [255, 0, 0, 255];
+ const sRGBRedInP3 = [234, 51, 35, 255];
+
+ canvas.width = 100;
+ canvas.height = 100;
+
+ let f = new FontFace("Ahem", "url(/fonts/Ahem.ttf)");
+ document.fonts.add(f);
+ f.load().then(function() {
+ t.step(function() {
+ ctx.font = "40px Ahem";
+
+ ctx.strokeStyle = "#f00";
+ ctx.lineWidth = 20;
+ ctx.strokeText("A", 0, 50);
+
+ ctx.strokeStyle = "black";
+ ctx.strokeStyle = "color(display-p3 100% 0 0)";
+ ctx.strokeText("A", 50, 50);
+
+ let pixels = ctx.getImageData(0, 0, canvas.width, canvas.height, { colorSpace: "display-p3" }).data;
+ let pixelAt = function(x, y) {
+ let offset = (y * canvas.width + x) * 4;
+ return [pixels[offset], pixels[offset + 1], pixels[offset + 2], pixels[offset + 3]];
+ };
+
+ assert_array_equals(pixelAt(25, 25), sRGBRedInP3);
+ assert_array_equals(pixelAt(75, 25), fullRedInP3);
+
+ t.done();
+ });
+ });
+
+- name: 2d.color.space.p3.fillText.shadow
+ desc: Test if fillText can be used with a display-p3 shadow color
+ attributes: |
+ {colorSpace: "display-p3"}
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ deferTest();
+
+ const fullRedInP3 = [255, 0, 0, 255];
+ const sRGBRedInP3 = [234, 51, 35, 255];
+
+ canvas.width = 100;
+ canvas.height = 100;
+
+ let f = new FontFace("Ahem", "url(/fonts/Ahem.ttf)");
+ document.fonts.add(f);
+ f.load().then(function() {
+ t.step(function() {
+ ctx.font = "40px Ahem";
+
+ ctx.fillStyle = "black";
+ ctx.shadowBlur = 4;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = "#f00";
+ ctx.fillText("A", 0, 0);
+
+ ctx.shadowColor = "black";
+ ctx.shadowColor = "color(display-p3 100% 0 0)";
+ ctx.fillText("A", 50, 0);
+
+ let pixels = ctx.getImageData(0, 0, canvas.width, canvas.height, { colorSpace: "display-p3" }).data;
+ let pixelAt = function(x, y) {
+ let offset = (y * canvas.width + x) * 4;
+ return [pixels[offset], pixels[offset + 1], pixels[offset + 2], pixels[offset + 3]];
+ };
+
+ assert_array_equals(pixelAt(25, 25), sRGBRedInP3);
+ assert_array_equals(pixelAt(75, 25), fullRedInP3);
+
+ t.done();
+ });
+ });
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/compositing.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/compositing.yaml
new file mode 100644
index 0000000000..c0b7b83e00
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/compositing.yaml
@@ -0,0 +1,262 @@
+- name: 2d.composite.globalAlpha.range
+ code: |
+ ctx.globalAlpha = 0.5;
+ var a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons
+ ctx.globalAlpha = 1.1;
+ @assert ctx.globalAlpha === a;
+ ctx.globalAlpha = -0.1;
+ @assert ctx.globalAlpha === a;
+ ctx.globalAlpha = 0;
+ @assert ctx.globalAlpha === 0;
+ ctx.globalAlpha = 1;
+ @assert ctx.globalAlpha === 1;
+
+- name: 2d.composite.globalAlpha.invalid
+ code: |
+ ctx.globalAlpha = 0.5;
+ var a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons
+ ctx.globalAlpha = Infinity;
+ @assert ctx.globalAlpha === a;
+ ctx.globalAlpha = -Infinity;
+ @assert ctx.globalAlpha === a;
+ ctx.globalAlpha = NaN;
+ @assert ctx.globalAlpha === a;
+
+- name: 2d.composite.globalAlpha.default
+ code: |
+ @assert ctx.globalAlpha === 1.0;
+
+- name: 2d.composite.globalAlpha.fill
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 2,253,0,255;
+ expected: green
+
+- name: 2d.composite.globalAlpha.image
+ images:
+ - red.png
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
+ ctx.drawImage(document.getElementById('red.png'), 0, 0);
+ @assert pixel 50,25 ==~ 2,253,0,255;
+ expected: green
+
+- name: 2d.composite.globalAlpha.canvas
+ canvasType: ['HTMLCanvas']
+ code: |
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
+ ctx.drawImage(canvas2, 0, 0);
+ @assert pixel 50,25 ==~ 2,253,0,255;
+ expected: green
+
+- name: 2d.composite.globalAlpha.imagepattern
+ images:
+ - red.png
+ canvasType: ['HTMLCanvas']
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = ctx.createPattern(document.getElementById('red.png'), 'no-repeat');
+ ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 2,253,0,255;
+ expected: green
+
+- name: 2d.composite.globalAlpha.canvaspattern
+ canvasType: ['HTMLCanvas']
+ code: |
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = ctx.createPattern(canvas2, 'no-repeat');
+ ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 2,253,0,255;
+ expected: green
+
+- name: 2d.composite.globalAlpha.canvascopy
+ canvasType: ['HTMLCanvas']
+ code: |
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.globalCompositeOperation = 'copy'
+ ctx.globalAlpha = 0.51;
+ ctx.drawImage(canvas2, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,130;
+ expected: green
+
+
+- name: 2d.composite.operation.get
+ code: |
+ var modes = ['source-atop', 'source-in', 'source-out', 'source-over',
+ 'destination-atop', 'destination-in', 'destination-out', 'destination-over',
+ 'lighter', 'copy', 'xor'];
+ for (var i = 0; i < modes.length; ++i)
+ {
+ ctx.globalCompositeOperation = modes[i];
+ @assert ctx.globalCompositeOperation === modes[i];
+ }
+
+- name: 2d.composite.operation.unrecognised
+ code: |
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'nonexistent';
+ @assert ctx.globalCompositeOperation === 'xor';
+
+- name: 2d.composite.operation.darker
+ code: |
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'darker';
+ @assert ctx.globalCompositeOperation === 'xor';
+
+- name: 2d.composite.operation.over
+ code: |
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'over';
+ @assert ctx.globalCompositeOperation === 'xor';
+
+- name: 2d.composite.operation.clear
+ code: |
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'clear';
+ @assert ctx.globalCompositeOperation === 'clear';
+
+- name: 2d.composite.operation.highlight
+ code: |
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'highlight';
+ @assert ctx.globalCompositeOperation === 'xor';
+
+- name: 2d.composite.operation.nullsuffix
+ code: |
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'source-over\0';
+ @assert ctx.globalCompositeOperation === 'xor';
+
+- name: 2d.composite.operation.casesensitive
+ code: |
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'Source-over';
+ @assert ctx.globalCompositeOperation === 'xor';
+
+- name: 2d.composite.operation.default
+ code: |
+ @assert ctx.globalCompositeOperation === 'source-over';
+
+
+- name: 2d.composite.globalAlpha.image
+ canvasType: ['OffscreenCanvas']
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/red.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ @assert pixel 50,25 ==~ 2,253,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.composite.globalAlpha.canvas
+ canvasType: ['OffscreenCanvas']
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ @assert pixel 50,25 ==~ 2,253,0,255;
+
+- name: 2d.composite.globalAlpha.imagepattern
+ canvasType: ['OffscreenCanvas']
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/red.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
+ ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 2,253,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.composite.globalAlpha.canvaspattern
+ canvasType: ['OffscreenCanvas']
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = ctx.createPattern(offscreenCanvas2, 'no-repeat');
+ ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 2,253,0,255;
+
+- name: 2d.composite.globalAlpha.canvascopy
+ canvasType: ['OffscreenCanvas']
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy'
+ ctx.globalAlpha = 0.51;
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,130;
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/conformance_requirements.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/conformance_requirements.yaml
new file mode 100644
index 0000000000..3483d115f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/conformance_requirements.yaml
@@ -0,0 +1,178 @@
+- name: 2d.conformance.requirements.delete
+ desc: window.CanvasRenderingContext2D is Configurable
+ notes: &bindings Defined in "Web IDL" (draft)
+ canvasType: ['HTMLCanvas']
+ code: |
+ @assert window.CanvasRenderingContext2D !== undefined;
+ @assert delete window.CanvasRenderingContext2D === true;
+ @assert window.CanvasRenderingContext2D === undefined;
+
+- name: 2d.conformance.requirements.basics
+ desc: void methods return undefined
+ notes: *bindings
+ code: |
+ @assert ctx.save() === undefined;
+ @assert ctx.restore() === undefined;
+ @assert ctx.scale(1, 1) === undefined;
+ @assert ctx.rotate(0) === undefined;
+ @assert ctx.translate(0, 0) === undefined;
+ if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported)
+ @assert ctx.transform(1, 0, 0, 1, 0, 0) === undefined;
+ }
+ if (ctx.setTransform) {
+ @assert ctx.setTransform(1, 0, 0, 1, 0, 0) === undefined;
+ @assert ctx.setTransform() === undefined;
+ }
+ @assert ctx.clearRect(0, 0, 0, 0) === undefined;
+ @assert ctx.fillRect(0, 0, 0, 0) === undefined;
+ @assert ctx.strokeRect(0, 0, 0, 0) === undefined;
+ @assert ctx.beginPath() === undefined;
+ @assert ctx.closePath() === undefined;
+ @assert ctx.moveTo(0, 0) === undefined;
+ @assert ctx.lineTo(0, 0) === undefined;
+ @assert ctx.quadraticCurveTo(0, 0, 0, 0) === undefined;
+ @assert ctx.bezierCurveTo(0, 0, 0, 0, 0, 0) === undefined;
+ @assert ctx.arcTo(0, 0, 0, 0, 1) === undefined;
+ @assert ctx.rect(0, 0, 0, 0) === undefined;
+ @assert ctx.arc(0, 0, 1, 0, 0, true) === undefined;
+ @assert ctx.fill() === undefined;
+ @assert ctx.stroke() === undefined;
+ @assert ctx.clip() === undefined;
+ if (ctx.fillText) {
+ @assert ctx.fillText('test', 0, 0) === undefined;
+ @assert ctx.strokeText('test', 0, 0) === undefined;
+ }
+ if (ctx.putImageData) {
+ @assert ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0) === undefined;
+ }
+ @assert ctx.drawImage(canvas, 0, 0, 1, 1, 0, 0, 0, 0) === undefined;
+ @assert ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white') === undefined;
+
+- name: 2d.conformance.requirements.missingargs
+ desc: Missing arguments cause TypeError
+ code: |
+ @assert throws TypeError ctx.scale();
+ @assert throws TypeError ctx.scale(1);
+ @assert throws TypeError ctx.rotate();
+ @assert throws TypeError ctx.translate();
+ @assert throws TypeError ctx.translate(0);
+ if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported)
+ @assert throws TypeError ctx.transform();
+ @assert throws TypeError ctx.transform(1);
+ @assert throws TypeError ctx.transform(1, 0);
+ @assert throws TypeError ctx.transform(1, 0, 0);
+ @assert throws TypeError ctx.transform(1, 0, 0, 1);
+ @assert throws TypeError ctx.transform(1, 0, 0, 1, 0);
+ }
+ if (ctx.setTransform) {
+ @assert throws TypeError ctx.setTransform(1);
+ @assert throws TypeError ctx.setTransform(1, 0);
+ @assert throws TypeError ctx.setTransform(1, 0, 0);
+ @assert throws TypeError ctx.setTransform(1, 0, 0, 1);
+ @assert throws TypeError ctx.setTransform(1, 0, 0, 1, 0);
+ }
+ @assert throws TypeError ctx.createLinearGradient();
+ @assert throws TypeError ctx.createLinearGradient(0);
+ @assert throws TypeError ctx.createLinearGradient(0, 0);
+ @assert throws TypeError ctx.createLinearGradient(0, 0, 1);
+ @assert throws TypeError ctx.createRadialGradient();
+ @assert throws TypeError ctx.createRadialGradient(0);
+ @assert throws TypeError ctx.createRadialGradient(0, 0);
+ @assert throws TypeError ctx.createRadialGradient(0, 0, 1);
+ @assert throws TypeError ctx.createRadialGradient(0, 0, 1, 0);
+ @assert throws TypeError ctx.createRadialGradient(0, 0, 1, 0, 0);
+ @assert throws TypeError ctx.createPattern(canvas);
+ @assert throws TypeError ctx.clearRect();
+ @assert throws TypeError ctx.clearRect(0);
+ @assert throws TypeError ctx.clearRect(0, 0);
+ @assert throws TypeError ctx.clearRect(0, 0, 0);
+ @assert throws TypeError ctx.fillRect();
+ @assert throws TypeError ctx.fillRect(0);
+ @assert throws TypeError ctx.fillRect(0, 0);
+ @assert throws TypeError ctx.fillRect(0, 0, 0);
+ @assert throws TypeError ctx.strokeRect();
+ @assert throws TypeError ctx.strokeRect(0);
+ @assert throws TypeError ctx.strokeRect(0, 0);
+ @assert throws TypeError ctx.strokeRect(0, 0, 0);
+ @assert throws TypeError ctx.moveTo();
+ @assert throws TypeError ctx.moveTo(0);
+ @assert throws TypeError ctx.lineTo();
+ @assert throws TypeError ctx.lineTo(0);
+ @assert throws TypeError ctx.quadraticCurveTo();
+ @assert throws TypeError ctx.quadraticCurveTo(0);
+ @assert throws TypeError ctx.quadraticCurveTo(0, 0);
+ @assert throws TypeError ctx.quadraticCurveTo(0, 0, 0);
+ @assert throws TypeError ctx.bezierCurveTo();
+ @assert throws TypeError ctx.bezierCurveTo(0);
+ @assert throws TypeError ctx.bezierCurveTo(0, 0);
+ @assert throws TypeError ctx.bezierCurveTo(0, 0, 0);
+ @assert throws TypeError ctx.bezierCurveTo(0, 0, 0, 0);
+ @assert throws TypeError ctx.bezierCurveTo(0, 0, 0, 0, 0);
+ @assert throws TypeError ctx.arcTo();
+ @assert throws TypeError ctx.arcTo(0);
+ @assert throws TypeError ctx.arcTo(0, 0);
+ @assert throws TypeError ctx.arcTo(0, 0, 0);
+ @assert throws TypeError ctx.arcTo(0, 0, 0, 0);
+ @assert throws TypeError ctx.rect();
+ @assert throws TypeError ctx.rect(0);
+ @assert throws TypeError ctx.rect(0, 0);
+ @assert throws TypeError ctx.rect(0, 0, 0);
+ @assert throws TypeError ctx.arc();
+ @assert throws TypeError ctx.arc(0);
+ @assert throws TypeError ctx.arc(0, 0);
+ @assert throws TypeError ctx.arc(0, 0, 1);
+ @assert throws TypeError ctx.arc(0, 0, 1, 0);
+ // (6th argument to arc is optional)
+ if (ctx.isPointInPath) {
+ @assert throws TypeError ctx.isPointInPath();
+ @assert throws TypeError ctx.isPointInPath(0);
+ }
+ if (ctx.drawFocusRing) {
+ @assert throws TypeError ctx.drawFocusRing();
+ @assert throws TypeError ctx.drawFocusRing(canvas);
+ @assert throws TypeError ctx.drawFocusRing(canvas, 0);
+ }
+ if (ctx.fillText) {
+ @assert throws TypeError ctx.fillText();
+ @assert throws TypeError ctx.fillText('test');
+ @assert throws TypeError ctx.fillText('test', 0);
+ @assert throws TypeError ctx.strokeText();
+ @assert throws TypeError ctx.strokeText('test');
+ @assert throws TypeError ctx.strokeText('test', 0);
+ @assert throws TypeError ctx.measureText();
+ }
+ @assert throws TypeError ctx.drawImage();
+ @assert throws TypeError ctx.drawImage(canvas);
+ @assert throws TypeError ctx.drawImage(canvas, 0);
+ // TODO: n >= 3 args on drawImage could be either a valid overload,
+ // or too few for another overload, or too many for another
+ // overload - what should happen?
+ if (ctx.createImageData) {
+ @assert throws TypeError ctx.createImageData();
+ @assert throws TypeError ctx.createImageData(1);
+ }
+ if (ctx.getImageData) {
+ @assert throws TypeError ctx.getImageData();
+ @assert throws TypeError ctx.getImageData(0);
+ @assert throws TypeError ctx.getImageData(0, 0);
+ @assert throws TypeError ctx.getImageData(0, 0, 1);
+ }
+ if (ctx.putImageData) {
+ var imgdata = ctx.getImageData(0, 0, 1, 1);
+ @assert throws TypeError ctx.putImageData();
+ @assert throws TypeError ctx.putImageData(imgdata);
+ @assert throws TypeError ctx.putImageData(imgdata, 0);
+ }
+ var g = ctx.createLinearGradient(0, 0, 0, 0);
+ @assert throws TypeError g.addColorStop(); @moz-todo
+ @assert throws TypeError g.addColorStop(0); @moz-todo
+
+
+- name: 2d.conformance.requirements.drawings
+ desc: void methods return undefined
+ images:
+ - yellow.png
+ canvasType: ['HTMLCanvas']
+ code: |
+ @assert ctx.drawImage(document.getElementById('yellow.png'), 0, 0, 1, 1, 0, 0, 0, 0) === undefined;
+
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml
new file mode 100644
index 0000000000..83de88113f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml
@@ -0,0 +1,1333 @@
+- name: 2d.drawImage.3arg
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ - green.png
+ code: |
+ ctx.drawImage(document.getElementById('green.png'), 0, 0);
+ ctx.drawImage(document.getElementById('red.png'), -100, 0);
+ ctx.drawImage(document.getElementById('red.png'), 100, 0);
+ ctx.drawImage(document.getElementById('red.png'), 0, -50);
+ ctx.drawImage(document.getElementById('red.png'), 0, 50);
+
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.5arg
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ - green.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('green.png'), 50, 0, 50, 50);
+ ctx.drawImage(document.getElementById('red.png'), 0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.9arg.basic
+ canvasType: ['HTMLCanvas']
+ images:
+ - green.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('green.png'), 0, 0, 100, 50, 0, 0, 100, 50);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.9arg.sourcepos
+ canvasType: ['HTMLCanvas']
+ images:
+ - rgrg-256x256.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('rgrg-256x256.png'), 140, 20, 100, 50, 0, 0, 100, 50);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.9arg.sourcesize
+ canvasType: ['HTMLCanvas']
+ images:
+ - rgrg-256x256.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('rgrg-256x256.png'), 0, 0, 256, 256, 0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 51, 26);
+ ctx.fillRect(49, 24, 51, 26);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ @assert pixel 20,20 ==~ 0,255,0,255;
+ @assert pixel 80,20 ==~ 0,255,0,255;
+ @assert pixel 20,30 ==~ 0,255,0,255;
+ @assert pixel 80,30 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.9arg.destpos
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ - green.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('green.png'), 0, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, -100, 0, 100, 50);
+ ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 100, 0, 100, 50);
+ ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, -50, 100, 50);
+ ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, 50, 100, 50);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.9arg.destsize
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ - green.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('green.png'), 1, 1, 1, 1, 0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, -50, 0, 50, 50);
+ ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 100, 0, 50, 50);
+ ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, -25, 100, 25);
+ ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, 50, 100, 25);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.canvas
+ canvasType: ['HTMLCanvas']
+ code: |
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.drawImage(canvas2, 0, 0);
+
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+
+ ctx.drawImage(document.createElement('canvas'), 0, 0);
+
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.self.1
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.drawImage(canvas, 50, 0);
+
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.self.2
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 1, 100, 49);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 1);
+ ctx.drawImage(canvas, 0, 1);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 2);
+
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.null
+ code: |
+ @assert throws TypeError ctx.drawImage(null, 0, 0);
+
+- name: 2d.drawImage.wrongtype
+ desc: Incorrect image types in drawImage do not match any defined overloads, so
+ WebIDL throws a TypeError
+ code: |
+ @assert throws TypeError ctx.drawImage(undefined, 0, 0);
+ @assert throws TypeError ctx.drawImage(0, 0, 0);
+ @assert throws TypeError ctx.drawImage("", 0, 0);
+
+- name: 2d.drawImage.wrongtype.paragraph
+ desc: Incorrect image types in drawImage do not match any defined overloads, so
+ WebIDL throws a TypeError
+ notes: &bindings Defined in "Web IDL" (draft)
+ canvasType: ['HTMLCanvas']
+ code: |
+ @assert throws TypeError ctx.drawImage(document.createElement('p'), 0, 0);
+
+- name: 2d.drawImage.floatsource
+ canvasType: ['HTMLCanvas']
+ images:
+ - green.png
+ code: |
+ ctx.drawImage(document.getElementById('green.png'), 10.1, 10.1, 0.1, 0.1, 0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.zerosource
+ desc: drawImage with zero-sized source rectangle draws nothing without exception
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('red.png'), 10, 10, 0, 1, 0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('red.png'), 10, 10, 1, 0, 0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('red.png'), 10, 10, 0, 0, 0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.zerosource.image
+ desc: drawImage with zero-sized source rectangle from image draws nothing without exception
+ canvasType: ['HTMLCanvas']
+ images:
+ - red-zerowidth.svg
+ - red-zeroheight.svg
+ - red-zerosize.svg
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('red-zerowidth.svg'), 0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('red-zeroheight.svg'), 0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('red-zerosize.svg'), 0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.negativesource
+ desc: Negative source width/height represents the correct rectangle
+ canvasType: ['HTMLCanvas']
+ mozilla: {throws: !!null ''}
+ images:
+ - ggrr-256x256.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('ggrr-256x256.png'), 100, 78, -100, 50, 0, 0, 50, 50);
+ ctx.drawImage(document.getElementById('ggrr-256x256.png'), 100, 128, -100, -50, 50, 0, 50, 50);
+ @assert pixel 1,1 ==~ 0,255,0,255;
+ @assert pixel 1,48 ==~ 0,255,0,255;
+ @assert pixel 98,1 ==~ 0,255,0,255;
+ @assert pixel 98,48 ==~ 0,255,0,255;
+ @assert pixel 48,1 ==~ 0,255,0,255;
+ @assert pixel 48,48 ==~ 0,255,0,255;
+ @assert pixel 51,1 ==~ 0,255,0,255;
+ @assert pixel 51,48 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.negativedest
+ desc: Negative destination width/height represents the correct rectangle
+ canvasType: ['HTMLCanvas']
+ mozilla: {throws: !!null ''}
+ images:
+ - ggrr-256x256.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('ggrr-256x256.png'), 100, 78, 50, 50, 0, 50, 50, -50);
+ ctx.drawImage(document.getElementById('ggrr-256x256.png'), 100, 128, 50, -50, 100, 50, -50, -50);
+ @assert pixel 1,1 ==~ 0,255,0,255;
+ @assert pixel 1,48 ==~ 0,255,0,255;
+ @assert pixel 98,1 ==~ 0,255,0,255;
+ @assert pixel 98,48 ==~ 0,255,0,255;
+ @assert pixel 48,1 ==~ 0,255,0,255;
+ @assert pixel 48,48 ==~ 0,255,0,255;
+ @assert pixel 51,1 ==~ 0,255,0,255;
+ @assert pixel 51,48 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.negativedir
+ desc: Negative dimensions do not affect the direction of the image
+ canvasType: ['HTMLCanvas']
+ mozilla: {throws: !!null ''}
+ images:
+ - ggrr-256x256.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('ggrr-256x256.png'), 0, 178, 50, -100, 0, 0, 50, 100);
+ ctx.drawImage(document.getElementById('ggrr-256x256.png'), 0, 78, 50, 100, 50, 100, 50, -100);
+ @assert pixel 1,1 ==~ 0,255,0,255;
+ @assert pixel 1,48 ==~ 0,255,0,255;
+ @assert pixel 98,1 ==~ 0,255,0,255;
+ @assert pixel 98,48 ==~ 0,255,0,255;
+ @assert pixel 48,1 ==~ 0,255,0,255;
+ @assert pixel 48,48 ==~ 0,255,0,255;
+ @assert pixel 51,1 ==~ 0,255,0,255;
+ @assert pixel 51,48 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.outsidesource
+ DISABLED: fix this to match the current spec (transparent black outside source)
+ canvasType: ['HTMLCanvas']
+ mozilla: {throws: !!null ''}
+ images:
+ - green.png
+ - red.png
+ code: |
+ ctx.drawImage(document.getElementById('green.png'), 10.5, 10.5, 89.5, 39.5, 0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('green.png'), 5.5, 5.5, -5.5, -5.5, 0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('green.png'), 100, 50, -5, -5, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), -0.001, 0, 100, 50, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, -0.001, 100, 50, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, 100.001, 50, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50.001, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 50, 0, 50.001, 50, 0, 0, 100, 50); @moz-todo
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, -5, 5, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, 5, -5, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 110, 60, -20, -20, 0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.drawImage.incomplete.nosrc
+ canvasType: ['HTMLCanvas']
+ mozilla: {throws: !!null ''}
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = new Image();
+ ctx.drawImage(img, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.incomplete.immediate
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = new Image();
+ img.src = '../images/red.png';
+ // This triggers the "update the image data" algorithm.
+ // The image will not go to the "completely available" state
+ // until a fetch task in the networking task source is processed,
+ // so the image must not be fully decodable yet:
+ ctx.drawImage(img, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.drawImage.incomplete.reload
+ canvasType: ['HTMLCanvas']
+ images:
+ - yellow.png
+ - red.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = document.getElementById('yellow.png');
+ img.src = '../images/red.png';
+ // This triggers the "update the image data" algorithm,
+ // and resets the image to the "unavailable" state.
+ // The image will not go to the "completely available" state
+ // until a fetch task in the networking task source is processed,
+ // so the image must not be fully decodable yet:
+ ctx.drawImage(img, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.drawImage.incomplete.emptysrc
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ mozilla: {throws: !!null ''}
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = document.getElementById('red.png');
+ img.src = "";
+ ctx.drawImage(img, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.incomplete.removedsrc
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ mozilla: {throws: !!null ''}
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = document.getElementById('red.png');
+ img.removeAttribute('src');
+ ctx.drawImage(img, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.broken
+ canvasType: ['HTMLCanvas']
+ images:
+ - broken.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = document.getElementById('broken.png');
+ @assert throws INVALID_STATE_ERR ctx.drawImage(img, 0, 0);
+ expected: green
+
+- name: 2d.drawImage.nonexistent
+ canvasType: ['HTMLCanvas']
+ images:
+ - not-found-at-all.png
+ code: |
+ var img = document.getElementById('not-found-at-all.png');
+ @assert throws INVALID_STATE_ERR ctx.drawImage(img, 0, 0);
+
+- name: 2d.drawImage.zerocanvas
+ desc: drawImage with zero-sized canvas as the source shoud throw exception
+ code: |
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 0;
+ canvas2.height = 50;
+ @assert throws INVALID_STATE_ERR ctx.drawImage(canvas2, 0, 0);
+
+ canvas2.width = 50;
+ canvas2.height = 0;
+ @assert throws INVALID_STATE_ERR ctx.drawImage(canvas2, 0, 0);
+
+ canvas2.width = 0;
+ canvas2.height = 0;
+ @assert throws INVALID_STATE_ERR ctx.drawImage(canvas2, 0, 0);
+
+- name: 2d.drawImage.svg
+ desc: drawImage() of an SVG image
+ canvasType: ['HTMLCanvas']
+ images:
+ - green.svg
+ code: |
+ ctx.drawImage(document.getElementById('green.svg'), 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.animated.gif
+ desc: drawImage() of an animated GIF draws the first frame
+ canvasType: ['HTMLCanvas']
+ images:
+ - anim-gr.gif
+ code: |
+ deferTest();
+ step_timeout(t.step_func_done(function () {
+ ctx.drawImage(document.getElementById('anim-gr.gif'), 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ }), 500);
+ expected: green
+
+- name: 2d.drawImage.animated.apng
+ desc: drawImage() of an APNG with no poster frame draws the first frame
+ canvasType: ['HTMLCanvas']
+ images:
+ - anim-gr.png
+ code: |
+ deferTest();
+ step_timeout(t.step_func_done(function () {
+ ctx.drawImage(document.getElementById('anim-gr.png'), 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ }), 500);
+ expected: green
+
+- name: 2d.drawImage.animated.poster
+ desc: drawImage() of an APNG draws the poster frame
+ canvasType: ['HTMLCanvas']
+ images:
+ - anim-poster-gr.png
+ code: |
+ ctx.drawImage(document.getElementById('anim-poster-gr.png'), 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.drawImage.path
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.rect(0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('red.png'), 0, 0);
+ ctx.fill();
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.transform
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.translate(100, 0);
+ ctx.drawImage(document.getElementById('red.png'), 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+# TODO: drawImage shadows
+
+- name: 2d.drawImage.alpha
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0;
+ ctx.drawImage(document.getElementById('red.png'), 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.clip
+ images:
+ - red.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(-10, -10, 1, 1);
+ ctx.clip();
+ ctx.drawImage(document.getElementById('red.png'), 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.composite
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.drawImage(document.getElementById('red.png'), 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.nowrap
+ desc: Stretched images do not get pixels wrapping around the edges
+ canvasType: ['HTMLCanvas']
+ images:
+ - redtransparent.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(document.getElementById('redtransparent.png'), -1950, 0, 2000, 50);
+ @assert pixel 45,25 ==~ 0,255,0,255;
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ @assert pixel 55,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.nonfinite
+ desc: drawImage() with Infinity/NaN is ignored
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var red = document.getElementById('red.png');
+ @nonfinite ctx.drawImage(<red>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>);
+ @nonfinite ctx.drawImage(<red>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+ @nonfinite ctx.drawImage(<red>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.3arg
+ canvasType: ['OffscreenCanvas']
+ timeout: long
+ images:
+ - red.png
+ - green.png
+ code: |
+ var promise1 = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/red.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ var promise2 = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/green.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ Promise.all([promise1, promise2]).then(function(response1, response2) {
+ var promise3 = createImageBitmap(response1);
+ var promise4 = createImageBitmap(response2);
+ Promise.all([promise3, promise4]).then(function(bitmap1, bitmap2) {
+ ctx.drawImage(bitmap2, 0, 0);
+ ctx.drawImage(bitmap1, -100, 0);
+ ctx.drawImage(bitmap1, 100, 0);
+ ctx.drawImage(bitmap1, 0, -50);
+ ctx.drawImage(bitmap1, 0, 50);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.5arg
+ images:
+ - red.png
+ - green.png
+ canvasType: ['OffscreenCanvas']
+ timeout: long
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var promise1 = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/red.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ var promise2 = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/green.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ Promise.all([promise1, promise2]).then(function(response1, response2) {
+ var promise3 = createImageBitmap(response1);
+ var promise4 = createImageBitmap(response2);
+ Promise.all([promise3, promise4]).then(function(bitmap1, bitmap2) {
+ ctx.drawImage(bitmap2, 50, 0, 50, 50);
+ ctx.drawImage(bitmap1, 0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.9arg.basic
+ canvasType: ['OffscreenCanvas']
+ images:
+ - green.png
+ timeout: long
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/green.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, 100, 50);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.9arg.sourcepos
+ canvasType: ['OffscreenCanvas']
+ images:
+ - rgrg-256x256.png
+ timeout: long
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/rgrg-256x256.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 140, 20, 100, 50, 0, 0, 100, 50);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.9arg.sourcesize
+ canvasType: ['OffscreenCanvas']
+ images:
+ - rgrg-256x256.png
+ timeout: long
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/rgrg-256x256.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0, 256, 256, 0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 51, 26);
+ ctx.fillRect(49, 24, 51, 26);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ @assert pixel 20,20 ==~ 0,255,0,255;
+ @assert pixel 80,20 ==~ 0,255,0,255;
+ @assert pixel 20,30 ==~ 0,255,0,255;
+ @assert pixel 80,30 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.9arg.destpos
+ canvasType: ['OffscreenCanvas']
+ images:
+ - red.png
+ - green.png
+ timeout: long
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var promise1 = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/red.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ var promise2 = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/green.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ Promise.all([promise1, promise2]).then(function(response1, response2) {
+ var promise3 = createImageBitmap(response1);
+ var promise4 = createImageBitmap(response2);
+ Promise.all([promise3, promise4]).then(function(bitmap1, bitmap2) {
+ ctx.drawImage(bitmap2, 0, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap1, 0, 0, 100, 50, -100, 0, 100, 50);
+ ctx.drawImage(bitmap1, 0, 0, 100, 50, 100, 0, 100, 50);
+ ctx.drawImage(bitmap1, 0, 0, 100, 50, 0, -50, 100, 50);
+ ctx.drawImage(bitmap1, 0, 0, 100, 50, 0, 50, 100, 50);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.9arg.destsize
+ canvasType: ['OffscreenCanvas']
+ images:
+ - red.png
+ - green.png
+ timeout: long
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var promise1 = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/red.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ var promise2 = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/green.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ Promise.all([promise1, promise2]).then(function(response1, response2) {
+ var promise3 = createImageBitmap(response1);
+ var promise4 = createImageBitmap(response2);
+ Promise.all([promise3, promise4]).then(function(bitmap1, bitmap2) {
+ ctx.drawImage(bitmap2, 1, 1, 1, 1, 0, 0, 100, 50);
+ ctx.drawImage(bitmap1, 0, 0, 100, 50, -50, 0, 50, 50);
+ ctx.drawImage(bitmap1, 0, 0, 100, 50, 100, 0, 50, 50);
+ ctx.drawImage(bitmap1, 0, 0, 100, 50, 0, -25, 100, 25);
+ ctx.drawImage(bitmap1, 0, 0, 100, 50, 0, 50, 100, 25);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.canvas
+ canvasType: ['OffscreenCanvas']
+ timeout: long
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+
+- name: 2d.drawImage.zerocanvas
+ canvasType: ['OffscreenCanvas']
+ timeout: long
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(0, 10);
+ @assert throws INVALID_STATE_ERR ctx.drawImage(offscreenCanvas2, 0, 0);
+
+ offscreenCanvas2.width = 10;
+ offscreenCanvas2.height = 0;
+ @assert throws INVALID_STATE_ERR ctx.drawImage(offscreenCanvas2, 0, 0);
+
+ offscreenCanvas2.width = 0;
+ offscreenCanvas2.height = 0;
+ @assert throws INVALID_STATE_ERR ctx.drawImage(offscreenCanvas2, 0, 0);
+
+- name: 2d.drawImage.floatsource
+ canvasType: ['OffscreenCanvas']
+ timeout: long
+ code: |
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/green.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 10.1, 10.1, 0.1, 0.1, 0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.zerosource
+ desc: drawImage with zero-sized source rectangle draws nothing without exception
+ canvasType: ['OffscreenCanvas']
+ timeout: long
+ images:
+ - red.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/green.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 10, 10, 0, 1, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 10, 10, 1, 0, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 10, 10, 0, 0, 0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.zerosource.image
+ desc: drawImage with zero-sized source rectangle from image draws nothing without exception
+ canvasType: ['OffscreenCanvas']
+ images:
+ - red-zerowidth.svg
+ - red-zeroheight.svg
+ - red-zerosize.svg
+ timeout: long
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/red-zerowidth.svg');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.negativesource
+ desc: Negative source width/height represents the correct rectangle
+ canvasType: ['OffscreenCanvas']
+ mozilla: {throws: !!null ''}
+ images:
+ - ggrr-256x256.png
+ timeout: long
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/ggrr-256x256.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 100, 78, -100, 50, 0, 0, 50, 50);
+ ctx.drawImage(bitmap, 100, 128, -100, -50, 50, 0, 50, 50);
+ @assert pixel 1,1 ==~ 0,255,0,255;
+ @assert pixel 1,48 ==~ 0,255,0,255;
+ @assert pixel 98,1 ==~ 0,255,0,255;
+ @assert pixel 98,48 ==~ 0,255,0,255;
+ @assert pixel 48,1 ==~ 0,255,0,255;
+ @assert pixel 48,48 ==~ 0,255,0,255;
+ @assert pixel 51,1 ==~ 0,255,0,255;
+ @assert pixel 51,48 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.negativedest
+ desc: Negative destination width/height represents the correct rectangle
+ canvasType: ['OffscreenCanvas']
+ mozilla: {throws: !!null ''}
+ timeout: long
+ images:
+ - ggrr-256x256.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/ggrr-256x256.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 100, 78, 50, 50, 0, 50, 50, -50);
+ ctx.drawImage(bitmap, 100, 128, 50, -50, 100, 50, -50, -50);
+ @assert pixel 1,1 ==~ 0,255,0,255;
+ @assert pixel 1,48 ==~ 0,255,0,255;
+ @assert pixel 98,1 ==~ 0,255,0,255;
+ @assert pixel 98,48 ==~ 0,255,0,255;
+ @assert pixel 48,1 ==~ 0,255,0,255;
+ @assert pixel 48,48 ==~ 0,255,0,255;
+ @assert pixel 51,1 ==~ 0,255,0,255;
+ @assert pixel 51,48 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.negativedir
+ desc: Negative dimensions do not affect the direction of the image
+ canvasType: ['OffscreenCanvas']
+ mozilla: {throws: !!null ''}
+ timeout: long
+ images:
+ - ggrr-256x256.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/ggrr-256x256.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 178, 50, -100, 0, 0, 50, 100);
+ ctx.drawImage(bitmap, 0, 78, 50, 100, 50, 100, 50, -100);
+ @assert pixel 1,1 ==~ 0,255,0,255;
+ @assert pixel 1,48 ==~ 0,255,0,255;
+ @assert pixel 98,1 ==~ 0,255,0,255;
+ @assert pixel 98,48 ==~ 0,255,0,255;
+ @assert pixel 48,1 ==~ 0,255,0,255;
+ @assert pixel 48,48 ==~ 0,255,0,255;
+ @assert pixel 51,1 ==~ 0,255,0,255;
+ @assert pixel 51,48 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.outsidesource
+ DISABLED: fix this to match the current spec (transparent black outside source)
+ canvasType: ['OffscreenCanvas']
+ code: |
+ var promise1 = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/red.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ var promise2 = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/green.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ Promise.all([promise1, promise2]).then(function(response1, response2) {
+ var promise3 = createImageBitmap(response1);
+ var promise4 = createImageBitmap(response2);
+ Promise.all([promise3, promise4]).then(function(bitmap1, bitmap2) {
+ ctx.drawImage(bitmap2, 10.5, 10.5, 89.5, 39.5, 0, 0, 100, 50);
+ ctx.drawImage(bitmap2, 5.5, 5.5, -5.5, -5.5, 0, 0, 100, 50);
+ ctx.drawImage(bitmap2, 100, 50, -5, -5, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, -0.001, 0, 100, 50, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, 0, -0.001, 100, 50, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, 0, 0, 100.001, 50, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, 0, 0, 100, 50.001, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, 50, 0, 50.001, 50, 0, 0, 100, 50); @moz-todo
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, 0, 0, -5, 5, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, 0, 0, 5, -5, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, 110, 60, -20, -20, 0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.broken
+ canvasType: ['OffscreenCanvas']
+ timeout: long
+ code: |
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/broken.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.svg
+ desc: drawImage() of an SVG image
+ canvasType: ['OffscreenCanvas']
+ timeout: long
+ code: |
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/green.svg');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.animated.poster
+ desc: drawImage() of an APNG draws the poster frame
+ canvasType: ['OffscreenCanvas']
+ images:
+ - anim-poster-gr.png
+ timeout: long
+ code: |
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/anim-poster-gr.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.path
+ canvasType: ['OffscreenCanvas']
+ timeout: long
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.rect(0, 0, 100, 50);
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/red.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ ctx.fill();
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.transform
+ canvasType: ['OffscreenCanvas']
+ images:
+ - red.png
+ timeout: long
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.translate(100, 0);
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/red.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.alpha
+ canvasType: ['OffscreenCanvas']
+ images:
+ - red.png
+ timeout: long
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0;
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/red.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.clip
+ canvasType: ['OffscreenCanvas']
+ images:
+ - red.png
+ timeout: long
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(-10, -10, 1, 1);
+ ctx.clip();
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/red.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.composite
+ canvasType: ['OffscreenCanvas']
+ images:
+ - red.png
+ timeout: long
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/red.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.nowrap
+ desc: Stretched images do not get pixels wrapping around the edges
+ canvasType: ['OffscreenCanvas']
+ images:
+ - redtransparent.png
+ timeout: long
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/redtransparent.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, -1950, 0, 2000, 50);
+ @assert pixel 45,25 ==~ 0,255,0,255;
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ @assert pixel 55,25 ==~ 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
+- name: 2d.drawImage.nonfinite
+ desc: drawImage() with Infinity/NaN is ignored
+ canvasType: ['OffscreenCanvas']
+ images:
+ - red.png
+ timeout: long
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/redtransparent.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ createImageBitmap(response).then(bitmap => {
+ @nonfinite ctx.drawImage(<bitmap>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>);
+ @nonfinite ctx.drawImage(<bitmap>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+ @nonfinite ctx.drawImage(<bitmap>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+ @assert pixel 50,25 == 0,255,0,255;
+ }, t_fail);
+ }).then(t_pass, t_fail);
+
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-rectangles-to-the-canvas.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-rectangles-to-the-canvas.yaml
new file mode 100644
index 0000000000..408e932abe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-rectangles-to-the-canvas.yaml
@@ -0,0 +1,469 @@
+- name: 2d.clearRect.basic
+ desc: clearRect clears to transparent black
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.clearRect.path
+ desc: clearRect does not affect the current path
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 16, 16);
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.clearRect.zero
+ desc: clearRect of zero pixels has no effect
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 100, 0);
+ ctx.clearRect(0, 0, 0, 50);
+ ctx.clearRect(0, 0, 0, 0);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.clearRect.negative
+ desc: clearRect of negative sizes works
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 50, 25);
+ ctx.clearRect(100, 0, -50, 25);
+ ctx.clearRect(0, 50, 50, -25);
+ ctx.clearRect(100, 50, -50, -25);
+ @assert pixel 25,12 == 0,0,0,0;
+ @assert pixel 75,12 == 0,0,0,0;
+ @assert pixel 25,37 == 0,0,0,0;
+ @assert pixel 75,37 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.clearRect.transform
+ desc: clearRect is affected by transforms
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(10, 10);
+ ctx.translate(0, 5);
+ ctx.clearRect(0, -5, 10, 5);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.clearRect.globalalpha
+ desc: clearRect is not affected by globalAlpha
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0.1;
+ ctx.clearRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.clearRect.globalcomposite
+ desc: clearRect is not affected by globalCompositeOperation
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.clearRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.clearRect.clip
+ desc: clearRect is affected by clipping regions
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.rect(0, 0, 16, 16);
+ ctx.clip();
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 16);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.clearRect.shadow
+ desc: clearRect does not draw shadows
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 0;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.clearRect(0, -50, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.clearRect.nonfinite
+ desc: clearRect() with Infinity/NaN is ignored
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ @nonfinite ctx.clearRect(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+
+- name: 2d.fillRect.basic
+ desc: fillRect works
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillRect.path
+ desc: fillRect does not affect the current path
+ code: |
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 16, 16);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillRect.zero
+ desc: fillRect of zero pixels has no effect
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 0);
+ ctx.fillRect(0, 0, 0, 50);
+ ctx.fillRect(0, 0, 0, 0);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillRect.negative
+ desc: fillRect of negative sizes works
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+ ctx.fillRect(100, 0, -50, 25);
+ ctx.fillRect(0, 50, 50, -25);
+ ctx.fillRect(100, 50, -50, -25);
+ @assert pixel 25,12 == 0,255,0,255;
+ @assert pixel 75,12 == 0,255,0,255;
+ @assert pixel 25,37 == 0,255,0,255;
+ @assert pixel 75,37 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillRect.transform
+ desc: fillRect is affected by transforms
+ code: |
+ ctx.scale(10, 10);
+ ctx.translate(0, 5);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, -5, 10, 5);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+# don't bother testing globalalpha, globalcomposite because they're already heavily used by other test cases
+
+- name: 2d.fillRect.clip
+ desc: fillRect is affected by clipping regions
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.rect(0, 0, 16, 16);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 16);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillRect.shadow
+ desc: fillRect draws shadows
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowBlur = 0;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillRect.nonfinite
+ desc: fillRect() with Infinity/NaN is ignored
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ @nonfinite ctx.fillRect(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+
+- name: 2d.strokeRect.basic
+ desc: strokeRect works
+ code: |
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeRect.path
+ desc: strokeRect does not affect the current path
+ code: |
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 5;
+ ctx.strokeRect(0, 0, 16, 16);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeRect.zero.1
+ desc: strokeRect of 0x0 pixels draws nothing
+ code: |
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 250;
+ ctx.strokeRect(50, 25, 0, 0);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.strokeRect.zero.2
+ desc: strokeRect of 0x0 pixels draws nothing, including caps and joins
+ code: |
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 250;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+ ctx.strokeRect(50, 25, 0, 0);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.strokeRect.zero.3
+ desc: strokeRect of Nx0 pixels draws a straight line
+ code: |
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(0, 25, 100, 0);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeRect.zero.4
+ desc: strokeRect of Nx0 pixels draws a closed line with no caps
+ code: |
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 250;
+ ctx.lineCap = 'round';
+ ctx.strokeRect(100, 25, 100, 0);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.strokeRect.zero.5
+ desc: strokeRect of Nx0 pixels draws a closed line with joins
+ code: |
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 250;
+ ctx.lineJoin = 'round';
+ ctx.strokeRect(100, 25, 100, 0);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeRect.negative
+ desc: strokeRect of negative sizes works
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 25;
+ ctx.strokeRect(12, 12, 26, 1);
+ ctx.strokeRect(88, 12, -26, 1);
+ ctx.strokeRect(12, 38, 26, -1);
+ ctx.strokeRect(88, 38, -26, -1);
+ @assert pixel 25,12 == 0,255,0,255;
+ @assert pixel 75,12 == 0,255,0,255;
+ @assert pixel 25,37 == 0,255,0,255;
+ @assert pixel 75,37 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeRect.transform
+ desc: fillRect is affected by transforms
+ code: |
+ ctx.scale(10, 10);
+ ctx.translate(0, 5);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 5;
+ ctx.strokeRect(2.5, -2.6, 5, 0.2);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeRect.globalalpha
+ desc: strokeRect is affected by globalAlpha
+ code: |
+ ctx.globalAlpha = 0;
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.strokeRect.globalcomposite
+ desc: strokeRect is not affected by globalCompositeOperation
+ code: |
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.strokeRect.clip
+ desc: strokeRect is affected by clipping regions
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.rect(0, 0, 16, 16);
+ ctx.clip();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 16);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeRect.shadow
+ desc: strokeRect draws shadows
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowBlur = 0;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(0, -75, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeRect.nonfinite
+ desc: strokeRect() with Infinity/NaN is ignored
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 150;
+ @nonfinite ctx.strokeRect(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillStyle.colorObject
+ desc: ctx.fillStyle works with color objects
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ ctx.fillStyle = {r: 1, g: 0, b: 0};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 255,0,0,255;
+ ctx.fillStyle = {r: 0, g: 0, b: 1};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,0,255,255;
+ ctx.fillStyle = {r: 0.2, g: 0.4, b: 0.6};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 51,102,153,255;
+ ctx.fillStyle = {r: 0, g: 1, b: 0};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ ctx.fillStyle = {r: -1, g: 0, b: 0};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,0,0,255;
+ ctx.fillStyle = {r: 0, g: 2, b: 0};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillStyle.colorObject.transparency
+ desc: ctx.fillStyle with color objects has transparency
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ ctx.fillStyle = {r: 0, g: 1, b: 0, a: 0};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,0,0,0;
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.fillStyle = {r: 0, g: 1, b: 0, a: -1};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,0,0,0;
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.fillStyle = {r: 0, g: 1, b: 0, a: 0.5};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,128;
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.fillStyle = {r: 0, g: 1, b: 0, a: 1};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeStyle.colorObject
+ desc: ctx.strokeStyle works with color objects
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = {r: 1, g: 0, b: 0};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 255,0,0,255;
+ ctx.strokeStyle = {r: 0, g: 0, b: 1};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,0,255,255;
+ ctx.strokeStyle = {r: 0.2, g: 0.4, b: 0.6};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 51,102,153,255;
+ ctx.strokeStyle = {r: 0, g: 1, b: 0};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,255,0,255;
+ ctx.strokeStyle = {r: -1, g: 0, b: 0};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,0,0,255;
+ ctx.strokeStyle = {r: 0, g: 2, b: 0};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeStyle.colorObject.transparency
+ desc: ctx.strokeStyle with color objects has transparency
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = {r: 0, g: 1, b: 0, a: 0};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,0,0,0;
+ ctx.strokeStyle = {r: 0, g: 1, b: 0, a: -1};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,0,0,0;
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.strokeStyle = {r: 0, g: 1, b: 0, a: 0.5};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,255,0,128;
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.strokeStyle = {r: 0, g: 1, b: 0, a: 1};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/filters.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/filters.yaml
new file mode 100644
index 0000000000..cc5dfe7fef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/filters.yaml
@@ -0,0 +1,450 @@
+- name: 2d.filter.value
+ desc: test if ctx.filter works correctly
+ code: |
+ @assert ctx.filter == 'none';
+ ctx.filter = 'blur(5px)';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.save();
+ ctx.filter = 'none';
+ @assert ctx.filter == 'none';
+ ctx.restore();
+ @assert ctx.filter == 'blur(5px)';
+
+ ctx.filter = 'blur(10)';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = 'blur 10px';
+ @assert ctx.filter == 'blur(5px)';
+
+ ctx.filter = 'inherit';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = 'initial';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = 'unset';
+ @assert ctx.filter == 'blur(5px)';
+
+ ctx.filter = '';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = null;
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = undefined;
+ @assert ctx.filter == 'blur(5px)';
+
+ ctx.filter = 'blur( 5px)';
+ assert_equals(ctx.filter, 'blur( 5px)');
+
+- name: 2d.filter.canvasFilterObject.tentative
+ desc: Test CanvasFilter() object
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ @assert ctx.filter == 'none';
+ ctx.filter = 'blur(5px)';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+ ctx.filter = new CanvasFilter([
+ {filter: "gaussianBlur", stdDeviation: 5},
+ {filter: "gaussianBlur", stdDeviation: 10}
+ ]);
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+ var canvas2 = document.createElement('canvas');
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.filter = ctx.filter;
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+ ctx.filter = 'blur(5px)';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = 'none';
+ @assert ctx.filter == 'none';
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.filter = "this string is not a filter and should do nothing";
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+
+- name: 2d.filter.canvasFilterObject.tentative
+ desc: Test CanvasFilter() object
+ canvasType: ['OffscreenCanvas']
+ code: |
+ @assert ctx.filter == 'none';
+ ctx.filter = 'blur(5px)';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+ ctx.filter = new CanvasFilter([
+ {filter: "gaussianBlur", stdDeviation: 5},
+ {filter: "gaussianBlur", stdDeviation: 10}
+ ]);
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.filter = ctx.filter;
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+ ctx.filter = 'blur(5px)';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = 'none';
+ @assert ctx.filter == 'none';
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.filter = "this string is not a filter and should do nothing";
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+
+- name: 2d.filter.canvasFilterObject.blur.exceptions.tentative
+ desc: Test exceptions on CanvasFilter() blur.object
+ code: |
+ @assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur"});
+ @assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: undefined});
+ @assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: "foo"});
+ @assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: [1,2]});
+ @assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: NaN});
+ @assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: {}});
+
+- name: 2d.filter.canvasFilterObject.colorMatrix.tentative
+ desc: Test the functionality of ColorMatrix filters in CanvasFilter objects
+ code: |
+ @assert throws TypeError new CanvasFilter({filter: "colorMatrix", values: undefined});
+ @assert throws TypeError new CanvasFilter({filter: "colorMatrix", values: "foo"});
+ @assert throws TypeError new CanvasFilter({filter: "colorMatrix", values: null});
+ @assert throws TypeError new CanvasFilter({filter: "colorMatrix", values: [1, 2, 3]});
+ @assert throws TypeError new CanvasFilter({filter: "colorMatrix", values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, "a"]});
+ @assert throws TypeError new CanvasFilter({filter: "colorMatrix", values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, Infinity]});
+ ctx.fillStyle = "#f00";
+ ctx.filter = new CanvasFilter({filter: "colorMatrix", type: "hueRotate", values: 0});
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 10,10 ==~ 255,0,0,255;
+ ctx.filter = new CanvasFilter({filter: "colorMatrix", type: "hueRotate", values: 90});
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 10,10 ==~ 0,91,0,255;
+ ctx.filter = new CanvasFilter({filter: "colorMatrix", type: "hueRotate", values: 180});
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 10,10 ==~ 0,109,109,255;
+ ctx.filter = new CanvasFilter({filter: "colorMatrix", type: "hueRotate", values: 270});
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 10,10 ==~ 109,18,255,255;
+ ctx.filter = new CanvasFilter({filter: "colorMatrix", type: "saturate", values: 0.5});
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 10,10 ==~ 155,27,27,255;
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.filter = new CanvasFilter({filter: "colorMatrix", type: "luminanceToAlpha"});
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 10,10 ==~ 0,0,0,54;
+ ctx.filter = new CanvasFilter({filter: "colorMatrix", values: [
+ 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0
+ ]});
+ ctx.fillRect(0, 0, 50, 25);
+ ctx.fillStyle = "#0f0";
+ ctx.fillRect(50, 0, 50, 25);
+ ctx.fillStyle = "#00f";
+ ctx.fillRect(0, 25, 50, 25);
+ ctx.fillStyle = "#fff";
+ ctx.fillRect(50, 25, 50, 25);
+ @assert pixel 10,10 ==~ 0,255,0,255;
+ @assert pixel 60,10 ==~ 0,255,0,255;
+ @assert pixel 10,30 ==~ 0,255,0,255;
+ @assert pixel 60,30 ==~ 0,255,0,255;
+
+- name: 2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative
+ desc: Test exceptions on CanvasFilter() convolveMatrix
+ code: |
+ @assert throws TypeError new CanvasFilter({filter: "convolveMatrix"});
+ @assert throws TypeError new CanvasFilter({filter: "convolveMatrix", divisor: 2});
+ @assert throws TypeError new CanvasFilter({filter: "convolveMatrix", kernelMatrix: null});
+ @assert throws TypeError new CanvasFilter({filter: "convolveMatrix", kernelMatrix: 1});
+ @assert throws TypeError new CanvasFilter({filter: "convolveMatrix", kernelMatrix: [[1, 0], [0]]});
+ @assert throws TypeError new CanvasFilter({filter: "convolveMatrix", kernelMatrix: [[1, "a"], [0]]});
+ @assert throws TypeError new CanvasFilter({filter: "convolveMatrix", kernelMatrix: [[1, 0], 0]});
+ @assert throws TypeError new CanvasFilter({filter: "convolveMatrix", kernelMatrix: [[1, 0], [0, Infinity]]});
+ @assert throws TypeError new CanvasFilter({filter: "convolveMatrix", kernelMatrix: []});
+ // This should not throw an error
+ ctx.filter = new CanvasFilter({filter: "convolveMatrix", kernelMatrix: [[]]});
+
+- name: 2d.filter.canvasFilterObject.componentTransfer.linear.tentative
+ desc: Test pixels on CanvasFilter() componentTransfer with linear type
+ code: |
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getColor(inputColor, slopes, intercepts) {
+ return [
+ Math.max(0, Math.min(1, inputColor[0]/255 * slopes[0] + intercepts[0])) * 255,
+ Math.max(0, Math.min(1, inputColor[1]/255 * slopes[1] + intercepts[1])) * 255,
+ Math.max(0, Math.min(1, inputColor[2]/255 * slopes[2] + intercepts[2])) * 255,
+ ];
+ }
+
+ const slopes = [0.5, 1.2, -0.2];
+ const intercepts = [0.25, 0, 0.5];
+ ctx.filter = new CanvasFilter({filter: "componentTransfer",
+ funcR: {type: "linear", slope: slopes[0], intercept: intercepts[0]},
+ funcG: {type: "linear", slope: slopes[1], intercept: intercepts[1]},
+ funcB: {type: "linear", slope: slopes[2], intercept: intercepts[2]},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, slopes, intercepts);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+
+- name: 2d.filter.canvasFilterObject.componentTransfer.identity.tentative
+ desc: Test pixels on CanvasFilter() componentTransfer with identity type
+ code: |
+ ctx.filter = new CanvasFilter({filter: "componentTransfer",
+ funcR: {type: "identity"},
+ funcG: {type: "identity"},
+ funcB: {type: "identity"},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ ctx.fillStyle = `rgba(${color[0]}, ${color[1]}, ${color[2]}, 1)`,
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixel(canvas, 5, 5, color[0],color[1],color[2],255);
+ }
+
+- name: 2d.filter.canvasFilterObject.componentTransfer.gamma.tentative
+ desc: Test pixels on CanvasFilter() componentTransfer with gamma type
+ code: |
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getColor(inputColor, amplitude, exponent, offset) {
+ return [
+ Math.max(0, Math.min(1, Math.pow(inputColor[0]/255, exponent[0]) * amplitude[0] + offset[0])) * 255,
+ Math.max(0, Math.min(1, Math.pow(inputColor[1]/255, exponent[1]) * amplitude[1] + offset[1])) * 255,
+ Math.max(0, Math.min(1, Math.pow(inputColor[2]/255, exponent[2]) * amplitude[2] + offset[2])) * 255,
+ ];
+ }
+
+ const amplitudes = [2, 1.1, 0.5];
+ const exponents = [5, 3, 1];
+ const offsets = [0.25, 0, 0.5];
+ ctx.filter = new CanvasFilter({filter: "componentTransfer",
+ funcR: {type: "gamma", amplitude: amplitudes[0], exponent: exponents[0], offset: offsets[0]},
+ funcG: {type: "gamma", amplitude: amplitudes[1], exponent: exponents[1], offset: offsets[1]},
+ funcB: {type: "gamma", amplitude: amplitudes[2], exponent: exponents[2], offset: offsets[2]},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, amplitudes, exponents, offsets);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+
+- name: 2d.filter.canvasFilterObject.componentTransfer.table.tentative
+ desc: Test pixels on CanvasFilter() componentTransfer with table type
+ code: |
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getTransformedValue(C, V) {
+ // Get the right interval
+ const n = V.length - 1;
+ const k = C == 1 ? n - 1 : Math.floor(C * n);
+ return V[k] + (C - k/n) * n * (V[k + 1] - V[k]);
+ }
+
+ function getColor(inputColor, tableValues) {
+ const result = [0, 0, 0];
+ for (const i in inputColor) {
+ const C = inputColor[i]/255;
+ const Cprime = getTransformedValue(C, tableValues[i]);
+ result[i] = Math.max(0, Math.min(1, Cprime)) * 255;
+ }
+ return result;
+ }
+
+ tableValuesR = [0, 0, 1, 1];
+ tableValuesG = [2, 0, 0.5, 3];
+ tableValuesB = [1, -1, 5, 0];
+ ctx.filter = new CanvasFilter({filter: "componentTransfer",
+ funcR: {type: "table", tableValues: tableValuesR},
+ funcG: {type: "table", tableValues: tableValuesG},
+ funcB: {type: "table", tableValues: tableValuesB},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+
+- name: 2d.filter.canvasFilterObject.componentTransfer.discrete.tentative
+ desc: Test pixels on CanvasFilter() componentTransfer with discrete type
+ code: |
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getTransformedValue(C, V) {
+ // Get the right interval
+ const n = V.length;
+ const k = C == 1 ? n - 1 : Math.floor(C * n);
+ return V[k];
+ }
+
+ function getColor(inputColor, tableValues) {
+ const result = [0, 0, 0];
+ for (const i in inputColor) {
+ const C = inputColor[i]/255;
+ const Cprime = getTransformedValue(C, tableValues[i]);
+ result[i] = Math.max(0, Math.min(1, Cprime)) * 255;
+ }
+ return result;
+ }
+
+ tableValuesR = [0, 0, 1, 1];
+ tableValuesG = [2, 0, 0.5, 3];
+ tableValuesB = [1, -1, 5, 0];
+ ctx.filter = new CanvasFilter({filter: "componentTransfer",
+ funcR: {type: "discrete", tableValues: tableValuesR},
+ funcG: {type: "discrete", tableValues: tableValuesG},
+ funcB: {type: "discrete", tableValues: tableValuesB},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+
+- name: 2d.filter.canvasFilterObject.turbulence.inputTypes.tentative
+ desc: Test exceptions on CanvasFilter() turbulence object
+ code: |
+ const errorTestCases = [
+ {baseFrequency: {}},
+ {baseFrequency: -1},
+ {baseFrequency: [0, -1]},
+ {baseFrequency: NaN},
+ {baseFrequency: Infinity},
+ {baseFrequency: undefined},
+ {baseFrequency: -Infinity},
+ {baseFrequency: "test"},
+
+ {numOctaves: {}},
+ {numOctaves: -1},
+ {numOctaves: NaN},
+ {numOctaves: Infinity},
+ {numOctaves: undefined},
+ {numOctaves: -Infinity},
+ {numOctaves: [1, 1]},
+ {numOctaves: "test"},
+
+ {seed: {}},
+ {seed: NaN},
+ {seed: Infinity},
+ {seed: undefined},
+ {seed: -Infinity},
+ {seed: [1, 1]},
+ {seed: "test"},
+
+ {stitchTiles: {}},
+ {stitchTiles: NaN},
+ {stitchTiles: Infinity},
+ {stitchTiles: undefined},
+ {stitchTiles: -Infinity},
+ {stitchTiles: [1, 1]},
+ {stitchTiles: "test"},
+ {stitchTiles: null},
+ {stitchTiles: []},
+ {stitchTiles: [10]},
+ {stitchTiles: 30},
+ {stitchTiles: false},
+ {stitchTiles: true},
+ {stitchTiles: "10"},
+ {stitchTiles: -1},
+
+ {type: {}},
+ {type: NaN},
+ {type: Infinity},
+ {type: undefined},
+ {type: -Infinity},
+ {type: [1, 1]},
+ {type: "test"},
+ {type: null},
+ {type: []},
+ {type: [10]},
+ {type: 30},
+ {type: false},
+ {type: true},
+ {type: "10"},
+ {type: -1},
+ ]
+
+ // null and [] = 0 when parsed as number
+ const workingTestCases = [
+ {baseFrequency: null},
+ {baseFrequency: []},
+ {baseFrequency: [10]},
+ {baseFrequency: [10, 3]},
+ {baseFrequency: 30},
+ {baseFrequency: false},
+ {baseFrequency: true},
+ {baseFrequency: "10"},
+
+ {numOctaves: null},
+ {numOctaves: []},
+ {numOctaves: [10]},
+ {numOctaves: 30},
+ {numOctaves: false},
+ {numOctaves: true},
+ {numOctaves: "10"},
+
+ {seed: null},
+ {seed: []},
+ {seed: [10]},
+ {seed: 30},
+ {seed: false},
+ {seed: true},
+ {seed: "10"},
+ {seed: -1},
+
+ {stitchTiles: "stitch"},
+ {stitchTiles: "noStitch"},
+
+ {type: "fractalNoise"},
+ {type: "turbulence"},
+ ]
+
+ for (testCase of errorTestCases) {
+ const filterOptions = {...{filter: "turbulence"}, ...testCase};
+ @assert throws TypeError CanvasFilter(filterOptions);
+ }
+
+ for (testCase of workingTestCases) {
+ const filterOptions = {...{filter: "turbulence"}, ...testCase};
+ @assert new CanvasFilter(filterOptions) != null;
+ }
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/reset.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/reset.yaml
new file mode 100644
index 0000000000..4107166248
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/reset.yaml
@@ -0,0 +1,15 @@
+- name: 2d.reset.basic
+ desc: reset clears to transparent black
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
+ ctx.reset();
+ @assert pixel 0,0 == 0,0,0,0;
+ @assert pixel 50,25 == 0,0,0,0;
+ @assert pixel 25,50 == 0,0,0,0;
+ @assert pixel 100,50 == 0,0,0,0;
+ @assert pixel 0,50 == 0,0,0,0;
+ @assert pixel 100,0 == 0,0,0,0;
+ t.done(); \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/scroll.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/scroll.yaml
new file mode 100644
index 0000000000..dd088aa396
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/scroll.yaml
@@ -0,0 +1,76 @@
+- name: 2d.scrollPathIntoView.basic
+ desc: scrollPathIntoView() works
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ var div = document.createElement('div');
+ div.style.cssText = 'width: 200vw; height: 200vh';
+ document.body.appendChild(div);
+ canvas.style.cssText = 'position: absolute; top: 100px; left: 200px; border: none;';
+ window.scrollTo(0, 0);
+
+ ctx.beginPath();
+ ctx.rect(4, 8, 16, 32);
+ ctx.scrollPathIntoView();
+ var rect = canvas.getBoundingClientRect();
+ @assert Math.round(rect.top) === -8;
+ @assert Math.round(rect.left) === 200;
+
+- name: 2d.scrollPathIntoView.verticalLR
+ desc: scrollPathIntoView() works in vertical-lr writing mode
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ document.documentElement.style.cssText = 'writing-mode: vertical-lr';
+ var div = document.createElement('div');
+ div.style.cssText = 'width: 200vw; height: 200vh';
+ document.body.appendChild(div);
+ canvas.style.cssText = 'position: absolute; top: 100px; left: 200px; border: none;';
+ window.scrollTo(0, 0);
+
+ ctx.beginPath();
+ ctx.rect(4, 8, 16, 32);
+ ctx.scrollPathIntoView();
+ var rect = canvas.getBoundingClientRect();
+ @assert Math.round(rect.top) === 100;
+ @assert Math.round(rect.left) === -4;
+
+- name: 2d.scrollPathIntoView.verticalRL
+ desc: scrollPathIntoView() works in vertical-rl writing mode
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ document.documentElement.style.cssText = 'writing-mode: vertical-rl';
+ var div = document.createElement('div');
+ div.style.cssText = 'width: 200vw; height: 200vh';
+ document.body.appendChild(div);
+ canvas.style.cssText = 'position: absolute; top: 100px; right: 200px; border: none;';
+ window.scrollTo(0, 0);
+
+ ctx.beginPath();
+ ctx.rect(4, 8, 16, 32);
+ ctx.scrollPathIntoView();
+ var rect = canvas.getBoundingClientRect();
+ var viewportWidth = document.scrollingElement.clientWidth;
+ var canvasWidth = canvas.width;
+ @assert Math.round(rect.top) === 100;
+ @assert Math.round(rect.right) === viewportWidth + (canvasWidth - 4 - 16);
+
+- name: 2d.scrollPathIntoView.path
+ desc: scrollPathIntoView() with path argument works
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ var div = document.createElement('div');
+ div.style.cssText = 'width: 200vw; height: 200vh';
+ document.body.appendChild(div);
+ canvas.style.cssText = 'position: absolute; top: 100px; left: 200px; border: none;';
+ window.scrollTo(0, 0);
+
+ var path = new Path2D();
+ path.rect(4, 8, 16, 32);
+ ctx.scrollPathIntoView(path);
+ var rect = canvas.getBoundingClientRect();
+ @assert Math.round(rect.top) === -8;
+ @assert Math.round(rect.left) === 200;
+
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/video.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/video.yaml
new file mode 100644
index 0000000000..f9b48fb8da
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/video.yaml
@@ -0,0 +1,10 @@
+- name: 2d.video.invalid
+ desc: Verify test doesn't crash with invalid video.
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ var v = document.createElement('video');
+ v.play();
+ // Test is deliberately not waiting for the 'playing' event to fire.
+ ctx.createPattern(v, 'repeat-x');
+ ctx.drawImage(v, 0, 0);