1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 06:27:45 +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(); line_box.trim_trailing_whitespace();
} }
// If there's an empty line box at the bottom, just remove it instead of giving it height. line_builder.remove_last_line_if_empty();
if (!containing_block().line_boxes().is_empty() && containing_block().line_boxes().last().fragments().is_empty())
containing_block().line_boxes().take_last();
} }
} }

View file

@ -26,7 +26,7 @@ public:
void trim_trailing_whitespace(); void trim_trailing_whitespace();
bool is_empty_or_ends_in_whitespace() const; 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; bool ends_with_forced_line_break() const;
private: private:

View file

@ -12,11 +12,13 @@ namespace Web::Layout {
LineBuilder::LineBuilder(InlineFormattingContext& context) LineBuilder::LineBuilder(InlineFormattingContext& context)
: m_context(context) : m_context(context)
{ {
begin_new_line();
} }
LineBuilder::~LineBuilder() LineBuilder::~LineBuilder()
{ {
update_last_line(); if (m_last_line_needs_update)
update_last_line();
} }
void LineBuilder::break_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); auto space = m_context.available_space_for_line(m_current_y);
m_available_width_for_current_line = space.right - space.left; m_available_width_for_current_line = space.right - space.left;
m_max_height_on_current_line = 0; m_max_height_on_current_line = 0;
m_last_line_needs_update = true;
} }
void LineBuilder::append_box(Box& box) void LineBuilder::append_box(Box& box)
@ -54,14 +58,17 @@ bool LineBuilder::should_break(LayoutMode layout_mode, float next_item_width, bo
return true; return true;
if (layout_mode == LayoutMode::OnlyRequiredLineBreaks) if (layout_mode == LayoutMode::OnlyRequiredLineBreaks)
return false; return false;
auto current_line_width = 0.0f; auto const& line_boxes = m_context.containing_block().line_boxes();
if (!m_context.containing_block().line_boxes().is_empty()) if (line_boxes.is_empty() || line_boxes.last().is_empty())
current_line_width = m_context.containing_block().line_boxes().last().width(); 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; return (current_line_width + next_item_width) > m_available_width_for_current_line;
} }
void LineBuilder::update_last_line() void LineBuilder::update_last_line()
{ {
m_last_line_needs_update = false;
if (m_context.containing_block().line_boxes().is_empty()) if (m_context.containing_block().line_boxes().is_empty())
return; 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 update_last_line();
void remove_last_line_if_empty();
private: private:
bool should_break(LayoutMode, float next_item_width, bool should_force_break); 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_available_width_for_current_line { 0 };
float m_current_y { 0 }; float m_current_y { 0 };
float m_max_height_on_current_line { 0 }; float m_max_height_on_current_line { 0 };
bool m_last_line_needs_update { false };
}; };
} }