From d5aca1c6c4addd9e1f64a31149bf10498b24238f Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 24 Mar 2022 16:06:43 +0100 Subject: [PATCH] LibWeb: Treate SVG paintable coordinates as relative to element Normally, paintable coordinates are relative to the nearest containing block, but in the SVG case, since doesn't form a containing block, we have to specialize the computation of SVGPaintable::absolute_rect(). --- .../Libraries/LibWeb/Painting/PaintableBox.cpp | 16 ++++++++++------ .../Libraries/LibWeb/Painting/PaintableBox.h | 2 ++ .../Libraries/LibWeb/Painting/SVGPaintable.cpp | 12 ++++++++++++ .../Libraries/LibWeb/Painting/SVGPaintable.h | 2 ++ 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp index b89eeb1b65..8b3814a305 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -66,14 +66,18 @@ Gfx::FloatPoint PaintableBox::effective_offset() const return m_offset; } +Gfx::FloatRect PaintableBox::compute_absolute_rect() const +{ + Gfx::FloatRect rect { effective_offset(), content_size() }; + for (auto const* block = containing_block(); block && block->paintable(); block = block->paintable()->containing_block()) + rect.translate_by(block->paint_box()->effective_offset()); + return rect; +} + Gfx::FloatRect PaintableBox::absolute_rect() const { - if (!m_absolute_rect.has_value()) { - Gfx::FloatRect rect { effective_offset(), content_size() }; - for (auto const* block = containing_block(); block && block->paintable(); block = block->paintable()->containing_block()) - rect.translate_by(block->paint_box()->effective_offset()); - m_absolute_rect = rect; - } + if (!m_absolute_rect.has_value()) + m_absolute_rect = compute_absolute_rect(); return *m_absolute_rect; } diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.h b/Userland/Libraries/LibWeb/Painting/PaintableBox.h index 4d3a7fc5f5..028a619fec 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.h +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.h @@ -126,6 +126,8 @@ protected: virtual void paint_background(PaintContext&) const; virtual void paint_box_shadow(PaintContext&) const; + virtual Gfx::FloatRect compute_absolute_rect() const; + private: Painting::BorderRadiusData normalized_border_radius_data() const; diff --git a/Userland/Libraries/LibWeb/Painting/SVGPaintable.cpp b/Userland/Libraries/LibWeb/Painting/SVGPaintable.cpp index 22f8898f5e..e1dae92297 100644 --- a/Userland/Libraries/LibWeb/Painting/SVGPaintable.cpp +++ b/Userland/Libraries/LibWeb/Painting/SVGPaintable.cpp @@ -5,6 +5,7 @@ */ #include +#include #include namespace Web::Painting { @@ -35,4 +36,15 @@ void SVGPaintable::after_children_paint(PaintContext& context, PaintPhase phase) context.svg_context().restore(); } +Gfx::FloatRect SVGPaintable::compute_absolute_rect() const +{ + if (auto* svg_svg_box = layout_box().first_ancestor_of_type()) { + Gfx::FloatRect rect { effective_offset(), content_size() }; + for (Layout::Box const* ancestor = svg_svg_box; ancestor && ancestor->paintable(); ancestor = ancestor->paintable()->containing_block()) + rect.translate_by(ancestor->paint_box()->effective_offset()); + return rect; + } + return PaintableBox::compute_absolute_rect(); +} + } diff --git a/Userland/Libraries/LibWeb/Painting/SVGPaintable.h b/Userland/Libraries/LibWeb/Painting/SVGPaintable.h index 59eb8f008e..b1783e16eb 100644 --- a/Userland/Libraries/LibWeb/Painting/SVGPaintable.h +++ b/Userland/Libraries/LibWeb/Painting/SVGPaintable.h @@ -20,6 +20,8 @@ public: protected: SVGPaintable(Layout::SVGBox const&); + + virtual Gfx::FloatRect compute_absolute_rect() const override; }; }