From 514fa837086c08b118e1d6b9a8a95dbc47b330cc Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 7 Sep 2022 13:29:58 +0200 Subject: LibWeb: Improve `float: right` behavior - Use the border box of the floated element when testing if something needs to flow around it. - Take the floated element's containing block size into account (instead of the BFC root) when calculating available space on a line where a right-side float intrudes. --- .../LibWeb/Layout/BlockFormattingContext.cpp | 8 +++---- .../LibWeb/Layout/InlineFormattingContext.cpp | 9 ++++---- Userland/Libraries/LibWeb/Layout/LayoutState.cpp | 25 ++++++++++++++++++++++ Userland/Libraries/LibWeb/Layout/LayoutState.h | 2 ++ 4 files changed, 35 insertions(+), 9 deletions(-) (limited to 'Userland/Libraries') diff --git a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp index da7e9ad96e..0513c42f80 100644 --- a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp @@ -626,7 +626,7 @@ void BlockFormattingContext::layout_floating_box(Box const& box, BlockContainer offset_from_edge = box_state.content_width() + box_state.margin_box_right(); }; - auto box_in_root_rect = margin_box_rect_in_ancestor_coordinate_space(box, root(), m_state); + auto box_in_root_rect = border_box_rect_in_ancestor_coordinate_space(box, root(), m_state); float y_in_root = box_in_root_rect.y(); float y = box_state.offset.y(); @@ -649,7 +649,7 @@ void BlockFormattingContext::layout_floating_box(Box const& box, BlockContainer } if (fits_on_line) { - auto const previous_rect = margin_box_rect_in_ancestor_coordinate_space(previous_box.box, root(), m_state); + auto const previous_rect = border_box_rect_in_ancestor_coordinate_space(previous_box.box, root(), m_state); if (previous_rect.contains_vertically(y_in_root + side_data.y_offset)) { // This box touches another already floating box. Stack after others. offset_from_edge = wanted_offset_from_edge; @@ -747,7 +747,7 @@ BlockFormattingContext::SpaceUsedByFloats BlockFormattingContext::space_used_by_ for (auto const& floating_box : m_left_floats.current_boxes.in_reverse()) { auto const& floating_box_state = m_state.get(floating_box.box); // NOTE: The floating box is *not* in the final horizontal position yet, but the size and vertical position is valid. - auto rect = margin_box_rect_in_ancestor_coordinate_space(floating_box.box, root(), m_state); + auto rect = border_box_rect_in_ancestor_coordinate_space(floating_box.box, root(), m_state); if (rect.contains_vertically(y)) { space_used_by_floats.left = floating_box.offset_from_edge + floating_box_state.content_width() @@ -759,7 +759,7 @@ BlockFormattingContext::SpaceUsedByFloats BlockFormattingContext::space_used_by_ for (auto const& floating_box : m_right_floats.current_boxes.in_reverse()) { auto const& floating_box_state = m_state.get(floating_box.box); // NOTE: The floating box is *not* in the final horizontal position yet, but the size and vertical position is valid. - auto rect = margin_box_rect_in_ancestor_coordinate_space(floating_box.box, root(), m_state); + auto rect = border_box_rect_in_ancestor_coordinate_space(floating_box.box, root(), m_state); if (rect.contains_vertically(y)) { space_used_by_floats.right = floating_box.offset_from_edge + floating_box_state.margin_box_left(); diff --git a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp index bb4c67e4a9..379425c3e9 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp @@ -52,7 +52,7 @@ BlockFormattingContext const& InlineFormattingContext::parent() const float InlineFormattingContext::leftmost_x_offset_at(float y) const { // NOTE: Floats are relative to the BFC root box, not necessarily the containing block of this IFC. - auto box_in_root_rect = margin_box_rect_in_ancestor_coordinate_space(containing_block(), parent().root(), m_state); + auto box_in_root_rect = border_box_rect_in_ancestor_coordinate_space(containing_block(), parent().root(), m_state); float y_in_root = box_in_root_rect.y() + y; auto space = parent().space_used_by_floats(y_in_root); float containing_block_x = m_containing_block_state.offset.x(); @@ -67,14 +67,13 @@ float InlineFormattingContext::available_space_for_line(float y) const return INFINITY; // NOTE: Floats are relative to the BFC root box, not necessarily the containing block of this IFC. - auto box_in_root_rect = margin_box_rect_in_ancestor_coordinate_space(containing_block(), parent().root(), m_state); + auto& root_block = parent().root(); + auto box_in_root_rect = border_box_rect_in_ancestor_coordinate_space(containing_block(), root_block, m_state); float y_in_root = box_in_root_rect.y() + y; auto space = parent().space_used_by_floats(y_in_root); - auto const& root_block_state = m_state.get(parent().root()); - space.left = max(space.left, m_containing_block_state.offset.x()) - m_containing_block_state.offset.x(); - space.right = min(root_block_state.content_width() - space.right, m_containing_block_state.offset.x() + m_effective_containing_block_width); + space.right = min(m_containing_block_state.content_width() - space.right, m_containing_block_state.offset.x() + m_effective_containing_block_width); return space.right - space.left; } diff --git a/Userland/Libraries/LibWeb/Layout/LayoutState.cpp b/Userland/Libraries/LibWeb/Layout/LayoutState.cpp index 5535070023..9d8aeae629 100644 --- a/Userland/Libraries/LibWeb/Layout/LayoutState.cpp +++ b/Userland/Libraries/LibWeb/Layout/LayoutState.cpp @@ -107,6 +107,31 @@ Gfx::FloatRect margin_box_rect(Box const& box, LayoutState const& state) return rect; } +Gfx::FloatRect border_box_rect(Box const& box, LayoutState const& state) +{ + auto const& box_state = state.get(box); + auto rect = Gfx::FloatRect { box_state.offset, { box_state.content_width(), box_state.content_height() } }; + rect.set_x(rect.x() - box_state.border_box_left()); + rect.set_width(rect.width() + box_state.border_box_left() + box_state.border_box_right()); + rect.set_y(rect.y() - box_state.border_box_top()); + rect.set_height(rect.height() + box_state.border_box_top() + box_state.border_box_bottom()); + return rect; +} + +Gfx::FloatRect border_box_rect_in_ancestor_coordinate_space(Box const& box, Box const& ancestor_box, LayoutState const& state) +{ + auto rect = border_box_rect(box, state); + for (auto const* current = box.parent(); current; current = current->parent()) { + if (current == &ancestor_box) + break; + if (is(*current)) { + auto const& current_state = state.get(static_cast(*current)); + rect.translate_by(current_state.offset); + } + } + return rect; +} + Gfx::FloatRect margin_box_rect_in_ancestor_coordinate_space(Box const& box, Box const& ancestor_box, LayoutState const& state) { auto rect = margin_box_rect(box, state); diff --git a/Userland/Libraries/LibWeb/Layout/LayoutState.h b/Userland/Libraries/LibWeb/Layout/LayoutState.h index b315068348..ddb4238499 100644 --- a/Userland/Libraries/LibWeb/Layout/LayoutState.h +++ b/Userland/Libraries/LibWeb/Layout/LayoutState.h @@ -149,5 +149,7 @@ struct LayoutState { Gfx::FloatRect absolute_content_rect(Box const&, LayoutState const&); Gfx::FloatRect margin_box_rect(Box const&, LayoutState const&); Gfx::FloatRect margin_box_rect_in_ancestor_coordinate_space(Box const& box, Box const& ancestor_box, LayoutState const&); +Gfx::FloatRect border_box_rect(Box const&, LayoutState const&); +Gfx::FloatRect border_box_rect_in_ancestor_coordinate_space(Box const& box, Box const& ancestor_box, LayoutState const&); } -- cgit v1.2.3