mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-24 19:28:48 +00:00
LibWeb: Allow layout nodes to have multiple paintables
CSS fragmentation implies 1:N relationship between layout nodes and paintables. This change is a preparation for implementation of inline fragmentation where InlinePaintable will be replaced with PaintableWithLines corresponding to each line.
This commit is contained in:
parent
a6718e5f3b
commit
7d22b1c5c8
Notes:
github-actions[bot]
2024-10-16 18:26:52 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 7d22b1c5c8
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1829
16 changed files with 90 additions and 30 deletions
|
@ -1924,6 +1924,11 @@ void Node::set_paintable(JS::GCPtr<Painting::Paintable> paintable)
|
|||
m_paintable = paintable;
|
||||
}
|
||||
|
||||
void Node::clear_paintable()
|
||||
{
|
||||
m_paintable = nullptr;
|
||||
}
|
||||
|
||||
Painting::Paintable const* Node::paintable() const
|
||||
{
|
||||
return m_paintable;
|
||||
|
|
|
@ -248,6 +248,7 @@ public:
|
|||
Painting::Paintable* paintable();
|
||||
|
||||
void set_paintable(JS::GCPtr<Painting::Paintable>);
|
||||
void clear_paintable();
|
||||
|
||||
void set_layout_node(Badge<Layout::Node>, JS::NonnullGCPtr<Layout::Node>);
|
||||
void detach_layout_node(Badge<Layout::TreeBuilder>);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <LibWeb/DOM/DocumentLoading.h>
|
||||
#include <LibWeb/DOM/Event.h>
|
||||
#include <LibWeb/DOM/Range.h>
|
||||
#include <LibWeb/DOM/Text.h>
|
||||
#include <LibWeb/Fetch/Fetching/Fetching.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/FetchAlgorithms.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/FetchController.h>
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <LibWeb/Layout/SVGFormattingContext.h>
|
||||
#include <LibWeb/Layout/SVGSVGBox.h>
|
||||
#include <LibWeb/Layout/TableFormattingContext.h>
|
||||
#include <LibWeb/Layout/TextNode.h>
|
||||
#include <LibWeb/Layout/Viewport.h>
|
||||
|
||||
namespace Web::Layout {
|
||||
|
|
|
@ -221,11 +221,11 @@ void LayoutState::commit(Box& root)
|
|||
// from the layout tree. This is done to ensure that we don't end up with any old-tree pointers
|
||||
// when text paintables shift around in the tree.
|
||||
root.for_each_in_inclusive_subtree([&](Layout::Node& node) {
|
||||
node.set_paintable(nullptr);
|
||||
node.clear_paintables();
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
root.document().for_each_shadow_including_inclusive_descendant([&](DOM::Node& node) {
|
||||
node.set_paintable(nullptr);
|
||||
node.clear_paintable();
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
|
||||
|
@ -248,7 +248,7 @@ void LayoutState::commit(Box& root)
|
|||
|
||||
auto paintable = node.create_paintable();
|
||||
|
||||
node.set_paintable(paintable);
|
||||
node.add_paintable(paintable);
|
||||
|
||||
// For boxes, transfer all the state needed for painting.
|
||||
if (paintable && is<Painting::PaintableBox>(*paintable)) {
|
||||
|
@ -351,7 +351,7 @@ void LayoutState::commit(Box& root)
|
|||
}
|
||||
|
||||
for (auto* text_node : text_nodes) {
|
||||
text_node->set_paintable(text_node->create_paintable());
|
||||
text_node->add_paintable(text_node->create_paintable());
|
||||
auto* paintable = text_node->paintable();
|
||||
auto const& font = text_node->first_available_font();
|
||||
auto const glyph_height = CSSPixels::nearest_value_for(font.pixel_size());
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <AK/Utf8View.h>
|
||||
#include <LibWeb/DOM/Range.h>
|
||||
#include <LibWeb/Layout/LayoutState.h>
|
||||
#include <LibWeb/Layout/TextNode.h>
|
||||
#include <LibWeb/Layout/Viewport.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
|
|
@ -48,7 +48,9 @@ void Node::visit_edges(Cell::Visitor& visitor)
|
|||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_dom_node);
|
||||
visitor.visit(m_paintable);
|
||||
for (auto const& paintable : m_paintable) {
|
||||
visitor.visit(JS::GCPtr { &paintable });
|
||||
}
|
||||
visitor.visit(m_pseudo_element_generator);
|
||||
TreeNode::visit_edges(visitor);
|
||||
}
|
||||
|
@ -1015,9 +1017,16 @@ void NodeWithStyle::transfer_table_box_computed_values_to_wrapper_computed_value
|
|||
reset_table_box_computed_values_used_by_wrapper_to_init_values();
|
||||
}
|
||||
|
||||
void Node::set_paintable(JS::GCPtr<Painting::Paintable> paintable)
|
||||
void Node::add_paintable(JS::GCPtr<Painting::Paintable> paintable)
|
||||
{
|
||||
m_paintable = move(paintable);
|
||||
if (!paintable)
|
||||
return;
|
||||
m_paintable.append(*paintable);
|
||||
}
|
||||
|
||||
void Node::clear_paintables()
|
||||
{
|
||||
m_paintable.clear();
|
||||
}
|
||||
|
||||
JS::GCPtr<Painting::Paintable> Node::create_paintable() const
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/Layout/BoxModelMetrics.h>
|
||||
#include <LibWeb/Painting/PaintContext.h>
|
||||
#include <LibWeb/Painting/Paintable.h>
|
||||
#include <LibWeb/TreeNode.h>
|
||||
|
||||
namespace Web::Layout {
|
||||
|
@ -64,9 +65,12 @@ public:
|
|||
m_pseudo_element_generator = &element;
|
||||
}
|
||||
|
||||
Painting::Paintable* paintable() { return m_paintable; }
|
||||
Painting::Paintable const* paintable() const { return m_paintable; }
|
||||
void set_paintable(JS::GCPtr<Painting::Paintable>);
|
||||
using PaintableList = IntrusiveList<&Painting::Paintable::m_list_node>;
|
||||
|
||||
Painting::Paintable* paintable() { return m_paintable.first(); }
|
||||
Painting::Paintable const* paintable() const { return m_paintable.first(); }
|
||||
void add_paintable(JS::GCPtr<Painting::Paintable>);
|
||||
void clear_paintables();
|
||||
|
||||
virtual JS::GCPtr<Painting::Paintable> create_paintable() const;
|
||||
|
||||
|
@ -181,7 +185,7 @@ private:
|
|||
friend class NodeWithStyle;
|
||||
|
||||
JS::NonnullGCPtr<DOM::Node> m_dom_node;
|
||||
JS::GCPtr<Painting::Paintable> m_paintable;
|
||||
PaintableList m_paintable;
|
||||
|
||||
JS::GCPtr<DOM::Element> m_pseudo_element_generator;
|
||||
|
||||
|
|
|
@ -309,7 +309,7 @@ void TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder::Context&
|
|||
if (!layout_node) {
|
||||
dom_node.for_each_in_inclusive_subtree([&](auto& node) {
|
||||
node.detach_layout_node({});
|
||||
node.set_paintable(nullptr);
|
||||
node.clear_paintable();
|
||||
if (is<DOM::Element>(node))
|
||||
static_cast<DOM::Element&>(node).clear_pseudo_element_nodes({});
|
||||
return TraversalDecision::Continue;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <LibWeb/DOM/Range.h>
|
||||
#include <LibWeb/Dump.h>
|
||||
#include <LibWeb/Layout/TextNode.h>
|
||||
#include <LibWeb/Layout/Viewport.h>
|
||||
#include <LibWeb/Painting/PaintableBox.h>
|
||||
#include <LibWeb/Painting/StackingContext.h>
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <LibWeb/CSS/Sizing.h>
|
||||
#include <LibWeb/Layout/Node.h>
|
||||
#include <LibWeb/Layout/TextNode.h>
|
||||
#include <LibWeb/Layout/Viewport.h>
|
||||
#include <LibWeb/Painting/BackgroundPainting.h>
|
||||
#include <LibWeb/Painting/InlinePaintable.h>
|
||||
|
|
|
@ -51,6 +51,38 @@ bool Paintable::is_visible() const
|
|||
return computed_values.visibility() == CSS::Visibility::Visible && computed_values.opacity() != 0;
|
||||
}
|
||||
|
||||
DOM::Document const& Paintable::document() const
|
||||
{
|
||||
return layout_node().document();
|
||||
}
|
||||
|
||||
DOM::Document& Paintable::document()
|
||||
{
|
||||
return layout_node().document();
|
||||
}
|
||||
|
||||
CSS::Display Paintable::display() const
|
||||
{
|
||||
return layout_node().display();
|
||||
}
|
||||
|
||||
PaintableBox* Paintable::containing_block() const
|
||||
{
|
||||
if (!m_containing_block.has_value()) {
|
||||
auto containing_layout_box = m_layout_node->containing_block();
|
||||
if (containing_layout_box)
|
||||
m_containing_block = const_cast<PaintableBox*>(containing_layout_box->paintable_box());
|
||||
else
|
||||
m_containing_block = nullptr;
|
||||
}
|
||||
return *m_containing_block;
|
||||
}
|
||||
|
||||
CSS::ImmutableComputedValues const& Paintable::computed_values() const
|
||||
{
|
||||
return m_layout_node->computed_values();
|
||||
}
|
||||
|
||||
void Paintable::set_dom_node(JS::GCPtr<DOM::Node> dom_node)
|
||||
{
|
||||
m_dom_node = dom_node;
|
||||
|
|
|
@ -7,10 +7,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <LibJS/Heap/Handle.h>
|
||||
#include <LibWeb/InvalidateDisplayList.h>
|
||||
#include <LibWeb/Layout/Box.h>
|
||||
#include <LibWeb/Layout/LineBox.h>
|
||||
#include <LibWeb/Layout/TextNode.h>
|
||||
#include <LibWeb/TraversalDecision.h>
|
||||
#include <LibWeb/TreeNode.h>
|
||||
|
||||
namespace Web::Painting {
|
||||
|
||||
|
@ -62,7 +63,7 @@ public:
|
|||
[[nodiscard]] bool is_floating() const { return m_floating; }
|
||||
[[nodiscard]] bool is_inline() const { return m_inline; }
|
||||
[[nodiscard]] bool is_selected() const { return m_selected; }
|
||||
[[nodiscard]] CSS::Display display() const { return layout_node().display(); }
|
||||
[[nodiscard]] CSS::Display display() const;
|
||||
|
||||
template<typename U, typename Callback>
|
||||
TraversalDecision for_each_in_inclusive_subtree_of_type(Callback callback)
|
||||
|
@ -194,7 +195,7 @@ public:
|
|||
[[nodiscard]] JS::GCPtr<DOM::Node const> dom_node() const;
|
||||
void set_dom_node(JS::GCPtr<DOM::Node>);
|
||||
|
||||
auto const& computed_values() const { return m_layout_node->computed_values(); }
|
||||
CSS::ImmutableComputedValues const& computed_values() const;
|
||||
|
||||
bool visible_for_hit_testing() const { return computed_values().pointer_events() != CSS::PointerEvents::None; }
|
||||
|
||||
|
@ -202,17 +203,7 @@ public:
|
|||
|
||||
virtual void set_needs_display(InvalidateDisplayList = InvalidateDisplayList::Yes);
|
||||
|
||||
PaintableBox* containing_block() const
|
||||
{
|
||||
if (!m_containing_block.has_value()) {
|
||||
auto containing_layout_box = m_layout_node->containing_block();
|
||||
if (containing_layout_box)
|
||||
m_containing_block = const_cast<PaintableBox*>(containing_layout_box->paintable_box());
|
||||
else
|
||||
m_containing_block = nullptr;
|
||||
}
|
||||
return *m_containing_block;
|
||||
}
|
||||
PaintableBox* containing_block() const;
|
||||
|
||||
template<typename T>
|
||||
bool fast_is() const = delete;
|
||||
|
@ -223,8 +214,8 @@ public:
|
|||
[[nodiscard]] virtual bool is_svg_paintable() const { return false; }
|
||||
[[nodiscard]] virtual bool is_text_paintable() const { return false; }
|
||||
|
||||
DOM::Document const& document() const { return layout_node().document(); }
|
||||
DOM::Document& document() { return layout_node().document(); }
|
||||
DOM::Document const& document() const;
|
||||
DOM::Document& document();
|
||||
|
||||
CSSPixelPoint box_type_agnostic_position() const;
|
||||
|
||||
|
@ -242,7 +233,15 @@ public:
|
|||
|
||||
Gfx::AffineTransform compute_combined_css_transform() const;
|
||||
|
||||
virtual void resolve_paint_properties() {};
|
||||
virtual void resolve_paint_properties() { }
|
||||
|
||||
virtual void finalize() override
|
||||
{
|
||||
if (m_list_node.is_in_list())
|
||||
m_list_node.remove();
|
||||
}
|
||||
|
||||
friend class Layout::Node;
|
||||
|
||||
protected:
|
||||
explicit Paintable(Layout::Node const&);
|
||||
|
@ -250,6 +249,7 @@ protected:
|
|||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
private:
|
||||
IntrusiveListNode<Paintable> m_list_node;
|
||||
JS::GCPtr<DOM::Node> m_dom_node;
|
||||
JS::NonnullGCPtr<Layout::Node const> m_layout_node;
|
||||
Optional<JS::GCPtr<PaintableBox>> mutable m_containing_block;
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibWeb/CSS/StyleValues/GridTrackSizeListStyleValue.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/Layout/Box.h>
|
||||
#include <LibWeb/Painting/BackgroundPainting.h>
|
||||
#include <LibWeb/Painting/BorderPainting.h>
|
||||
#include <LibWeb/Painting/BorderRadiusCornerClipper.h>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/Layout/TextNode.h>
|
||||
#include <LibWeb/Painting/PaintableBox.h>
|
||||
|
||||
namespace Web::Painting {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <LibWeb/DOM/Range.h>
|
||||
#include <LibWeb/Layout/TextNode.h>
|
||||
#include <LibWeb/Layout/Viewport.h>
|
||||
#include <LibWeb/Painting/StackingContext.h>
|
||||
#include <LibWeb/Painting/ViewportPaintable.h>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue