LibWeb: Add accessors for UsedValues::computed_{width,height}

This is preparation for doing some more work when assigning to these
values.
This commit is contained in:
Andreas Kling 2022-07-17 17:59:02 +02:00
parent c12c9eed38
commit ed8930fff5
Notes: sideshowbarker 2024-07-17 08:45:44 +09:00
11 changed files with 155 additions and 137 deletions

View File

@ -620,8 +620,8 @@ void Document::update_layout()
auto& icb = static_cast<Layout::InitialContainingBlock&>(*m_layout_root);
auto& icb_state = layout_state.get_mutable(icb);
icb_state.content_width = viewport_rect.width();
icb_state.content_height = viewport_rect.height();
icb_state.set_content_width(viewport_rect.width());
icb_state.set_content_height(viewport_rect.height());
icb.set_has_definite_width(true);
icb.set_has_definite_height(true);

View File

@ -222,7 +222,7 @@ void BlockFormattingContext::compute_width(Box const& box, LayoutMode layout_mod
auto& box_state = m_state.get_mutable(box);
if (!is<ReplacedBox>(box))
box_state.content_width = used_width.to_px(box);
box_state.set_content_width(used_width.to_px(box));
box_state.margin_left = margin_left.to_px(box);
box_state.margin_right = margin_right.to_px(box);
@ -294,7 +294,7 @@ void BlockFormattingContext::compute_width_for_floating_box(Box const& box, Layo
}
auto& box_state = m_state.get_mutable(box);
box_state.content_width = width.to_px(box);
box_state.set_content_width(width.to_px(box));
box_state.margin_left = margin_left.to_px(box);
box_state.margin_right = margin_right.to_px(box);
box_state.border_left = computed_values.border_left().width;
@ -305,7 +305,7 @@ void BlockFormattingContext::compute_width_for_floating_box(Box const& box, Layo
void BlockFormattingContext::compute_width_for_block_level_replaced_element_in_normal_flow(ReplacedBox const& box)
{
m_state.get_mutable(box).content_width = compute_width_for_replaced_element(m_state, box);
m_state.get_mutable(box).set_content_width(compute_width_for_replaced_element(m_state, box));
}
float BlockFormattingContext::compute_theoretical_height(LayoutState const& state, Box const& box)
@ -359,7 +359,7 @@ void BlockFormattingContext::compute_height(Box const& box, LayoutState& state)
box_state.padding_top = computed_values.padding().top.resolved(box, width_of_containing_block_as_length).to_px(box);
box_state.padding_bottom = computed_values.padding().bottom.resolved(box, width_of_containing_block_as_length).to_px(box);
box_state.content_height = compute_theoretical_height(state, box);
box_state.set_content_height(compute_theoretical_height(state, box));
}
void BlockFormattingContext::layout_inline_children(BlockContainer const& block_container, LayoutMode layout_mode)
@ -370,9 +370,9 @@ void BlockFormattingContext::layout_inline_children(BlockContainer const& block_
if (layout_mode == LayoutMode::IntrinsicSizeDetermination) {
if (block_container.computed_values().width().is_auto() || block_container_state.width_constraint != SizeConstraint::None)
block_container_state.content_width = containing_block_width_for(block_container);
block_container_state.set_content_width(containing_block_width_for(block_container));
if (block_container.computed_values().height().is_auto() || block_container_state.height_constraint != SizeConstraint::None)
block_container_state.content_height = containing_block_height_for(block_container);
block_container_state.set_content_height(containing_block_height_for(block_container));
}
InlineFormattingContext context(m_state, block_container, *this);
@ -388,11 +388,11 @@ void BlockFormattingContext::layout_inline_children(BlockContainer const& block_
if (layout_mode == LayoutMode::IntrinsicSizeDetermination) {
if (block_container.computed_values().width().is_auto() || block_container_state.width_constraint != SizeConstraint::None)
block_container_state.content_width = max_line_width;
block_container_state.set_content_width(max_line_width);
}
// FIXME: This is weird. Figure out a way to make callers responsible for setting the content height.
block_container_state.content_height = content_height;
block_container_state.set_content_height(content_height);
}
void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContainer const& block_container, LayoutMode layout_mode, float& content_height)
@ -410,7 +410,7 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain
if (box.is_floating()) {
layout_floating_box(box, block_container, layout_mode);
content_height = max(content_height, box_state.offset.y() + box_state.content_height + box_state.margin_box_bottom());
content_height = max(content_height, box_state.offset.y() + box_state.content_height() + box_state.margin_box_bottom());
return;
}
@ -446,7 +446,7 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain
layout_list_item_marker(static_cast<ListItemBox const&>(box));
}
content_height = max(content_height, box_state.offset.y() + box_state.content_height + box_state.margin_box_bottom());
content_height = max(content_height, box_state.offset.y() + box_state.content_height() + box_state.margin_box_bottom());
if (independent_formatting_context)
independent_formatting_context->parent_context_did_dimension_child_root_box();
@ -457,10 +457,10 @@ void BlockFormattingContext::run_intrinsic_size_determination(Box const& box)
auto& box_state = m_state.get_mutable(box);
if (box.has_definite_width())
box_state.content_width = box.computed_values().width().resolved(box, CSS::Length::make_px(containing_block_width_for(box))).to_px(box);
box_state.set_content_width(box.computed_values().width().resolved(box, CSS::Length::make_px(containing_block_width_for(box))).to_px(box));
if (box.has_definite_height())
box_state.content_height = box.computed_values().height().resolved(box, CSS::Length::make_px(containing_block_height_for(box))).to_px(box);
box_state.set_content_height(box.computed_values().height().resolved(box, CSS::Length::make_px(containing_block_height_for(box))).to_px(box));
run(box, LayoutMode::IntrinsicSizeDetermination);
}
@ -474,9 +474,9 @@ void BlockFormattingContext::layout_block_level_children(BlockContainer const& b
if (layout_mode == LayoutMode::IntrinsicSizeDetermination) {
auto& block_container_state = m_state.get_mutable(block_container);
if (block_container.computed_values().width().is_auto() || block_container_state.width_constraint != SizeConstraint::None)
block_container_state.content_width = containing_block_width_for(block_container);
block_container_state.set_content_width(containing_block_width_for(block_container));
if (block_container.computed_values().height().is_auto() || block_container_state.height_constraint != SizeConstraint::None)
block_container_state.content_height = containing_block_height_for(block_container);
block_container_state.set_content_height(containing_block_height_for(block_container));
}
block_container.for_each_child_of_type<Box>([&](Box& box) {
@ -487,9 +487,9 @@ void BlockFormattingContext::layout_block_level_children(BlockContainer const& b
if (layout_mode == LayoutMode::IntrinsicSizeDetermination) {
auto& block_container_state = m_state.get_mutable(block_container);
if (block_container.computed_values().width().is_auto() || block_container_state.width_constraint != SizeConstraint::None)
block_container_state.content_width = greatest_child_width(block_container);
block_container_state.set_content_width(greatest_child_width(block_container));
if (block_container.computed_values().height().is_auto() || block_container_state.height_constraint != SizeConstraint::None)
block_container_state.content_height = content_height;
block_container_state.set_content_height(content_height);
}
}
@ -559,7 +559,7 @@ void BlockFormattingContext::place_block_level_element_in_normal_flow_vertically
auto const& relevant_sibling_state = m_state.get(*relevant_sibling);
y += relevant_sibling_state.offset.y()
+ relevant_sibling_state.content_height
+ relevant_sibling_state.content_height()
+ relevant_sibling_state.border_box_bottom()
+ collapsed_margin;
} else {
@ -601,7 +601,7 @@ void BlockFormattingContext::place_block_level_element_in_normal_flow_horizontal
}
if (containing_block.computed_values().text_align() == CSS::TextAlign::LibwebCenter) {
x += (available_width_within_containing_block / 2) - box_state.content_width / 2;
x += (available_width_within_containing_block / 2) - box_state.content_width() / 2;
} else {
x += box_state.margin_box_left();
}
@ -682,7 +682,7 @@ void BlockFormattingContext::layout_floating_box(Box const& box, BlockContainer
if (side == FloatSide::Left)
offset_from_edge = box_state.margin_box_left();
else
offset_from_edge = box_state.content_width + box_state.margin_box_right();
offset_from_edge = box_state.content_width() + box_state.margin_box_right();
};
auto box_in_root_rect = margin_box_rect_in_ancestor_coordinate_space(box, root(), m_state);
@ -701,9 +701,9 @@ void BlockFormattingContext::layout_floating_box(Box const& box, BlockContainer
if (side == FloatSide::Left) {
wanted_offset_from_edge = side_data.current_width + box_state.margin_box_left();
fits_on_line = (wanted_offset_from_edge + box_state.content_width + box_state.margin_box_right()) <= width_of_containing_block;
fits_on_line = (wanted_offset_from_edge + box_state.content_width() + box_state.margin_box_right()) <= width_of_containing_block;
} else {
wanted_offset_from_edge = side_data.current_width + box_state.margin_box_right() + box_state.content_width;
wanted_offset_from_edge = side_data.current_width + box_state.margin_box_right() + box_state.content_width();
fits_on_line = (wanted_offset_from_edge - box_state.margin_box_left()) >= 0;
}
@ -739,12 +739,12 @@ void BlockFormattingContext::layout_floating_box(Box const& box, BlockContainer
.box = box,
.offset_from_edge = offset_from_edge,
.top_margin_edge = y - box_state.margin_box_top(),
.bottom_margin_edge = y + box_state.content_height + box_state.margin_box_bottom(),
.bottom_margin_edge = y + box_state.content_height() + box_state.margin_box_bottom(),
}));
side_data.current_boxes.append(*side_data.all_boxes.last());
if (side == FloatSide::Left) {
side_data.current_width = offset_from_edge + box_state.content_width + box_state.margin_box_right();
side_data.current_width = offset_from_edge + box_state.content_width() + box_state.margin_box_right();
} else {
side_data.current_width = offset_from_edge + box_state.margin_box_left();
}
@ -782,21 +782,21 @@ void BlockFormattingContext::layout_list_item_marker(ListItemBox const& list_ite
int default_marker_width = max(4, marker.font().glyph_height() - 4);
if (marker.text().is_empty()) {
marker_state.content_width = image_width + default_marker_width;
marker_state.set_content_width(image_width + default_marker_width);
} else {
auto text_width = marker.font().width(marker.text());
marker_state.content_width = image_width + text_width;
marker_state.set_content_width(image_width + text_width);
}
marker_state.content_height = max(image_height, marker.font().glyph_height() + 1);
marker_state.set_content_height(max(image_height, marker.font().glyph_height() + 1));
marker_state.offset = {
-(marker_state.content_width + default_marker_width),
max(0.f, (marker.line_height() - marker_state.content_height) / 2.f)
-(marker_state.content_width() + default_marker_width),
max(0.f, (marker.line_height() - marker_state.content_height()) / 2.f)
};
if (marker_state.content_height > list_item_state.content_height)
list_item_state.content_height = marker_state.content_height;
if (marker_state.content_height() > list_item_state.content_height())
list_item_state.set_content_height(marker_state.content_height());
}
BlockFormattingContext::SpaceUsedByFloats BlockFormattingContext::space_used_by_floats(float y) const
@ -809,7 +809,7 @@ BlockFormattingContext::SpaceUsedByFloats BlockFormattingContext::space_used_by_
auto rect = margin_box_rect_in_ancestor_coordinate_space(floating_box.box, root(), m_state);
if (rect.contains_vertically(y)) {
space_used_by_floats.left = floating_box.offset_from_edge
+ floating_box_state.content_width
+ floating_box_state.content_width()
+ floating_box_state.margin_box_right();
break;
}
@ -841,7 +841,7 @@ float BlockFormattingContext::greatest_child_width(Box const& box)
for (auto& left_float : m_left_floats.all_boxes) {
if (line_box.baseline() >= left_float->top_margin_edge || line_box.baseline() <= left_float->bottom_margin_edge) {
auto const& left_float_state = m_state.get(left_float->box);
extra_width_from_left_floats = max(extra_width_from_left_floats, left_float->offset_from_edge + left_float_state.content_width + left_float_state.margin_box_right());
extra_width_from_left_floats = max(extra_width_from_left_floats, left_float->offset_from_edge + left_float_state.content_width() + left_float_state.margin_box_right());
}
}
float extra_width_from_right_floats = 0;

View File

@ -31,7 +31,7 @@ static float get_pixel_size(LayoutState const& state, Box const& box, Optional<C
{
if (!length_percentage.has_value())
return 0;
auto inner_main_size = CSS::Length::make_px(state.get(*box.containing_block()).content_width);
auto inner_main_size = CSS::Length::make_px(state.get(*box.containing_block()).content_width());
return length_percentage->resolved(box, inner_main_size).to_px(box);
}
@ -145,7 +145,7 @@ void FlexFormattingContext::run(Box const& run_box, LayoutMode layout_mode)
void FlexFormattingContext::populate_specified_margins(FlexItem& item, CSS::FlexDirection flex_direction) const
{
auto width_of_containing_block = m_state.get(*item.box.containing_block()).content_width;
auto width_of_containing_block = m_state.get(*item.box.containing_block()).content_width();
auto width_of_containing_block_as_length = CSS::Length::make_px(width_of_containing_block);
// FIXME: This should also take reverse-ness into account
if (flex_direction == CSS::FlexDirection::Row || flex_direction == CSS::FlexDirection::RowReverse) {
@ -264,13 +264,13 @@ bool FlexFormattingContext::has_definite_main_size(Box const& box) const
float FlexFormattingContext::specified_main_size(Box const& box) const
{
auto const& box_state = m_state.get(box);
return is_row_layout() ? box_state.content_width : box_state.content_height;
return is_row_layout() ? box_state.content_width() : box_state.content_height();
}
float FlexFormattingContext::specified_cross_size(Box const& box) const
{
auto const& box_state = m_state.get(box);
return is_row_layout() ? box_state.content_height : box_state.content_width;
return is_row_layout() ? box_state.content_height() : box_state.content_width();
}
float FlexFormattingContext::resolved_definite_cross_size(Box const& box) const
@ -364,7 +364,7 @@ float FlexFormattingContext::specified_cross_max_size(Box const& box) const
float FlexFormattingContext::calculated_main_size(Box const& box) const
{
auto const& box_state = m_state.get(box);
return is_row_layout() ? box_state.content_width : box_state.content_height;
return is_row_layout() ? box_state.content_width() : box_state.content_height();
}
bool FlexFormattingContext::is_cross_auto(Box const& box) const
@ -390,17 +390,17 @@ bool FlexFormattingContext::is_main_axis_margin_second_auto(Box const& box) cons
void FlexFormattingContext::set_main_size(Box const& box, float size)
{
if (is_row_layout())
m_state.get_mutable(box).content_width = size;
m_state.get_mutable(box).set_content_width(size);
else
m_state.get_mutable(box).content_height = size;
m_state.get_mutable(box).set_content_height(size);
}
void FlexFormattingContext::set_cross_size(Box const& box, float size)
{
if (is_row_layout())
m_state.get_mutable(box).content_height = size;
m_state.get_mutable(box).set_content_height(size);
else
m_state.get_mutable(box).content_width = size;
m_state.get_mutable(box).set_content_width(size);
}
void FlexFormattingContext::set_offset(Box const& box, float main_offset, float cross_offset)
@ -534,7 +534,7 @@ float FlexFormattingContext::calculate_indefinite_main_size(FlexItem const& item
// NOTE: Flex items should always create an independent formatting context!
VERIFY(independent_formatting_context);
box_state.content_width = fit_content_cross_size;
box_state.set_content_width(fit_content_cross_size);
independent_formatting_context->run(item.box, LayoutMode::Normal);
return BlockFormattingContext::compute_theoretical_height(throwaway_state, item.box);
@ -985,16 +985,16 @@ void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem&
VERIFY(independent_formatting_context);
if (is_row_layout()) {
box_state.content_width = resolved_definite_main_size(item.box);
box_state.set_content_width(resolved_definite_main_size(item.box));
} else {
box_state.content_height = resolved_definite_main_size(item.box);
box_state.set_content_height(resolved_definite_main_size(item.box));
}
independent_formatting_context->run(item.box, LayoutMode::Normal);
if (is_row_layout())
item.hypothetical_cross_size = BlockFormattingContext::compute_theoretical_height(throwaway_state, item.box);
else
item.hypothetical_cross_size = box_state.content_width;
item.hypothetical_cross_size = box_state.content_width();
} else {
// Item has indefinite main size, layout with "fit-content"
item.hypothetical_cross_size = calculate_fit_content_cross_size(item);
@ -1165,7 +1165,7 @@ void FlexFormattingContext::distribute_any_remaining_free_space()
void FlexFormattingContext::dump_items() const
{
dbgln("\033[34;1mflex-container\033[0m {}, direction: {}, current-size: {}x{}", flex_container().debug_description(), is_row_layout() ? "row" : "column", m_flex_container_state.content_width, m_flex_container_state.content_height);
dbgln("\033[34;1mflex-container\033[0m {}, direction: {}, current-size: {}x{}", flex_container().debug_description(), is_row_layout() ? "row" : "column", m_flex_container_state.content_width(), m_flex_container_state.content_height());
for (size_t i = 0; i < m_flex_lines.size(); ++i) {
dbgln("{} flex-line #{}:", flex_container().debug_description(), i);
for (size_t j = 0; j < m_flex_lines[i].items.size(); ++j) {
@ -1296,15 +1296,15 @@ void FlexFormattingContext::copy_dimensions_from_flex_items_to_boxes()
auto const& box = flex_item.box;
auto& box_state = m_state.get_mutable(box);
box_state.padding_left = box.computed_values().padding().left.resolved(box, CSS::Length::make_px(m_flex_container_state.content_width)).to_px(box);
box_state.padding_right = box.computed_values().padding().right.resolved(box, CSS::Length::make_px(m_flex_container_state.content_width)).to_px(box);
box_state.padding_top = box.computed_values().padding().top.resolved(box, CSS::Length::make_px(m_flex_container_state.content_width)).to_px(box);
box_state.padding_bottom = box.computed_values().padding().bottom.resolved(box, CSS::Length::make_px(m_flex_container_state.content_width)).to_px(box);
box_state.padding_left = box.computed_values().padding().left.resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.padding_right = box.computed_values().padding().right.resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.padding_top = box.computed_values().padding().top.resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.padding_bottom = box.computed_values().padding().bottom.resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.margin_left = box.computed_values().margin().left.resolved(box, CSS::Length::make_px(m_flex_container_state.content_width)).to_px(box);
box_state.margin_right = box.computed_values().margin().right.resolved(box, CSS::Length::make_px(m_flex_container_state.content_width)).to_px(box);
box_state.margin_top = box.computed_values().margin().top.resolved(box, CSS::Length::make_px(m_flex_container_state.content_width)).to_px(box);
box_state.margin_bottom = box.computed_values().margin().bottom.resolved(box, CSS::Length::make_px(m_flex_container_state.content_width)).to_px(box);
box_state.margin_left = box.computed_values().margin().left.resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.margin_right = box.computed_values().margin().right.resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.margin_top = box.computed_values().margin().top.resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.margin_bottom = box.computed_values().margin().bottom.resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.border_left = box.computed_values().border_left().width;
box_state.border_right = box.computed_values().border_right().width;
@ -1325,11 +1325,11 @@ void FlexFormattingContext::determine_intrinsic_size_of_flex_container(LayoutMod
float main_size = calculate_intrinsic_main_size_of_flex_container(layout_mode);
float cross_size = calculate_intrinsic_cross_size_of_flex_container(layout_mode);
if (is_row_layout()) {
m_flex_container_state.content_width = main_size;
m_flex_container_state.content_height = cross_size;
m_flex_container_state.set_content_width(main_size);
m_flex_container_state.set_content_height(cross_size);
} else {
m_flex_container_state.content_height = main_size;
m_flex_container_state.content_width = cross_size;
m_flex_container_state.set_content_height(main_size);
m_flex_container_state.set_content_width(cross_size);
}
}

View File

@ -33,10 +33,10 @@ void FormattingContext::run_intrinsic_size_determination(Box const& box)
auto& box_state = m_state.get_mutable(box);
if (box.has_definite_width())
box_state.content_width = box.computed_values().width().resolved(box, CSS::Length::make_px(containing_block_width_for(box))).to_px(box);
box_state.set_content_width(box.computed_values().width().resolved(box, CSS::Length::make_px(containing_block_width_for(box))).to_px(box));
if (box.has_definite_height())
box_state.content_height = box.computed_values().height().resolved(box, CSS::Length::make_px(containing_block_height_for(box))).to_px(box);
box_state.set_content_height(box.computed_values().height().resolved(box, CSS::Length::make_px(containing_block_height_for(box))).to_px(box));
run(box, LayoutMode::IntrinsicSizeDetermination);
}
@ -187,8 +187,8 @@ static Gfx::FloatSize solve_replaced_size_constraint(LayoutState const& state, f
auto const& containing_block = *box.containing_block();
auto const& containing_block_state = state.get(containing_block);
auto width_of_containing_block = CSS::Length::make_px(containing_block_state.content_width);
auto height_of_containing_block = CSS::Length::make_px(containing_block_state.content_height);
auto width_of_containing_block = CSS::Length::make_px(containing_block_state.content_width());
auto height_of_containing_block = CSS::Length::make_px(containing_block_state.content_height());
auto specified_min_width = box.computed_values().min_width().is_auto() ? 0 : box.computed_values().min_width().resolved(box, width_of_containing_block).to_px(box);
auto specified_max_width = box.computed_values().max_width().is_auto() ? w : box.computed_values().max_width().resolved(box, width_of_containing_block).to_px(box);
@ -232,7 +232,7 @@ float FormattingContext::compute_auto_height_for_block_level_element(LayoutState
auto display = box.computed_values().display();
if (display.is_flex_inside())
return box_state.content_height;
return box_state.content_height();
// https://www.w3.org/TR/CSS22/visudet.html#normal-block
// 10.6.3 Block-level non-replaced elements in normal flow when 'overflow' computes to 'visible'
@ -263,7 +263,7 @@ float FormattingContext::compute_auto_height_for_block_level_element(LayoutState
continue;
// FIXME: Handle margin collapsing.
return max(0, child_box_state.offset.y() + child_box_state.content_height + child_box_state.margin_box_bottom());
return max(0, child_box_state.offset.y() + child_box_state.content_height() + child_box_state.margin_box_bottom());
}
}
@ -303,7 +303,7 @@ float FormattingContext::compute_auto_height_for_block_formatting_context_root(L
auto const& child_box_state = state.get(child_box);
float child_box_top = child_box_state.offset.y() - child_box_state.margin_box_top();
float child_box_bottom = child_box_state.offset.y() + child_box_state.content_height + child_box_state.margin_box_bottom();
float child_box_bottom = child_box_state.offset.y() + child_box_state.content_height() + child_box_state.margin_box_bottom();
if (!top.has_value() || child_box_top < top.value())
top = child_box_top;
@ -323,7 +323,7 @@ float FormattingContext::compute_auto_height_for_block_formatting_context_root(L
return IterationDecision::Continue;
auto const& child_box_state = state.get(child_box);
float child_box_bottom = child_box_state.offset.y() + child_box_state.content_height + child_box_state.margin_box_bottom();
float child_box_bottom = child_box_state.offset.y() + child_box_state.content_height() + child_box_state.margin_box_bottom();
if (!bottom.has_value() || child_box_bottom > bottom.value())
bottom = child_box_bottom;
@ -338,7 +338,7 @@ float FormattingContext::compute_auto_height_for_block_formatting_context_root(L
float FormattingContext::tentative_width_for_replaced_element(LayoutState const& state, ReplacedBox const& box, CSS::LengthPercentage const& computed_width)
{
auto const& containing_block = *box.containing_block();
auto height_of_containing_block = CSS::Length::make_px(state.get(containing_block).content_height);
auto height_of_containing_block = CSS::Length::make_px(state.get(containing_block).content_height());
auto computed_height = box.computed_values().height().resolved(box, height_of_containing_block).resolved(box);
float used_width = computed_width.resolved(box, CSS::Length::make_px(containing_block_width_for(box, state))).to_px(box);
@ -618,7 +618,7 @@ void FormattingContext::compute_width_for_absolutely_positioned_non_replaced_ele
}
auto& box_state = m_state.get_mutable(box);
box_state.content_width = used_width.to_px(box);
box_state.set_content_width(used_width.to_px(box));
box_state.margin_left = margin_left.to_px(box);
box_state.margin_right = margin_right.to_px(box);
@ -634,7 +634,7 @@ void FormattingContext::compute_width_for_absolutely_positioned_replaced_element
// The used value of 'width' is determined as for inline replaced elements.
// FIXME: This const_cast is gross.
const_cast<ReplacedBox&>(box).prepare_for_replaced_layout();
m_state.get_mutable(box).content_width = compute_width_for_replaced_element(m_state, box);
m_state.get_mutable(box).set_content_width(compute_width_for_replaced_element(m_state, box));
}
// https://www.w3.org/TR/CSS22/visudet.html#abs-non-replaced-height
@ -691,7 +691,7 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
used_height = min(used_height, specified_max_height.to_px(box));
if (!specified_min_height.is_auto())
used_height = max(used_height, specified_min_height.to_px(box));
box_state.content_height = used_height;
box_state.set_content_height(used_height);
}
}
@ -745,7 +745,7 @@ void FormattingContext::layout_absolutely_positioned_element(Box const& box)
float x_offset = 0
- box_state.inset_right
- box_state.border_box_right();
used_offset.set_x(width_of_containing_block + x_offset - box_state.content_width - box_state.margin_right);
used_offset.set_x(width_of_containing_block + x_offset - box_state.content_width() - box_state.margin_right);
} else {
float x_offset = box_state.margin_box_left();
used_offset.set_x(x_offset);
@ -759,7 +759,7 @@ void FormattingContext::layout_absolutely_positioned_element(Box const& box)
float y_offset = 0
- box_state.inset_bottom
- box_state.border_box_bottom();
used_offset.set_y(height_of_containing_block + y_offset - box_state.content_height - box_state.margin_bottom);
used_offset.set_y(height_of_containing_block + y_offset - box_state.content_height() - box_state.margin_bottom);
} else {
float y_offset = box_state.margin_box_top();
used_offset.set_y(y_offset);
@ -775,7 +775,7 @@ void FormattingContext::compute_height_for_absolutely_positioned_replaced_elemen
{
// 10.6.5 Absolutely positioned, replaced elements
// The used value of 'height' is determined as for inline replaced elements.
m_state.get_mutable(box).content_height = compute_height_for_replaced_element(m_state, box);
m_state.get_mutable(box).set_content_height(compute_height_for_replaced_element(m_state, box));
}
// https://www.w3.org/TR/css-position-3/#relpos-insets
@ -868,10 +868,10 @@ float FormattingContext::calculate_min_content_width(Layout::Box const& box) con
LayoutState throwaway_state(&m_state);
auto const& containing_block = *box.containing_block();
auto& containing_block_state = throwaway_state.get_mutable(containing_block);
containing_block_state.content_width = 0;
containing_block_state.set_content_width(0);
if (!containing_block.has_definite_height())
containing_block_state.content_height = INFINITY;
containing_block_state.set_content_height(INFINITY);
auto& box_state = throwaway_state.get_mutable(box);
box_state.width_constraint = SizeConstraint::MinContent;
@ -880,7 +880,7 @@ float FormattingContext::calculate_min_content_width(Layout::Box const& box) con
VERIFY(context);
context->run_intrinsic_size_determination(box);
if (context->type() == FormattingContext::Type::Flex) {
cache.min_content_width = box_state.content_width;
cache.min_content_width = box_state.content_width();
} else {
cache.min_content_width = context->greatest_child_width(box);
}
@ -908,10 +908,10 @@ float FormattingContext::calculate_max_content_width(Layout::Box const& box) con
LayoutState throwaway_state(&m_state);
auto const& containing_block = *box.containing_block();
auto& containing_block_state = throwaway_state.get_mutable(containing_block);
containing_block_state.content_width = INFINITY;
containing_block_state.set_content_width(INFINITY);
if (!containing_block.has_definite_height())
containing_block_state.content_height = INFINITY;
containing_block_state.set_content_height(INFINITY);
auto& box_state = throwaway_state.get_mutable(box);
box_state.width_constraint = SizeConstraint::MaxContent;
@ -920,7 +920,7 @@ float FormattingContext::calculate_max_content_width(Layout::Box const& box) con
VERIFY(context);
context->run_intrinsic_size_determination(box);
if (context->type() == FormattingContext::Type::Flex) {
cache.max_content_width = box_state.content_width;
cache.max_content_width = box_state.content_width();
} else {
cache.max_content_width = context->greatest_child_width(box);
}
@ -948,10 +948,10 @@ float FormattingContext::calculate_min_content_height(Layout::Box const& box) co
LayoutState throwaway_state(&m_state);
auto const& containing_block = *box.containing_block();
auto& containing_block_state = throwaway_state.get_mutable(containing_block);
containing_block_state.content_height = 0;
containing_block_state.set_content_height(0);
if (!containing_block.has_definite_width())
containing_block_state.content_width = INFINITY;
containing_block_state.set_content_width(INFINITY);
auto& box_state = throwaway_state.get_mutable(box);
box_state.height_constraint = SizeConstraint::MinContent;
@ -960,7 +960,7 @@ float FormattingContext::calculate_min_content_height(Layout::Box const& box) co
VERIFY(context);
context->run_intrinsic_size_determination(box);
if (context->type() == FormattingContext::Type::Flex) {
cache.min_content_height = box_state.content_height;
cache.min_content_height = box_state.content_height();
} else {
cache.min_content_height = calculate_auto_height(throwaway_state, box);
}
@ -988,10 +988,10 @@ float FormattingContext::calculate_max_content_height(Layout::Box const& box) co
LayoutState throwaway_state(&m_state);
auto const& containing_block = *box.containing_block();
auto& containing_block_state = throwaway_state.get_mutable(containing_block);
containing_block_state.content_height = INFINITY;
containing_block_state.set_content_height(INFINITY);
if (!containing_block.has_definite_width())
containing_block_state.content_width = INFINITY;
containing_block_state.set_content_width(INFINITY);
auto& box_state = throwaway_state.get_mutable(box);
box_state.height_constraint = SizeConstraint::MaxContent;
@ -1000,7 +1000,7 @@ float FormattingContext::calculate_max_content_height(Layout::Box const& box) co
VERIFY(context);
context->run_intrinsic_size_determination(box);
if (context->type() == FormattingContext::Type::Flex) {
cache.max_content_height = box_state.content_height;
cache.max_content_height = box_state.content_height();
} else {
cache.max_content_height = calculate_auto_height(throwaway_state, box);
}
@ -1025,7 +1025,7 @@ float FormattingContext::containing_block_width_for(Box const& box, LayoutState
case SizeConstraint::MaxContent:
return INFINITY;
case SizeConstraint::None:
return containing_block_state.content_width;
return containing_block_state.content_width();
}
VERIFY_NOT_REACHED();
}
@ -1041,7 +1041,7 @@ float FormattingContext::containing_block_height_for(Box const& box, LayoutState
case SizeConstraint::MaxContent:
return INFINITY;
case SizeConstraint::None:
return containing_block_state.content_height;
return containing_block_state.content_height();
}
VERIFY_NOT_REACHED();
}

View File

@ -32,7 +32,7 @@ InlineFormattingContext::InlineFormattingContext(LayoutState& state, BlockContai
m_effective_containing_block_width = INFINITY;
break;
default:
m_effective_containing_block_width = m_containing_block_state.content_width;
m_effective_containing_block_width = m_containing_block_state.content_width();
break;
}
}
@ -74,7 +74,7 @@ float InlineFormattingContext::available_space_for_line(float y) const
auto const& root_block_state = m_state.get(parent().root());
space.left = max(space.left, m_containing_block_state.offset.x()) - m_containing_block_state.offset.x();
space.right = min(root_block_state.content_width - space.right, m_containing_block_state.offset.x() + m_effective_containing_block_width);
space.right = min(root_block_state.content_width() - space.right, m_containing_block_state.offset.x() + m_effective_containing_block_width);
return space.right - space.left;
}
@ -113,8 +113,8 @@ void InlineFormattingContext::dimension_box_on_line(Box const& box, LayoutMode l
if (is<SVGSVGBox>(box))
(void)layout_inside(replaced, layout_mode);
box_state.content_width = compute_width_for_replaced_element(m_state, replaced);
box_state.content_height = compute_height_for_replaced_element(m_state, replaced);
box_state.set_content_width(compute_width_for_replaced_element(m_state, replaced));
box_state.set_content_height(compute_height_for_replaced_element(m_state, replaced));
return;
}
@ -125,7 +125,7 @@ void InlineFormattingContext::dimension_box_on_line(Box const& box, LayoutMode l
if (width_value.is_auto()) {
auto result = calculate_shrink_to_fit_widths(inline_block);
auto available_width = m_containing_block_state.content_width
auto available_width = m_containing_block_state.content_width()
- box_state.margin_left
- box_state.border_left
- box_state.padding_left
@ -134,10 +134,10 @@ void InlineFormattingContext::dimension_box_on_line(Box const& box, LayoutMode l
- box_state.margin_right;
auto width = min(max(result.preferred_minimum_width, available_width), result.preferred_width);
box_state.content_width = width;
box_state.set_content_width(width);
} else {
auto container_width = CSS::Length::make_px(m_effective_containing_block_width);
box_state.content_width = width_value.resolved(box, container_width).to_px(inline_block);
box_state.set_content_width(width_value.resolved(box, container_width).to_px(inline_block));
}
auto independent_formatting_context = layout_inside(inline_block, layout_mode);
@ -146,8 +146,8 @@ void InlineFormattingContext::dimension_box_on_line(Box const& box, LayoutMode l
// FIXME: (10.6.6) If 'height' is 'auto', the height depends on the element's descendants per 10.6.7.
BlockFormattingContext::compute_height(inline_block, m_state);
} else {
auto container_height = CSS::Length::make_px(m_containing_block_state.content_height);
box_state.content_height = height_value.resolved(box, container_height).to_px(inline_block);
auto container_height = CSS::Length::make_px(m_containing_block_state.content_height());
box_state.set_content_height(height_value.resolved(box, container_height).to_px(inline_block));
}
independent_formatting_context->parent_context_did_dimension_child_root_box();

View File

@ -34,9 +34,9 @@ void InlineLevelIterator::enter_node_with_box_model_metrics(Layout::NodeWithStyl
auto& used_values = m_layout_state.get_mutable(node);
auto const& computed_values = node.computed_values();
used_values.margin_left = computed_values.margin().left.resolved(node, CSS::Length::make_px(m_container_state.content_width)).to_px(node);
used_values.margin_left = computed_values.margin().left.resolved(node, CSS::Length::make_px(m_container_state.content_width())).to_px(node);
used_values.border_left = computed_values.border_left().width;
used_values.padding_left = computed_values.padding().left.resolved(node, CSS::Length::make_px(m_container_state.content_width)).to_px(node);
used_values.padding_left = computed_values.padding().left.resolved(node, CSS::Length::make_px(m_container_state.content_width())).to_px(node);
m_extra_leading_metrics->margin += used_values.margin_left;
m_extra_leading_metrics->border += used_values.border_left;
@ -54,9 +54,9 @@ void InlineLevelIterator::exit_node_with_box_model_metrics()
auto& used_values = m_layout_state.get_mutable(node);
auto const& computed_values = node.computed_values();
used_values.margin_right = computed_values.margin().right.resolved(node, CSS::Length::make_px(m_container_state.content_width)).to_px(node);
used_values.margin_right = computed_values.margin().right.resolved(node, CSS::Length::make_px(m_container_state.content_width())).to_px(node);
used_values.border_right = computed_values.border_right().width;
used_values.padding_right = computed_values.padding().right.resolved(node, CSS::Length::make_px(m_container_state.content_width)).to_px(node);
used_values.padding_right = computed_values.padding().right.resolved(node, CSS::Length::make_px(m_container_state.content_width())).to_px(node);
m_extra_trailing_metrics->margin += used_values.margin_right;
m_extra_trailing_metrics->border += used_values.border_right;
@ -209,7 +209,7 @@ Optional<InlineLevelIterator::Item> InlineLevelIterator::next(float available_wi
.node = &box,
.offset_in_node = 0,
.length_in_node = 0,
.width = box_state.content_width,
.width = box_state.content_width(),
.padding_start = box_state.padding_left,
.padding_end = box_state.padding_right,
.border_start = box_state.border_left,

View File

@ -71,7 +71,7 @@ void LayoutState::commit()
auto& box = static_cast<Layout::Box&>(node);
auto& paint_box = const_cast<Painting::PaintableBox&>(*box.paint_box());
paint_box.set_offset(used_values.offset);
paint_box.set_content_size(used_values.content_width, used_values.content_height);
paint_box.set_content_size(used_values.content_width(), used_values.content_height());
paint_box.set_overflow_data(move(used_values.overflow_data));
paint_box.set_containing_line_box_fragment(used_values.containing_line_box_fragment);
@ -94,7 +94,7 @@ void LayoutState::commit()
Gfx::FloatRect margin_box_rect(Box const& box, LayoutState const& state)
{
auto const& box_state = state.get(box);
auto rect = Gfx::FloatRect { box_state.offset, { box_state.content_width, box_state.content_height } };
auto rect = Gfx::FloatRect { box_state.offset, { box_state.content_width(), box_state.content_height() } };
rect.set_x(rect.x() - box_state.margin_box_left());
rect.set_width(rect.width() + box_state.margin_box_left() + box_state.margin_box_right());
rect.set_y(rect.y() - box_state.margin_box_top());
@ -119,10 +119,20 @@ Gfx::FloatRect margin_box_rect_in_ancestor_coordinate_space(Box const& box, Box
Gfx::FloatRect absolute_content_rect(Box const& box, LayoutState const& state)
{
auto const& box_state = state.get(box);
Gfx::FloatRect rect { box_state.offset, { box_state.content_width, box_state.content_height } };
Gfx::FloatRect 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_content_width(float width)
{
m_content_width = width;
}
void LayoutState::UsedValues::set_content_height(float height)
{
m_content_height = height;
}
}

View File

@ -44,8 +44,12 @@ struct LayoutState {
struct UsedValues {
Layout::NodeWithStyleAndBoxModelMetrics* node { nullptr };
float content_width { 0 };
float content_height { 0 };
float content_width() const { return m_content_width; }
float content_height() const { return m_content_height; }
void set_content_width(float);
void set_content_height(float);
Gfx::FloatPoint offset;
SizeConstraint width_constraint { SizeConstraint::None };
@ -78,16 +82,16 @@ struct LayoutState {
float margin_box_top() const { return margin_top + border_top + padding_top; }
float margin_box_bottom() const { return margin_bottom + border_bottom + padding_bottom; }
float margin_box_width() const { return margin_box_left() + content_width + margin_box_right(); }
float margin_box_height() const { return margin_box_top() + content_height + margin_box_bottom(); }
float margin_box_width() const { return margin_box_left() + content_width() + margin_box_right(); }
float margin_box_height() const { return margin_box_top() + content_height() + margin_box_bottom(); }
float border_box_left() const { return border_left + padding_left; }
float border_box_right() const { return border_right + padding_right; }
float border_box_top() const { return border_top + padding_top; }
float border_box_bottom() const { return border_bottom + padding_bottom; }
float border_box_width() const { return border_box_left() + content_width + border_box_right(); }
float border_box_height() const { return border_box_top() + content_height + border_box_bottom(); }
float border_box_width() const { return border_box_left() + content_width() + border_box_right(); }
float border_box_height() const { return border_box_top() + content_height() + border_box_bottom(); }
Optional<Painting::PaintableBox::OverflowData> overflow_data;
@ -99,6 +103,10 @@ struct LayoutState {
}
Optional<LineBoxFragmentCoordinate> containing_line_box_fragment;
private:
float m_content_width { 0 };
float m_content_height { 0 };
};
void commit();

View File

@ -52,7 +52,7 @@ void LineBuilder::append_box(Box const& box, float leading_size, float trailing_
{
auto& box_state = m_layout_state.get_mutable(box);
auto& line_box = ensure_last_line_box();
line_box.add_fragment(box, 0, 0, leading_size, trailing_size, leading_margin, trailing_margin, box_state.content_width, box_state.content_height, box_state.border_box_top(), box_state.border_box_bottom());
line_box.add_fragment(box, 0, 0, leading_size, trailing_size, leading_margin, trailing_margin, box_state.content_width(), box_state.content_height(), box_state.border_box_top(), box_state.border_box_bottom());
m_max_height_on_current_line = max(m_max_height_on_current_line, box_state.border_box_height());
box_state.containing_line_box_fragment = LineBoxFragmentCoordinate {
@ -86,7 +86,7 @@ static float box_baseline(LayoutState const& state, Box const& box)
case CSS::VerticalAlign::Top:
return box_state.border_box_top();
case CSS::VerticalAlign::Bottom:
return box_state.content_height + box_state.border_box_bottom();
return box_state.content_height() + box_state.border_box_bottom();
default:
break;
}
@ -215,7 +215,7 @@ void LineBuilder::update_last_line()
if (fragment.layout_node().is_replaced_box() || fragment.layout_node().is_inline_block()) {
auto const& fragment_box_state = m_layout_state.get(static_cast<Box const&>(fragment.layout_node()));
top_of_inline_box = fragment.offset().y() - fragment_box_state.margin_box_top();
bottom_of_inline_box = fragment.offset().y() + fragment_box_state.content_height + fragment_box_state.margin_box_bottom();
bottom_of_inline_box = fragment.offset().y() + fragment_box_state.content_height() + fragment_box_state.margin_box_bottom();
} else {
auto font_metrics = fragment.layout_node().font().pixel_metrics();
auto typographic_height = font_metrics.ascent + font_metrics.descent;

View File

@ -37,8 +37,8 @@ void SVGFormattingContext::run(Box const& box, LayoutMode)
auto& layout_node = *svg_svg_element.layout_node();
// FIXME: Allow for relative lengths here
geometry_box_state.content_width = layout_node.computed_values().width().resolved(layout_node, { 0, CSS::Length::Type::Px }).to_px(layout_node);
geometry_box_state.content_height = layout_node.computed_values().height().resolved(layout_node, { 0, CSS::Length::Type::Px }).to_px(layout_node);
geometry_box_state.set_content_width(layout_node.computed_values().width().resolved(layout_node, { 0, CSS::Length::Type::Px }).to_px(layout_node));
geometry_box_state.set_content_height(layout_node.computed_values().height().resolved(layout_node, { 0, CSS::Length::Type::Px }).to_px(layout_node));
return IterationDecision::Continue;
}
@ -64,15 +64,15 @@ void SVGFormattingContext::run(Box const& box, LayoutMode)
Gfx::FloatPoint viewbox_offset = { view_box.min_x, view_box.min_y };
geometry_box_state.offset = path_bounding_box.top_left() + viewbox_offset;
geometry_box_state.content_width = view_box.width;
geometry_box_state.content_height = view_box.height;
geometry_box_state.set_content_width(view_box.width);
geometry_box_state.set_content_height(view_box.height);
return IterationDecision::Continue;
}
geometry_box_state.offset = path_bounding_box.top_left();
geometry_box_state.content_width = path_bounding_box.width();
geometry_box_state.content_height = path_bounding_box.height();
geometry_box_state.set_content_width(path_bounding_box.width());
geometry_box_state.set_content_height(path_bounding_box.height());
}
return IterationDecision::Continue;

View File

@ -28,7 +28,7 @@ void TableFormattingContext::run(Box const& box, LayoutMode)
auto& box_state = m_state.get_mutable(box);
compute_width(box);
auto table_width = CSS::Length::make_px(box_state.content_width);
auto table_width = CSS::Length::make_px(box_state.content_width());
auto table_width_is_auto = box.computed_values().width().is_auto();
float total_content_width = 0;
@ -47,8 +47,8 @@ void TableFormattingContext::run(Box const& box, LayoutMode)
box.for_each_child_of_type<TableRowGroupBox>([&](auto& row_group_box) {
auto& row_group_box_state = m_state.get_mutable(row_group_box);
float remaining_for_max = box_state.content_width;
float remaining_for_min = box_state.content_width;
float remaining_for_max = box_state.content_width();
float remaining_for_min = box_state.content_width();
for (auto& column_width : column_widths) {
remaining_for_max -= column_width.max;
remaining_for_min -= column_width.min;
@ -90,24 +90,24 @@ void TableFormattingContext::run(Box const& box, LayoutMode)
auto& row_state = m_state.get_mutable(row);
row_state.offset = { 0, content_height };
layout_row(row, column_widths);
content_width = max(content_width, row_state.content_width);
content_height += row_state.content_height;
content_width = max(content_width, row_state.content_width());
content_height += row_state.content_height();
});
if (row_group_box.computed_values().width().is_auto())
row_group_box_state.content_width = content_width;
row_group_box_state.content_height = content_height;
row_group_box_state.set_content_width(content_width);
row_group_box_state.set_content_height(content_height);
row_group_box_state.offset = { 0, total_content_height };
total_content_height += content_height;
total_content_width = max(total_content_width, row_group_box_state.content_width);
total_content_width = max(total_content_width, row_group_box_state.content_width());
});
if (table_width_is_auto)
box_state.content_width = total_content_width;
box_state.set_content_width(total_content_width);
// FIXME: This is a total hack, we should respect the 'height' property.
box_state.content_height = total_content_height;
box_state.set_content_height(total_content_height);
}
void TableFormattingContext::calculate_column_widths(Box const& row, CSS::Length const& table_width, Vector<ColumnWidth>& column_widths)
@ -121,7 +121,7 @@ void TableFormattingContext::calculate_column_widths(Box const& row, CSS::Length
if (specified_width.is_auto()) {
auto width = calculate_max_content_width(cell);
cell_state.content_width = width;
cell_state.set_content_width(width);
} else {
compute_width(cell, LayoutMode::Normal);
}
@ -182,7 +182,7 @@ void TableFormattingContext::layout_row(Box const& row, Vector<ColumnWidth>& col
float span_width = 0;
for (size_t i = 0; i < cell.colspan(); ++i)
span_width += column_widths[column_index++].used;
cell_state.content_width = span_width - cell_state.border_box_left() - cell_state.border_box_right();
cell_state.set_content_width(span_width - cell_state.border_box_left() - cell_state.border_box_right());
BlockFormattingContext::compute_height(cell, m_state);
cell_state.offset = row_state.offset.translated(cell_state.border_box_left() + content_width, cell_state.border_box_top());
@ -194,18 +194,18 @@ void TableFormattingContext::layout_row(Box const& row, Vector<ColumnWidth>& col
tallest_cell_height = max(tallest_cell_height, cell_state.border_box_height());
});
row_state.content_height = tallest_cell_height;
row_state.set_content_height(tallest_cell_height);
row.for_each_child_of_type<TableCellBox>([&](auto& cell) {
auto& cell_state = m_state.get_mutable(cell);
cell_state.content_height = tallest_cell_height - cell_state.border_box_top() - cell_state.border_box_bottom();
cell_state.set_content_height(tallest_cell_height - cell_state.border_box_top() - cell_state.border_box_bottom());
});
if (use_auto_layout) {
row_state.content_width = content_width;
row_state.set_content_width(content_width);
} else {
auto& table_state = m_state.get_mutable(*table);
row_state.content_width = table_state.content_width;
row_state.set_content_width(table_state.content_width());
}
}