1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 14:17:36 +00:00

LibWeb: Don't do horizontal inline line layout twice for last line

After pruning empty last line boxes, we now avoid re-running the
horizontal fragment positioning step, since that would be wasted work.
This commit is contained in:
Andreas Kling 2022-01-22 10:32:49 +01:00
parent b1fd801436
commit 70a56d21dc
4 changed files with 27 additions and 8 deletions

View file

@ -201,9 +201,7 @@ void InlineFormattingContext::generate_line_boxes(LayoutMode layout_mode)
line_box.trim_trailing_whitespace();
}
// If there's an empty line box at the bottom, just remove it instead of giving it height.
if (!containing_block().line_boxes().is_empty() && containing_block().line_boxes().last().fragments().is_empty())
containing_block().line_boxes().take_last();
line_builder.remove_last_line_if_empty();
}
}

View file

@ -26,7 +26,7 @@ public:
void trim_trailing_whitespace();
bool is_empty_or_ends_in_whitespace() const;
bool is_empty() { return m_fragments.is_empty(); }
bool is_empty() const { return m_fragments.is_empty(); }
bool ends_with_forced_line_break() const;
private:

View file

@ -12,11 +12,13 @@ namespace Web::Layout {
LineBuilder::LineBuilder(InlineFormattingContext& context)
: m_context(context)
{
begin_new_line();
}
LineBuilder::~LineBuilder()
{
update_last_line();
if (m_last_line_needs_update)
update_last_line();
}
void LineBuilder::break_line()
@ -32,6 +34,8 @@ void LineBuilder::begin_new_line()
auto space = m_context.available_space_for_line(m_current_y);
m_available_width_for_current_line = space.right - space.left;
m_max_height_on_current_line = 0;
m_last_line_needs_update = true;
}
void LineBuilder::append_box(Box& box)
@ -54,14 +58,17 @@ bool LineBuilder::should_break(LayoutMode layout_mode, float next_item_width, bo
return true;
if (layout_mode == LayoutMode::OnlyRequiredLineBreaks)
return false;
auto current_line_width = 0.0f;
if (!m_context.containing_block().line_boxes().is_empty())
current_line_width = m_context.containing_block().line_boxes().last().width();
auto const& line_boxes = m_context.containing_block().line_boxes();
if (line_boxes.is_empty() || line_boxes.last().is_empty())
return false;
auto current_line_width = m_context.containing_block().line_boxes().last().width();
return (current_line_width + next_item_width) > m_available_width_for_current_line;
}
void LineBuilder::update_last_line()
{
m_last_line_needs_update = false;
if (m_context.containing_block().line_boxes().is_empty())
return;
@ -144,4 +151,14 @@ void LineBuilder::update_last_line()
}
}
void LineBuilder::remove_last_line_if_empty()
{
// If there's an empty line box at the bottom, just remove it instead of giving it height.
auto& line_boxes = m_context.containing_block().line_boxes();
if (!line_boxes.is_empty() && line_boxes.last().fragments().is_empty()) {
line_boxes.take_last();
m_last_line_needs_update = false;
}
}
}

View file

@ -33,6 +33,8 @@ public:
void update_last_line();
void remove_last_line_if_empty();
private:
bool should_break(LayoutMode, float next_item_width, bool should_force_break);
@ -40,6 +42,8 @@ private:
float m_available_width_for_current_line { 0 };
float m_current_y { 0 };
float m_max_height_on_current_line { 0 };
bool m_last_line_needs_update { false };
};
}