diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp index 63d7e2239e..c420cb485f 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -92,6 +91,28 @@ Gfx::FloatRect PaintableBox::absolute_rect() const return *m_absolute_rect; } +Gfx::FloatRect PaintableBox::compute_absolute_paint_rect() const +{ + // FIXME: This likely incomplete: + auto rect = absolute_border_box_rect(); + auto resolved_box_shadow_data = resolve_box_shadow_data(); + for (auto const& shadow : resolved_box_shadow_data) { + if (shadow.placement == ShadowPlacement::Inner) + continue; + auto inflate = shadow.spread_distance + shadow.blur_radius; + auto shadow_rect = rect.inflated(inflate, inflate, inflate, inflate).translated(shadow.offset_x, shadow.offset_y); + rect = rect.united(shadow_rect); + } + return rect; +} + +Gfx::FloatRect PaintableBox::absolute_paint_rect() const +{ + if (!m_absolute_paint_rect.has_value()) + m_absolute_paint_rect = compute_absolute_paint_rect(); + return *m_absolute_paint_rect; +} + void PaintableBox::set_containing_line_box_fragment(Optional fragment_coordinate) { m_containing_line_box_fragment = fragment_coordinate; @@ -235,11 +256,11 @@ void PaintableBox::paint_background(PaintContext& context) const Painting::paint_background(context, layout_box(), background_rect, background_color, computed_values().image_rendering(), background_layers, normalized_border_radii_data()); } -void PaintableBox::paint_box_shadow(PaintContext& context) const +Vector PaintableBox::resolve_box_shadow_data() const { auto box_shadow_data = computed_values().box_shadow(); if (box_shadow_data.is_empty()) - return; + return {}; Vector resolved_box_shadow_data; resolved_box_shadow_data.ensure_capacity(box_shadow_data.size()); @@ -252,6 +273,15 @@ void PaintableBox::paint_box_shadow(PaintContext& context) const static_cast(layer.spread_distance.to_px(layout_box())), layer.placement == CSS::ShadowPlacement::Outer ? ShadowPlacement::Outer : ShadowPlacement::Inner); } + + return resolved_box_shadow_data; +} + +void PaintableBox::paint_box_shadow(PaintContext& context) const +{ + auto resolved_box_shadow_data = resolve_box_shadow_data(); + if (resolved_box_shadow_data.is_empty()) + return; Painting::paint_box_shadow(context, absolute_border_box_rect().to_rounded(), normalized_border_radii_data(), resolved_box_shadow_data); } diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.h b/Userland/Libraries/LibWeb/Painting/PaintableBox.h index e19c476173..0aeb132cf5 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.h +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.h @@ -9,6 +9,7 @@ #include #include #include +#include namespace Web::Painting { @@ -68,6 +69,8 @@ public: return rect; } + Gfx::FloatRect absolute_paint_rect() const; + float border_box_width() const { auto border_box = box_model().border_box(); @@ -123,6 +126,7 @@ protected: virtual void paint_box_shadow(PaintContext&) const; virtual Gfx::FloatRect compute_absolute_rect() const; + virtual Gfx::FloatRect compute_absolute_paint_rect() const; enum class ShrinkRadiiForBorders { Yes, @@ -131,6 +135,8 @@ protected: Painting::BorderRadiiData normalized_border_radii_data(ShrinkRadiiForBorders shrink = ShrinkRadiiForBorders::No) const; + Vector resolve_box_shadow_data() const; + private: Optional m_overflow_data; @@ -143,6 +149,7 @@ private: OwnPtr m_stacking_context; Optional mutable m_absolute_rect; + Optional mutable m_absolute_paint_rect; mutable bool m_clipping_overflow { false }; Optional mutable m_overflow_corner_radius_clipper;