1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 14:38:11 +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:
Andreas Kling 2023-05-31 10:18:34 +02:00
parent 4f08fcde29
commit 42470d837e
10 changed files with 155 additions and 152 deletions

View file

@ -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;