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 5bbc155f22..079befc78c 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 397a262917..8c68f14082 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 8b02cc8c44..ca4081ad54 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 4276b4eaee..5ab8c869a9 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 a5e2a2bbfc..d7ea26d59f 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 a630de43b7..0890641b1f 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 d2a0f8b460..0ca04e8c09 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 bcf67189b9..d574d9048e 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 1985f7fbd6..098e06db8b 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 d37e5d8145..55b8afc370 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 d4155bff34..b53d42d5ea 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