LibWeb: Store flex item used sizes as Optional<CSSPixels>

This will allow us to tell whether values have been assigned by the flex
layout algorithm yet.
This commit is contained in:
Andreas Kling 2023-01-07 19:28:06 +01:00
parent dbbc75f8fd
commit ab2f105344
Notes: sideshowbarker 2024-07-17 20:33:50 +09:00
2 changed files with 23 additions and 18 deletions

View file

@ -193,7 +193,7 @@ void FlexFormattingContext::run(Box const& run_box, LayoutMode, AvailableSpace c
auto const& flex_container_computed_cross_size = is_row_layout() ? flex_container().computed_values().height() : flex_container().computed_values().width();
if (flex_container_computed_cross_size.is_auto()) {
for (auto& item : m_flex_items) {
set_cross_size(item.box, item.cross_size);
set_cross_size(item.box, item.cross_size.value());
}
}
}
@ -1044,7 +1044,7 @@ void FlexFormattingContext::resolve_flexible_lengths()
// 6.5.
for (auto& flex_item : flex_line.items) {
flex_item->main_size = flex_item->target_main_size;
set_main_size(flex_item->box, flex_item->main_size);
set_main_size(flex_item->box, flex_item->main_size.value());
}
flex_line.remaining_free_space = calculate_free_space();
@ -1089,7 +1089,7 @@ void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem&
CSSPixels fit_content_cross_size = 0;
if (is_row_layout()) {
auto available_width = AvailableSize::make_definite(item.main_size);
auto available_width = item.main_size.has_value() ? AvailableSize::make_definite(item.main_size.value()) : AvailableSize::make_indefinite();
auto available_height = AvailableSize::make_indefinite();
fit_content_cross_size = calculate_fit_content_height(item.box, AvailableSpace(available_width, available_height));
} else {
@ -1105,9 +1105,9 @@ void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem&
auto& box_state = throwaway_state.get_mutable(item.box);
if (is_row_layout()) {
box_state.set_content_width(item.main_size);
box_state.set_content_width(item.main_size.value());
} else {
box_state.set_content_height(item.main_size);
box_state.set_content_height(item.main_size.value());
}
// Item has definite main size, layout with that as the used main size.
@ -1115,8 +1115,8 @@ void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem&
// NOTE: Flex items should always create an independent formatting context!
VERIFY(independent_formatting_context);
auto available_width = is_row_layout() ? AvailableSize::make_definite(item.main_size) : AvailableSize::make_indefinite();
auto available_height = is_row_layout() ? AvailableSize::make_indefinite() : AvailableSize::make_definite(item.main_size);
auto available_width = is_row_layout() ? AvailableSize::make_definite(item.main_size.value()) : AvailableSize::make_indefinite();
auto available_height = is_row_layout() ? AvailableSize::make_indefinite() : AvailableSize::make_definite(item.main_size.value());
independent_formatting_context->run(item.box, LayoutMode::Normal, AvailableSpace(available_width, available_height));
@ -1203,7 +1203,7 @@ void FlexFormattingContext::distribute_any_remaining_free_space()
CSSPixels used_main_space = 0;
size_t auto_margins = 0;
for (auto& flex_item : flex_line.items) {
used_main_space += flex_item->main_size;
used_main_space += flex_item->main_size.value();
if (flex_item->margins.main_before_is_auto)
++auto_margins;
@ -1296,7 +1296,7 @@ void FlexFormattingContext::distribute_any_remaining_free_space()
item_margin_after = 0;
}
auto amount_of_main_size_used = item.main_size
auto amount_of_main_size_used = item.main_size.value()
+ item_margin_before
+ item.borders.main_before
+ item.padding.main_before
@ -1306,7 +1306,7 @@ void FlexFormattingContext::distribute_any_remaining_free_space()
+ space_between_items;
if (is_direction_reverse()) {
item.main_offset = cursor_offset - item.main_size - item_margin_after - item.borders.main_after - item.padding.main_after;
item.main_offset = cursor_offset - item.main_size.value() - item_margin_after - item.borders.main_after - item.padding.main_after;
cursor_offset -= amount_of_main_size_used;
} else if (flex_region_render_cursor == FlexRegionRenderCursor::Right) {
cursor_offset -= amount_of_main_size_used;
@ -1338,7 +1338,7 @@ void FlexFormattingContext::dump_items() const
dbgln("{} flex-line #{}:", flex_container().debug_description(), i);
for (size_t j = 0; j < m_flex_lines[i].items.size(); ++j) {
auto& item = *m_flex_lines[i].items[j];
dbgln("{} flex-item #{}: {} (main:{}, cross:{})", flex_container().debug_description(), j, item.box.debug_description(), item.main_size, item.cross_size);
dbgln("{} flex-item #{}: {} (main:{}, cross:{})", flex_container().debug_description(), j, item.box.debug_description(), item.main_size.value_or(-1), item.cross_size.value_or(-1));
}
}
}
@ -1388,10 +1388,10 @@ void FlexFormattingContext::align_all_flex_items_along_the_cross_axis()
flex_item->cross_offset = -half_line_size + flex_item->margins.cross_before + flex_item->borders.cross_before + flex_item->padding.cross_before;
break;
case CSS::AlignItems::FlexEnd:
flex_item->cross_offset = half_line_size - flex_item->cross_size - flex_item->margins.cross_after - flex_item->borders.cross_after - flex_item->padding.cross_after;
flex_item->cross_offset = half_line_size - flex_item->cross_size.value() - flex_item->margins.cross_after - flex_item->borders.cross_after - flex_item->padding.cross_after;
break;
case CSS::AlignItems::Center:
flex_item->cross_offset = -(flex_item->cross_size / 2.0f);
flex_item->cross_offset = -(flex_item->cross_size.value() / 2.0f);
break;
default:
break;
@ -1528,8 +1528,8 @@ void FlexFormattingContext::copy_dimensions_from_flex_items_to_boxes()
box_state.border_top = box.computed_values().border_top().width;
box_state.border_bottom = box.computed_values().border_bottom().width;
set_main_size(box, flex_item.main_size);
set_cross_size(box, flex_item.cross_size);
set_main_size(box, flex_item.main_size.value());
set_cross_size(box, flex_item.cross_size.value());
set_offset(box, flex_item.main_offset, flex_item.cross_offset);
}
}
@ -1928,7 +1928,7 @@ void FlexFormattingContext::resolve_cross_axis_auto_margins()
// If its outer cross size (treating those auto margins as zero) is less than the cross size of its flex line,
// distribute the difference in those sizes equally to the auto margins.
auto outer_cross_size = item->cross_size + item->padding.cross_before + item->padding.cross_after + item->borders.cross_before + item->borders.cross_after;
auto outer_cross_size = item->cross_size.value() + item->padding.cross_before + item->padding.cross_after + item->borders.cross_before + item->borders.cross_after;
if (outer_cross_size < line.cross_size) {
CSSPixels remainder = line.cross_size - outer_cross_size;
if (item->margins.cross_before_is_auto && item->margins.cross_after_is_auto) {

View file

@ -60,8 +60,13 @@ private:
Optional<float> flex_factor {};
float scaled_flex_shrink_factor { 0 };
float desired_flex_fraction { 0 };
CSSPixels main_size { 0 };
CSSPixels cross_size { 0 };
// The used main size of this flex item. Empty until determined.
Optional<CSSPixels> main_size {};
// The used cross size of this flex item. Empty until determined.
Optional<CSSPixels> cross_size {};
CSSPixels main_offset { 0 };
CSSPixels cross_offset { 0 };
DirectionAgnosticMargins margins {};