From 766d816db3642635e79dc4a8026534098c4d922a Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 21 Jan 2022 13:34:29 +0100 Subject: [PATCH] LibWeb: Remove old Layout::Node::split_into_lines() API Now that we build lines incrementally, we no longer need the atomic line splitting API. The new InlineLevelIterator and LineBuilder setup does have some regressions from the old behavior, but we can deal with them as we go. --- .../LibWeb/Layout/BlockContainer.cpp | 17 ---- .../Libraries/LibWeb/Layout/BlockContainer.h | 2 - .../Libraries/LibWeb/Layout/BreakNode.cpp | 6 -- Userland/Libraries/LibWeb/Layout/BreakNode.h | 2 - .../Libraries/LibWeb/Layout/InlineNode.cpp | 21 ----- Userland/Libraries/LibWeb/Layout/InlineNode.h | 2 - Userland/Libraries/LibWeb/Layout/Node.cpp | 7 -- Userland/Libraries/LibWeb/Layout/Node.h | 2 - .../Libraries/LibWeb/Layout/ReplacedBox.cpp | 13 --- .../Libraries/LibWeb/Layout/ReplacedBox.h | 3 - Userland/Libraries/LibWeb/Layout/TextNode.cpp | 89 ------------------- Userland/Libraries/LibWeb/Layout/TextNode.h | 3 - 12 files changed, 167 deletions(-) diff --git a/Userland/Libraries/LibWeb/Layout/BlockContainer.cpp b/Userland/Libraries/LibWeb/Layout/BlockContainer.cpp index 5bbc155f229..079befc78c6 100644 --- a/Userland/Libraries/LibWeb/Layout/BlockContainer.cpp +++ b/Userland/Libraries/LibWeb/Layout/BlockContainer.cpp @@ -104,23 +104,6 @@ HitTestResult BlockContainer::hit_test(const Gfx::IntPoint& position, HitTestTyp return { absolute_rect().contains(position.x(), position.y()) ? this : nullptr }; } -void BlockContainer::split_into_lines(InlineFormattingContext& context, LayoutMode layout_mode) -{ - auto& containing_block = context.containing_block(); - auto* line_box = &containing_block.ensure_last_line_box(); - - context.dimension_box_on_line(*this, layout_mode); - - float available_width = context.available_width_at_line(containing_block.line_boxes().size() - 1); - - if (layout_mode == LayoutMode::AllPossibleLineBreaks && line_box->width() > 0) { - line_box = &containing_block.add_line_box(); - } else if (layout_mode == LayoutMode::Default && line_box->width() > 0 && line_box->width() + border_box_width() > available_width) { - line_box = &containing_block.add_line_box(); - } - line_box->add_fragment(*this, 0, 0, border_box_width(), height()); -} - bool BlockContainer::is_scrollable() const { // FIXME: Support horizontal scroll as well (overflow-x) diff --git a/Userland/Libraries/LibWeb/Layout/BlockContainer.h b/Userland/Libraries/LibWeb/Layout/BlockContainer.h index 397a262917e..8c68f140820 100644 --- a/Userland/Libraries/LibWeb/Layout/BlockContainer.h +++ b/Userland/Libraries/LibWeb/Layout/BlockContainer.h @@ -32,8 +32,6 @@ public: template void for_each_fragment(Callback) const; - virtual void split_into_lines(InlineFormattingContext&, LayoutMode) override; - bool is_scrollable() const; const Gfx::FloatPoint& scroll_offset() const { return m_scroll_offset; } void set_scroll_offset(const Gfx::FloatPoint&); diff --git a/Userland/Libraries/LibWeb/Layout/BreakNode.cpp b/Userland/Libraries/LibWeb/Layout/BreakNode.cpp index 8b02cc8c449..ca4081ad549 100644 --- a/Userland/Libraries/LibWeb/Layout/BreakNode.cpp +++ b/Userland/Libraries/LibWeb/Layout/BreakNode.cpp @@ -20,12 +20,6 @@ BreakNode::~BreakNode() { } -void BreakNode::split_into_lines(InlineFormattingContext& context, LayoutMode) -{ - auto& line_box = context.containing_block().add_line_box(); - line_box.add_fragment(*this, 0, 0, 0, context.containing_block().line_height()); -} - void BreakNode::paint(PaintContext&, PaintPhase) { } diff --git a/Userland/Libraries/LibWeb/Layout/BreakNode.h b/Userland/Libraries/LibWeb/Layout/BreakNode.h index 4276b4eaee6..5ab8c869a92 100644 --- a/Userland/Libraries/LibWeb/Layout/BreakNode.h +++ b/Userland/Libraries/LibWeb/Layout/BreakNode.h @@ -21,8 +21,6 @@ public: private: virtual bool is_break_node() const final { return true; } virtual void paint(PaintContext&, PaintPhase) override; - - virtual void split_into_lines(InlineFormattingContext&, LayoutMode) override; }; template<> diff --git a/Userland/Libraries/LibWeb/Layout/InlineNode.cpp b/Userland/Libraries/LibWeb/Layout/InlineNode.cpp index a5e2a2bbfc0..d7ea26d59fc 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineNode.cpp +++ b/Userland/Libraries/LibWeb/Layout/InlineNode.cpp @@ -27,27 +27,6 @@ InlineNode::~InlineNode() { } -void InlineNode::split_into_lines(InlineFormattingContext& context, LayoutMode layout_mode) -{ - auto& containing_block = context.containing_block(); - - auto is_not_undefined_or_auto = [](auto const& length_percentage) { - return !(length_percentage.is_length() && length_percentage.length().is_undefined_or_auto()); - }; - - if (is_not_undefined_or_auto(computed_values().padding().left)) { - float padding_left = computed_values().padding().left.resolved(CSS::Length::make_px(containing_block.width())).resolved(CSS::Length::make_px(0), *this).to_px(*this); - containing_block.ensure_last_line_box().add_fragment(*this, 0, 0, padding_left, 0, LineBoxFragment::Type::Leading); - } - - NodeWithStyleAndBoxModelMetrics::split_into_lines(context, layout_mode); - - if (is_not_undefined_or_auto(computed_values().padding().right)) { - float padding_right = computed_values().padding().right.resolved(CSS::Length::make_px(containing_block.width())).resolved(CSS::Length::make_px(0), *this).to_px(*this); - containing_block.ensure_last_line_box().add_fragment(*this, 0, 0, padding_right, 0, LineBoxFragment::Type::Trailing); - } -} - void InlineNode::paint(PaintContext& context, PaintPhase phase) { auto& painter = context.painter(); diff --git a/Userland/Libraries/LibWeb/Layout/InlineNode.h b/Userland/Libraries/LibWeb/Layout/InlineNode.h index a630de43b7b..0890641b1f2 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineNode.h +++ b/Userland/Libraries/LibWeb/Layout/InlineNode.h @@ -17,8 +17,6 @@ public: virtual void paint(PaintContext&, PaintPhase) override; - virtual void split_into_lines(InlineFormattingContext&, LayoutMode) override; - private: template void for_each_fragment(Callback); diff --git a/Userland/Libraries/LibWeb/Layout/Node.cpp b/Userland/Libraries/LibWeb/Layout/Node.cpp index d2a0f8b460d..0ca04e8c09d 100644 --- a/Userland/Libraries/LibWeb/Layout/Node.cpp +++ b/Userland/Libraries/LibWeb/Layout/Node.cpp @@ -115,13 +115,6 @@ InitialContainingBlock& Node::root() return *document().layout_node(); } -void Node::split_into_lines(InlineFormattingContext& context, LayoutMode layout_mode) -{ - for_each_child([&](auto& child) { - child.split_into_lines(context, layout_mode); - }); -} - void Node::set_needs_display() { if (auto* block = containing_block()) { diff --git a/Userland/Libraries/LibWeb/Layout/Node.h b/Userland/Libraries/LibWeb/Layout/Node.h index bcf67189b98..d574d9048ed 100644 --- a/Userland/Libraries/LibWeb/Layout/Node.h +++ b/Userland/Libraries/LibWeb/Layout/Node.h @@ -134,8 +134,6 @@ public: void removed_from(Node&) { } void children_changed() { } - virtual void split_into_lines(InlineFormattingContext&, LayoutMode); - bool is_visible() const { return m_visible; } void set_visible(bool visible) { m_visible = visible; } diff --git a/Userland/Libraries/LibWeb/Layout/ReplacedBox.cpp b/Userland/Libraries/LibWeb/Layout/ReplacedBox.cpp index 1985f7fbd6d..098e06db8b9 100644 --- a/Userland/Libraries/LibWeb/Layout/ReplacedBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/ReplacedBox.cpp @@ -22,17 +22,4 @@ ReplacedBox::~ReplacedBox() { } -void ReplacedBox::split_into_lines(InlineFormattingContext& context, LayoutMode layout_mode) -{ - auto& containing_block = context.containing_block(); - - prepare_for_replaced_layout(); - context.dimension_box_on_line(*this, layout_mode); - - auto* line_box = &containing_block.ensure_last_line_box(); - if (line_box->width() > 0 && line_box->width() + width() > context.available_width_at_line(containing_block.line_boxes().size() - 1)) - line_box = &containing_block.add_line_box(); - line_box->add_fragment(*this, 0, 0, width(), height()); -} - } diff --git a/Userland/Libraries/LibWeb/Layout/ReplacedBox.h b/Userland/Libraries/LibWeb/Layout/ReplacedBox.h index d37e5d8145f..55b8afc3708 100644 --- a/Userland/Libraries/LibWeb/Layout/ReplacedBox.h +++ b/Userland/Libraries/LibWeb/Layout/ReplacedBox.h @@ -31,9 +31,6 @@ public: virtual bool can_have_children() const override { return false; } -protected: - virtual void split_into_lines(InlineFormattingContext&, LayoutMode) override; - private: Optional m_intrinsic_width; Optional m_intrinsic_height; diff --git a/Userland/Libraries/LibWeb/Layout/TextNode.cpp b/Userland/Libraries/LibWeb/Layout/TextNode.cpp index d4155bff340..b53d42d5eac 100644 --- a/Userland/Libraries/LibWeb/Layout/TextNode.cpp +++ b/Userland/Libraries/LibWeb/Layout/TextNode.cpp @@ -192,95 +192,6 @@ void TextNode::compute_text_for_rendering(bool collapse, bool previous_is_empty_ m_text_for_rendering = builder.to_string(); } -void TextNode::split_into_lines_by_rules(InlineFormattingContext& context, LayoutMode layout_mode, bool do_collapse, bool do_wrap_lines, bool do_respect_linebreaks) -{ - auto& containing_block = context.containing_block(); - - auto& font = this->font(); - - auto& line_boxes = containing_block.line_boxes(); - containing_block.ensure_last_line_box(); - float available_width = context.available_width_at_line(line_boxes.size() - 1) - line_boxes.last().width(); - - compute_text_for_rendering(do_collapse, line_boxes.last().is_empty_or_ends_in_whitespace()); - ChunkIterator iterator(m_text_for_rendering, layout_mode, do_wrap_lines, do_respect_linebreaks); - - for (;;) { - auto chunk_opt = iterator.next(); - if (!chunk_opt.has_value()) - break; - auto& chunk = chunk_opt.value(); - - // Collapse entire fragment into non-existence if previous fragment on line ended in whitespace. - if (do_collapse && line_boxes.last().is_empty_or_ends_in_whitespace() && chunk.is_all_whitespace) - continue; - - float chunk_width; - if (do_wrap_lines) { - if (do_collapse && is_ascii_space(*chunk.view.begin()) && (line_boxes.last().is_empty_or_ends_in_whitespace() || line_boxes.last().ends_with_forced_line_break())) { - // This is a non-empty chunk that starts with collapsible whitespace. - // We are at either at the start of a new line, or after something that ended in whitespace, - // so we don't need to contribute our own whitespace to the line. Skip over it instead! - ++chunk.start; - --chunk.length; - chunk.view = chunk.view.substring_view(1, chunk.view.byte_length() - 1); - } - - chunk_width = font.width(chunk.view) + font.glyph_spacing(); - - if (line_boxes.last().width() > 0 && chunk_width > available_width) { - containing_block.add_line_box(); - available_width = context.available_width_at_line(line_boxes.size() - 1); - - if (do_collapse && chunk.is_all_whitespace) - continue; - } - } else { - chunk_width = font.width(chunk.view); - } - - line_boxes.last().add_fragment(*this, chunk.start, chunk.length, chunk_width, font.glyph_height()); - available_width -= chunk_width; - - if (do_wrap_lines && available_width < 0) { - containing_block.add_line_box(); - available_width = context.available_width_at_line(line_boxes.size() - 1); - } - - if (do_respect_linebreaks && chunk.has_breaking_newline) { - containing_block.add_line_box(); - available_width = context.available_width_at_line(line_boxes.size() - 1); - } - } -} - -void TextNode::split_into_lines(InlineFormattingContext& context, LayoutMode layout_mode) -{ - bool do_collapse = true; - bool do_wrap_lines = true; - bool do_respect_linebreaks = false; - - if (computed_values().white_space() == CSS::WhiteSpace::Nowrap) { - do_collapse = true; - do_wrap_lines = false; - do_respect_linebreaks = false; - } else if (computed_values().white_space() == CSS::WhiteSpace::Pre) { - do_collapse = false; - do_wrap_lines = false; - do_respect_linebreaks = true; - } else if (computed_values().white_space() == CSS::WhiteSpace::PreLine) { - do_collapse = true; - do_wrap_lines = true; - do_respect_linebreaks = true; - } else if (computed_values().white_space() == CSS::WhiteSpace::PreWrap) { - do_collapse = false; - do_wrap_lines = true; - do_respect_linebreaks = true; - } - - split_into_lines_by_rules(context, layout_mode, do_collapse, do_wrap_lines, do_respect_linebreaks); -} - bool TextNode::wants_mouse_events() const { return parent() && is