From ee5d66c5d5a76a5b55a8bd1801d5256231fef041 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Sat, 13 Jan 2024 10:38:07 +0100 Subject: [PATCH] LibWeb: Resolve text shadows in `LayoutState::commit()` Rather than resolving the text-shadow each time painting commands are recorded, we can resolve it once during the layout commit and save the resolved values in paintable fragments. This is also step towards getting rid of layout node pointer in paintable fragment. --- .../Libraries/LibWeb/Layout/LayoutState.cpp | 24 +++++++++++++++++++ .../Libraries/LibWeb/Layout/LayoutState.h | 1 + .../LibWeb/Painting/PaintableBox.cpp | 19 +-------------- .../LibWeb/Painting/PaintableFragment.h | 6 +++++ 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/Userland/Libraries/LibWeb/Layout/LayoutState.cpp b/Userland/Libraries/LibWeb/Layout/LayoutState.cpp index 9e07eb5328..a6a248ec6a 100644 --- a/Userland/Libraries/LibWeb/Layout/LayoutState.cpp +++ b/Userland/Libraries/LibWeb/Layout/LayoutState.cpp @@ -357,6 +357,29 @@ void LayoutState::resolve_box_shadow_data() } } +void LayoutState::resolve_text_shadows(Vector const& paintables_with_lines) +{ + for (auto const& paintable_with_lines : paintables_with_lines) { + for (auto const& fragment : paintable_with_lines.fragments()) { + auto const& text_shadow = fragment.m_layout_node->computed_values().text_shadow(); + if (!text_shadow.is_empty()) { + Vector resolved_shadow_data; + resolved_shadow_data.ensure_capacity(text_shadow.size()); + for (auto const& layer : text_shadow) { + resolved_shadow_data.empend( + layer.color, + layer.offset_x.to_px(paintable_with_lines.layout_node()), + layer.offset_y.to_px(paintable_with_lines.layout_node()), + layer.blur_radius.to_px(paintable_with_lines.layout_node()), + layer.spread_distance.to_px(paintable_with_lines.layout_node()), + Painting::ShadowPlacement::Outer); + } + const_cast(fragment).set_shadows(move(resolved_shadow_data)); + } + } + } +} + void LayoutState::commit(Box& root) { // Only the top-level LayoutState should ever be committed. @@ -452,6 +475,7 @@ void LayoutState::commit(Box& root) resolve_border_radii(); resolve_box_shadow_data(); + resolve_text_shadows(paintables_with_lines); for (auto& it : used_values_per_layout_node) { auto& used_values = *it.value; diff --git a/Userland/Libraries/LibWeb/Layout/LayoutState.h b/Userland/Libraries/LibWeb/Layout/LayoutState.h index a28a49034b..1c168b855b 100644 --- a/Userland/Libraries/LibWeb/Layout/LayoutState.h +++ b/Userland/Libraries/LibWeb/Layout/LayoutState.h @@ -188,6 +188,7 @@ private: void resolve_relative_positions(Vector const&); void resolve_border_radii(); void resolve_box_shadow_data(); + void resolve_text_shadows(Vector const& paintables_with_lines); }; } diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp index 4b2dd7a248..93f9265746 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -662,24 +662,7 @@ void PaintableWithLines::paint(PaintContext& context, PaintPhase phase) const for (auto& fragment : fragments()) { if (fragment.contained_by_inline_node()) continue; - if (is(fragment.layout_node())) { - auto& text_shadow = fragment.layout_node().computed_values().text_shadow(); - if (!text_shadow.is_empty()) { - Vector resolved_shadow_data; - resolved_shadow_data.ensure_capacity(text_shadow.size()); - for (auto const& layer : text_shadow) { - resolved_shadow_data.empend( - layer.color, - layer.offset_x.to_px(layout_box()), - layer.offset_y.to_px(layout_box()), - layer.blur_radius.to_px(layout_box()), - layer.spread_distance.to_px(layout_box()), - ShadowPlacement::Outer); - } - context.recording_painter().set_font(fragment.layout_node().first_available_font()); - paint_text_shadow(context, fragment, resolved_shadow_data); - } - } + paint_text_shadow(context, fragment, fragment.shadows()); } } diff --git a/Userland/Libraries/LibWeb/Painting/PaintableFragment.h b/Userland/Libraries/LibWeb/Painting/PaintableFragment.h index 8c35cdf834..c378bbe4ea 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableFragment.h +++ b/Userland/Libraries/LibWeb/Painting/PaintableFragment.h @@ -14,6 +14,8 @@ namespace Web::Painting { class PaintableFragment { + friend struct Layout::LayoutState; + public: explicit PaintableFragment(Layout::LineBoxFragment const&); @@ -30,6 +32,9 @@ public: BorderRadiiData const& border_radii_data() const { return m_border_radii_data; } void set_border_radii_data(BorderRadiiData const& border_radii_data) { m_border_radii_data = border_radii_data; } + Vector const& shadows() const { return m_shadows; } + void set_shadows(Vector&& shadows) { m_shadows = shadows; } + CSSPixelRect const absolute_rect() const; Vector const& glyph_run() const { return m_glyph_run; } @@ -53,6 +58,7 @@ private: int m_length; Painting::BorderRadiiData m_border_radii_data; Vector m_glyph_run; + Vector m_shadows; bool m_contained_by_inline_node { false }; };