LibWeb: Replace 1px iteration in y_for_float_to_be_inserted_here()

...with a loop through already inserted floating boxes that probes
potential insertion points on their edges.

Makes www.nyan.cat go faster.
This commit is contained in:
Aliaksandr Kalenik 2025-03-26 11:55:39 +00:00 committed by Jelle Raaijmakers
parent d8ff71fbb5
commit 85e28a29f0
Notes: github-actions[bot] 2025-03-26 13:52:54 +00:00
2 changed files with 25 additions and 7 deletions

View file

@ -40,6 +40,19 @@ public:
void resolve_used_height_if_not_treated_as_auto(Box const&, AvailableSpace const&);
void resolve_used_height_if_treated_as_auto(Box const&, AvailableSpace const&, FormattingContext const* box_formatting_context = nullptr);
template<typename Callback>
void for_each_floating_box(Callback callback)
{
for (auto const& floating_box : m_left_floats.all_boxes) {
if (callback(*floating_box) == IterationDecision::Break)
return;
}
for (auto const& floating_box : m_right_floats.all_boxes) {
if (callback(*floating_box) == IterationDecision::Break)
return;
}
}
SpaceUsedAndContainingMarginForFloats space_used_and_containing_margin_for_floats(CSSPixels y) const;
[[nodiscard]] SpaceUsedByFloats intrusion_by_floats_into_box(Box const&, CSSPixels y_in_box) const;
[[nodiscard]] SpaceUsedByFloats intrusion_by_floats_into_box(LayoutState::UsedValues const&, CSSPixels y_in_box) const;

View file

@ -124,20 +124,25 @@ CSSPixels LineBuilder::y_for_float_to_be_inserted_here(Box const& box)
candidate_block_offset += current_line.height();
// Then, look for the next Y position where we can fit the new float.
// FIXME: This is super dumb, we move 1px downwards per iteration and stop
// when we find an Y value where we don't collide with other floats.
while (true) {
auto box_in_root_rect = m_context.parent().content_box_rect_in_ancestor_coordinate_space(box_state, m_context.parent().root());
m_context.parent().for_each_floating_box([&](auto const& float_box) {
auto candidate_block_offset_in_root = box_in_root_rect.y() + candidate_block_offset;
if (float_box.margin_box_rect_in_root_coordinate_space.bottom() < candidate_block_offset_in_root)
return IterationDecision::Continue;
auto space_at_y_top = m_context.available_space_for_line(candidate_block_offset);
auto space_at_y_bottom = m_context.available_space_for_line(candidate_block_offset + height);
if (width > space_at_y_top || width > space_at_y_bottom) {
if (!m_context.any_floats_intrude_at_block_offset(candidate_block_offset) && !m_context.any_floats_intrude_at_block_offset(candidate_block_offset + height)) {
return candidate_block_offset;
return IterationDecision::Break;
}
} else {
return candidate_block_offset;
return IterationDecision::Break;
}
candidate_block_offset += 1;
}
// candidate_block_offset needs to stay relative to the current box
candidate_block_offset = float_box.margin_box_rect_in_root_coordinate_space.bottom() - box_in_root_rect.y();
return IterationDecision::Continue;
});
return candidate_block_offset;
}
bool LineBuilder::should_break(CSSPixels next_item_width)