diff --git a/Libraries/LibWeb/Painting/Paintable.h b/Libraries/LibWeb/Painting/Paintable.h index 30e99bc63de..50ea317c5cb 100644 --- a/Libraries/LibWeb/Painting/Paintable.h +++ b/Libraries/LibWeb/Painting/Paintable.h @@ -79,6 +79,9 @@ public: virtual void apply_scroll_offset(PaintContext&, PaintPhase) const { } virtual void reset_scroll_offset(PaintContext&, PaintPhase) const { } + virtual void apply_own_clip_rect(PaintContext&, PaintPhase) const { } + virtual void clear_own_clip_rect(PaintContext&, PaintPhase) const { } + virtual void apply_clip_overflow_rect(PaintContext&, PaintPhase) const { } virtual void clear_clip_overflow_rect(PaintContext&, PaintPhase) const { } diff --git a/Libraries/LibWeb/Painting/PaintableBox.cpp b/Libraries/LibWeb/Painting/PaintableBox.cpp index 1a3ac5e8667..4c9cc64fa64 100644 --- a/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -326,6 +326,8 @@ void PaintableBox::before_paint(PaintContext& context, [[maybe_unused]] PaintPha if (!is_visible()) return; + apply_own_clip_rect(context, phase); + if (!has_css_transform()) { apply_clip_overflow_rect(context, phase); } @@ -337,6 +339,8 @@ void PaintableBox::after_paint(PaintContext& context, [[maybe_unused]] PaintPhas if (!is_visible()) return; + clear_own_clip_rect(context, phase); + reset_scroll_offset(context, phase); if (!has_css_transform()) { clear_clip_overflow_rect(context, phase); @@ -651,6 +655,38 @@ void PaintableBox::clear_clip_overflow_rect(PaintContext& context, PaintPhase ph restore_clip(context, enclosing_clip_frame()); } +void PaintableBox::apply_own_clip_rect(PaintContext& context, PaintPhase phase) const +{ + if (!own_clip_frame()) + return; + + // FIXME: This should apply to SVGs + if (is(*this) || is(*this)) + return; + + // FIXME: This should also apply to borders and outlines. + if (!first_is_one_of(phase, PaintPhase::Background, PaintPhase::Foreground)) + return; + + apply_clip(context, own_clip_frame()); +} + +void PaintableBox::clear_own_clip_rect(PaintContext& context, PaintPhase phase) const +{ + if (!own_clip_frame()) + return; + + // FIXME: This should apply to SVGs + if (is(*this) || is(*this)) + return; + + // FIXME: This should also apply to borders and outlines. + if (!first_is_one_of(phase, PaintPhase::Background, PaintPhase::Foreground)) + return; + + restore_clip(context, own_clip_frame()); +} + void paint_cursor_if_needed(PaintContext& context, TextPaintable const& paintable, PaintableFragment const& fragment) { auto const& navigable = *paintable.navigable(); @@ -870,12 +906,7 @@ void PaintableWithLines::paint(PaintContext& context, PaintPhase phase) const PaintableBox::paint(context, phase); - if (own_clip_frame()) { - apply_clip(context, own_clip_frame()); - if (own_scroll_frame_id().has_value()) { - context.display_list_recorder().push_scroll_frame_id(own_scroll_frame_id().value()); - } - } + apply_own_clip_rect(context, phase); // Text shadows // This is yet another loop, but done here because all shadows should appear under all text. @@ -899,12 +930,7 @@ void PaintableWithLines::paint(PaintContext& context, PaintPhase phase) const paint_text_fragment(context, static_cast(fragment.paintable()), fragment, phase); } - if (own_clip_frame()) { - if (own_scroll_frame_id().has_value()) { - context.display_list_recorder().pop_scroll_frame_id(); - } - restore_clip(context, own_clip_frame()); - } + clear_own_clip_rect(context, phase); } Paintable::DispatchEventOfSameName PaintableBox::handle_mousedown(Badge, CSSPixelPoint position, unsigned, unsigned) diff --git a/Libraries/LibWeb/Painting/PaintableBox.h b/Libraries/LibWeb/Painting/PaintableBox.h index c6a3e2e3f80..786068b0521 100644 --- a/Libraries/LibWeb/Painting/PaintableBox.h +++ b/Libraries/LibWeb/Painting/PaintableBox.h @@ -142,6 +142,9 @@ public: virtual void apply_clip_overflow_rect(PaintContext&, PaintPhase) const override; virtual void clear_clip_overflow_rect(PaintContext&, PaintPhase) const override; + virtual void apply_own_clip_rect(PaintContext&, PaintPhase) const override; + virtual void clear_own_clip_rect(PaintContext&, PaintPhase) const override; + [[nodiscard]] virtual TraversalDecision hit_test(CSSPixelPoint position, HitTestType type, Function const& callback) const override; Optional hit_test(CSSPixelPoint, HitTestType) const; [[nodiscard]] TraversalDecision hit_test_continuation(Function const& callback) const; diff --git a/Tests/LibWeb/Ref/expected/wpt-import/css/css-masking/clip/reference/clip-full-ref.html b/Tests/LibWeb/Ref/expected/wpt-import/css/css-masking/clip/reference/clip-full-ref.html new file mode 100644 index 00000000000..f556d5f12a9 --- /dev/null +++ b/Tests/LibWeb/Ref/expected/wpt-import/css/css-masking/clip/reference/clip-full-ref.html @@ -0,0 +1,11 @@ + + + + CSS Reftest Reference + + + +

The test passes if there is a green square and no red.

+
+ + \ No newline at end of file diff --git a/Tests/LibWeb/Ref/expected/wpt-import/css/css-masking/clip/reference/clip-no-clipping-ref.html b/Tests/LibWeb/Ref/expected/wpt-import/css/css-masking/clip/reference/clip-no-clipping-ref.html new file mode 100644 index 00000000000..724f8c51941 --- /dev/null +++ b/Tests/LibWeb/Ref/expected/wpt-import/css/css-masking/clip/reference/clip-no-clipping-ref.html @@ -0,0 +1,11 @@ + + + + CSS Reftest Reference + + + +

The test passes if there is a green square with a blue border.

+
+ + \ No newline at end of file diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/CSS2/visufx/clip-001.xht b/Tests/LibWeb/Ref/input/wpt-import/css/CSS2/visufx/clip-001.xht new file mode 100644 index 00000000000..695ae091175 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/CSS2/visufx/clip-001.xht @@ -0,0 +1,64 @@ + + + + + + + CSS Test: clip - auto value + + + + + + + + + + + + + + + + + + +

Test passes if there is a filled green square and no red.

+ +
+ +
+
+
+ + + \ No newline at end of file diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/CSS2/visufx/clip-005.xht b/Tests/LibWeb/Ref/input/wpt-import/css/CSS2/visufx/clip-005.xht new file mode 100644 index 00000000000..ab9714c2450 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/CSS2/visufx/clip-005.xht @@ -0,0 +1,25 @@ + + + + CSS Test: Clip using pixels with a zero value, 0px + + + + + + + + +

Test passes if there is no red visible on the page.

+
+ + \ No newline at end of file diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/CSS2/visufx/clip-007.xht b/Tests/LibWeb/Ref/input/wpt-import/css/CSS2/visufx/clip-007.xht new file mode 100644 index 00000000000..4ba86fca15e --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/CSS2/visufx/clip-007.xht @@ -0,0 +1,25 @@ + + + + CSS Test: Clip using pixels with a nominal value, 96px + + + + + + + + +

Test passes if there is no red visible on the page.

+
+ + \ No newline at end of file diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-masking/clip/clip-negative-values-001.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-masking/clip/clip-negative-values-001.html new file mode 100644 index 00000000000..cca8113e5f0 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-masking/clip/clip-negative-values-001.html @@ -0,0 +1,19 @@ + + + + CSS Masking: Test clip property does not clip on with negative values - 1 + + + + + + + +

The test passes if there is a green square and no red.

+
+
+
+ + \ No newline at end of file diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-masking/clip/clip-rect-auto-002.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-masking/clip/clip-rect-auto-002.html new file mode 100644 index 00000000000..0ff20d76e0b --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-masking/clip/clip-rect-auto-002.html @@ -0,0 +1,18 @@ + + + + CSS Masking: Test clip property with rect function and auto values clip to border box - 2 + + + + + + + +

The test passes if there is a green square with a blue border.

+
+ + \ No newline at end of file diff --git a/Tests/LibWeb/Screenshot/images/color-scheme-ref.png b/Tests/LibWeb/Screenshot/images/color-scheme-ref.png index e9841a2adff..b456969ddc9 100644 Binary files a/Tests/LibWeb/Screenshot/images/color-scheme-ref.png and b/Tests/LibWeb/Screenshot/images/color-scheme-ref.png differ diff --git a/Tests/LibWeb/Screenshot/images/css-backgrounds-ref.png b/Tests/LibWeb/Screenshot/images/css-backgrounds-ref.png index edc8041a3f3..3b2c462e54d 100644 Binary files a/Tests/LibWeb/Screenshot/images/css-backgrounds-ref.png and b/Tests/LibWeb/Screenshot/images/css-backgrounds-ref.png differ diff --git a/Tests/LibWeb/Screenshot/images/nested-boxes-with-hidden-overflow-and-border-radius-ref.png b/Tests/LibWeb/Screenshot/images/nested-boxes-with-hidden-overflow-and-border-radius-ref.png index 365600c05e6..25a9c2691a3 100644 Binary files a/Tests/LibWeb/Screenshot/images/nested-boxes-with-hidden-overflow-and-border-radius-ref.png and b/Tests/LibWeb/Screenshot/images/nested-boxes-with-hidden-overflow-and-border-radius-ref.png differ