From 615a4d4f71db0750313ae8ac1494e65f67f25b31 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 5 Dec 2020 20:10:39 +0100 Subject: [PATCH] LibWeb: First slightly naive implementation of CSS floats :^) Boxes can now be floated left or right, which makes text within the same block formatting context flow around them. We were creating way too many block formatting contexts. As it turns out, we don't need one for every new block, but rather there's a set of rules that determines whether a given block creates a new block formatting context. Each BFC keeps track of the floating boxes within it, and IFC's can then query it to find the available space for line boxes. There's a huge hack in here where we assume all lines are the exact line-height. Making this work with vertically non-uniform lines will require some architectural changes. --- Libraries/LibWeb/Layout/BlockBox.cpp | 9 +++- Libraries/LibWeb/Layout/BlockBox.h | 2 +- .../LibWeb/Layout/BlockFormattingContext.cpp | 46 +++++++++++++++- .../LibWeb/Layout/BlockFormattingContext.h | 11 ++++ Libraries/LibWeb/Layout/BreakNode.cpp | 5 +- Libraries/LibWeb/Layout/BreakNode.h | 2 +- Libraries/LibWeb/Layout/FormattingContext.cpp | 40 ++++++++++++-- Libraries/LibWeb/Layout/FormattingContext.h | 12 +++-- .../LibWeb/Layout/InlineFormattingContext.cpp | 52 +++++++++++++++++-- .../LibWeb/Layout/InlineFormattingContext.h | 2 + Libraries/LibWeb/Layout/InlineNode.cpp | 7 ++- Libraries/LibWeb/Layout/InlineNode.h | 2 +- Libraries/LibWeb/Layout/Node.cpp | 15 +++++- Libraries/LibWeb/Layout/Node.h | 2 +- Libraries/LibWeb/Layout/ReplacedBox.cpp | 11 ++-- Libraries/LibWeb/Layout/ReplacedBox.h | 2 +- Libraries/LibWeb/Layout/TextNode.cpp | 26 +++++----- Libraries/LibWeb/Layout/TextNode.h | 4 +- 18 files changed, 209 insertions(+), 41 deletions(-) diff --git a/Libraries/LibWeb/Layout/BlockBox.cpp b/Libraries/LibWeb/Layout/BlockBox.cpp index 2fbebba10a4..ed10978314c 100644 --- a/Libraries/LibWeb/Layout/BlockBox.cpp +++ b/Libraries/LibWeb/Layout/BlockBox.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -107,10 +108,14 @@ HitTestResult BlockBox::hit_test(const Gfx::IntPoint& position, HitTestType type return { absolute_rect().contains(position.x(), position.y()) ? this : nullptr }; } -void BlockBox::split_into_lines(BlockBox& container, LayoutMode layout_mode) +void BlockBox::split_into_lines(InlineFormattingContext& context, LayoutMode layout_mode) { + auto& container = context.context_box(); auto* line_box = &container.ensure_last_line_box(); - if (layout_mode != LayoutMode::OnlyRequiredLineBreaks && line_box->width() > 0 && line_box->width() + width() > container.width()) { + + float available_width = context.available_width_at_line(container.line_boxes().size()); + + if (layout_mode != LayoutMode::OnlyRequiredLineBreaks && line_box->width() > 0 && line_box->width() + width() > available_width) { line_box = &container.add_line_box(); } line_box->add_fragment(*this, 0, 0, width(), height()); diff --git a/Libraries/LibWeb/Layout/BlockBox.h b/Libraries/LibWeb/Layout/BlockBox.h index 8d1b43d3a87..83929ac14ec 100644 --- a/Libraries/LibWeb/Layout/BlockBox.h +++ b/Libraries/LibWeb/Layout/BlockBox.h @@ -52,7 +52,7 @@ public: template void for_each_fragment(Callback) const; - virtual void split_into_lines(BlockBox& container, LayoutMode) override; + virtual void split_into_lines(InlineFormattingContext&, LayoutMode) override; private: virtual bool is_block() const override { return true; } diff --git a/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Libraries/LibWeb/Layout/BlockFormattingContext.cpp index 4b888bdd7d8..e6e1421743b 100644 --- a/Libraries/LibWeb/Layout/BlockFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/BlockFormattingContext.cpp @@ -65,6 +65,8 @@ void BlockFormattingContext::run(LayoutMode layout_mode) if (layout_mode == LayoutMode::Default) compute_width(context_box()); + layout_floating_descendants(); + if (context_box().children_are_inline()) { layout_inline_children(layout_mode); } else { @@ -403,7 +405,7 @@ void BlockFormattingContext::layout_block_level_children(LayoutMode layout_mode) float content_width = 0; context_box().for_each_in_subtree_of_type([&](auto& box) { - if (box.is_absolutely_positioned() || box.containing_block() != &context_box()) + if (box.is_absolutely_positioned() || box.is_floating() || box.containing_block() != &context_box()) return IterationDecision::Continue; compute_width(box); @@ -530,6 +532,8 @@ void BlockFormattingContext::layout_initial_containing_block(LayoutMode layout_m icb.set_width(viewport_rect.width()); + layout_floating_descendants(); + layout_block_level_children(layout_mode); ASSERT(!icb.children_are_inline()); @@ -564,6 +568,46 @@ void BlockFormattingContext::layout_absolutely_positioned_descendants() }); } +void BlockFormattingContext::layout_floating_descendants() +{ + context_box().for_each_in_subtree_of_type([&](auto& box) { + if (box.is_floating() && box.containing_block() == &context_box()) { + layout_floating_descendant(box); + } + return IterationDecision::Continue; + }); +} + +void BlockFormattingContext::layout_floating_descendant(Box& box) +{ + ASSERT(box.is_floating()); + auto& containing_block = context_box(); + + compute_width(box); + layout_inside(box, LayoutMode::Default); + compute_height(box); + + if (box.style().float_() == CSS::Float::Left) { + float x = 0; + if (!m_left_floating_boxes.is_empty()) { + auto& previous_floating_box = *m_left_floating_boxes.last(); + x = previous_floating_box.effective_offset().x() + previous_floating_box.width(); + } + box.set_offset(x, 0); + m_left_floating_boxes.append(&box); + } else if (box.style().float_() == CSS::Float::Right) { + float x = 0; + if (!m_right_floating_boxes.is_empty()) { + auto& previous_floating_box = *m_right_floating_boxes.last(); + x = previous_floating_box.effective_offset().x() - box.width(); + } else { + x = containing_block.width() - box.width(); + } + box.set_offset(x, 0); + m_right_floating_boxes.append(&box); + } +} + void BlockFormattingContext::layout_absolutely_positioned_descendant(Box& box) { auto& containing_block = context_box(); diff --git a/Libraries/LibWeb/Layout/BlockFormattingContext.h b/Libraries/LibWeb/Layout/BlockFormattingContext.h index dbbbbe5caf0..dd304699355 100644 --- a/Libraries/LibWeb/Layout/BlockFormattingContext.h +++ b/Libraries/LibWeb/Layout/BlockFormattingContext.h @@ -26,6 +26,7 @@ #pragma once +#include #include #include @@ -40,22 +41,32 @@ public: bool is_initial() const; + const Vector& left_floating_boxes() const { return m_left_floating_boxes; } + const Vector& right_floating_boxes() const { return m_right_floating_boxes; } + protected: void compute_width(Box&); void compute_height(Box&); private: + virtual bool is_block_formatting_context() const final { return true; } + void compute_width_for_absolutely_positioned_block(Box&); void layout_initial_containing_block(LayoutMode); void layout_block_level_children(LayoutMode); void layout_inline_children(LayoutMode); void layout_absolutely_positioned_descendants(); + void layout_floating_descendants(); void place_block_level_replaced_element_in_normal_flow(Box&); void place_block_level_non_replaced_element_in_normal_flow(Box&); void layout_absolutely_positioned_descendant(Box&); + void layout_floating_descendant(Box&); + + Vector m_left_floating_boxes; + Vector m_right_floating_boxes; }; } diff --git a/Libraries/LibWeb/Layout/BreakNode.cpp b/Libraries/LibWeb/Layout/BreakNode.cpp index 0a230a98731..a16633e71ae 100644 --- a/Libraries/LibWeb/Layout/BreakNode.cpp +++ b/Libraries/LibWeb/Layout/BreakNode.cpp @@ -26,6 +26,7 @@ #include #include +#include namespace Web::Layout { @@ -39,9 +40,9 @@ BreakNode::~BreakNode() { } -void BreakNode::split_into_lines(BlockBox& block, LayoutMode) +void BreakNode::split_into_lines(InlineFormattingContext& block, LayoutMode) { - block.add_line_box(); + block.context_box().add_line_box(); } } diff --git a/Libraries/LibWeb/Layout/BreakNode.h b/Libraries/LibWeb/Layout/BreakNode.h index 07ecb6926fc..2bc15fc5297 100644 --- a/Libraries/LibWeb/Layout/BreakNode.h +++ b/Libraries/LibWeb/Layout/BreakNode.h @@ -41,7 +41,7 @@ public: private: virtual bool is_break() const override { return true; } virtual const char* class_name() const override { return "BreakNode"; } - virtual void split_into_lines(BlockBox&, LayoutMode) override; + virtual void split_into_lines(InlineFormattingContext&, LayoutMode) override; }; } diff --git a/Libraries/LibWeb/Layout/FormattingContext.cpp b/Libraries/LibWeb/Layout/FormattingContext.cpp index 670191f41fc..5d81536260e 100644 --- a/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include @@ -34,7 +35,7 @@ namespace Web::Layout { FormattingContext::FormattingContext(Box& context_box, FormattingContext* parent) : m_parent(parent) - , m_context_box(context_box) + , m_context_box(&context_box) { } @@ -42,8 +43,37 @@ FormattingContext::~FormattingContext() { } +bool FormattingContext::creates_block_formatting_context(const Box& box) +{ + if (box.is_root_element()) + return true; + if (box.is_floating()) + return true; + if (box.is_absolutely_positioned()) + return true; + if (box.is_inline_block()) + return true; + if (box.is_table_cell()) + return true; + // FIXME: table-caption + // FIXME: anonymous table cells + // FIXME: Block elements where overflow has a value other than visible and clip. + // FIXME: display: flow-root + // FIXME: Elements with contain: layout, content, or paint. + // FIXME: flex + // FIXME: grid + // FIXME: multicol + // FIXME: column-span: all + return false; +} + void FormattingContext::layout_inside(Box& box, LayoutMode layout_mode) { + if (creates_block_formatting_context(box)) { + BlockFormattingContext context(box, this); + context.run(layout_mode); + return; + } if (box.is_table()) { TableFormattingContext context(box, this); context.run(layout_mode); @@ -51,8 +81,12 @@ void FormattingContext::layout_inside(Box& box, LayoutMode layout_mode) InlineFormattingContext context(box, this); context.run(layout_mode); } else { - BlockFormattingContext context(box, this); - context.run(layout_mode); + // FIXME: This needs refactoring! + ASSERT(is_block_formatting_context()); + auto& old_box = context_box(); + set_context_box(box); + run(layout_mode); + set_context_box(old_box); } } diff --git a/Libraries/LibWeb/Layout/FormattingContext.h b/Libraries/LibWeb/Layout/FormattingContext.h index c8f7487dc27..b505702d673 100644 --- a/Libraries/LibWeb/Layout/FormattingContext.h +++ b/Libraries/LibWeb/Layout/FormattingContext.h @@ -34,16 +34,22 @@ class FormattingContext { public: virtual void run(LayoutMode) = 0; - Box& context_box() { return m_context_box; } - const Box& context_box() const { return m_context_box; } + Box& context_box() { return *m_context_box; } + const Box& context_box() const { return *m_context_box; } FormattingContext* parent() { return m_parent; } const FormattingContext* parent() const { return m_parent; } + virtual bool is_block_formatting_context() const { return false; } + + static bool creates_block_formatting_context(const Box&); + protected: FormattingContext(Box&, FormattingContext* parent = nullptr); virtual ~FormattingContext(); + void set_context_box(Box& box) { m_context_box = &box; } + void layout_inside(Box&, LayoutMode); struct ShrinkToFitResult { @@ -54,7 +60,7 @@ protected: ShrinkToFitResult calculate_shrink_to_fit_widths(Box&); FormattingContext* m_parent { nullptr }; - Box& m_context_box; + Box* m_context_box { nullptr }; }; } diff --git a/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Libraries/LibWeb/Layout/InlineFormattingContext.cpp index 105dffa1193..270a80a97db 100644 --- a/Libraries/LibWeb/Layout/InlineFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/InlineFormattingContext.cpp @@ -45,6 +45,50 @@ InlineFormattingContext::~InlineFormattingContext() { } +struct AvailableSpaceForLineInfo { + float left { 0 }; + float right { 0 }; +}; + +static AvailableSpaceForLineInfo available_space_for_line(const InlineFormattingContext& context, size_t line_index) +{ + AvailableSpaceForLineInfo info; + + // FIXME: This is a total hack guess since we don't actually know the final y position of lines here! + float line_height = context.context_box().specified_style().line_height(context.context_box()); + float y = (line_index * line_height) + line_height / 2; + + auto& bfc = static_cast(*context.parent()); + + for (ssize_t i = bfc.left_floating_boxes().size() - 1; i >= 0; --i) { + auto& floating_box = *bfc.left_floating_boxes().at(i); + Gfx::FloatRect rect { floating_box.effective_offset(), floating_box.size() }; + if (rect.contains_vertically(y)) { + info.left = rect.right() + 1; + break; + } + } + + info.right = context.context_box().width(); + + for (ssize_t i = bfc.right_floating_boxes().size() - 1; i >= 0; --i) { + auto& floating_box = *bfc.right_floating_boxes().at(i); + Gfx::FloatRect rect { floating_box.effective_offset(), floating_box.size() }; + if (rect.contains_vertically(y)) { + info.right = rect.left() - 1; + break; + } + } + + return info; +} + +float InlineFormattingContext::available_width_at_line(size_t line_index) const +{ + auto info = available_space_for_line(*this, line_index); + return info.right - info.left; +} + void InlineFormattingContext::run(LayoutMode layout_mode) { auto& containing_block = downcast(context_box()); @@ -56,7 +100,7 @@ void InlineFormattingContext::run(LayoutMode layout_mode) if (child.is_absolutely_positioned()) return; - child.split_into_lines(containing_block, layout_mode); + child.split_into_lines(*this, layout_mode); }); for (auto& line_box : containing_block.line_boxes()) { @@ -73,13 +117,15 @@ void InlineFormattingContext::run(LayoutMode layout_mode) float content_height = 0; float max_linebox_width = 0; - for (auto& line_box : containing_block.line_boxes()) { + for (size_t line_index = 0; line_index < containing_block.line_boxes().size(); ++line_index) { + auto& line_box = containing_block.line_boxes()[line_index]; float max_height = min_line_height; for (auto& fragment : line_box.fragments()) { max_height = max(max_height, fragment.height()); } - float x_offset = 0; + float x_offset = available_space_for_line(*this, line_index).left; + float excess_horizontal_space = (float)containing_block.width() - line_box.width(); switch (text_align) { diff --git a/Libraries/LibWeb/Layout/InlineFormattingContext.h b/Libraries/LibWeb/Layout/InlineFormattingContext.h index 2cc6c5f88fb..a96f0c9901c 100644 --- a/Libraries/LibWeb/Layout/InlineFormattingContext.h +++ b/Libraries/LibWeb/Layout/InlineFormattingContext.h @@ -38,6 +38,8 @@ public: virtual void run(LayoutMode) override; + float available_width_at_line(size_t line_index) const; + private: void dimension_box_on_line(Box&, LayoutMode); }; diff --git a/Libraries/LibWeb/Layout/InlineNode.cpp b/Libraries/LibWeb/Layout/InlineNode.cpp index b34237f4002..4a69afe6ff4 100644 --- a/Libraries/LibWeb/Layout/InlineNode.cpp +++ b/Libraries/LibWeb/Layout/InlineNode.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include namespace Web::Layout { @@ -41,14 +42,16 @@ InlineNode::~InlineNode() { } -void InlineNode::split_into_lines(BlockBox& containing_block, LayoutMode layout_mode) +void InlineNode::split_into_lines(InlineFormattingContext& context, LayoutMode layout_mode) { + auto& containing_block = context.context_box(); + if (!style().padding().left.is_undefined_or_auto()) { float padding_left = style().padding().left.resolved(CSS::Length::make_px(0), *this, containing_block.width()).to_px(*this); containing_block.ensure_last_line_box().add_fragment(*this, 0, 0, padding_left, 0, LineBoxFragment::Type::Leading); } - NodeWithStyleAndBoxModelMetrics::split_into_lines(containing_block, layout_mode); + NodeWithStyleAndBoxModelMetrics::split_into_lines(context, layout_mode); if (!style().padding().right.is_undefined_or_auto()) { float padding_right = style().padding().right.resolved(CSS::Length::make_px(0), *this, containing_block.width()).to_px(*this); diff --git a/Libraries/LibWeb/Layout/InlineNode.h b/Libraries/LibWeb/Layout/InlineNode.h index a140339599c..9725651b2e6 100644 --- a/Libraries/LibWeb/Layout/InlineNode.h +++ b/Libraries/LibWeb/Layout/InlineNode.h @@ -38,7 +38,7 @@ public: virtual void paint_fragment(PaintContext&, const LineBoxFragment&, PaintPhase) const override; - virtual void split_into_lines(BlockBox& containing_block, LayoutMode) override; + virtual void split_into_lines(InlineFormattingContext&, LayoutMode) override; private: virtual bool is_inline_node() const final { return true; } diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index a7eafcef39c..b2c79b922c1 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +66,13 @@ const BlockBox* Node::containing_block() const return downcast(ancestor); }; + auto nearest_block_ancestor_that_creates_a_block_formatting_context = [this] { + auto* ancestor = parent(); + while (ancestor && (!is(*ancestor) || !FormattingContext::creates_block_formatting_context(downcast(*ancestor)))) + ancestor = ancestor->parent(); + return downcast(ancestor); + }; + if (is_text()) return nearest_block_ancestor(); @@ -82,6 +90,9 @@ const BlockBox* Node::containing_block() const if (position == CSS::Position::Fixed) return &root(); + if (is_floating()) + return nearest_block_ancestor_that_creates_a_block_formatting_context(); + return nearest_block_ancestor(); } @@ -140,10 +151,10 @@ InitialContainingBlockBox& Node::root() return *document().layout_node(); } -void Node::split_into_lines(BlockBox& container, LayoutMode layout_mode) +void Node::split_into_lines(InlineFormattingContext& context, LayoutMode layout_mode) { for_each_child([&](auto& child) { - child.split_into_lines(container, layout_mode); + child.split_into_lines(context, layout_mode); }); } diff --git a/Libraries/LibWeb/Layout/Node.h b/Libraries/LibWeb/Layout/Node.h index 90121e76218..3a7f702e0b0 100644 --- a/Libraries/LibWeb/Layout/Node.h +++ b/Libraries/LibWeb/Layout/Node.h @@ -150,7 +150,7 @@ public: void removed_from(Node&) { } void children_changed() { } - virtual void split_into_lines(BlockBox& container, LayoutMode); + 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/Libraries/LibWeb/Layout/ReplacedBox.cpp b/Libraries/LibWeb/Layout/ReplacedBox.cpp index 340d96462c9..be2b4d77ec9 100644 --- a/Libraries/LibWeb/Layout/ReplacedBox.cpp +++ b/Libraries/LibWeb/Layout/ReplacedBox.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include @@ -117,17 +118,19 @@ float ReplacedBox::calculate_height() const return used_height; } -void ReplacedBox::split_into_lines(Layout::BlockBox& container, LayoutMode) +void ReplacedBox::split_into_lines(InlineFormattingContext& context, LayoutMode) { + auto& containing_block = context.context_box(); + // FIXME: This feels out of place. It would be nice if someone at a higher level // made sure we had usable geometry by the time we start splitting. prepare_for_replaced_layout(); auto width = calculate_width(); auto height = calculate_height(); - auto* line_box = &container.ensure_last_line_box(); - if (line_box->width() > 0 && line_box->width() + width > container.width()) - line_box = &container.add_line_box(); + 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())) + line_box = &containing_block.add_line_box(); line_box->add_fragment(*this, 0, 0, width, height); } diff --git a/Libraries/LibWeb/Layout/ReplacedBox.h b/Libraries/LibWeb/Layout/ReplacedBox.h index 1a9ded51afc..081bfd8348d 100644 --- a/Libraries/LibWeb/Layout/ReplacedBox.h +++ b/Libraries/LibWeb/Layout/ReplacedBox.h @@ -65,7 +65,7 @@ public: virtual bool can_have_children() const override { return false; } protected: - virtual void split_into_lines(Layout::BlockBox& container, LayoutMode) override; + virtual void split_into_lines(InlineFormattingContext&, LayoutMode) override; private: virtual const char* class_name() const override { return "ReplacedBox"; } diff --git a/Libraries/LibWeb/Layout/TextNode.cpp b/Libraries/LibWeb/Layout/TextNode.cpp index 3846627fa0c..04331670930 100644 --- a/Libraries/LibWeb/Layout/TextNode.cpp +++ b/Libraries/LibWeb/Layout/TextNode.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -189,14 +190,15 @@ void TextNode::for_each_chunk(Callback callback, LayoutMode layout_mode, bool do commit_chunk(view.end(), false, true); } -void TextNode::split_into_lines_by_rules(BlockBox& container, LayoutMode layout_mode, bool do_collapse, bool do_wrap_lines, bool do_wrap_breaks) +void TextNode::split_into_lines_by_rules(InlineFormattingContext& context, LayoutMode layout_mode, bool do_collapse, bool do_wrap_lines, bool do_wrap_breaks) { + auto& containing_block = context.context_box(); auto& font = specified_style().font(); float space_width = font.glyph_width(' ') + font.glyph_spacing(); - auto& line_boxes = container.line_boxes(); - container.ensure_last_line_box(); - float available_width = container.width() - line_boxes.last().width(); + auto& line_boxes = containing_block.line_boxes(); + containing_block.ensure_last_line_box(); + float available_width = context.available_width_at_line(line_boxes.size()) - line_boxes.last().width(); // Collapse whitespace into single spaces if (do_collapse) { @@ -261,8 +263,8 @@ void TextNode::split_into_lines_by_rules(BlockBox& container, LayoutMode layout_ chunk_width = font.width(chunk.view) + font.glyph_spacing(); if (line_boxes.last().width() > 0 && chunk_width > available_width) { - container.add_line_box(); - available_width = container.width(); + containing_block.add_line_box(); + available_width = context.available_width_at_line(line_boxes.size()); } if (need_collapse & line_boxes.last().fragments().is_empty()) continue; @@ -275,21 +277,21 @@ void TextNode::split_into_lines_by_rules(BlockBox& container, LayoutMode layout_ if (do_wrap_lines) { if (available_width < 0) { - container.add_line_box(); - available_width = container.width(); + containing_block.add_line_box(); + available_width = context.available_width_at_line(line_boxes.size()); } } if (do_wrap_breaks) { if (chunk.is_break) { - container.add_line_box(); - available_width = container.width(); + containing_block.add_line_box(); + available_width = context.available_width_at_line(line_boxes.size()); } } } } -void TextNode::split_into_lines(BlockBox& container, LayoutMode layout_mode) +void TextNode::split_into_lines(InlineFormattingContext& context, LayoutMode layout_mode) { bool do_collapse = true; bool do_wrap_lines = true; @@ -313,7 +315,7 @@ void TextNode::split_into_lines(BlockBox& container, LayoutMode layout_mode) do_wrap_breaks = true; } - split_into_lines_by_rules(container, layout_mode, do_collapse, do_wrap_lines, do_wrap_breaks); + split_into_lines_by_rules(context, layout_mode, do_collapse, do_wrap_lines, do_wrap_breaks); } } diff --git a/Libraries/LibWeb/Layout/TextNode.h b/Libraries/LibWeb/Layout/TextNode.h index 389cf0f3e8e..e19692511ef 100644 --- a/Libraries/LibWeb/Layout/TextNode.h +++ b/Libraries/LibWeb/Layout/TextNode.h @@ -48,12 +48,12 @@ public: virtual void paint_fragment(PaintContext&, const LineBoxFragment&, PaintPhase) const override; - virtual void split_into_lines(BlockBox& container, LayoutMode) override; + virtual void split_into_lines(InlineFormattingContext&, LayoutMode) override; const CSS::StyleProperties& specified_style() const { return parent()->specified_style(); } private: - void split_into_lines_by_rules(BlockBox& container, LayoutMode, bool do_collapse, bool do_wrap_lines, bool do_wrap_breaks); + void split_into_lines_by_rules(InlineFormattingContext&, LayoutMode, bool do_collapse, bool do_wrap_lines, bool do_wrap_breaks); void paint_cursor_if_needed(PaintContext&, const LineBoxFragment&) const; template