From b99c0c6a7f243f9c78f9fc2ab75d1895a79495bd Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Tue, 21 Oct 2025 10:09:46 +0100 Subject: [PATCH] LibWeb: Account for paint style and global alpha when drawing shadows --- .../LibWeb/HTML/CanvasRenderingContext2D.cpp | 18 ++++++++- .../element/shadows/2d.shadow.alpha.1.txt | 6 +++ .../element/shadows/2d.shadow.alpha.2.txt | 6 +++ .../element/shadows/2d.shadow.alpha.3.txt | 6 +++ .../element/shadows/2d.shadow.alpha.4.txt | 6 +++ .../element/shadows/2d.shadow.alpha.5.txt | 6 +++ .../element/shadows/2d.shadow.alpha.1.html | 33 +++++++++++++++++ .../element/shadows/2d.shadow.alpha.2.html | 33 +++++++++++++++++ .../element/shadows/2d.shadow.alpha.2.png | Bin 0 -> 206 bytes .../element/shadows/2d.shadow.alpha.3.html | 35 ++++++++++++++++++ .../element/shadows/2d.shadow.alpha.3.png | Bin 0 -> 206 bytes .../element/shadows/2d.shadow.alpha.4.html | 35 ++++++++++++++++++ .../element/shadows/2d.shadow.alpha.4.png | Bin 0 -> 206 bytes .../element/shadows/2d.shadow.alpha.5.html | 34 +++++++++++++++++ .../element/shadows/2d.shadow.alpha.5.png | Bin 0 -> 206 bytes 15 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.1.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.2.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.3.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.4.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.5.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.1.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.2.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.2.png create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.3.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.3.png create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.4.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.4.png create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.5.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.5.png diff --git a/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp b/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp index e851eaeed87..24cc27d27b2 100644 --- a/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp +++ b/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp @@ -1062,12 +1062,19 @@ void CanvasRenderingContext2D::paint_shadow_for_fill_internal(Gfx::Path const& p if (state.current_compositing_and_blending_operator == Gfx::CompositingAndBlendingOperator::Copy) return; + auto alpha = state.global_alpha * (state.shadow_color.alpha() / 255.0f); + auto fill_style_color = state.fill_style.as_color(); + if (fill_style_color.has_value() && fill_style_color->alpha() > 0) + alpha = (fill_style_color->alpha() / 255.0f) * state.global_alpha; + if (alpha == 0.0f) + return; + painter->save(); Gfx::AffineTransform transform; transform.translate(state.shadow_offset_x, state.shadow_offset_y); painter->set_transform(transform); - painter->fill_path(path, state.shadow_color.with_opacity(state.global_alpha), winding_rule, state.shadow_blur, state.current_compositing_and_blending_operator); + painter->fill_path(path, state.shadow_color.with_opacity(alpha), winding_rule, state.shadow_blur, state.current_compositing_and_blending_operator); painter->restore(); @@ -1085,12 +1092,19 @@ void CanvasRenderingContext2D::paint_shadow_for_stroke_internal(Gfx::Path const& if (state.current_compositing_and_blending_operator == Gfx::CompositingAndBlendingOperator::Copy) return; + auto alpha = state.global_alpha * (state.shadow_color.alpha() / 255.0f); + auto fill_style_color = state.fill_style.as_color(); + if (fill_style_color.has_value() && fill_style_color->alpha() > 0) + alpha = (fill_style_color->alpha() / 255.0f) * state.global_alpha; + if (alpha == 0.0f) + return; + painter->save(); Gfx::AffineTransform transform; transform.translate(state.shadow_offset_x, state.shadow_offset_y); painter->set_transform(transform); - painter->stroke_path(path, state.shadow_color.with_opacity(state.global_alpha), state.line_width, state.shadow_blur, state.current_compositing_and_blending_operator); + painter->stroke_path(path, state.shadow_color.with_opacity(alpha), state.line_width, state.shadow_blur, state.current_compositing_and_blending_operator); painter->restore(); diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.1.txt b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.1.txt new file mode 100644 index 00000000000..04bdedfed89 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.1.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass Shadow color alpha components are used \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.2.txt b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.2.txt new file mode 100644 index 00000000000..04bdedfed89 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.2.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass Shadow color alpha components are used \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.3.txt b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.3.txt new file mode 100644 index 00000000000..70b5cfd29e8 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.3.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass Shadows are affected by globalAlpha \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.4.txt b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.4.txt new file mode 100644 index 00000000000..d9404b2aa7e --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.4.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass Shadows with alpha components are correctly affected by globalAlpha \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.5.txt b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.5.txt new file mode 100644 index 00000000000..2128d541275 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.5.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass Shadows of shapes with alpha components are drawn correctly \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.1.html b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.1.html new file mode 100644 index 00000000000..1cb62d5418b --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.1.html @@ -0,0 +1,33 @@ + + + +Canvas test: 2d.shadow.alpha.1 + + + + + + +

2d.shadow.alpha.1

+

Shadow color alpha components are used

+ + +

Actual output:

+

FAIL (fallback content)

+

Expected output:

+

+ + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.2.html b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.2.html new file mode 100644 index 00000000000..ee873c19742 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.2.html @@ -0,0 +1,33 @@ + + + +Canvas test: 2d.shadow.alpha.2 + + + + + + +

2d.shadow.alpha.2

+

Shadow color alpha components are used

+ + +

Actual output:

+

FAIL (fallback content)

+

Expected output:

+

+ + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.2.png b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.2.png new file mode 100644 index 0000000000000000000000000000000000000000..8764e89b371d41428f0ba45d9c0391e41b0dd8a2 GIT binary patch literal 206 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z*!2~2#!(YAxQfx`y?k)`fL2$v|<&%LT&7Llf zAsLNtFF0~CC@>swFx`1^?SnX_JE{`1tKS@)`_<}!dKxQjA$wBRx^RlVeoYI Kb6Mw<&;$U*t~bH} literal 0 HcmV?d00001 diff --git a/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.3.html b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.3.html new file mode 100644 index 00000000000..95e97b28691 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.3.html @@ -0,0 +1,35 @@ + + + +Canvas test: 2d.shadow.alpha.3 + + + + + + +

2d.shadow.alpha.3

+

Shadows are affected by globalAlpha

+ + +

Actual output:

+

FAIL (fallback content)

+

Expected output:

+

+ + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.3.png b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.3.png new file mode 100644 index 0000000000000000000000000000000000000000..8764e89b371d41428f0ba45d9c0391e41b0dd8a2 GIT binary patch literal 206 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z*!2~2#!(YAxQfx`y?k)`fL2$v|<&%LT&7Llf zAsLNtFF0~CC@>swFx`1^?SnX_JE{`1tKS@)`_<}!dKxQjA$wBRx^RlVeoYI Kb6Mw<&;$U*t~bH} literal 0 HcmV?d00001 diff --git a/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.4.html b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.4.html new file mode 100644 index 00000000000..37547293907 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.4.html @@ -0,0 +1,35 @@ + + + +Canvas test: 2d.shadow.alpha.4 + + + + + + +

2d.shadow.alpha.4

+

Shadows with alpha components are correctly affected by globalAlpha

+ + +

Actual output:

+

FAIL (fallback content)

+

Expected output:

+

    + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.4.png b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.4.png new file mode 100644 index 0000000000000000000000000000000000000000..8764e89b371d41428f0ba45d9c0391e41b0dd8a2 GIT binary patch literal 206 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z*!2~2#!(YAxQfx`y?k)`fL2$v|<&%LT&7Llf zAsLNtFF0~CC@>swFx`1^?SnX_JE{`1tKS@)`_<}!dKxQjA$wBRx^RlVeoYI Kb6Mw<&;$U*t~bH} literal 0 HcmV?d00001 diff --git a/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.5.html b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.5.html new file mode 100644 index 00000000000..10144359aab --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.5.html @@ -0,0 +1,34 @@ + + + +Canvas test: 2d.shadow.alpha.5 + + + + + + +

    2d.shadow.alpha.5

    +

    Shadows of shapes with alpha components are drawn correctly

    + + +

    Actual output:

    +

    FAIL (fallback content)

    +

    Expected output:

    +

      + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.5.png b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/shadows/2d.shadow.alpha.5.png new file mode 100644 index 0000000000000000000000000000000000000000..8764e89b371d41428f0ba45d9c0391e41b0dd8a2 GIT binary patch literal 206 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z*!2~2#!(YAxQfx`y?k)`fL2$v|<&%LT&7Llf zAsLNtFF0~CC@>swFx`1^?SnX_JE{`1tKS@)`_<}!dKxQjA$wBRx^RlVeoYI Kb6Mw<&;$U*t~bH} literal 0 HcmV?d00001