mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-22 10:19:20 +00:00
LibWeb: Store final box model metrics in paint tree, not layout tree
This was a weird case of layout results being stored in the layout tree instead of in the paint tree like everything else.
This commit is contained in:
parent
71cb04d8cb
commit
fb020a3c8f
Notes:
github-actions[bot]
2025-02-17 17:29:27 +00:00
Author: https://github.com/awesomekling
Commit: fb020a3c8f
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3603
Reviewed-by: https://github.com/gmta ✅
8 changed files with 65 additions and 58 deletions
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Layout/BoxModelMetrics.h>
|
||||
|
||||
namespace Web::Layout {
|
||||
|
||||
PixelBox BoxModelMetrics::margin_box() const
|
||||
{
|
||||
return {
|
||||
margin.top + border.top + padding.top,
|
||||
margin.right + border.right + padding.right,
|
||||
margin.bottom + border.bottom + padding.bottom,
|
||||
margin.left + border.left + padding.left,
|
||||
};
|
||||
}
|
||||
|
||||
PixelBox BoxModelMetrics::padding_box() const
|
||||
{
|
||||
return {
|
||||
padding.top,
|
||||
padding.right,
|
||||
padding.bottom,
|
||||
padding.left,
|
||||
};
|
||||
}
|
||||
|
||||
PixelBox BoxModelMetrics::border_box() const
|
||||
{
|
||||
return {
|
||||
border.top + padding.top,
|
||||
border.right + padding.right,
|
||||
border.bottom + padding.bottom,
|
||||
border.left + padding.left,
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGfx/Size.h>
|
||||
#include <LibWeb/PixelUnits.h>
|
||||
|
||||
namespace Web::Layout {
|
||||
|
||||
struct PixelBox {
|
||||
CSSPixels top { 0 };
|
||||
CSSPixels right { 0 };
|
||||
CSSPixels bottom { 0 };
|
||||
CSSPixels left { 0 };
|
||||
};
|
||||
|
||||
struct BoxModelMetrics {
|
||||
public:
|
||||
PixelBox margin;
|
||||
PixelBox padding;
|
||||
PixelBox border;
|
||||
PixelBox inset;
|
||||
|
||||
PixelBox margin_box() const;
|
||||
PixelBox padding_box() const;
|
||||
PixelBox border_box() const;
|
||||
};
|
||||
|
||||
}
|
|
@ -141,7 +141,7 @@ static CSSPixelRect measure_scrollable_overflow(Box const& box)
|
|||
// to enable a scroll position that satisfies the requirements of place-content: end alignment.
|
||||
auto has_scrollable_overflow = !paintable_box.absolute_padding_box_rect().contains(scrollable_overflow_rect);
|
||||
if (has_scrollable_overflow) {
|
||||
scrollable_overflow_rect.set_height(max(scrollable_overflow_rect.height(), content_overflow_rect.height() + box.box_model().padding.bottom));
|
||||
scrollable_overflow_rect.set_height(max(scrollable_overflow_rect.height(), content_overflow_rect.height() + paintable_box.box_model().padding.bottom));
|
||||
}
|
||||
|
||||
paintable_box.set_overflow_data(Painting::PaintableBox::OverflowData {
|
||||
|
@ -177,7 +177,8 @@ void LayoutState::resolve_relative_positions()
|
|||
if (!ancestor->display().is_inline_outside() || !ancestor->display().is_flow_inside())
|
||||
break;
|
||||
if (ancestor->computed_values().position() == CSS::Positioning::Relative) {
|
||||
auto const& ancestor_node = static_cast<Layout::NodeWithStyleAndBoxModelMetrics const&>(*ancestor);
|
||||
VERIFY(ancestor->first_paintable());
|
||||
auto const& ancestor_node = as<Painting::PaintableBox>(*ancestor->first_paintable());
|
||||
auto const& inset = ancestor_node.box_model().inset;
|
||||
offset.translate_by(inset.left, inset.top);
|
||||
}
|
||||
|
@ -235,12 +236,21 @@ void LayoutState::commit(Box& root)
|
|||
HashTable<Layout::TextNode*> text_nodes;
|
||||
HashTable<Painting::PaintableWithLines*> inline_node_paintables;
|
||||
|
||||
auto transfer_box_model_metrics = [&](Painting::BoxModelMetrics& box_model, UsedValues const& used_values) {
|
||||
box_model.inset = { used_values.inset_top, used_values.inset_right, used_values.inset_bottom, used_values.inset_left };
|
||||
box_model.padding = { used_values.padding_top, used_values.padding_right, used_values.padding_bottom, used_values.padding_left };
|
||||
box_model.border = { used_values.border_top, used_values.border_right, used_values.border_bottom, used_values.border_left };
|
||||
box_model.margin = { used_values.margin_top, used_values.margin_right, used_values.margin_bottom, used_values.margin_left };
|
||||
};
|
||||
|
||||
auto try_to_relocate_fragment_in_inline_node = [&](auto& fragment, size_t line_index) -> bool {
|
||||
for (auto const* parent = fragment.layout_node().parent(); parent; parent = parent->parent()) {
|
||||
if (is<InlineNode>(*parent)) {
|
||||
auto& inline_node = const_cast<InlineNode&>(static_cast<InlineNode const&>(*parent));
|
||||
auto line_paintable = inline_node.create_paintable_for_line_with_index(line_index);
|
||||
line_paintable->add_fragment(fragment);
|
||||
if (auto const* used_values = used_values_per_layout_node.get(inline_node).value_or(nullptr))
|
||||
transfer_box_model_metrics(line_paintable->box_model(), *used_values);
|
||||
if (!inline_node_paintables.contains(line_paintable.ptr())) {
|
||||
inline_node_paintables.set(line_paintable.ptr());
|
||||
inline_node.add_paintable(line_paintable);
|
||||
|
@ -255,21 +265,15 @@ void LayoutState::commit(Box& root)
|
|||
auto& used_values = *it.value;
|
||||
auto& node = const_cast<NodeWithStyle&>(used_values.node());
|
||||
|
||||
if (is<NodeWithStyleAndBoxModelMetrics>(node)) {
|
||||
// Transfer box model metrics.
|
||||
auto& box_model = static_cast<NodeWithStyleAndBoxModelMetrics&>(node).box_model();
|
||||
box_model.inset = { used_values.inset_top, used_values.inset_right, used_values.inset_bottom, used_values.inset_left };
|
||||
box_model.padding = { used_values.padding_top, used_values.padding_right, used_values.padding_bottom, used_values.padding_left };
|
||||
box_model.border = { used_values.border_top, used_values.border_right, used_values.border_bottom, used_values.border_left };
|
||||
box_model.margin = { used_values.margin_top, used_values.margin_right, used_values.margin_bottom, used_values.margin_left };
|
||||
}
|
||||
|
||||
auto paintable = node.create_paintable();
|
||||
node.add_paintable(paintable);
|
||||
|
||||
// For boxes, transfer all the state needed for painting.
|
||||
if (paintable && is<Painting::PaintableBox>(*paintable)) {
|
||||
auto& paintable_box = static_cast<Painting::PaintableBox&>(*paintable);
|
||||
|
||||
transfer_box_model_metrics(paintable_box.box_model(), used_values);
|
||||
|
||||
paintable_box.set_offset(used_values.offset);
|
||||
paintable_box.set_content_size(used_values.content_width(), used_values.content_height());
|
||||
if (used_values.override_borders_data().has_value()) {
|
||||
|
@ -319,6 +323,8 @@ void LayoutState::commit(Box& root)
|
|||
auto line_paintable = inline_node->create_paintable_for_line_with_index(0);
|
||||
inline_node->add_paintable(line_paintable);
|
||||
inline_node_paintables.set(line_paintable.ptr());
|
||||
if (auto const* used_values = used_values_per_layout_node.get(*inline_node).value_or(nullptr))
|
||||
transfer_box_model_metrics(line_paintable->box_model(), *used_values);
|
||||
}
|
||||
|
||||
// Resolve relative positions for regular boxes (not line box fragments):
|
||||
|
@ -331,7 +337,7 @@ void LayoutState::commit(Box& root)
|
|||
if (!node.is_box())
|
||||
continue;
|
||||
|
||||
auto& paintable = static_cast<Painting::PaintableBox&>(*node.first_paintable());
|
||||
auto& paintable = as<Painting::PaintableBox>(*node.first_paintable());
|
||||
CSSPixelPoint offset;
|
||||
|
||||
if (used_values.containing_line_box_fragment.has_value()) {
|
||||
|
@ -351,7 +357,7 @@ void LayoutState::commit(Box& root)
|
|||
}
|
||||
// Apply relative position inset if appropriate.
|
||||
if (node.computed_values().position() == CSS::Positioning::Relative && is<NodeWithStyleAndBoxModelMetrics>(node)) {
|
||||
auto const& inset = static_cast<NodeWithStyleAndBoxModelMetrics const&>(node).box_model().inset;
|
||||
auto const& inset = paintable.box_model().inset;
|
||||
offset.translate_by(inset.left, inset.top);
|
||||
}
|
||||
paintable.set_offset(offset);
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <LibWeb/CSS/StyleValues/ImageStyleValue.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/Layout/BoxModelMetrics.h>
|
||||
#include <LibWeb/Painting/PaintContext.h>
|
||||
#include <LibWeb/Painting/Paintable.h>
|
||||
#include <LibWeb/TreeNode.h>
|
||||
|
@ -263,9 +262,6 @@ class NodeWithStyleAndBoxModelMetrics : public NodeWithStyle {
|
|||
GC_CELL(NodeWithStyleAndBoxModelMetrics, NodeWithStyle);
|
||||
|
||||
public:
|
||||
BoxModelMetrics& box_model() { return m_box_model; }
|
||||
BoxModelMetrics const& box_model() const { return m_box_model; }
|
||||
|
||||
GC::Ptr<NodeWithStyleAndBoxModelMetrics> continuation_of_node() const { return m_continuation_of_node; }
|
||||
void set_continuation_of_node(Badge<TreeBuilder>, GC::Ptr<NodeWithStyleAndBoxModelMetrics> node) { m_continuation_of_node = node; }
|
||||
|
||||
|
@ -287,7 +283,6 @@ protected:
|
|||
private:
|
||||
virtual bool is_node_with_style_and_box_model_metrics() const final { return true; }
|
||||
|
||||
BoxModelMetrics m_box_model;
|
||||
GC::Ptr<NodeWithStyleAndBoxModelMetrics> m_continuation_of_node;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue