LibWeb: Remove scroll_offset() usage in PaintableWithLines

A display list should not contain coordinates shifted by scroll offset.
Instead, "scroll frame id" needs to be used. In the future it's going to
allow us reuse a display list in cases when only scroll offsets need to
be updated.
This commit is contained in:
Aliaksandr Kalenik 2024-08-14 21:52:10 +02:00 committed by Andreas Kling
parent c61262684b
commit 5b23190174
Notes: github-actions[bot] 2024-08-15 11:45:56 +00:00
5 changed files with 40 additions and 5 deletions

View file

@ -9,6 +9,13 @@
namespace Web::Painting {
Optional<int> ClippableAndScrollable::own_scroll_frame_id() const
{
if (m_own_scroll_frame)
return m_own_scroll_frame->id;
return {};
}
Optional<int> ClippableAndScrollable::scroll_frame_id() const
{
if (m_enclosing_scroll_frame)

View file

@ -23,6 +23,9 @@ public:
[[nodiscard]] CSSPixelPoint enclosing_scroll_frame_offset() const;
[[nodiscard]] Optional<CSSPixelRect> clip_rect_for_hit_testing() const;
[[nodiscard]] Optional<int> own_scroll_frame_id() const;
void set_own_scroll_frame(RefPtr<ScrollFrame> scroll_frame) { m_own_scroll_frame = scroll_frame; }
void apply_clip(PaintContext&) const;
void restore_clip(PaintContext&) const;
@ -31,6 +34,7 @@ public:
private:
RefPtr<ScrollFrame const> m_enclosing_scroll_frame;
RefPtr<ScrollFrame const> m_own_scroll_frame;
RefPtr<ClipFrame const> m_enclosing_clip_frame;
Gfx::AffineTransform m_combined_css_transform;

View file

@ -59,6 +59,20 @@ public:
[[nodiscard]] bool is_inline() const { return m_inline; }
[[nodiscard]] CSS::Display display() const { return layout_node().display(); }
template<typename U, typename Callback>
TraversalDecision for_each_in_inclusive_subtree_of_type(Callback callback)
{
if (is<U>(*this)) {
if (auto decision = callback(static_cast<U&>(*this)); decision != TraversalDecision::Continue)
return decision;
}
for (auto* child = first_child(); child; child = child->next_sibling()) {
if (child->template for_each_in_inclusive_subtree_of_type<U>(callback) == TraversalDecision::Break)
return TraversalDecision::Break;
}
return TraversalDecision::Continue;
}
template<typename U, typename Callback>
TraversalDecision for_each_in_inclusive_subtree_of_type(Callback callback) const
{
@ -73,6 +87,16 @@ public:
return TraversalDecision::Continue;
}
template<typename U, typename Callback>
TraversalDecision for_each_in_subtree_of_type(Callback callback)
{
for (auto* child = first_child(); child; child = child->next_sibling()) {
if (child->template for_each_in_inclusive_subtree_of_type<U>(callback) == TraversalDecision::Break)
return TraversalDecision::Break;
}
return TraversalDecision::Continue;
}
template<typename U, typename Callback>
TraversalDecision for_each_in_subtree_of_type(Callback callback) const
{

View file

@ -680,9 +680,9 @@ void PaintableWithLines::paint(PaintContext& context, PaintPhase phase) const
context.display_list_recorder().add_rounded_rect_clip(corner_radii, context.rounded_device_rect(clip_box).to_type<int>(), CornerClip::Outside);
}
context.display_list_recorder().save();
auto scroll_offset = context.rounded_device_point(this->scroll_offset());
context.display_list_recorder().translate(-scroll_offset.to_type<int>());
if (own_scroll_frame_id().has_value()) {
context.display_list_recorder().set_scroll_frame_id(own_scroll_frame_id().value());
}
}
// Text shadows
@ -710,7 +710,6 @@ void PaintableWithLines::paint(PaintContext& context, PaintPhase phase) const
if (should_clip_overflow) {
context.display_list_recorder().restore();
context.display_list_recorder().restore();
}
}

View file

@ -71,10 +71,11 @@ void ViewportPaintable::assign_scroll_frames()
scroll_state.set(this, move(viewport_scroll_frame));
int next_id = 1;
for_each_in_subtree_of_type<PaintableBox>([&](auto const& paintable_box) {
for_each_in_subtree_of_type<PaintableBox>([&](auto& paintable_box) {
if (paintable_box.has_scrollable_overflow()) {
auto scroll_frame = adopt_ref(*new ScrollFrame());
scroll_frame->id = next_id++;
paintable_box.set_own_scroll_frame(scroll_frame);
scroll_state.set(paintable_box, move(scroll_frame));
}
return TraversalDecision::Continue;