From cdf8b9e9436795febb5b71271e073a688bb9d1ca Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Tue, 8 Aug 2023 15:02:35 +0200 Subject: [PATCH] LibWeb/Painting: Translate by scroll offset before painting descendants Fixes painting of nested nodes in scrollable containers by moving painter's scroll offset translation from paint_node() to before_children_paint() and after_children_paint(). --- Userland/Libraries/LibWeb/Painting/PaintableBox.cpp | 12 ++++++++++++ Userland/Libraries/LibWeb/Painting/PaintableBox.h | 3 +++ .../Libraries/LibWeb/Painting/StackingContext.cpp | 12 ++---------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp index feb3488578..3277c57c20 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -429,6 +429,18 @@ Optional PaintableBox::calculate_overflow_clipped_rect() const return m_clip_rect; } +void PaintableBox::before_children_paint(PaintContext& context, PaintPhase) const +{ + auto scroll_offset = -this->scroll_offset(); + context.painter().translate({ context.enclosing_device_pixels(scroll_offset.x()), context.enclosing_device_pixels(scroll_offset.y()) }); +} + +void PaintableBox::after_children_paint(PaintContext& context, PaintPhase) const +{ + auto scroll_offset = this->scroll_offset(); + context.painter().translate({ context.enclosing_device_pixels(scroll_offset.x()), context.enclosing_device_pixels(scroll_offset.y()) }); +} + void PaintableBox::apply_clip_overflow_rect(PaintContext& context, PaintPhase phase) const { if (!AK::first_is_one_of(phase, PaintPhase::Background, PaintPhase::Border, PaintPhase::Foreground)) diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.h b/Userland/Libraries/LibWeb/Painting/PaintableBox.h index bf1e6899ff..3a788a4be9 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.h +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.h @@ -125,6 +125,9 @@ public: DOM::Document const& document() const { return layout_box().document(); } DOM::Document& document() { return layout_box().document(); } + virtual void before_children_paint(PaintContext&, PaintPhase) const override; + virtual void after_children_paint(PaintContext&, PaintPhase) const override; + virtual void apply_clip_overflow_rect(PaintContext&, PaintPhase) const override; virtual void clear_clip_overflow_rect(PaintContext&, PaintPhase) const override; diff --git a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp index bc22065903..fadb8e655d 100644 --- a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp +++ b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp @@ -26,16 +26,8 @@ namespace Web::Painting { static void paint_node(Layout::Node const& layout_node, PaintContext& context, PaintPhase phase) { - if (auto const* paintable = layout_node.paintable()) { - if (paintable->containing_block() && paintable->containing_block()->is_scrollable()) { - Gfx::PainterStateSaver saver(context.painter()); - auto scroll_offset = -paintable->containing_block()->paintable_box()->scroll_offset(); - context.painter().translate({ context.enclosing_device_pixels(scroll_offset.x()), context.enclosing_device_pixels(scroll_offset.y()) }); - paintable->paint(context, phase); - } else { - paintable->paint(context, phase); - } - } + if (auto const* paintable = layout_node.paintable()) + paintable->paint(context, phase); } StackingContext::StackingContext(Layout::Box& box, StackingContext* parent, size_t index_in_tree_order)