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",