1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 04:27:44 +00:00

LibWeb: Put BFC floating object state into a struct

This patch adds a BFC::FloatSideData struct so we can contain left and
right floating object layout state in a struct. This is preparation for
adding more per-side state.
This commit is contained in:
Andreas Kling 2022-01-22 15:19:18 +01:00
parent 70a56d21dc
commit 0ea438e45b
3 changed files with 28 additions and 24 deletions

View file

@ -515,22 +515,22 @@ void BlockFormattingContext::place_block_level_non_replaced_element_in_normal_fl
} }
} }
auto clear_floating_boxes = [&](auto& floating_boxes) { auto clear_floating_boxes = [&](auto& float_side) {
if (!floating_boxes.is_empty()) { if (!float_side.boxes.is_empty()) {
float clearance_y = 0; float clearance_y = 0;
for (auto* floating_box : floating_boxes) { for (auto& floating_box : float_side.boxes) {
clearance_y = max(clearance_y, floating_box->effective_offset().y() + floating_box->border_box_height()); clearance_y = max(clearance_y, floating_box.effective_offset().y() + floating_box.border_box_height());
} }
y = max(y, clearance_y); y = max(y, clearance_y);
floating_boxes.clear(); float_side.boxes.clear();
} }
}; };
// Flex-items don't float and also don't clear. // Flex-items don't float and also don't clear.
if ((computed_values.clear() == CSS::Clear::Left || computed_values.clear() == CSS::Clear::Both) && !child_box.is_flex_item()) if ((computed_values.clear() == CSS::Clear::Left || computed_values.clear() == CSS::Clear::Both) && !child_box.is_flex_item())
clear_floating_boxes(m_left_floating_boxes); clear_floating_boxes(m_left_floats);
if ((computed_values.clear() == CSS::Clear::Right || computed_values.clear() == CSS::Clear::Both) && !child_box.is_flex_item()) if ((computed_values.clear() == CSS::Clear::Right || computed_values.clear() == CSS::Clear::Both) && !child_box.is_flex_item())
clear_floating_boxes(m_right_floating_boxes); clear_floating_boxes(m_right_floats);
child_box.set_offset(x, y); child_box.set_offset(x, y);
} }
@ -601,8 +601,8 @@ void BlockFormattingContext::layout_floating_child(Box& box, BlockContainer cons
// Next, float to the left and/or right // Next, float to the left and/or right
if (box.computed_values().float_() == CSS::Float::Left) { if (box.computed_values().float_() == CSS::Float::Left) {
if (!m_left_floating_boxes.is_empty()) { if (!m_left_floats.boxes.is_empty()) {
auto& previous_floating_box = *m_left_floating_boxes.last(); auto& previous_floating_box = m_left_floats.boxes.last();
auto previous_rect = rect_in_coordinate_space(previous_floating_box, root()); auto previous_rect = rect_in_coordinate_space(previous_floating_box, root());
if (previous_rect.contains_vertically(y_in_root)) { if (previous_rect.contains_vertically(y_in_root)) {
// This box touches another already floating box. Stack to the right. // This box touches another already floating box. Stack to the right.
@ -611,16 +611,16 @@ void BlockFormattingContext::layout_floating_child(Box& box, BlockContainer cons
// This box does not touch another floating box, go all the way to the left. // This box does not touch another floating box, go all the way to the left.
x = box.box_model().margin_box().left; x = box.box_model().margin_box().left;
// Also, forget all previous left-floating boxes while we're here since they're no longer relevant. // Also, forget all previous left-floating boxes while we're here since they're no longer relevant.
m_left_floating_boxes.clear(); m_left_floats.boxes.clear();
} }
} else { } else {
// This is the first left-floating box. Go all the way to the left. // This is the first left-floating box. Go all the way to the left.
x = box.box_model().margin_box().left; x = box.box_model().margin_box().left;
} }
m_left_floating_boxes.append(&box); m_left_floats.boxes.append(box);
} else if (box.computed_values().float_() == CSS::Float::Right) { } else if (box.computed_values().float_() == CSS::Float::Right) {
if (!m_right_floating_boxes.is_empty()) { if (!m_right_floats.boxes.is_empty()) {
auto& previous_floating_box = *m_right_floating_boxes.last(); auto& previous_floating_box = m_right_floats.boxes.last();
auto previous_rect = rect_in_coordinate_space(previous_floating_box, root()); auto previous_rect = rect_in_coordinate_space(previous_floating_box, root());
if (previous_rect.contains_vertically(y_in_root)) { if (previous_rect.contains_vertically(y_in_root)) {
// This box touches another already floating box. Stack to the left. // This box touches another already floating box. Stack to the left.
@ -629,13 +629,13 @@ void BlockFormattingContext::layout_floating_child(Box& box, BlockContainer cons
// This box does not touch another floating box, go all the way to the right. // This box does not touch another floating box, go all the way to the right.
x = containing_block.width() - box.box_model().margin_box().right - box.width(); x = containing_block.width() - box.box_model().margin_box().right - box.width();
// Also, forget all previous right-floating boxes while we're here since they're no longer relevant. // Also, forget all previous right-floating boxes while we're here since they're no longer relevant.
m_right_floating_boxes.clear(); m_right_floats.boxes.clear();
} }
} else { } else {
// This is the first right-floating box. Go all the way to the right. // This is the first right-floating box. Go all the way to the right.
x = containing_block.width() - box.box_model().margin_box().right - box.width(); x = containing_block.width() - box.box_model().margin_box().right - box.width();
} }
m_right_floating_boxes.append(&box); m_right_floats.boxes.append(box);
} }
box.set_offset(x, box.effective_offset().y()); box.set_offset(x, box.effective_offset().y());

View file

@ -23,8 +23,8 @@ public:
bool is_initial() const; bool is_initial() const;
const Vector<Box*>& left_floating_boxes() const { return m_left_floating_boxes; } auto const& left_side_floats() const { return m_left_floats; }
const Vector<Box*>& right_floating_boxes() const { return m_right_floating_boxes; } auto const& right_side_floats() const { return m_right_floats; }
static float compute_theoretical_height(Box const&); static float compute_theoretical_height(Box const&);
void compute_width(Box&); void compute_width(Box&);
@ -50,14 +50,18 @@ private:
void layout_inline_children(BlockContainer&, LayoutMode); void layout_inline_children(BlockContainer&, LayoutMode);
void place_block_level_replaced_element_in_normal_flow(Box& child, BlockContainer const&); void place_block_level_replaced_element_in_normal_flow(Box& child, BlockContainer const&);
void place_block_level_non_replaced_element_in_normal_flow(Box& child, BlockContainer const&); void place_block_level_non_replaced_element_in_normal_flow(Box& float_side, BlockContainer const&);
void layout_floating_child(Box& child, BlockContainer const& containing_block); void layout_floating_child(Box& child, BlockContainer const& containing_block);
void apply_transformations_to_children(Box&); void apply_transformations_to_children(Box&);
Vector<Box*> m_left_floating_boxes; struct FloatSideData {
Vector<Box*> m_right_floating_boxes; Vector<Box&> boxes;
};
FloatSideData m_left_floats;
FloatSideData m_right_floats;
}; };
} }

View file

@ -35,8 +35,8 @@ InlineFormattingContext::AvailableSpaceForLineInfo InlineFormattingContext::avai
auto const& bfc = static_cast<BlockFormattingContext const&>(*parent()); auto const& bfc = static_cast<BlockFormattingContext const&>(*parent());
for (ssize_t i = bfc.left_floating_boxes().size() - 1; i >= 0; --i) { for (ssize_t i = bfc.left_side_floats().boxes.size() - 1; i >= 0; --i) {
auto& floating_box = *bfc.left_floating_boxes().at(i); auto const& floating_box = bfc.left_side_floats().boxes.at(i);
auto rect = floating_box.margin_box_as_relative_rect(); auto rect = floating_box.margin_box_as_relative_rect();
if (rect.contains_vertically(y)) { if (rect.contains_vertically(y)) {
info.left = rect.right() + 1; info.left = rect.right() + 1;
@ -46,8 +46,8 @@ InlineFormattingContext::AvailableSpaceForLineInfo InlineFormattingContext::avai
info.right = containing_block().width(); info.right = containing_block().width();
for (ssize_t i = bfc.right_floating_boxes().size() - 1; i >= 0; --i) { for (ssize_t i = bfc.right_side_floats().boxes.size() - 1; i >= 0; --i) {
auto& floating_box = *bfc.right_floating_boxes().at(i); auto const& floating_box = bfc.right_side_floats().boxes.at(i);
auto rect = floating_box.margin_box_as_relative_rect(); auto rect = floating_box.margin_box_as_relative_rect();
if (rect.contains_vertically(y)) { if (rect.contains_vertically(y)) {
info.right = rect.left() - 1; info.right = rect.left() - 1;