diff options
author | Andreas Kling <kling@serenityos.org> | 2022-01-22 10:32:49 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-01-23 01:22:41 +0100 |
commit | 70a56d21dcca95f86ea5c76a68e53f2a887a2365 (patch) | |
tree | 465a68c3bd94fcde1f041f2f8a565de5ff4d1c32 /Userland | |
parent | b1fd80143618f33d35b2a6b121d07ccf1fe9d52a (diff) | |
download | serenity-70a56d21dcca95f86ea5c76a68e53f2a887a2365.zip |
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.
Diffstat (limited to 'Userland')
4 files changed, 27 insertions, 8 deletions
diff --git a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp index 0e16fa1f21..5339045fff 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp @@ -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(); } } diff --git a/Userland/Libraries/LibWeb/Layout/LineBox.h b/Userland/Libraries/LibWeb/Layout/LineBox.h index fa786b0a54..5a02a4ea06 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBox.h +++ b/Userland/Libraries/LibWeb/Layout/LineBox.h @@ -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: diff --git a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp index 2dff8fd1df..606ded8c7a 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp @@ -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; + } +} + } diff --git a/Userland/Libraries/LibWeb/Layout/LineBuilder.h b/Userland/Libraries/LibWeb/Layout/LineBuilder.h index 0fd2c5d180..b2c4a9e1ce 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBuilder.h +++ b/Userland/Libraries/LibWeb/Layout/LineBuilder.h @@ -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 }; }; } |