From d3adc94ce8641831e1c06b58134cc2006970a735 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 20 Jan 2022 13:46:04 +0100 Subject: [PATCH] LibWeb: Dimension inline-block boxes before deciding about line breaks We won't know if we need to break before the inline-block box until after we've dimensioned it. --- Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp | 4 ++-- Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp | 1 + Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h | 1 + Userland/Libraries/LibWeb/Layout/LineBuilder.cpp | 3 ++- Userland/Libraries/LibWeb/Layout/LineBuilder.h | 2 +- 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp index ad4f5f18d3..1fcc42a270 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp @@ -169,8 +169,6 @@ void InlineFormattingContext::generate_line_boxes(LayoutMode layout_mode) break; auto& item = item_opt.value(); - line_builder.break_if_needed(layout_mode, item.width); - switch (item.type) { case InlineLevelIterator::Item::Type::ForcedBreak: line_builder.break_line(); @@ -178,11 +176,13 @@ void InlineFormattingContext::generate_line_boxes(LayoutMode layout_mode) case InlineLevelIterator::Item::Type::Element: { auto& box = verify_cast(*item.node); dimension_box_on_line(box, layout_mode); + line_builder.break_if_needed(layout_mode, box.width(), item.should_force_break); line_builder.append_box(box); break; } case InlineLevelIterator::Item::Type::Text: { auto& text_node = verify_cast(*item.node); + line_builder.break_if_needed(layout_mode, item.width, item.should_force_break); line_builder.append_text_chunk( text_node, item.offset_in_node, diff --git a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp index bf7a1bdf6a..b2d27bc5a7 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp +++ b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp @@ -62,6 +62,7 @@ Optional InlineLevelIterator::next(float available_wi .offset_in_node = chunk.start, .length_in_node = chunk.length, .width = chunk_width, + .should_force_break = m_text_node_context->do_respect_linebreaks && chunk.has_breaking_newline, }; return item; diff --git a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h index 174e3385bc..d605f53bc7 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h +++ b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h @@ -31,6 +31,7 @@ public: size_t offset_in_node { 0 }; size_t length_in_node { 0 }; float width { 0.0f }; + bool should_force_break { false }; }; explicit InlineLevelIterator(Layout::Box& container, LayoutMode layout_mode) diff --git a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp index a80d6b7bd4..ce156711ac 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp @@ -46,9 +46,10 @@ void LineBuilder::append_text_chunk(TextNode& text_node, size_t offset_in_node, m_max_height_on_current_line = max(m_max_height_on_current_line, height); } -void LineBuilder::break_if_needed(LayoutMode layout_mode, float next_item_width) +void LineBuilder::break_if_needed(LayoutMode layout_mode, float next_item_width, bool should_force_break) { if (layout_mode == LayoutMode::AllPossibleLineBreaks + || should_force_break || (m_context.containing_block().line_boxes().last().width() + next_item_width) > m_available_width_for_current_line) break_line(); } diff --git a/Userland/Libraries/LibWeb/Layout/LineBuilder.h b/Userland/Libraries/LibWeb/Layout/LineBuilder.h index 7dfe7bed8c..f32dfa5aa5 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBuilder.h +++ b/Userland/Libraries/LibWeb/Layout/LineBuilder.h @@ -23,7 +23,7 @@ public: void append_box(Box&); void append_text_chunk(TextNode&, size_t offset_in_node, size_t length_in_node, float width, float height); - void break_if_needed(LayoutMode, float next_item_width); + void break_if_needed(LayoutMode, float next_item_width, bool should_force_break); float available_width_for_current_line() const { return m_available_width_for_current_line; }