From 5a874cc62a02c8829860b0305c02bb4e2d2c636b Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Mon, 7 Jul 2025 19:17:19 +0200 Subject: [PATCH] LibWeb: Remove ClippableAndScrollable mixin Initially ClippableAndScrollable was introduced, because we had PaintableBox and InlinePaintable and both wanted to share clipping and scrolling logic. Now, when InlinePaintable is gone, we could inline ClippableAndScrollable implementation into PaintableBox. --- Libraries/LibWeb/CMakeLists.txt | 1 - .../Painting/ClippableAndScrollable.cpp | 74 ------------------- .../LibWeb/Painting/ClippableAndScrollable.h | 55 -------------- Libraries/LibWeb/Painting/PaintableBox.cpp | 63 +++++++++++++++- Libraries/LibWeb/Painting/PaintableBox.h | 37 +++++++++- .../Libraries/LibWeb/Painting/BUILD.gn | 1 - 6 files changed, 95 insertions(+), 136 deletions(-) delete mode 100644 Libraries/LibWeb/Painting/ClippableAndScrollable.cpp delete mode 100644 Libraries/LibWeb/Painting/ClippableAndScrollable.h diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index e66e9eb8117..d85221b8549 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -707,7 +707,6 @@ set(SOURCES Painting/CanvasPaintable.cpp Painting/CheckBoxPaintable.cpp Painting/ClipFrame.cpp - Painting/ClippableAndScrollable.cpp Painting/Command.cpp Painting/DisplayList.cpp Painting/DisplayListPlayerSkia.cpp diff --git a/Libraries/LibWeb/Painting/ClippableAndScrollable.cpp b/Libraries/LibWeb/Painting/ClippableAndScrollable.cpp deleted file mode 100644 index 5587bfd79ac..00000000000 --- a/Libraries/LibWeb/Painting/ClippableAndScrollable.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2024, Aliaksandr Kalenik - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include - -namespace Web::Painting { - -Optional ClippableAndScrollable::own_scroll_frame_id() const -{ - if (m_own_scroll_frame) - return m_own_scroll_frame->id(); - return {}; -} - -Optional ClippableAndScrollable::scroll_frame_id() const -{ - if (m_enclosing_scroll_frame) - return m_enclosing_scroll_frame->id(); - return {}; -} - -CSSPixelPoint ClippableAndScrollable::cumulative_offset_of_enclosing_scroll_frame() const -{ - if (m_enclosing_scroll_frame) - return m_enclosing_scroll_frame->cumulative_offset(); - return {}; -} - -Optional ClippableAndScrollable::clip_rect_for_hit_testing() const -{ - if (m_enclosing_clip_frame) - return m_enclosing_clip_frame->clip_rect_for_hit_testing(); - return {}; -} - -void ClippableAndScrollable::apply_clip(PaintContext& context, RefPtr from_clip_frame) const -{ - auto const& clip_rects = from_clip_frame->clip_rects(); - if (clip_rects.is_empty()) - return; - - auto& display_list_recorder = context.display_list_recorder(); - display_list_recorder.save(); - for (auto const& clip_rect : clip_rects) { - Optional clip_scroll_frame_id; - if (clip_rect.enclosing_scroll_frame) - clip_scroll_frame_id = clip_rect.enclosing_scroll_frame->id(); - display_list_recorder.push_scroll_frame_id(clip_scroll_frame_id); - auto rect = context.rounded_device_rect(clip_rect.rect).to_type(); - auto corner_radii = clip_rect.corner_radii.as_corners(context); - if (corner_radii.has_any_radius()) { - display_list_recorder.add_rounded_rect_clip(corner_radii, rect, CornerClip::Outside); - } else { - display_list_recorder.add_clip_rect(rect); - } - display_list_recorder.pop_scroll_frame_id(); - } -} - -void ClippableAndScrollable::restore_clip(PaintContext& context, RefPtr from_clip_frame) const -{ - auto const& clip_rects = from_clip_frame->clip_rects(); - if (clip_rects.is_empty()) - return; - - context.display_list_recorder().restore(); -} - -} diff --git a/Libraries/LibWeb/Painting/ClippableAndScrollable.h b/Libraries/LibWeb/Painting/ClippableAndScrollable.h deleted file mode 100644 index dfd67a2b5de..00000000000 --- a/Libraries/LibWeb/Painting/ClippableAndScrollable.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2024, Aliaksandr Kalenik - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include - -namespace Web::Painting { - -class ClippableAndScrollable { -public: - virtual ~ClippableAndScrollable() = default; - - void set_enclosing_scroll_frame(RefPtr scroll_frame) { m_enclosing_scroll_frame = scroll_frame; } - void set_own_scroll_frame(RefPtr scroll_frame) { m_own_scroll_frame = scroll_frame; } - void set_enclosing_clip_frame(RefPtr clip_frame) { m_enclosing_clip_frame = clip_frame; } - void set_own_clip_frame(RefPtr clip_frame) { m_own_clip_frame = clip_frame; } - - [[nodiscard]] RefPtr enclosing_scroll_frame() const { return m_enclosing_scroll_frame; } - [[nodiscard]] Optional scroll_frame_id() const; - [[nodiscard]] CSSPixelPoint cumulative_offset_of_enclosing_scroll_frame() const; - [[nodiscard]] Optional clip_rect_for_hit_testing() const; - - [[nodiscard]] RefPtr own_scroll_frame() const { return m_own_scroll_frame; } - [[nodiscard]] Optional own_scroll_frame_id() const; - [[nodiscard]] CSSPixelPoint own_scroll_frame_offset() const - { - if (m_own_scroll_frame) - return m_own_scroll_frame->own_offset(); - return {}; - } - - [[nodiscard]] RefPtr enclosing_clip_frame() const { return m_enclosing_clip_frame; } - [[nodiscard]] RefPtr own_clip_frame() const { return m_own_clip_frame; } - - void apply_clip(PaintContext&, RefPtr) const; - void restore_clip(PaintContext&, RefPtr) const; - - Gfx::AffineTransform const& combined_css_transform() const { return m_combined_css_transform; } - void set_combined_css_transform(Gfx::AffineTransform const& transform) { m_combined_css_transform = transform; } - -private: - RefPtr m_enclosing_scroll_frame; - RefPtr m_own_scroll_frame; - RefPtr m_enclosing_clip_frame; - RefPtr m_own_clip_frame; - - Gfx::AffineTransform m_combined_css_transform; -}; - -} diff --git a/Libraries/LibWeb/Painting/PaintableBox.cpp b/Libraries/LibWeb/Painting/PaintableBox.cpp index d2855cef5e5..8abfc4cddef 100644 --- a/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2022-2023, Andreas Kling * Copyright (c) 2022-2025, Sam Atkins - * Copyright (c) 2024, Aliaksandr Kalenik + * Copyright (c) 2024-2025, Aliaksandr Kalenik * Copyright (c) 2025, Jelle Raaijmakers * * SPDX-License-Identifier: BSD-2-Clause @@ -619,6 +619,67 @@ BorderRadiiData PaintableBox::normalized_border_radii_data(ShrinkRadiiForBorders return border_radii_data; } +Optional PaintableBox::own_scroll_frame_id() const +{ + if (m_own_scroll_frame) + return m_own_scroll_frame->id(); + return {}; +} + +Optional PaintableBox::scroll_frame_id() const +{ + if (m_enclosing_scroll_frame) + return m_enclosing_scroll_frame->id(); + return {}; +} + +CSSPixelPoint PaintableBox::cumulative_offset_of_enclosing_scroll_frame() const +{ + if (m_enclosing_scroll_frame) + return m_enclosing_scroll_frame->cumulative_offset(); + return {}; +} + +Optional PaintableBox::clip_rect_for_hit_testing() const +{ + if (m_enclosing_clip_frame) + return m_enclosing_clip_frame->clip_rect_for_hit_testing(); + return {}; +} + +void PaintableBox::apply_clip(PaintContext& context, RefPtr const& from_clip_frame) +{ + auto const& clip_rects = from_clip_frame->clip_rects(); + if (clip_rects.is_empty()) + return; + + auto& display_list_recorder = context.display_list_recorder(); + display_list_recorder.save(); + for (auto const& clip_rect : clip_rects) { + Optional clip_scroll_frame_id; + if (clip_rect.enclosing_scroll_frame) + clip_scroll_frame_id = clip_rect.enclosing_scroll_frame->id(); + display_list_recorder.push_scroll_frame_id(clip_scroll_frame_id); + auto rect = context.rounded_device_rect(clip_rect.rect).to_type(); + auto corner_radii = clip_rect.corner_radii.as_corners(context); + if (corner_radii.has_any_radius()) { + display_list_recorder.add_rounded_rect_clip(corner_radii, rect, CornerClip::Outside); + } else { + display_list_recorder.add_clip_rect(rect); + } + display_list_recorder.pop_scroll_frame_id(); + } +} + +void PaintableBox::restore_clip(PaintContext& context, RefPtr const& from_clip_frame) +{ + auto const& clip_rects = from_clip_frame->clip_rects(); + if (clip_rects.is_empty()) + return; + + context.display_list_recorder().restore(); +} + void PaintableBox::apply_scroll_offset(PaintContext& context) const { if (scroll_frame_id().has_value()) { diff --git a/Libraries/LibWeb/Painting/PaintableBox.h b/Libraries/LibWeb/Painting/PaintableBox.h index 641d287a472..477329bb6e1 100644 --- a/Libraries/LibWeb/Painting/PaintableBox.h +++ b/Libraries/LibWeb/Painting/PaintableBox.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2022-2025, Andreas Kling - * Copyright (c) 2024, Aliaksandr Kalenik + * Copyright (c) 2024-2025, Aliaksandr Kalenik * * SPDX-License-Identifier: BSD-2-Clause */ @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -25,8 +24,7 @@ namespace Web::Painting { extern bool g_paint_viewport_scrollbars; class PaintableBox : public Paintable - , public Weakable - , public ClippableAndScrollable { + , public Weakable { GC_CELL(PaintableBox, Paintable); public: @@ -241,6 +239,28 @@ public: void set_used_values_for_grid_template_rows(RefPtr style_value) { m_used_values_for_grid_template_rows = move(style_value); } RefPtr const& used_values_for_grid_template_rows() const { return m_used_values_for_grid_template_rows; } + void set_enclosing_scroll_frame(RefPtr const& scroll_frame) { m_enclosing_scroll_frame = scroll_frame; } + void set_own_scroll_frame(RefPtr const& scroll_frame) { m_own_scroll_frame = scroll_frame; } + void set_enclosing_clip_frame(RefPtr const& clip_frame) { m_enclosing_clip_frame = clip_frame; } + void set_own_clip_frame(RefPtr const& clip_frame) { m_own_clip_frame = clip_frame; } + + [[nodiscard]] RefPtr enclosing_scroll_frame() const { return m_enclosing_scroll_frame; } + [[nodiscard]] Optional scroll_frame_id() const; + [[nodiscard]] CSSPixelPoint cumulative_offset_of_enclosing_scroll_frame() const; + [[nodiscard]] Optional clip_rect_for_hit_testing() const; + + [[nodiscard]] RefPtr own_scroll_frame() const { return m_own_scroll_frame; } + [[nodiscard]] Optional own_scroll_frame_id() const; + [[nodiscard]] CSSPixelPoint own_scroll_frame_offset() const + { + if (m_own_scroll_frame) + return m_own_scroll_frame->own_offset(); + return {}; + } + + [[nodiscard]] RefPtr enclosing_clip_frame() const { return m_enclosing_clip_frame; } + [[nodiscard]] RefPtr own_clip_frame() const { return m_own_clip_frame; } + protected: explicit PaintableBox(Layout::Box const&); explicit PaintableBox(Layout::InlineNode const&); @@ -272,6 +292,9 @@ protected: TraversalDecision hit_test_scrollbars(CSSPixelPoint position, Function const& callback) const; CSSPixelPoint adjust_position_for_cumulative_scroll_offset(CSSPixelPoint) const; + Gfx::AffineTransform const& combined_css_transform() const { return m_combined_css_transform; } + void set_combined_css_transform(Gfx::AffineTransform const& transform) { m_combined_css_transform = transform; } + private: [[nodiscard]] virtual bool is_paintable_box() const final { return true; } @@ -282,6 +305,9 @@ private: bool scrollbar_contains_mouse_position(ScrollDirection, CSSPixelPoint); void scroll_to_mouse_position(CSSPixelPoint); + static void apply_clip(PaintContext&, RefPtr const&); + static void restore_clip(PaintContext&, RefPtr const&); + OwnPtr m_stacking_context; Optional m_overflow_data; @@ -293,7 +319,9 @@ private: Optional mutable m_absolute_paint_rect; RefPtr m_enclosing_scroll_frame; + RefPtr m_own_scroll_frame; RefPtr m_enclosing_clip_frame; + RefPtr m_own_clip_frame; Optional m_override_borders_data; Optional m_table_cell_coordinates; @@ -302,6 +330,7 @@ private: Vector m_box_shadow_data; Gfx::FloatMatrix4x4 m_transform { Gfx::FloatMatrix4x4::identity() }; CSSPixelPoint m_transform_origin; + Gfx::AffineTransform m_combined_css_transform; Optional m_outline_data; CSSPixels m_outline_offset { 0 }; diff --git a/Meta/gn/secondary/Userland/Libraries/LibWeb/Painting/BUILD.gn b/Meta/gn/secondary/Userland/Libraries/LibWeb/Painting/BUILD.gn index 774d711e131..4c55467d89e 100644 --- a/Meta/gn/secondary/Userland/Libraries/LibWeb/Painting/BUILD.gn +++ b/Meta/gn/secondary/Userland/Libraries/LibWeb/Painting/BUILD.gn @@ -16,7 +16,6 @@ source_set("Painting") { "CanvasPaintable.cpp", "CheckBoxPaintable.cpp", "ClipFrame.cpp", - "ClippableAndScrollable.cpp", "Command.cpp", "DisplayList.cpp", "DisplayListPlayerSkia.cpp",