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.
This commit is contained in:
Andreas Kling 2022-01-21 13:34:29 +01:00
parent ba49dc82e0
commit 766d816db3
Notes: sideshowbarker 2024-07-18 00:41:35 +09:00
12 changed files with 0 additions and 167 deletions

View File

@ -104,23 +104,6 @@ HitTestResult BlockContainer::hit_test(const Gfx::IntPoint& position, HitTestTyp
return { absolute_rect().contains(position.x(), position.y()) ? this : nullptr }; 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 bool BlockContainer::is_scrollable() const
{ {
// FIXME: Support horizontal scroll as well (overflow-x) // FIXME: Support horizontal scroll as well (overflow-x)

View File

@ -32,8 +32,6 @@ public:
template<typename Callback> template<typename Callback>
void for_each_fragment(Callback) const; void for_each_fragment(Callback) const;
virtual void split_into_lines(InlineFormattingContext&, LayoutMode) override;
bool is_scrollable() const; bool is_scrollable() const;
const Gfx::FloatPoint& scroll_offset() const { return m_scroll_offset; } const Gfx::FloatPoint& scroll_offset() const { return m_scroll_offset; }
void set_scroll_offset(const Gfx::FloatPoint&); void set_scroll_offset(const Gfx::FloatPoint&);

View File

@ -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) void BreakNode::paint(PaintContext&, PaintPhase)
{ {
} }

View File

@ -21,8 +21,6 @@ public:
private: private:
virtual bool is_break_node() const final { return true; } virtual bool is_break_node() const final { return true; }
virtual void paint(PaintContext&, PaintPhase) override; virtual void paint(PaintContext&, PaintPhase) override;
virtual void split_into_lines(InlineFormattingContext&, LayoutMode) override;
}; };
template<> template<>

View File

@ -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) void InlineNode::paint(PaintContext& context, PaintPhase phase)
{ {
auto& painter = context.painter(); auto& painter = context.painter();

View File

@ -17,8 +17,6 @@ public:
virtual void paint(PaintContext&, PaintPhase) override; virtual void paint(PaintContext&, PaintPhase) override;
virtual void split_into_lines(InlineFormattingContext&, LayoutMode) override;
private: private:
template<typename Callback> template<typename Callback>
void for_each_fragment(Callback); void for_each_fragment(Callback);

View File

@ -115,13 +115,6 @@ InitialContainingBlock& Node::root()
return *document().layout_node(); 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() void Node::set_needs_display()
{ {
if (auto* block = containing_block()) { if (auto* block = containing_block()) {

View File

@ -134,8 +134,6 @@ public:
void removed_from(Node&) { } void removed_from(Node&) { }
void children_changed() { } void children_changed() { }
virtual void split_into_lines(InlineFormattingContext&, LayoutMode);
bool is_visible() const { return m_visible; } bool is_visible() const { return m_visible; }
void set_visible(bool visible) { m_visible = visible; } void set_visible(bool visible) { m_visible = visible; }

View File

@ -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());
}
} }

View File

@ -31,9 +31,6 @@ public:
virtual bool can_have_children() const override { return false; } virtual bool can_have_children() const override { return false; }
protected:
virtual void split_into_lines(InlineFormattingContext&, LayoutMode) override;
private: private:
Optional<float> m_intrinsic_width; Optional<float> m_intrinsic_width;
Optional<float> m_intrinsic_height; Optional<float> m_intrinsic_height;

View File

@ -192,95 +192,6 @@ void TextNode::compute_text_for_rendering(bool collapse, bool previous_is_empty_
m_text_for_rendering = builder.to_string(); 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 bool TextNode::wants_mouse_events() const
{ {
return parent() && is<Label>(parent()); return parent() && is<Label>(parent());

View File

@ -25,8 +25,6 @@ public:
virtual void paint_fragment(PaintContext&, const LineBoxFragment&, PaintPhase) const override; virtual void paint_fragment(PaintContext&, const LineBoxFragment&, PaintPhase) const override;
virtual void split_into_lines(InlineFormattingContext&, LayoutMode) override;
struct Chunk { struct Chunk {
Utf8View view; Utf8View view;
size_t start { 0 }; size_t start { 0 };
@ -60,7 +58,6 @@ private:
virtual void handle_mousedown(Badge<EventHandler>, const Gfx::IntPoint&, unsigned button, unsigned modifiers) override; virtual void handle_mousedown(Badge<EventHandler>, const Gfx::IntPoint&, unsigned button, unsigned modifiers) override;
virtual void handle_mouseup(Badge<EventHandler>, const Gfx::IntPoint&, unsigned button, unsigned modifiers) override; virtual void handle_mouseup(Badge<EventHandler>, const Gfx::IntPoint&, unsigned button, unsigned modifiers) override;
virtual void handle_mousemove(Badge<EventHandler>, const Gfx::IntPoint&, unsigned button, unsigned modifiers) override; virtual void handle_mousemove(Badge<EventHandler>, const Gfx::IntPoint&, unsigned button, unsigned modifiers) override;
void split_into_lines_by_rules(InlineFormattingContext&, LayoutMode, bool do_collapse, bool do_wrap_lines, bool do_respect_linebreaks);
void paint_cursor_if_needed(PaintContext&, const LineBoxFragment&) const; void paint_cursor_if_needed(PaintContext&, const LineBoxFragment&) const;
void paint_text_decoration(Gfx::Painter&, LineBoxFragment const&) const; void paint_text_decoration(Gfx::Painter&, LineBoxFragment const&) const;
virtual void paint(PaintContext&, PaintPhase) override; virtual void paint(PaintContext&, PaintPhase) override;