Bladeren bron

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().
Aliaksandr Kalenik 2 jaren geleden
bovenliggende
commit
cdf8b9e943

+ 12 - 0
Userland/Libraries/LibWeb/Painting/PaintableBox.cpp

@@ -429,6 +429,18 @@ Optional<CSSPixelRect> 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))

+ 3 - 0
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;
 

+ 2 - 10
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)