summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-01-22 10:32:49 +0100
committerAndreas Kling <kling@serenityos.org>2022-01-23 01:22:41 +0100
commit70a56d21dcca95f86ea5c76a68e53f2a887a2365 (patch)
tree465a68c3bd94fcde1f041f2f8a565de5ff4d1c32 /Userland
parentb1fd80143618f33d35b2a6b121d07ccf1fe9d52a (diff)
downloadserenity-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')
-rw-r--r--Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp4
-rw-r--r--Userland/Libraries/LibWeb/Layout/LineBox.h2
-rw-r--r--Userland/Libraries/LibWeb/Layout/LineBuilder.cpp25
-rw-r--r--Userland/Libraries/LibWeb/Layout/LineBuilder.h4
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 };
};
}