mirror of
https://github.com/RGBCube/serenity
synced 2025-07-17 11:47:37 +00:00
LibWeb: Move layout box rect helpers into FormattingContext
These are only used during layout, and always within formatting context code, so we might as well put them in FormattingContext and avoid having to pass the LayoutState around all the time.
This commit is contained in:
parent
4f08fcde29
commit
42470d837e
10 changed files with 155 additions and 152 deletions
|
@ -752,7 +752,7 @@ BlockFormattingContext::DidIntroduceClearance BlockFormattingContext::clear_floa
|
|||
// First, find the lowest margin box edge on this float side and calculate the Y offset just below it.
|
||||
CSSPixels clearance_y_in_root = 0;
|
||||
for (auto const& floating_box : float_side.current_boxes) {
|
||||
auto floating_box_rect_in_root = margin_box_rect_in_ancestor_coordinate_space(floating_box.box, root(), m_state);
|
||||
auto floating_box_rect_in_root = margin_box_rect_in_ancestor_coordinate_space(floating_box.box, root());
|
||||
clearance_y_in_root = max(clearance_y_in_root, floating_box_rect_in_root.bottom());
|
||||
}
|
||||
|
||||
|
@ -795,7 +795,7 @@ void BlockFormattingContext::place_block_level_element_in_normal_flow_horizontal
|
|||
|
||||
if ((!m_left_floats.current_boxes.is_empty() || !m_right_floats.current_boxes.is_empty())
|
||||
&& creates_block_formatting_context(child_box)) {
|
||||
auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(child_box, root(), m_state);
|
||||
auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(child_box, root());
|
||||
auto space = space_used_by_floats(box_in_root_rect.y());
|
||||
available_width_within_containing_block -= space.left + space.right;
|
||||
x += space.left;
|
||||
|
@ -810,10 +810,10 @@ void BlockFormattingContext::place_block_level_element_in_normal_flow_horizontal
|
|||
box_state.set_content_offset({ x.value(), box_state.offset.y() });
|
||||
}
|
||||
|
||||
static void measure_scrollable_overflow(LayoutState const& state, Box const& box, CSSPixels& bottom_edge, CSSPixels& right_edge)
|
||||
void BlockFormattingContext::measure_scrollable_overflow(Box const& box, CSSPixels& bottom_edge, CSSPixels& right_edge) const
|
||||
{
|
||||
auto const& child_state = state.get(box);
|
||||
auto child_rect = absolute_content_rect(box, state);
|
||||
auto const& child_state = m_state.get(box);
|
||||
auto child_rect = absolute_content_rect(box);
|
||||
child_rect.inflate(child_state.border_box_top(), child_state.border_box_right(), child_state.border_box_bottom(), child_state.border_box_left());
|
||||
|
||||
bottom_edge = max(bottom_edge, child_rect.bottom() - 1);
|
||||
|
@ -833,7 +833,7 @@ static void measure_scrollable_overflow(LayoutState const& state, Box const& box
|
|||
}
|
||||
} else {
|
||||
box.for_each_child_of_type<Box>([&](Box const& child) {
|
||||
measure_scrollable_overflow(state, child, bottom_edge, right_edge);
|
||||
measure_scrollable_overflow(child, bottom_edge, right_edge);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
@ -862,7 +862,7 @@ void BlockFormattingContext::layout_viewport(LayoutMode layout_mode, AvailableSp
|
|||
|
||||
CSSPixels bottom_edge = 0;
|
||||
CSSPixels right_edge = 0;
|
||||
measure_scrollable_overflow(m_state, viewport, bottom_edge, right_edge);
|
||||
measure_scrollable_overflow(viewport, bottom_edge, right_edge);
|
||||
|
||||
if (bottom_edge >= viewport_rect.height() || right_edge >= viewport_rect.width()) {
|
||||
// FIXME: Move overflow data to LayoutState!
|
||||
|
@ -906,7 +906,7 @@ void BlockFormattingContext::layout_floating_box(Box const& box, BlockContainer
|
|||
offset_from_edge = box_state.content_width() + box_state.margin_box_right();
|
||||
};
|
||||
|
||||
auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(box, root(), m_state);
|
||||
auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(box, root());
|
||||
CSSPixels y_in_root = box_in_root_rect.y();
|
||||
CSSPixels y = box_state.offset.y();
|
||||
|
||||
|
@ -927,7 +927,7 @@ void BlockFormattingContext::layout_floating_box(Box const& box, BlockContainer
|
|||
// Walk all currently tracked floats on the side we're floating towards.
|
||||
// We're looking for the innermost preceding float that intersects vertically with `box`.
|
||||
for (auto& preceding_float : side_data.current_boxes.in_reverse()) {
|
||||
auto const preceding_float_rect = margin_box_rect_in_ancestor_coordinate_space(preceding_float.box, root(), m_state);
|
||||
auto const preceding_float_rect = margin_box_rect_in_ancestor_coordinate_space(preceding_float.box, root());
|
||||
if (!preceding_float_rect.contains_vertically(y_in_root))
|
||||
continue;
|
||||
// We found a preceding float that intersects vertically with the current float.
|
||||
|
@ -1060,7 +1060,7 @@ BlockFormattingContext::SpaceUsedByFloats BlockFormattingContext::space_used_by_
|
|||
auto const& floating_box = *floating_box_ptr;
|
||||
auto const& floating_box_state = m_state.get(floating_box.box);
|
||||
// NOTE: The floating box is *not* in the final horizontal position yet, but the size and vertical position is valid.
|
||||
auto rect = margin_box_rect_in_ancestor_coordinate_space(floating_box.box, root(), m_state);
|
||||
auto rect = margin_box_rect_in_ancestor_coordinate_space(floating_box.box, root());
|
||||
if (rect.contains_vertically(y.value())) {
|
||||
CSSPixels offset_from_containing_block_chain_margins_between_here_and_root = 0;
|
||||
for (auto const* containing_block = floating_box.box->containing_block(); containing_block && containing_block != &root(); containing_block = containing_block->containing_block()) {
|
||||
|
@ -1079,7 +1079,7 @@ BlockFormattingContext::SpaceUsedByFloats BlockFormattingContext::space_used_by_
|
|||
auto const& floating_box = *floating_box_ptr;
|
||||
auto const& floating_box_state = m_state.get(floating_box.box);
|
||||
// NOTE: The floating box is *not* in the final horizontal position yet, but the size and vertical position is valid.
|
||||
auto rect = margin_box_rect_in_ancestor_coordinate_space(floating_box.box, root(), m_state);
|
||||
auto rect = margin_box_rect_in_ancestor_coordinate_space(floating_box.box, root());
|
||||
if (rect.contains_vertically(y.value())) {
|
||||
CSSPixels offset_from_containing_block_chain_margins_between_here_and_root = 0;
|
||||
for (auto const* containing_block = floating_box.box->containing_block(); containing_block && containing_block != &root(); containing_block = containing_block->containing_block()) {
|
||||
|
@ -1099,7 +1099,7 @@ BlockFormattingContext::SpaceUsedByFloats BlockFormattingContext::space_used_by_
|
|||
FormattingContext::SpaceUsedByFloats BlockFormattingContext::intrusion_by_floats_into_box(Box const& box, CSSPixels y_in_box) const
|
||||
{
|
||||
// NOTE: Floats are relative to the BFC root box, not necessarily the containing block of this IFC.
|
||||
auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(box, root(), m_state);
|
||||
auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(box, root());
|
||||
CSSPixels y_in_root = box_in_root_rect.y() + y_in_box;
|
||||
auto space_used_by_floats_in_root = space_used_by_floats(y_in_root);
|
||||
|
||||
|
|
|
@ -72,6 +72,8 @@ private:
|
|||
|
||||
void layout_list_item_marker(ListItemBox const&);
|
||||
|
||||
void measure_scrollable_overflow(Box const&, CSSPixels& bottom_edge, CSSPixels& right_edge) const;
|
||||
|
||||
enum class DidIntroduceClearance {
|
||||
Yes,
|
||||
No,
|
||||
|
|
|
@ -2187,8 +2187,8 @@ CSSPixelPoint FlexFormattingContext::calculate_static_position(Box const& box) c
|
|||
|
||||
auto static_position_offset = is_row_layout() ? CSSPixelPoint { main_offset, cross_offset } : CSSPixelPoint { cross_offset, main_offset };
|
||||
|
||||
auto absolute_position_of_flex_container = absolute_content_rect(flex_container(), m_state).location();
|
||||
auto absolute_position_of_abspos_containing_block = absolute_content_rect(*box.containing_block(), m_state).location();
|
||||
auto absolute_position_of_flex_container = absolute_content_rect(flex_container()).location();
|
||||
auto absolute_position_of_abspos_containing_block = absolute_content_rect(*box.containing_block()).location();
|
||||
auto diff = absolute_position_of_flex_container - absolute_position_of_abspos_containing_block;
|
||||
|
||||
return static_position_offset + diff;
|
||||
|
|
|
@ -355,7 +355,7 @@ CSSPixels FormattingContext::compute_auto_height_for_block_formatting_context_ro
|
|||
for (auto floating_box : m_state.get(root).floating_descendants()) {
|
||||
// NOTE: Floating box coordinates are relative to their own containing block,
|
||||
// which may or may not be the BFC root.
|
||||
auto margin_box = margin_box_rect_in_ancestor_coordinate_space(*floating_box, root, m_state);
|
||||
auto margin_box = margin_box_rect_in_ancestor_coordinate_space(*floating_box, root);
|
||||
CSSPixels floating_box_bottom_margin_edge = margin_box.bottom();
|
||||
if (!bottom.has_value() || floating_box_bottom_margin_edge > bottom.value())
|
||||
bottom = floating_box_bottom_margin_edge;
|
||||
|
@ -913,15 +913,15 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
|
|||
}
|
||||
|
||||
// NOTE: This is different from content_box_rect_in_ancestor_coordinate_space() as this does *not* follow the containing block chain up, but rather the parent() chain.
|
||||
static CSSPixelRect content_box_rect_in_static_position_ancestor_coordinate_space(Box const& box, Box const& ancestor_box, LayoutState const& state)
|
||||
CSSPixelRect FormattingContext::content_box_rect_in_static_position_ancestor_coordinate_space(Box const& box, Box const& ancestor_box) const
|
||||
{
|
||||
auto rect = content_box_rect(box, state);
|
||||
auto rect = content_box_rect(box);
|
||||
if (&box == &ancestor_box)
|
||||
return rect;
|
||||
for (auto const* current = box.parent(); current; current = current->parent()) {
|
||||
if (current == &ancestor_box)
|
||||
return rect;
|
||||
auto const& current_state = state.get(static_cast<Box const&>(*current));
|
||||
auto const& current_state = m_state.get(static_cast<Box const&>(*current));
|
||||
rect.translate_by(current_state.offset);
|
||||
}
|
||||
// If we get here, ancestor_box was not an ancestor of `box`!
|
||||
|
@ -968,7 +968,7 @@ CSSPixelPoint FormattingContext::calculate_static_position(Box const& box) const
|
|||
// We're among block siblings, Y can be calculated easily.
|
||||
y = m_state.get(box).margin_box_top();
|
||||
}
|
||||
auto offset_to_static_parent = content_box_rect_in_static_position_ancestor_coordinate_space(box, *box.containing_block(), m_state);
|
||||
auto offset_to_static_parent = content_box_rect_in_static_position_ancestor_coordinate_space(box, *box.containing_block());
|
||||
return offset_to_static_parent.location().translated(x, y);
|
||||
}
|
||||
|
||||
|
@ -1490,4 +1490,123 @@ bool FormattingContext::can_skip_is_anonymous_text_run(Box& box)
|
|||
return false;
|
||||
}
|
||||
|
||||
CSSPixelRect FormattingContext::absolute_content_rect(Box const& box) const
|
||||
{
|
||||
auto const& box_state = m_state.get(box);
|
||||
CSSPixelRect rect { box_state.offset, { box_state.content_width(), box_state.content_height() } };
|
||||
for (auto* block = box.containing_block(); block; block = block->containing_block())
|
||||
rect.translate_by(m_state.get(*block).offset);
|
||||
return rect;
|
||||
}
|
||||
|
||||
CSSPixels FormattingContext::box_baseline(Box const& box) const
|
||||
{
|
||||
auto const& box_state = m_state.get(box);
|
||||
|
||||
// https://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align
|
||||
auto const& vertical_align = box.computed_values().vertical_align();
|
||||
if (vertical_align.has<CSS::VerticalAlign>()) {
|
||||
switch (vertical_align.get<CSS::VerticalAlign>()) {
|
||||
case CSS::VerticalAlign::Top:
|
||||
// Top: Align the top of the aligned subtree with the top of the line box.
|
||||
return box_state.border_box_top();
|
||||
case CSS::VerticalAlign::Bottom:
|
||||
// Bottom: Align the bottom of the aligned subtree with the bottom of the line box.
|
||||
return box_state.content_height() + box_state.margin_box_top();
|
||||
case CSS::VerticalAlign::TextTop:
|
||||
// TextTop: Align the top of the box with the top of the parent's content area (see 10.6.1).
|
||||
return box.computed_values().font_size();
|
||||
case CSS::VerticalAlign::TextBottom:
|
||||
// TextTop: Align the bottom of the box with the bottom of the parent's content area (see 10.6.1).
|
||||
return box_state.content_height() - (box.containing_block()->font().pixel_metrics().descent * 2);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!box_state.line_boxes.is_empty())
|
||||
return box_state.margin_box_top() + box_state.offset.y() + box_state.line_boxes.last().baseline();
|
||||
if (box.has_children() && !box.children_are_inline()) {
|
||||
auto const* child_box = box.last_child_of_type<Box>();
|
||||
VERIFY(child_box);
|
||||
return box_baseline(*child_box);
|
||||
}
|
||||
return box_state.margin_box_height();
|
||||
}
|
||||
|
||||
CSSPixelRect FormattingContext::margin_box_rect(Box const& box) const
|
||||
{
|
||||
auto const& box_state = m_state.get(box);
|
||||
return {
|
||||
box_state.offset.translated(-box_state.margin_box_left(), -box_state.margin_box_top()),
|
||||
{
|
||||
box_state.margin_box_left() + box_state.content_width() + box_state.margin_box_right(),
|
||||
box_state.margin_box_top() + box_state.content_height() + box_state.margin_box_bottom(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
CSSPixelRect FormattingContext::border_box_rect(Box const& box) const
|
||||
{
|
||||
auto const& box_state = m_state.get(box);
|
||||
return {
|
||||
box_state.offset.translated(-box_state.border_box_left(), -box_state.border_box_top()),
|
||||
{
|
||||
box_state.border_box_left() + box_state.content_width() + box_state.border_box_right(),
|
||||
box_state.border_box_top() + box_state.content_height() + box_state.border_box_bottom(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
CSSPixelRect FormattingContext::border_box_rect_in_ancestor_coordinate_space(Box const& box, Box const& ancestor_box) const
|
||||
{
|
||||
auto rect = border_box_rect(box);
|
||||
if (&box == &ancestor_box)
|
||||
return rect;
|
||||
for (auto const* current = box.containing_block(); current; current = current->containing_block()) {
|
||||
if (current == &ancestor_box)
|
||||
return rect;
|
||||
auto const& current_state = m_state.get(static_cast<Box const&>(*current));
|
||||
rect.translate_by(current_state.offset);
|
||||
}
|
||||
// If we get here, ancestor_box was not a containing block ancestor of `box`!
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
CSSPixelRect FormattingContext::content_box_rect(Box const& box) const
|
||||
{
|
||||
auto const& box_state = m_state.get(box);
|
||||
return CSSPixelRect { box_state.offset, { box_state.content_width(), box_state.content_height() } };
|
||||
}
|
||||
|
||||
CSSPixelRect FormattingContext::content_box_rect_in_ancestor_coordinate_space(Box const& box, Box const& ancestor_box) const
|
||||
{
|
||||
auto rect = content_box_rect(box);
|
||||
if (&box == &ancestor_box)
|
||||
return rect;
|
||||
for (auto const* current = box.containing_block(); current; current = current->containing_block()) {
|
||||
if (current == &ancestor_box)
|
||||
return rect;
|
||||
auto const& current_state = m_state.get(static_cast<Box const&>(*current));
|
||||
rect.translate_by(current_state.offset);
|
||||
}
|
||||
// If we get here, ancestor_box was not a containing block ancestor of `box`!
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
CSSPixelRect FormattingContext::margin_box_rect_in_ancestor_coordinate_space(Box const& box, Box const& ancestor_box) const
|
||||
{
|
||||
auto rect = margin_box_rect(box);
|
||||
if (&box == &ancestor_box)
|
||||
return rect;
|
||||
for (auto const* current = box.containing_block(); current; current = current->containing_block()) {
|
||||
if (current == &ancestor_box)
|
||||
return rect;
|
||||
auto const& current_state = m_state.get(static_cast<Box const&>(*current));
|
||||
rect.translate_by(current_state.offset);
|
||||
}
|
||||
// If we get here, ancestor_box was not a containing block ancestor of `box`!
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -70,6 +70,16 @@ public:
|
|||
|
||||
virtual CSSPixels greatest_child_width(Box const&) const;
|
||||
|
||||
[[nodiscard]] CSSPixelRect absolute_content_rect(Box const&) const;
|
||||
[[nodiscard]] CSSPixelRect margin_box_rect(Box const&) const;
|
||||
[[nodiscard]] CSSPixelRect margin_box_rect_in_ancestor_coordinate_space(Box const&, Box const& ancestor_box) const;
|
||||
[[nodiscard]] CSSPixelRect border_box_rect(Box const&) const;
|
||||
[[nodiscard]] CSSPixelRect border_box_rect_in_ancestor_coordinate_space(Box const&, Box const& ancestor_box) const;
|
||||
[[nodiscard]] CSSPixelRect content_box_rect(Box const&) const;
|
||||
[[nodiscard]] CSSPixelRect content_box_rect_in_ancestor_coordinate_space(Box const&, Box const& ancestor_box) const;
|
||||
[[nodiscard]] CSSPixels box_baseline(Box const&) const;
|
||||
[[nodiscard]] CSSPixelRect content_box_rect_in_static_position_ancestor_coordinate_space(Box const&, Box const& ancestor_box) const;
|
||||
|
||||
[[nodiscard]] CSSPixels containing_block_width_for(Box const&) const;
|
||||
[[nodiscard]] CSSPixels containing_block_height_for(Box const&) const;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ BlockFormattingContext const& InlineFormattingContext::parent() const
|
|||
CSSPixels InlineFormattingContext::leftmost_x_offset_at(CSSPixels y) const
|
||||
{
|
||||
// NOTE: Floats are relative to the BFC root box, not necessarily the containing block of this IFC.
|
||||
auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(containing_block(), parent().root(), m_state);
|
||||
auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(containing_block(), parent().root());
|
||||
CSSPixels y_in_root = box_in_root_rect.y() + y;
|
||||
auto space = parent().space_used_by_floats(y_in_root);
|
||||
if (box_in_root_rect.x() >= space.left) {
|
||||
|
@ -321,7 +321,7 @@ void InlineFormattingContext::generate_line_boxes(LayoutMode layout_mode)
|
|||
|
||||
bool InlineFormattingContext::any_floats_intrude_at_y(CSSPixels y) const
|
||||
{
|
||||
auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(containing_block(), parent().root(), m_state);
|
||||
auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(containing_block(), parent().root());
|
||||
CSSPixels y_in_root = box_in_root_rect.y() + y;
|
||||
auto space = parent().space_used_by_floats(y_in_root);
|
||||
return space.left > 0 || space.right > 0;
|
||||
|
|
|
@ -107,125 +107,6 @@ void LayoutState::commit()
|
|||
text_node->set_paintable(text_node->create_paintable());
|
||||
}
|
||||
|
||||
CSSPixels box_baseline(LayoutState const& state, Box const& box)
|
||||
{
|
||||
auto const& box_state = state.get(box);
|
||||
|
||||
// https://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align
|
||||
auto const& vertical_align = box.computed_values().vertical_align();
|
||||
if (vertical_align.has<CSS::VerticalAlign>()) {
|
||||
switch (vertical_align.get<CSS::VerticalAlign>()) {
|
||||
case CSS::VerticalAlign::Top:
|
||||
// Top: Align the top of the aligned subtree with the top of the line box.
|
||||
return box_state.border_box_top();
|
||||
case CSS::VerticalAlign::Bottom:
|
||||
// Bottom: Align the bottom of the aligned subtree with the bottom of the line box.
|
||||
return box_state.content_height() + box_state.margin_box_top();
|
||||
case CSS::VerticalAlign::TextTop:
|
||||
// TextTop: Align the top of the box with the top of the parent's content area (see 10.6.1).
|
||||
return box.computed_values().font_size();
|
||||
case CSS::VerticalAlign::TextBottom:
|
||||
// TextTop: Align the bottom of the box with the bottom of the parent's content area (see 10.6.1).
|
||||
return box_state.content_height() - (box.containing_block()->font().pixel_metrics().descent * 2);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!box_state.line_boxes.is_empty())
|
||||
return box_state.margin_box_top() + box_state.offset.y() + box_state.line_boxes.last().baseline();
|
||||
if (box.has_children() && !box.children_are_inline()) {
|
||||
auto const* child_box = box.last_child_of_type<Box>();
|
||||
VERIFY(child_box);
|
||||
return box_baseline(state, *child_box);
|
||||
}
|
||||
return box_state.margin_box_height();
|
||||
}
|
||||
|
||||
CSSPixelRect margin_box_rect(Box const& box, LayoutState const& state)
|
||||
{
|
||||
auto const& box_state = state.get(box);
|
||||
return {
|
||||
box_state.offset.translated(-box_state.margin_box_left(), -box_state.margin_box_top()),
|
||||
{
|
||||
box_state.margin_box_left() + box_state.content_width() + box_state.margin_box_right(),
|
||||
box_state.margin_box_top() + box_state.content_height() + box_state.margin_box_bottom(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
CSSPixelRect border_box_rect(Box const& box, LayoutState const& state)
|
||||
{
|
||||
auto const& box_state = state.get(box);
|
||||
return {
|
||||
box_state.offset.translated(-box_state.border_box_left(), -box_state.border_box_top()),
|
||||
{
|
||||
box_state.border_box_left() + box_state.content_width() + box_state.border_box_right(),
|
||||
box_state.border_box_top() + box_state.content_height() + box_state.border_box_bottom(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
CSSPixelRect border_box_rect_in_ancestor_coordinate_space(Box const& box, Box const& ancestor_box, LayoutState const& state)
|
||||
{
|
||||
auto rect = border_box_rect(box, state);
|
||||
if (&box == &ancestor_box)
|
||||
return rect;
|
||||
for (auto const* current = box.containing_block(); current; current = current->containing_block()) {
|
||||
if (current == &ancestor_box)
|
||||
return rect;
|
||||
auto const& current_state = state.get(static_cast<Box const&>(*current));
|
||||
rect.translate_by(current_state.offset);
|
||||
}
|
||||
// If we get here, ancestor_box was not a containing block ancestor of `box`!
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
CSSPixelRect content_box_rect(Box const& box, LayoutState const& state)
|
||||
{
|
||||
auto const& box_state = state.get(box);
|
||||
return CSSPixelRect { box_state.offset, { box_state.content_width(), box_state.content_height() } };
|
||||
}
|
||||
|
||||
CSSPixelRect content_box_rect_in_ancestor_coordinate_space(Box const& box, Box const& ancestor_box, LayoutState const& state)
|
||||
{
|
||||
auto rect = content_box_rect(box, state);
|
||||
if (&box == &ancestor_box)
|
||||
return rect;
|
||||
for (auto const* current = box.containing_block(); current; current = current->containing_block()) {
|
||||
if (current == &ancestor_box)
|
||||
return rect;
|
||||
auto const& current_state = state.get(static_cast<Box const&>(*current));
|
||||
rect.translate_by(current_state.offset);
|
||||
}
|
||||
// If we get here, ancestor_box was not a containing block ancestor of `box`!
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
CSSPixelRect margin_box_rect_in_ancestor_coordinate_space(Box const& box, Box const& ancestor_box, LayoutState const& state)
|
||||
{
|
||||
auto rect = margin_box_rect(box, state);
|
||||
if (&box == &ancestor_box)
|
||||
return rect;
|
||||
for (auto const* current = box.containing_block(); current; current = current->containing_block()) {
|
||||
if (current == &ancestor_box)
|
||||
return rect;
|
||||
auto const& current_state = state.get(static_cast<Box const&>(*current));
|
||||
rect.translate_by(current_state.offset);
|
||||
}
|
||||
// If we get here, ancestor_box was not a containing block ancestor of `box`!
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
CSSPixelRect absolute_content_rect(Box const& box, LayoutState const& state)
|
||||
{
|
||||
auto const& box_state = state.get(box);
|
||||
CSSPixelRect rect { box_state.offset, { box_state.content_width(), box_state.content_height() } };
|
||||
for (auto* block = box.containing_block(); block; block = block->containing_block())
|
||||
rect.translate_by(state.get(*block).offset);
|
||||
return rect;
|
||||
}
|
||||
|
||||
void LayoutState::UsedValues::set_node(NodeWithStyleAndBoxModelMetrics& node, UsedValues const* containing_block_used_values)
|
||||
{
|
||||
m_node = &node;
|
||||
|
|
|
@ -173,13 +173,4 @@ struct LayoutState {
|
|||
LayoutState const& m_root;
|
||||
};
|
||||
|
||||
CSSPixelRect absolute_content_rect(Box const&, LayoutState const&);
|
||||
CSSPixelRect margin_box_rect(Box const&, LayoutState const&);
|
||||
CSSPixelRect margin_box_rect_in_ancestor_coordinate_space(Box const& box, Box const& ancestor_box, LayoutState const&);
|
||||
CSSPixelRect border_box_rect(Box const&, LayoutState const&);
|
||||
CSSPixelRect border_box_rect_in_ancestor_coordinate_space(Box const& box, Box const& ancestor_box, LayoutState const&);
|
||||
CSSPixelRect content_box_rect(Box const&, LayoutState const&);
|
||||
CSSPixelRect content_box_rect_in_ancestor_coordinate_space(Box const& box, Box const& ancestor_box, LayoutState const&);
|
||||
CSSPixels box_baseline(LayoutState const& state, Box const& box);
|
||||
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ void LineBuilder::update_last_line()
|
|||
fragment_baseline = CSSPixels(font_metrics.ascent) + half_leading;
|
||||
} else {
|
||||
auto const& box = verify_cast<Layout::Box>(fragment.layout_node());
|
||||
fragment_baseline = box_baseline(m_layout_state, box);
|
||||
fragment_baseline = m_context.box_baseline(box);
|
||||
}
|
||||
|
||||
// Remember the baseline used for this fragment. This will be used when painting the fragment.
|
||||
|
|
|
@ -476,7 +476,7 @@ void TableFormattingContext::compute_table_height(LayoutMode layout_mode)
|
|||
independent_formatting_context->parent_context_did_dimension_child_root_box();
|
||||
}
|
||||
|
||||
cell.baseline = box_baseline(m_state, cell.box);
|
||||
cell.baseline = box_baseline(cell.box);
|
||||
|
||||
// Only cells spanning the current row exclusively are part of computing minimum height of a row,
|
||||
// as described in https://www.w3.org/TR/css-tables-3/#computing-the-table-height
|
||||
|
@ -554,7 +554,7 @@ void TableFormattingContext::compute_table_height(LayoutMode layout_mode)
|
|||
independent_formatting_context->parent_context_did_dimension_child_root_box();
|
||||
}
|
||||
|
||||
cell.baseline = box_baseline(m_state, cell.box);
|
||||
cell.baseline = box_baseline(cell.box);
|
||||
|
||||
row.reference_height = max(row.reference_height, cell_state.border_box_height());
|
||||
row.baseline = max(row.baseline, cell.baseline);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue