From c6cf240f9a30c659313f4d26a90bac44d94ddd14 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 27 Feb 2022 13:34:34 +0100 Subject: [PATCH] LibWeb: Store bottom edge location with each LineBox Previously we were computing the bottom edge of a line box by finding the bottommost fragment on the line. That method didn't give correct results for line boxes with no fragments (which is exactly what you get when inserting a bunch of
elements.) To cover all situations, we now keep track of the bottommost edge in the LineBox object itself. --- Userland/Libraries/LibWeb/Dump.cpp | 5 +++-- Userland/Libraries/LibWeb/Layout/FormattingContext.cpp | 6 +----- Userland/Libraries/LibWeb/Layout/LineBox.h | 2 ++ Userland/Libraries/LibWeb/Layout/LineBuilder.cpp | 6 +++++- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Userland/Libraries/LibWeb/Dump.cpp b/Userland/Libraries/LibWeb/Dump.cpp index 8fdf2e6d760309..7fc367cf58825b 100644 --- a/Userland/Libraries/LibWeb/Dump.cpp +++ b/Userland/Libraries/LibWeb/Dump.cpp @@ -229,11 +229,12 @@ void dump_tree(StringBuilder& builder, Layout::Node const& layout_node, bool sho auto& line_box = block.line_boxes()[line_box_index]; for (size_t i = 0; i < indent; ++i) builder.append(" "); - builder.appendff(" {}line {}{} width: {}\n", + builder.appendff(" {}line {}{} width: {}, bottom: {}\n", line_box_color_on, line_box_index, color_off, - (int)line_box.width()); + line_box.width(), + line_box.bottom()); for (size_t fragment_index = 0; fragment_index < line_box.fragments().size(); ++fragment_index) { auto& fragment = line_box.fragments()[fragment_index]; for (size_t i = 0; i < indent; ++i) diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp index b3a731d9d2f9ea..efbae4e745c184 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -225,11 +225,7 @@ float FormattingContext::compute_auto_height_for_block_level_element(FormattingS top = fragment_top; } // Find the bottom edge. - for (auto const& fragment : line_boxes.last().fragments()) { - float fragment_bottom = fragment.offset().y() + fragment.height() + fragment.border_box_bottom(); - if (!bottom.has_value() || fragment_bottom > *bottom) - bottom = fragment_bottom; - } + bottom = line_boxes.last().bottom(); } } else { // If it has block-level children, the height is the distance between diff --git a/Userland/Libraries/LibWeb/Layout/LineBox.h b/Userland/Libraries/LibWeb/Layout/LineBox.h index 90d5d103397f4b..73e2e75f343b68 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBox.h +++ b/Userland/Libraries/LibWeb/Layout/LineBox.h @@ -16,6 +16,7 @@ class LineBox { LineBox() { } float width() const { return m_width; } + float bottom() const { return m_bottom; } void add_fragment(Node const& layout_node, int start, int length, float leading_size, float trailing_size, float content_width, float content_height, float border_box_top, float border_box_bottom, LineBoxFragment::Type = LineBoxFragment::Type::Normal); @@ -34,6 +35,7 @@ class LineBox { Vector m_fragments; float m_width { 0 }; + float m_bottom { 0 }; }; } diff --git a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp index ce01a1193dcd34..e4421a16ac61d8 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp @@ -96,7 +96,7 @@ void LineBuilder::update_last_line() auto text_align = m_context.containing_block().computed_values().text_align(); float x_offset = m_context.available_space_for_line(m_current_y).left; - + float bottom = m_current_y + m_context.containing_block().line_height(); float excess_horizontal_space = m_containing_block_state.content_width - line_box.width(); switch (text_align) { @@ -175,6 +175,8 @@ void LineBuilder::update_last_line() last_fragment_x_adjustment = new_fragment_x - fragment.offset().x(); fragment.set_offset({ new_fragment_x, new_fragment_y }); + bottom = max(bottom, new_fragment_y + fragment.height() + fragment.border_box_bottom()); + if (text_align == CSS::TextAlign::Justify && fragment.is_justifiable_whitespace() && fragment.width() != justified_space_width) { @@ -191,6 +193,8 @@ void LineBuilder::update_last_line() if (!line_box.fragments().is_empty()) line_box.m_width += last_fragment_x_adjustment; + + line_box.m_bottom = bottom; } void LineBuilder::remove_last_line_if_empty()