summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/canvas/element/manual/filters
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/html/canvas/element/manual/filters')
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-fillStyle-opacity.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity-alpha-and-fillStyle-expected.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity-alpha-and-fillStyle.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-blur-expected.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-blur.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-expected.html21
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-expected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-globalAlpha.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-blend-modes-expected.html48
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-blend-modes.html50
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-expected.html66
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/svg-filter-crash.html14
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-blur-expected.html19
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-blur.html24
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-component-transfer-expected.html65
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-component-transfer.html62
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix-expected.html77
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix.html60
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence-expected.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-boolean-conversion-expected.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-boolean-conversion.html58
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-long-conversion-expected.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-long-conversion.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-sequence-conversion.html55
28 files changed, 1059 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-fillStyle-opacity.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-fillStyle-opacity.html
new file mode 100644
index 0000000000..b5f9d98b89
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-fillStyle-opacity.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<link rel="match" href="canvas-opacity-expected.html"/>
+<meta name="fuzzy" content="maxDifference=0-2; totalPixels=0-14000">
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.fillStyle = 'rgba(0, 128, 128, 0.75)';
+ ctx.fillRect(10, 10, 50, 50);
+ ctx.fillStyle = 'rgba(255, 0, 255, 0.5)';
+ ctx.fillRect(70, 10, 50, 50);
+ ctx.fillStyle = 'rgba(255, 165, 0, 0.25)';
+ ctx.fillRect(10, 70, 50, 50);
+ ctx.fillStyle = 'rgba(210, 105, 30, 0)';
+ ctx.fillRect(70, 70, 50, 50);
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.8)';
+ ctx.fillRect(10, 150, 50, 50);
+ ctx.fillStyle = 'rgba(255, 0, 0, 0.6)';
+ ctx.fillRect(20, 150, 50, 50);
+ ctx.fillStyle = 'rgba(255, 255, 0, 0.4)';
+ ctx.fillRect(30, 150, 50, 50);
+ ctx.fillStyle = 'rgba(0, 128, 0, 0.2)';
+ ctx.fillRect(40, 150, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity-alpha-and-fillStyle-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity-alpha-and-fillStyle-expected.html
new file mode 100644
index 0000000000..f87794f0b7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity-alpha-and-fillStyle-expected.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<body>
+ <div id="sq-1"></div>
+ <div id="sq-2"></div>
+ <div id="sq-3"></div>
+ <div id="sq-4"></div>
+</body>
+<style>
+ /*The expected behavior when setting the opacity through different methods
+ is that the opacity of the resulting drawn element is the product of the opacity
+ value set by each of the methods.*/
+ div{
+ width: 50px;
+ height: 50px;
+ position: absolute;
+ }
+ #sq-1{
+ background-color: black;
+ left: 18px;
+ top: 18px;
+ opacity: 0.125;
+ }
+ #sq-2{
+ background-color: black;
+ left: 78px;
+ top: 18px;
+ opacity: 0.03125;
+ }
+ #sq-3{
+ background-color: black;
+ left: 18px;
+ top: 78px;
+ opacity: 0.1875;
+ }
+ #sq-4{
+ background-color: black;
+ left: 78px;
+ top: 78px;
+ opacity: 0.016;
+ }
+</style>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity-alpha-and-fillStyle.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity-alpha-and-fillStyle.html
new file mode 100644
index 0000000000..24c97d62ec
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity-alpha-and-fillStyle.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<link rel="match" href="canvas-filter-opacity-alpha-and-fillStyle-expected.html"/>
+<meta name="fuzzy" content="maxDifference=0-2; totalPixels=0-10000">
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ /*
+ The expected behavior when setting the opacity through different methods
+ is that the opacity of the resulting drawn element is the product of the opacity
+ value set by each of the methods.
+ */
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalAlpha = 0.5;
+ ctx.fillStyle = 'rgba(0,0,0,0.5)';
+ ctx.filter = 'opacity(50%)';
+ ctx.fillRect(10, 10, 50, 50);
+
+ ctx.globalAlpha = 0.5;
+ ctx.fillStyle = 'rgba(0,0,0,0.25)';
+ ctx.filter = 'opacity(25%)';
+ ctx.fillRect(70, 10, 50, 50);
+
+ ctx.globalAlpha = 0.75;
+ ctx.fillStyle = 'rgba(0,0,0,0.5)';
+ ctx.filter = 'opacity(50%)';
+ ctx.fillRect(10, 70, 50, 50);
+
+ ctx.globalAlpha = 0.8;
+ ctx.fillStyle = 'rgba(0,0,0,0.2)';
+ ctx.filter = 'opacity(10%)';
+ ctx.fillRect(70, 70, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity.html
new file mode 100644
index 0000000000..cb2fc018af
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<link rel="match" href="canvas-opacity-expected.html"/>
+<meta name="fuzzy" content="maxDifference=0-2; totalPixels=0-14000">
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.filter = 'opacity(75%)';
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(10, 10, 50, 50);
+ ctx.filter = 'opacity(50%)';
+ ctx.fillStyle = 'magenta';
+ ctx.fillRect(70, 10, 50, 50);
+ ctx.filter = 'opacity(25%)';
+ ctx.fillStyle = 'orange';
+ ctx.fillRect(10, 70, 50, 50);
+ ctx.filter = 'opacity(0%)';
+ ctx.fillStyle = 'chocolate';
+ ctx.fillRect(70, 70, 50, 50);
+
+ ctx.filter = 'opacity(80%)';
+ ctx.fillStyle = 'cyan';
+ ctx.fillRect(10, 150, 50, 50);
+ ctx.filter = 'opacity(60%)';
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 150, 50, 50);
+ ctx.filter = 'opacity(40%)';
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(30, 150, 50, 50);
+ ctx.filter = 'opacity(20%)';
+ ctx.fillStyle = 'green';
+ ctx.fillRect(40, 150, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-blur-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-blur-expected.html
new file mode 100644
index 0000000000..1f218b4bd2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-blur-expected.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ /*
+ The shadow and shadow blur effects should be the same regardless if they were
+ defined with filters or properties. The blur parameter is set as double when
+ using the shadowBlur property since its uses havlf of the value set as the
+ standard deviation for the gaussian blur (https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-shadowblur-dev)
+ while the filter parameter is used directly as the standard deviation
+ (https://drafts.fxtf.org/filter-effects/#funcdef-filter-drop-shadow). The
+ fuzziness is defined with a maxDifference of 13 as to be the 5% of 256, since
+ the CSS spec defines the expected behavior in relation to an ideal Gaussian blur
+ with a tolerance of 5%. See: https://drafts.csswg.org/css-backgrounds-3/#shadow-blur.
+ */
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.shadowOffsetX = 10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowBlur = 4;
+ ctx.shadowColor = 'red';
+ ctx.fillRect(20, 20, 50, 50);
+ ctx.shadowBlur = 8;
+ ctx.shadowColor = 'blue';
+ ctx.fillRect(100, 20, 50, 50);
+ ctx.shadowBlur = 20;
+ ctx.shadowColor = 'yellow';
+ ctx.fillRect(20, 100, 50, 50);
+ ctx.shadowBlur = 30;
+ ctx.shadowColor = 'cyan';
+ ctx.fillRect(100, 100, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-blur.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-blur.html
new file mode 100644
index 0000000000..ab3699906d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-blur.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<link rel="match" href="canvas-filter-shadow-and-properties-blur-expected.html"/>
+<meta name="fuzzy" content="maxDifference=0-13; totalPixels=0-25600">
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ /*
+ The shadow and shadow blur effects should be the same regardless if they were
+ defined with filters or properties. The blur parameter is set as double when
+ using the shadowBlur property since its uses havlf of the value set as the
+ standard deviation for the gaussian blur (https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-shadowblur-dev)
+ while the filter parameter is used directly as the standard deviation
+ (https://drafts.fxtf.org/filter-effects/#funcdef-filter-drop-shadow). The
+ fuzziness is defined with a maxDifference of 13 as to be the 5% of 256, since
+ the CSS spec defines the expected behavior in relation to an ideal Gaussian blur
+ with a tolerance of 5%. See: https://drafts.csswg.org/css-backgrounds-3/#shadow-blur.
+ */
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.filter = 'drop-shadow(10px 10px 2px red)';
+ ctx.fillRect(20, 20, 50, 50);
+ ctx.filter = 'drop-shadow(10px 10px 4px blue)';
+ ctx.fillRect(100, 20, 50, 50);
+ ctx.filter = 'drop-shadow(10px 10px 10px yellow)';
+ ctx.fillRect(20, 100, 50, 50);
+ ctx.filter = 'drop-shadow(10px 10px 15px cyan)';
+ ctx.fillRect(100, 100, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-expected.html
new file mode 100644
index 0000000000..294a219b70
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-expected.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ /*
+ The expected behavior when both shadow properties and filters are used at the
+ same time is that the filter is applied to the elements drawn and the shadow
+ properties create another shadow that includes even shadows of the
+ filter-generated shadows.
+ */
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.fillStyle = 'cyan';
+ ctx.fillRect(40, 40, 50, 50);
+ ctx.fillRect(30, 30, 50, 50);
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 20, 50, 50);
+ ctx.fillStyle = 'black';
+ ctx.fillRect(10, 10, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties.html
new file mode 100644
index 0000000000..2057b95c3e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<link rel="match" href="canvas-filter-shadow-and-properties-expected.html"/>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ /*
+ The expected behavior when both shadow properties and filters are used at the
+ same time is that the filter is applied to the elements drawn and the shadow
+ properties create another shadow that includes even shadows of the
+ filter-generated shadows.
+ */
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.shadowColor = 'cyan';
+ ctx.shadowOffsetX = 20;
+ ctx.shadowOffsetY = 20;
+ ctx.filter = 'drop-shadow(10px 10px 0 red)';
+ ctx.fillRect(10, 10, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-expected.html
new file mode 100644
index 0000000000..04bc6392cc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-expected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ /*
+ The expected behavior of filter-generated shadows is tested against
+ a drawing using only rectangles that draws the shadows manually.
+ */
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 20, 50, 50);
+ ctx.fillStyle = 'black';
+ ctx.fillRect(10, 10, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow.html
new file mode 100644
index 0000000000..ddc6c89ee5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<link rel="match" href="canvas-filter-shadow-expected.html"/>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ /*
+ The expected behavior of filter-generated shadows is tested against
+ a drawing using only rectangles that draws the shadows manually.
+ */
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.filter = 'drop-shadow(10px 10px 0 red)';
+ ctx.fillRect(10, 10, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-globalAlpha.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-globalAlpha.html
new file mode 100644
index 0000000000..6d7bbcd03d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-globalAlpha.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<link rel="match" href="canvas-opacity-expected.html"/>
+<meta name="fuzzy" content="maxDifference=0-2; totalPixels=0-14000">
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.globalAlpha = 0.75;
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(10, 10, 50, 50);
+ ctx.globalAlpha = 0.5;
+ ctx.fillStyle = 'magenta';
+ ctx.fillRect(70, 10, 50, 50);
+ ctx.globalAlpha = 0.25;
+ ctx.fillStyle = 'orange';
+ ctx.fillRect(10, 70, 50, 50);
+ ctx.globalAlpha = 0;
+ ctx.fillStyle = 'chocolate';
+ ctx.fillRect(70, 70, 50, 50);
+
+ ctx.globalAlpha = 0.8;
+ ctx.fillStyle = 'cyan';
+ ctx.fillRect(10, 150, 50, 50);
+ ctx.globalAlpha = 0.6;
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 150, 50, 50);
+ ctx.globalAlpha = 0.4;
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(30, 150, 50, 50);
+ ctx.globalAlpha = 0.2;
+ ctx.fillStyle = 'green';
+ ctx.fillRect(40, 150, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-blend-modes-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-blend-modes-expected.html
new file mode 100644
index 0000000000..3eb7581981
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-blend-modes-expected.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<body>
+</body>
+<script>
+ /*
+ Compare how the opacity is handled in different blend modes when setting its
+ value with filters or with properties.
+ */
+
+ function drawSquares(canvasId, x, y, compositeOperation) {
+ var canvas = document.getElementById(canvasId);
+ var ctx = canvas.getContext('2d');
+ canvas.style.position = 'absolute';
+ canvas.style.left = `${x}px`;
+ canvas.style.top = `${y}px`;
+
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.globalAlpha = 1.0;
+ ctx.fillStyle = 'green';
+ ctx.fillRect(0, 0, 200, 60);
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.globalAlpha = 0.7;
+ ctx.fillStyle = 'red';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.globalCompositeOperation = compositeOperation;
+ ctx.globalAlpha = 0.5;
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(25, 25, 50, 50);
+ }
+
+ // Fomatted in the same matrix as the drawn elements.
+ var compositeOperations =
+ ['source-over', 'source-in', 'source-out', 'source-atop','destination-over',
+ 'destination-in', 'destination-out', 'destination-atop', 'lighter', 'copy',
+ 'xor', 'multiply', 'screen', 'overlay', 'darken',
+ 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light',
+ 'difference', 'exclusion', 'hue', 'saturation', 'color',
+ 'luminosity'];
+
+ for (var i = 0; i < compositeOperations.length; i++){
+ var canvas = document.createElement('canvas');
+ canvas.id = `canvas-${i}`;
+ document.body.appendChild(canvas);
+ drawSquares(canvas.id, (i%5)*300, Math.floor(i/5)*300,
+ compositeOperations[i]);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-blend-modes.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-blend-modes.html
new file mode 100644
index 0000000000..a2d513eb62
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-blend-modes.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<link rel="match" href="canvas-opacity-blend-modes-expected.html"/>
+<meta name="fuzzy" content="maxDifference=0-2; totalPixels=0-390000">
+<body>
+</body>
+<script>
+ /*
+ Compare how the opacity is handled in different blend modes when setting its
+ value with filters or with properties.
+ */
+
+ function drawSquares(canvasId, x, y, compositeOperation) {
+ var canvas = document.getElementById(canvasId);
+ var ctx = canvas.getContext('2d');
+ canvas.style.position = 'absolute';
+ canvas.style.left = `${x}px`;
+ canvas.style.top = `${y}px`;
+
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.filter = 'opacity(100%)';
+ ctx.fillStyle = 'green';
+ ctx.fillRect(0, 0, 200, 60);
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.filter = 'opacity(70%)';
+ ctx.fillStyle = 'red';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.globalCompositeOperation = compositeOperation;
+ ctx.filter = 'opacity(50%)';
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(25, 25, 50, 50);
+ }
+
+ // Fomatted in the same matrix as the drawn elements.
+ var compositeOperations =
+ ['source-over', 'source-in', 'source-out', 'source-atop','destination-over',
+ 'destination-in', 'destination-out', 'destination-atop', 'lighter', 'copy',
+ 'xor', 'multiply', 'screen', 'overlay', 'darken',
+ 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light',
+ 'difference', 'exclusion', 'hue', 'saturation', 'color',
+ 'luminosity'];
+
+ for (var i = 0; i < compositeOperations.length; i++){
+ var canvas = document.createElement('canvas');
+ canvas.id = `canvas-${i}`;
+ document.body.appendChild(canvas);
+ drawSquares(canvas.id, (i%5)*300, Math.floor(i/5)*300,
+ compositeOperations[i]);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-expected.html
new file mode 100644
index 0000000000..caf6b53ce3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-expected.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<body>
+ <div id="sq-1"></div>
+ <div id="sq-2"></div>
+ <div id="sq-3"></div>
+ <div id="sq-4"></div>
+ <div id="sq-5"></div>
+ <div id="sq-6"></div>
+ <div id="sq-7"></div>
+ <div id="sq-8"></div>
+</body>
+<style>
+ div{
+ width: 50px;
+ height: 50px;
+ position: absolute;
+ }
+ #sq-1{
+ background-color: teal;
+ left: 18px;
+ top: 18px;
+ opacity: 0.75;
+ }
+ #sq-2{
+ background-color: magenta;
+ left: 78px;
+ top: 18px;
+ opacity: 0.5;
+ }
+ #sq-3{
+ background-color: orange;
+ left: 18px;
+ top: 78px;
+ opacity: 0.25;
+ }
+ #sq-4{
+ background-color: chocolate;
+ left: 78px;
+ top: 78px;
+ opacity: 0;
+ }
+ #sq-5{
+ background-color: cyan;
+ left: 18px;
+ top: 158px;
+ opacity: 0.8;
+ }
+ #sq-6{
+ background-color: red;
+ left: 28px;
+ top: 158px;
+ opacity: 0.6;
+ }
+ #sq-7{
+ background-color: yellow;
+ left: 38px;
+ top: 158px;
+ opacity: 0.4;
+ }
+ #sq-8{
+ background-color: green;
+ left: 48px;
+ top: 158px;
+ opacity: 0.2;
+ }
+</style>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/svg-filter-crash.html b/testing/web-platform/tests/html/canvas/element/manual/filters/svg-filter-crash.html
new file mode 100644
index 0000000000..f64379c792
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/svg-filter-crash.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script>
+ document.addEventListener('DOMContentLoaded', async () => {
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
+ const filter = document.createElementNS('http://www.w3.org/2000/svg', 'filter')
+ filter.setAttribute('id', 'id_0')
+ svg.appendChild(filter)
+ document.documentElement.appendChild(svg)
+ const canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas')
+ const context = canvas.getContext('2d')
+ context.filter = 'url(#id_0) url(#id_0) sepia() url(#id_0)'
+ svg.setAttribute('style', 'display: inline-block;')
+ })
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-blur-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-blur-expected.html
new file mode 100644
index 0000000000..ae8911b2de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-blur-expected.html
@@ -0,0 +1,19 @@
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.filter = 'blur(2px)';
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(10,10,100,100);
+ ctx.filter = 'blur(5px)';
+ ctx.fillStyle = 'magenta';
+ ctx.fillRect(120, 10, 100, 100);
+ ctx.filter = 'blur(5px) blur(10px)';
+ ctx.fillStyle = 'cyan';
+ ctx.fillRect(10, 120, 100, 100);
+ ctx.filter = 'none';
+ ctx.fillStyle = 'black';
+ ctx.fillRect(120, 120, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-blur.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-blur.html
new file mode 100644
index 0000000000..9fe7ef120c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-blur.html
@@ -0,0 +1,24 @@
+<head>
+ <link rel="match" href="canvas-filter-object-blur-expected.html">
+</head>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.filter = new CanvasFilter({name: "gaussianBlur", stdDeviation: 2});
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(10,10,100,100);
+ ctx.filter = new CanvasFilter({name: "gaussianBlur", stdDeviation: 5});
+ ctx.fillStyle = 'magenta';
+ ctx.fillRect(120, 10, 100, 100);
+ ctx.filter = new CanvasFilter([
+ {name: "gaussianBlur", stdDeviation: 5},
+ {name: "gaussianBlur", stdDeviation: 10}]);
+ ctx.fillStyle = 'cyan';
+ ctx.fillRect(10, 120, 100, 100);
+ ctx.filter = 'none';
+ ctx.fillStyle = 'black';
+ ctx.fillRect(120, 120, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-component-transfer-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-component-transfer-expected.html
new file mode 100644
index 0000000000..a2351cbcf2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-component-transfer-expected.html
@@ -0,0 +1,65 @@
+<body>
+ <canvas id="canvas" width="500" height="100"></canvas>
+ <svg width="0", height="0">
+ <defs>
+ <filter color-interpolation-filters='sRGB' id="Identity" filterUnits="objectBoundingBox"
+ x="0%" y="0%" width="100%" height="100%">
+ <feComponentTransfer>
+ <feFuncR type="identity"/>
+ <feFuncG type="identity"/>
+ <feFuncB type="identity"/>
+ <feFuncA type="identity"/>
+ </feComponentTransfer>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="Table">
+ <feComponentTransfer>
+ <feFuncR type="table" tableValues="0 2 0.5 1"/>
+ <feFuncG type="table" tableValues="1 -1 5 0"/>
+ <feFuncB type="table" tableValues="0 1 1 0"/>
+ </feComponentTransfer>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="Discrete">
+ <feComponentTransfer>
+ <feFuncR type="discrete" tableValues="0 2 0.5 1"/>
+ <feFuncG type="discrete" tableValues="1 -1 5 0"/>
+ <feFuncB type="discrete" tableValues="0 1 1 0"/>
+ </feComponentTransfer>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="Linear">
+ <feComponentTransfer>
+ <feFuncR type="linear" slope=".5" intercept=".25"/>
+ <feFuncG type="linear" slope="1.5" intercept="0"/>
+ <feFuncB type="linear" slope="-0.5" intercept=".5"/>
+ </feComponentTransfer>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="Gamma">
+ <feComponentTransfer>
+ <feFuncR type="gamma" amplitude="2" exponent="5" offset="-0.5"/>
+ <feFuncG type="gamma" amplitude="0.9" exponent="3" offset="0.3"/>
+ <feFuncB type="gamma" amplitude="1.1" exponent="1" offset="0.1"/>
+ </feComponentTransfer>
+ </filter>
+ </defs>
+ </svg>
+</body>
+<script type="text/javascript">
+ const ctx = document.getElementById("canvas").getContext("2d");
+
+ const grad = ctx.createLinearGradient(10, 0, 490, 0);
+ grad.addColorStop(0, "#f00");
+ grad.addColorStop(0.33, "#0f0");
+ grad.addColorStop(0.67, "#00f");
+ grad.addColorStop(1, "#000");
+ ctx.fillStyle = grad;
+
+ ctx.filter = "url('#Identity')";
+ ctx.fillRect(10, 10, 480, 10);
+ ctx.filter = "url('#Table')";
+ ctx.fillRect(10, 30, 480, 10);
+ ctx.filter = "url('#Discrete')";
+ ctx.fillRect(10, 50, 480, 10);
+ ctx.filter = "url('#Linear')";
+ ctx.fillRect(10, 70, 480, 10);
+ ctx.filter = "url('#Gamma')";
+ ctx.fillRect(10, 90, 480, 10);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-component-transfer.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-component-transfer.html
new file mode 100644
index 0000000000..47889c0db2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-component-transfer.html
@@ -0,0 +1,62 @@
+<head>
+ <link rel="match" href="canvas-filter-object-component-transfer-expected.html">
+</head>
+<body>
+ <canvas id="canvas" width="500" height="100"></canvas>
+</body>
+<script>
+ const ctx = document.getElementById("canvas").getContext("2d");
+
+ const grad = ctx.createLinearGradient(10, 0, 490, 0);
+ grad.addColorStop(0, "#f00");
+ grad.addColorStop(0.33, "#0f0");
+ grad.addColorStop(0.67, "#00f");
+ grad.addColorStop(1, "#000");
+ ctx.fillStyle = grad;
+
+ const identityFilter = new CanvasFilter({
+ name: "componentTransfer",
+ funcR: {type: "identity"},
+ funcG: {type: "identity"},
+ funcB: {type: "identity"},
+ funcA: {type: "identity"},
+ });
+ ctx.filter = identityFilter;
+ ctx.fillRect(10, 10, 480, 10);
+
+ const tableFilter = new CanvasFilter({
+ name: "componentTransfer",
+ funcR: {type: "table", tableValues: [0, 2, 0.5, 1]},
+ funcG: {type: "table", tableValues: [1, -1, 5, 0]},
+ funcB: {type: "table", tableValues: [0, 1, 1, 0]},
+ });
+ ctx.filter = tableFilter;
+ ctx.fillRect(10, 30, 480, 10);
+
+ const discreteFilter = new CanvasFilter({
+ name: "componentTransfer",
+ funcR: {type: "discrete", tableValues: [0, 2, 0.5, 1]},
+ funcG: {type: "discrete", tableValues: [1, -1, 5, 0]},
+ funcB: {type: "discrete", tableValues: [0, 1, 1, 0]},
+ });
+ ctx.filter = discreteFilter;
+ ctx.fillRect(10, 50, 480, 10);
+
+ const linearFilter = new CanvasFilter({
+ name: "componentTransfer",
+ funcR: {type: "linear", slope: 0.5, intercept: 0.25},
+ funcG: {type: "linear", slope: 1.5, intercept: 0},
+ funcB: {type: "linear", slope: -0.5, intercept: 0.5},
+ });
+ ctx.filter = linearFilter;
+ ctx.fillRect(10, 70, 480, 10);
+
+ const gammaFilter = new CanvasFilter({
+ name: "componentTransfer",
+ funcR: {type: "gamma", amplitude: 2, exponent: 5, offset: -0.5},
+ funcG: {type: "gamma", amplitude: 0.9, exponent: 3, offset: 0.3},
+ funcB: {type: "gamma", amplitude: 1.1, exponent: 1, offset: 0.1},
+ });
+ ctx.filter = gammaFilter;
+ ctx.fillRect(10, 90, 480, 10);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix-expected.html
new file mode 100644
index 0000000000..896a93542e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix-expected.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<style type="text/css">
+ canvas {
+ margin: 5px;
+ }
+</style>
+<body>
+ <svg width="0" height="0">
+ <filter color-interpolation-filters='sRGB' id="justKernel">
+ <feConvolveMatrix
+ kernelMatrix="3 0 0 0 0 0 0 0 -3"/>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="preserveAlpha">
+ <feConvolveMatrix
+ kernelMatrix="3 0 0 0 0 0 0 0 -3"
+ preserveAlpha="true"/>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="target">
+ <feConvolveMatrix
+ kernelMatrix="3 0 0 0 0 0 0 0 -3"
+ targetX="2" targetY="2"/>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="divisor">
+ <feConvolveMatrix
+ kernelMatrix="3 0 0 0 0 0 0 0 -3"
+ divisor="3"/>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="bias">
+ <feConvolveMatrix
+ kernelMatrix="3 0 0 0 0 0 0 0 -3"
+ bias="0.5"/>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="edgeMode">
+ <feConvolveMatrix
+ kernelMatrix="3 0 0 0 0 0 0 0 -3"
+ edgeMode="wrap"/>
+ </filter>
+ </svg>
+</body>
+<script type="text/javascript">
+
+const filters = [
+ "url('#justKernel')",
+ "url('#preserveAlpha')",
+ "url('#target')",
+ "url('#divisor')",
+ "url('#bias')",
+ "url('#edgeMode')",
+];
+
+function draw(ctx) {
+ ctx.fillRect(0, 20, 120, 100);
+
+ ctx.beginPath();
+ ctx.arc(150, 70, 50, 0, 2*Math.PI);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(220, 20);
+ ctx.lineTo(170, 120);
+ ctx.lineTo(270, 120);
+ ctx.lineTo(220, 20);
+ ctx.fill();
+}
+
+for (f of filters) {
+ const canvas = document.createElement("canvas");
+ document.body.prepend(canvas);
+ const ctx = canvas.getContext("2d");
+ ctx.filter = "blur(0px)";
+ ctx.fillStyle = "rgba(0,255,0,0.5)";
+ draw(ctx);
+ ctx.fillStyle = "rgba(255,0,255,0.5)";
+ ctx.filter = f;
+ draw(ctx);
+}
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix.html
new file mode 100644
index 0000000000..1dfd602d13
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<head>
+ <link rel="match" href="canvas-filter-object-convolve-matrix-expected.html">
+ <style type="text/css">
+ canvas {
+ margin: 5px;
+ }
+ </style>
+</head>
+<body>
+</body>
+<script>
+function makeConvolveFilter(options) {
+ const KERNEL_MATRIX = [
+ [3, 0, 0],
+ [0, 0, 0],
+ [0, 0, -3],
+ ];
+
+ options = Object.assign(options, {
+ kernelMatrix: KERNEL_MATRIX, name: "convolveMatrix"});
+ return new CanvasFilter(options);
+}
+
+const test_cases = [
+ {},
+ {preserveAlpha: true},
+ {targetX: 2, targetY: 2},
+ {divisor: 3},
+ {bias: 0.5},
+ {edgeMode: "wrap"}
+];
+
+function draw(ctx) {
+ ctx.fillRect(0, 20, 120, 100);
+
+ ctx.beginPath();
+ ctx.arc(150, 70, 50, 0, 2*Math.PI);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(220, 20);
+ ctx.lineTo(170, 120);
+ ctx.lineTo(270, 120);
+ ctx.lineTo(220, 20);
+ ctx.fill();
+}
+
+for (tc of test_cases) {
+ const canvas = document.createElement("canvas");
+ document.body.prepend(canvas);
+ const ctx = canvas.getContext("2d");
+ ctx.filter = "blur(0px)";
+ ctx.fillStyle = "rgba(0,255,0,0.5)";
+ draw(ctx);
+ ctx.fillStyle = "rgba(255,0,255,0.5)";
+ ctx.filter = makeConvolveFilter(tc);
+ draw(ctx);
+}
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence-expected.html
new file mode 100644
index 0000000000..ff0eebe2e0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence-expected.html
@@ -0,0 +1,37 @@
+<body>
+ <svg style="display:none">>
+ <filter id="base">
+ <feTurbulence baseFrequency="0.025"/>
+ </filter>
+ <filter id="base2d">
+ <feTurbulence baseFrequency="0.025, 0.1"/>
+ </filter>
+ <filter id="highFrequency">
+ <feTurbulence baseFrequency="0.05"/>
+ </filter>
+ <filter id="seed">
+ <feTurbulence baseFrequency="0.025" seed="100"/>
+ </filter>
+ <filter id="numOctaves">
+ <feTurbulence baseFrequency="0.025" numOctaves="2"/>
+ </filter>
+ <filter id="empty">
+ <feTurbulence/>
+ </filter>
+ <filter id="fractalNoise">
+ <feTurbulence baseFrequency="0.025" type="fractalNoise"/>
+ </filter>
+ <filter id="stitchTiles">
+ <feTurbulence baseFrequency="0.025" stitchTiles="noStitch"/>
+ </filter>
+</body>
+<script>
+ testCases = document.getElementsByTagName("filter");
+ for (tc of testCases) {
+ const canvas = document.createElement("canvas");
+ document.body.appendChild(canvas);
+ const ctx = canvas.getContext("2d");
+ ctx.filter = `url(#${tc.id})`;
+ ctx.fillRect(0, 0, 1, 1);
+ }
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html
new file mode 100644
index 0000000000..b5b494825e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html
@@ -0,0 +1,26 @@
+<head>
+ <link rel="match" href="canvas-filter-object-blur-expected.html">
+</head>
+<body>
+</body>
+<script>
+ const testCases = [
+ {baseFrequency: 0.025},
+ {baseFrequency: [0.025, 0.1]},
+ {baseFrequency: 0.05},
+ {baseFrequency: 0.025, seed: 100},
+ {baseFrequency: 0.025, numOctaves: 2},
+ {},
+ {baseFrequency: 0.025, type: "fractalNoise"},
+ {baseFrequency: 0.025, stitchTiles: "stitch"},
+ ]
+
+ for (tc of testCases) {
+ const canvas = document.createElement("canvas");
+ document.body.appendChild(canvas);
+ const ctx = canvas.getContext("2d");
+ const filterOptions = {...{name: "turbulence"}, ...tc};
+ ctx.filter = new CanvasFilter(filterOptions);
+ ctx.fillRect(0, 0, 1, 1);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-boolean-conversion-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-boolean-conversion-expected.html
new file mode 100644
index 0000000000..f043b0e762
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-boolean-conversion-expected.html
@@ -0,0 +1,30 @@
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // preserveAlpha for convolveMatrix is the only boolean so far implemented
+ function drawWithConvolveFilter(x, y, preserveAlphaValue) {
+ ctx.filter = new CanvasFilter({
+ name: "convolveMatrix",
+ kernelMatrix: [[1, 0], [0, 1]],
+ preserveAlpha: preserveAlphaValue,
+ });
+ ctx.fillRect(x, y, 30, 30);
+ }
+
+ ctx.fillStyle = "rgba(255,0,255,0.5)";
+ let x = 10;
+ let y = 10;
+ for (var i = 0; i < 6; i++) {
+ drawWithConvolveFilter(x, y, true);
+ x += 40;
+ }
+ y = 50;
+ x = 10;
+ for (var i = 0; i < 5; i++) {
+ drawWithConvolveFilter(x, y, false);
+ x += 40;
+ }
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-boolean-conversion.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-boolean-conversion.html
new file mode 100644
index 0000000000..97ade79f37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-boolean-conversion.html
@@ -0,0 +1,58 @@
+<head>
+ <link rel="match" href="canvas-filter-boolean-conversion-expected.html">
+</head>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ // Test the built-in ECMAScript types Undefined, Null, Boolean, String, Number, and Object
+ // as input to the CanvasFilter resolver when a bool is the intended result.
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // preserveAlpha for convolveMatrix is the only boolean so far implemented
+ function drawWithConvolveFilter(x, y, preserveAlphaValue) {
+ ctx.filter = new CanvasFilter({
+ name: "convolveMatrix",
+ kernelMatrix: [[1, 0], [0, 1]],
+ preserveAlpha: preserveAlphaValue,
+ });
+ ctx.fillRect(x, y, 30, 30);
+ }
+
+ const trueTestCases = [
+ true,
+ { valueOf() { return false; }},
+ "foo",
+ 1,
+ {},
+ []
+ ];
+
+ const falseTestCases = [
+ false,
+ "",
+ 0,
+ null,
+ undefined,
+ ];
+
+ ctx.fillStyle = "rgba(255,0,255,0.5)";
+ let x = 10;
+ let y = 10;
+ for (tc of trueTestCases) {
+ drawWithConvolveFilter(x, y, tc);
+ x += 40;
+ }
+ y = 50;
+ x = 10;
+ for (tc of falseTestCases) {
+ drawWithConvolveFilter(x, y, tc);
+ x += 40;
+ }
+
+ ctx.filter = new CanvasFilter({
+ name: "componentTransfer",
+ funcR: {type: "discrete", tableValues: 0.5},
+ });
+ ctx.fillRect(10, 10, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-long-conversion-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-long-conversion-expected.html
new file mode 100644
index 0000000000..8b4262ed04
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-long-conversion-expected.html
@@ -0,0 +1,26 @@
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ var ctx = document.getElementById('canvas').getContext('2d');
+ // Null and False both evaluate to zero
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 0});
+ ctx.fillRect(10, 10, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 0});
+ ctx.fillRect(50, 10, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 0});
+ ctx.fillRect(90, 10, 30, 30);
+ // True evaluates to one
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 1});
+ ctx.fillRect(130, 10, 30, 30);
+ // String, Number and Object should all work
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.fillRect(10, 50, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.fillRect(50, 50, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.fillRect(90, 50, 30, 30);
+ // Valid sequence
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.fillRect(130, 50, 30, 30);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-long-conversion.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-long-conversion.html
new file mode 100644
index 0000000000..c742633224
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-long-conversion.html
@@ -0,0 +1,35 @@
+<head>
+ <link rel="match" href="canvas-filter-long-conversion-expected.html">
+</head>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ // Test the built-in ECMAScript types Undefined, Null, Boolean, String, Number, and Object
+ // as input to the CanvasFilter resolver when a long is the intended result.
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // Null, False and [] evaluate to zero
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: null});
+ ctx.fillRect(10, 10, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: false});
+ ctx.fillRect(50, 10, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: []});
+ ctx.fillRect(90, 10, 30, 30);
+ // True evaluates to one
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: true});
+ ctx.fillRect(130, 10, 30, 30);
+ // String, Number and Object should all work
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: "5"});
+ ctx.fillRect(10, 50, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.fillRect(50, 50, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: { valueOf() { return 5; }}});
+ ctx.fillRect(90, 50, 30, 30);
+ // Valid sequence
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: [5]});
+ ctx.fillRect(130, 50, 30, 30);
+
+ // Undefined and other inputs that throw exceptions are tested in:
+ // html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.html
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-sequence-conversion.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-sequence-conversion.html
new file mode 100644
index 0000000000..d48627867e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-sequence-conversion.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<title>Canvas test: canvas-filter-sequence-conversion</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>canvas-filter-sequence-conversion</h1>
+<p class="desc">Test converting types into sequences</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test pixels on CanvasFilter() various inputs to tableValues (which is a sequence)");
+_addTest(function(canvas, ctx) {
+
+ // Inputs to parameters that are expecting sequence<long>. Results are either the value of the
+ // red pixel drawing using the resultant filter or that we expect this input to throw an error.
+ const testCases = [
+ {input: [], result: 0},
+ {input: [0.5], result: 127},
+ {input: ["0.5"], result: 127},
+ {input: 1, result: "throws"},
+ {input: {}, result: "throws"},
+ {input: false, result: "throws"},
+ {input: true, result: "throws"},
+ {input: NaN, result: "throws"},
+ {input: { valueOf() { return [1]; }}, result: "throws"},
+ ];
+
+ // A simple filter that just overrides the red channel if successful.
+ function makeFilter(value) {
+ return new CanvasFilter({
+ name: "componentTransfer",
+ funcR: {type: "table", tableValues: value}
+ });
+ }
+
+ for (const tc of testCases) {
+ if (tc.result === "throws") {
+ assert_throws_js(TypeError, function(){ makeFilter(tc.input) });
+ } else {
+ ctx.reset();
+ ctx.filter = makeFilter(tc.input);
+ ctx.fillRect(0, 0, 100, 100);
+ _assertPixelApprox(canvas, 5, 5, tc.result,0,0,255, 2);
+ }
+ }
+ t.done();
+});
+</script>