Browse Source

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.
Andreas Kling 3 years ago
parent
commit
d3adc94ce8

+ 2 - 2
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<Layout::Box>(*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<Layout::TextNode>(*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,

+ 1 - 0
Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp

@@ -62,6 +62,7 @@ Optional<InlineLevelIterator::Item> 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;

+ 1 - 0
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)

+ 2 - 1
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();
 }

+ 1 - 1
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; }