Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit da20961

Browse files
graveljpmoz-wptsync-bot
authored andcommitted
Bug 1827989 [wpt PR 39530] - Add support for different X&Y blurs for dropShadow CanvasFilter., a=testonly
Automatic update from web-platform-tests Add support for different X&Y blurs for dropShadow CanvasFilter. This aligns the CanvasFilter dropShadow implementation with SVG, which supports separable X & Y blurs: https://drafts.fxtf.org/filter-effects/#feDropShadowElement Note that SVG's `color-interpolation-filters` attribute defaults to `linearRBG`, whereas all other interpolations, as configured by `color-interpolation`, default to `sRGB`: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/color-interpolation-filters It's unclear at this point which default CanvasFilter should use. In the mean time, we must manually set `color-interpolation-filters` to `sRGB` in the WPT test or else, the CanvasFilter and SVG filters won't produce the same results. Change-Id: I3ed1546a901fe3ab2752bc9feff04f9f67018390 Bug: 1428652 Fixed: 1430524 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4415135 Reviewed-by: Aaron Krajeski <[email protected]> Reviewed-by: Xianzhu Wang <[email protected]> Commit-Queue: Jean-Philippe Gravel <[email protected]> Cr-Commit-Position: refs/heads/main@{#1131422} -- wpt-commits: 09a5492c48f7cfa03774c6f050af9fe4bdbfc356 wpt-pr: 39530
1 parent f743e7a commit da20961

9 files changed

+396
-185
lines changed

testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,6 @@ <h1>2d.filter.canvasFilterObject.dropShadow.exceptions.tentative</h1>
3939
_assert(new CanvasFilter({filter: 'dropShadow', dy: []}), "new CanvasFilter({filter: 'dropShadow', dy: []})");
4040
_assert(new CanvasFilter({filter: 'dropShadow', dy: [20]}), "new CanvasFilter({filter: 'dropShadow', dy: [\""+(20)+"\"]})");
4141
_assert(new CanvasFilter({filter: 'dropShadow', dy: '30'}), "new CanvasFilter({filter: 'dropShadow', dy: '30'})");
42-
// stdDeviation
43-
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: 10}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: 10})");
44-
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: -1}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: -1})");
45-
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: 0.5}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: 0.5})");
46-
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: null}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: null})");
47-
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: true}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: true})");
48-
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: false}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: false})");
49-
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: []}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: []})");
50-
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: [20]}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: [\""+(20)+"\"]})");
51-
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: '30'}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: '30'})");
5242
// floodOpacity
5343
_assert(new CanvasFilter({filter: 'dropShadow', floodOpacity: 10}), "new CanvasFilter({filter: 'dropShadow', floodOpacity: 10})");
5444
_assert(new CanvasFilter({filter: 'dropShadow', floodOpacity: -1}), "new CanvasFilter({filter: 'dropShadow', floodOpacity: -1})");
@@ -59,6 +49,21 @@ <h1>2d.filter.canvasFilterObject.dropShadow.exceptions.tentative</h1>
5949
_assert(new CanvasFilter({filter: 'dropShadow', floodOpacity: []}), "new CanvasFilter({filter: 'dropShadow', floodOpacity: []})");
6050
_assert(new CanvasFilter({filter: 'dropShadow', floodOpacity: [20]}), "new CanvasFilter({filter: 'dropShadow', floodOpacity: [\""+(20)+"\"]})");
6151
_assert(new CanvasFilter({filter: 'dropShadow', floodOpacity: '30'}), "new CanvasFilter({filter: 'dropShadow', floodOpacity: '30'})");
52+
// stdDeviation
53+
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: 10}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: 10})");
54+
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: -1}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: -1})");
55+
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: 0.5}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: 0.5})");
56+
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: null}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: null})");
57+
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: true}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: true})");
58+
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: false}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: false})");
59+
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: []}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: []})");
60+
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: [20]}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: [\""+(20)+"\"]})");
61+
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: '30'}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: '30'})");
62+
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: [10, -1]}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: [10, -1]})");
63+
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: [0.5, null]}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: [0.5, null]})");
64+
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: [true, false]}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: [true, false]})");
65+
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: [[], [20]]}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: [[], [\""+(20)+"\"]]})");
66+
_assert(new CanvasFilter({filter: 'dropShadow', stdDeviation: ['30', ['40']]}), "new CanvasFilter({filter: 'dropShadow', stdDeviation: ['30', ['40']]})");
6267
// floodColor
6368
_assert(new CanvasFilter({filter: 'dropShadow', floodColor: 'red'}), "new CanvasFilter({filter: 'dropShadow', floodColor: 'red'})");
6469
_assert(new CanvasFilter({filter: 'dropShadow', floodColor: 'canvas'}), "new CanvasFilter({filter: 'dropShadow', floodColor: 'canvas'})");
@@ -82,14 +87,6 @@ <h1>2d.filter.canvasFilterObject.dropShadow.exceptions.tentative</h1>
8287
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', dy: 'test'}); });
8388
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', dy: {}}); });
8489
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', dy: [1, 2]}); });
85-
// stdDeviation
86-
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: NaN}); });
87-
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: Infinity}); });
88-
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: -Infinity}); });
89-
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: undefined}); });
90-
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: 'test'}); });
91-
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: {}}); });
92-
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: [1, 2]}); });
9390
// floodOpacity
9491
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', floodOpacity: NaN}); });
9592
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', floodOpacity: Infinity}); });
@@ -98,6 +95,21 @@ <h1>2d.filter.canvasFilterObject.dropShadow.exceptions.tentative</h1>
9895
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', floodOpacity: 'test'}); });
9996
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', floodOpacity: {}}); });
10097
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', floodOpacity: [1, 2]}); });
98+
// stdDeviation
99+
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: NaN}); });
100+
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: Infinity}); });
101+
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: -Infinity}); });
102+
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: undefined}); });
103+
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: 'test'}); });
104+
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: {}}); });
105+
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: [1, 2, 3]}); });
106+
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: [1, NaN]}); });
107+
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: [1, Infinity]}); });
108+
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: [1, -Infinity]}); });
109+
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: [1, undefined]}); });
110+
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: [1, 'test']}); });
111+
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: [1, {}]}); });
112+
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', stdDeviation: [1, [2, 3]]}); });
101113
// floodColor
102114
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', floodColor: 'test'}); });
103115
assert_throws_js(TypeError, function() { new CanvasFilter({filter: 'dropShadow', floodColor: 'rgba(NaN, 3, 2, 1)'}); });

testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,54 @@
44
<h1>2d.filter.canvasFilterObject.dropShadow.tentative</h1>
55
<p class="desc">Test CanvasFilter() dropShadow object.</p>
66

7-
<svg width=620 height=320 xmlns="http://www.w3.org/2000/svg">
7+
<svg xmlns="http://www.w3.org/2000/svg"
8+
width=520 height=420
9+
color-interpolation-filters="sRGB">
810
<rect x=0 y=0 width=100% height=50 fill="teal" />
911
<rect x=0 y=100 width=100% height=50 fill="teal" />
1012
<rect x=0 y=200 width=100% height=50 fill="teal" />
13+
<rect x=0 y=300 width=100% height=50 fill="teal" />
1114

1215
<rect x=10 y=10 width=80 height=80 fill="crimson"
13-
style="filter: drop-shadow(2px 2px 2px black)"/>
16+
filter="drop-shadow(2px 2px 2px black)"/>
1417
<rect x=110 y=10 width=80 height=80 fill="crimson"
15-
style="filter: drop-shadow(15px 10px 5px rgba(128, 0, 128, 0.7))"/>
18+
filter="drop-shadow(9px 12px 5px rgba(128, 0, 128, 0.7))"/>
1619

1720
<rect x=10 y=110 width=80 height=80 fill="crimson"
18-
style="filter: drop-shadow(10px 10px 3px purple)"/>
21+
filter="drop-shadow(9px 12px 3px purple)"/>
1922
<rect x=110 y=110 width=80 height=80 fill="crimson"
20-
style="filter: drop-shadow(15px 10px 3px LinkText)"/>
23+
filter="drop-shadow(9px 12px 3px LinkText)"/>
2124
<rect x=210 y=110 width=80 height=80 fill="crimson"
22-
style="filter: drop-shadow(10px 15px 0px purple)"/>
25+
filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))"/>
2326
<rect x=310 y=110 width=80 height=80 fill="crimson"
24-
style="filter: drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))"/>
27+
filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 0.7))"/>
2528
<rect x=410 y=110 width=80 height=80 fill="crimson"
26-
style="filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.7))"/>
27-
<rect x=510 y=110 width=80 height=80 fill="crimson"
28-
style="filter: drop-shadow(15px 10px 3px rgba(20, 50, 130, 0.49))"/>
29+
filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 0.49))"/>
2930

3031
<rect x=10 y=210 width=80 height=80 fill="crimson"
31-
style="filter: drop-shadow(-5px 0px 0px purple)"/>
32+
filter="drop-shadow(9px 12px 0px purple)"/>
3233
<rect x=110 y=210 width=80 height=80 fill="crimson"
33-
style="filter: drop-shadow(0px 5px 0px rgba(128, 0, 128, 0.8))"/>
34+
filter="drop-shadow(9px 12px 5px purple)"/>
3435
<rect x=210 y=210 width=80 height=80 fill="crimson"
35-
style="filter: drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4))"/>
36+
filter="drop-shadow(9px 12px 0px purple)"/>
37+
<filter id="separable-filter"
38+
x="-100%" y="-100%" width="300%" height="300%">
39+
<feDropShadow dx=9 dy=12 stdDeviation="3 5" flood-color="purple"/>
40+
</filter>
41+
<rect x=310 y=210 width=80 height=80 fill="crimson"
42+
filter="url(#separable-filter)"/>
43+
<rect x=410 y=210 width=80 height=80 fill="crimson"
44+
filter="drop-shadow(9px 12px 0px purple)"/>
45+
46+
<rect x=10 y=310 width=80 height=80 fill="crimson"
47+
filter="drop-shadow(-5px 0px 0px purple)"/>
48+
<filter id="separable-filter-degenerate"
49+
x="-100%" y="-100%" width="300%" height="300%">
50+
<feDropShadow dx=0 dy=5 stdDeviation="0 3"
51+
flood-color="rgba(128, 0, 128, 0.8)"/>
52+
</filter>
53+
<rect x=110 y=310 width=80 height=80 fill="crimson"
54+
filter="url(#separable-filter-degenerate)"/>
55+
<rect x=210 y=310 width=80 height=80 fill="crimson"
56+
filter="drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4))"/>
3657
</svg>

testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@
44
<title>Canvas test: 2d.filter.canvasFilterObject.dropShadow.tentative</title>
55
<h1>2d.filter.canvasFilterObject.dropShadow.tentative</h1>
66
<p class="desc">Test CanvasFilter() dropShadow object.</p>
7-
<canvas id="canvas" width="620" height="320">
7+
<canvas id="canvas" width="520" height="420">
88
<p class="fallback">FAIL (fallback content)</p>
99
</canvas>
1010
<script>
1111
const canvas = document.getElementById("canvas");
1212
const ctx = canvas.getContext('2d');
1313

1414
ctx.fillStyle = 'teal';
15-
ctx.fillRect(0, 0, 620, 50);
16-
ctx.fillRect(0, 100, 620, 50);
17-
ctx.fillRect(0, 200, 620, 50);
15+
ctx.fillRect(0, 0, 520, 50);
16+
ctx.fillRect(0, 100, 520, 50);
17+
ctx.fillRect(0, 200, 520, 50);
18+
ctx.fillRect(0, 300, 520, 50);
1819

1920
ctx.fillStyle = 'crimson';
2021

@@ -24,59 +25,83 @@ <h1>2d.filter.canvasFilterObject.dropShadow.tentative</h1>
2425

2526
// All parameters specified.
2627
ctx.filter = new CanvasFilter(
27-
{filter: 'dropShadow', dx: 15, dy: 10, stdDeviation: 5,
28+
{filter: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5,
2829
floodColor: 'purple', floodOpacity: 0.7});
2930
ctx.fillRect(110, 10, 80, 80);
3031

3132
// Named color.
3233
ctx.filter = new CanvasFilter(
33-
{filter: 'dropShadow', dx: 10, dy: 10, stdDeviation: 3,
34+
{filter: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
3435
floodColor: 'purple'});
3536
ctx.fillRect(10, 110, 80, 80);
3637

3738
// System color.
3839
ctx.filter = new CanvasFilter(
39-
{filter: 'dropShadow', dx: 15, dy: 10, stdDeviation: 3,
40+
{filter: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
4041
floodColor: 'LinkText'});
4142
ctx.fillRect(110, 110, 80, 80);
4243

43-
// No blur.
44-
ctx.filter = new CanvasFilter(
45-
{filter: 'dropShadow', dx: 10, dy: 15, stdDeviation: 0,
46-
floodColor: 'purple'});
47-
ctx.fillRect(210, 110, 80, 80);
48-
4944
// Numerical color.
5045
ctx.filter = new CanvasFilter(
5146
{filter: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
5247
floodColor: 'rgba(20, 50, 130, 1)'});
53-
ctx.fillRect(310, 110, 80, 80);
48+
ctx.fillRect(210, 110, 80, 80);
5449

5550
// Transparent floodColor.
5651
ctx.filter = new CanvasFilter(
57-
{filter: 'dropShadow', dx: 15, dy: 10, stdDeviation: 3,
52+
{filter: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
5853
floodColor: 'rgba(20, 50, 130, 0.7)'});
59-
ctx.fillRect(410, 110, 80, 80);
54+
ctx.fillRect(310, 110, 80, 80);
6055

6156
// Transparent floodColor and floodOpacity.
6257
ctx.filter = new CanvasFilter(
63-
{filter: 'dropShadow', dx: 15, dy: 10, stdDeviation: 3,
58+
{filter: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
6459
floodColor: 'rgba(20, 50, 130, 0.7)', floodOpacity: 0.7});
65-
ctx.fillRect(510, 110, 80, 80);
60+
ctx.fillRect(410, 110, 80, 80);
61+
62+
// No blur.
63+
ctx.filter = new CanvasFilter(
64+
{filter: 'dropShadow', dx: 9, dy: 12, stdDeviation: 0,
65+
floodColor: 'purple'});
66+
ctx.fillRect(10, 210, 80, 80);
67+
68+
// Single float blur.
69+
ctx.filter = new CanvasFilter(
70+
{filter: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5,
71+
floodColor: 'purple'});
72+
ctx.fillRect(110, 210, 80, 80);
73+
74+
// Single negative float blur.
75+
ctx.filter = new CanvasFilter(
76+
{filter: 'dropShadow', dx: 9, dy: 12, stdDeviation: -5,
77+
floodColor: 'purple'});
78+
ctx.fillRect(210, 210, 80, 80);
79+
80+
// Two floats (X&Y) blur.
81+
ctx.filter = new CanvasFilter(
82+
{filter: 'dropShadow', dx: 9, dy: 12, stdDeviation: [3, 5],
83+
floodColor: 'purple'});
84+
ctx.fillRect(310, 210, 80, 80);
85+
86+
// Two negative floats (X&Y) blur.
87+
ctx.filter = new CanvasFilter(
88+
{filter: 'dropShadow', dx: 9, dy: 12, stdDeviation: [-3, -5],
89+
floodColor: 'purple'});
90+
ctx.fillRect(410, 210, 80, 80);
6691

6792
// Degenerate parameter values.
6893
ctx.filter = new CanvasFilter(
6994
{filter: 'dropShadow', dx: [-5], dy: [], stdDeviation: null,
7095
floodColor: 'purple', floodOpacity: [2]});
71-
ctx.fillRect(10, 210, 80, 80);
96+
ctx.fillRect(10, 310, 80, 80);
7297

7398
ctx.filter = new CanvasFilter(
74-
{filter: 'dropShadow', dx: null, dy: '5', stdDeviation: -5,
99+
{filter: 'dropShadow', dx: null, dy: '5', stdDeviation: [[-5], ['3']],
75100
floodColor: 'purple', floodOpacity: '0.8'});
76-
ctx.fillRect(110, 210, 80, 80);
101+
ctx.fillRect(110, 310, 80, 80);
77102

78103
ctx.filter = new CanvasFilter(
79104
{filter: 'dropShadow', dx: true, dy: ['10'], stdDeviation: false,
80105
floodColor: 'purple', floodOpacity: ['0.4']});
81-
ctx.fillRect(210, 210, 80, 80);
106+
ctx.fillRect(210, 310, 80, 80);
82107
</script>

0 commit comments

Comments
 (0)