mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:37:35 +00:00
LibWeb: Keep the "remaining free space" across flexbox algo steps
Instead of recomputing the "remaining free space" per flex line, remember it after calculating it during the "resolve flexible lengths" step so we can reuse it later.
This commit is contained in:
parent
83a6be593c
commit
4935055407
2 changed files with 13 additions and 15 deletions
|
@ -853,6 +853,7 @@ void FlexFormattingContext::resolve_flexible_lengths()
|
|||
};
|
||||
|
||||
float initial_free_space = calculate_free_space();
|
||||
flex_line.remaining_free_space = initial_free_space;
|
||||
|
||||
// 6.4 Loop
|
||||
auto for_each_unfrozen_item = [&flex_line](auto callback) {
|
||||
|
@ -864,7 +865,7 @@ void FlexFormattingContext::resolve_flexible_lengths()
|
|||
|
||||
while (number_of_unfrozen_items_on_line > 0) {
|
||||
// b Calculate the remaining free space
|
||||
auto remaining_free_space = calculate_free_space();
|
||||
flex_line.remaining_free_space = calculate_free_space();
|
||||
float sum_of_unfrozen_flex_items_flex_factors = 0;
|
||||
for_each_unfrozen_item([&](FlexItem* item) {
|
||||
sum_of_unfrozen_flex_items_flex_factors += item->flex_factor.value_or(1);
|
||||
|
@ -872,17 +873,17 @@ void FlexFormattingContext::resolve_flexible_lengths()
|
|||
|
||||
if (sum_of_unfrozen_flex_items_flex_factors < 1) {
|
||||
auto intermediate_free_space = initial_free_space * sum_of_unfrozen_flex_items_flex_factors;
|
||||
if (AK::abs(intermediate_free_space) < AK::abs(remaining_free_space))
|
||||
remaining_free_space = intermediate_free_space;
|
||||
if (AK::abs(intermediate_free_space) < AK::abs(flex_line.remaining_free_space))
|
||||
flex_line.remaining_free_space = intermediate_free_space;
|
||||
}
|
||||
|
||||
// c Distribute free space proportional to the flex factors
|
||||
if (remaining_free_space != 0) {
|
||||
if (flex_line.remaining_free_space != 0) {
|
||||
if (used_flex_factor == FlexFactor::FlexGrowFactor) {
|
||||
float sum_of_flex_grow_factor_of_unfrozen_items = sum_of_unfrozen_flex_items_flex_factors;
|
||||
for_each_unfrozen_item([&](FlexItem* flex_item) {
|
||||
float ratio = flex_item->flex_factor.value_or(1) / sum_of_flex_grow_factor_of_unfrozen_items;
|
||||
flex_item->target_main_size = flex_item->flex_base_size + (remaining_free_space * ratio);
|
||||
flex_item->target_main_size = flex_item->flex_base_size + (flex_line.remaining_free_space * ratio);
|
||||
});
|
||||
} else if (used_flex_factor == FlexFactor::FlexShrinkFactor) {
|
||||
float sum_of_scaled_flex_shrink_factor_of_unfrozen_items = 0;
|
||||
|
@ -895,7 +896,7 @@ void FlexFormattingContext::resolve_flexible_lengths()
|
|||
float ratio = 1.0f;
|
||||
if (sum_of_scaled_flex_shrink_factor_of_unfrozen_items != 0.0f)
|
||||
ratio = flex_item->scaled_flex_shrink_factor / sum_of_scaled_flex_shrink_factor_of_unfrozen_items;
|
||||
flex_item->target_main_size = flex_item->flex_base_size - (AK::abs(remaining_free_space) * ratio);
|
||||
flex_item->target_main_size = flex_item->flex_base_size - (AK::abs(flex_line.remaining_free_space) * ratio);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
|
@ -1088,17 +1089,13 @@ void FlexFormattingContext::distribute_any_remaining_free_space()
|
|||
used_main_space += flex_item->main_size;
|
||||
if (is_main_axis_margin_first_auto(flex_item->box))
|
||||
++auto_margins;
|
||||
else
|
||||
used_main_space += flex_item->margins.main_before + flex_item->borders.main_before + flex_item->padding.main_before;
|
||||
|
||||
if (is_main_axis_margin_second_auto(flex_item->box))
|
||||
++auto_margins;
|
||||
else
|
||||
used_main_space += flex_item->margins.main_after + flex_item->borders.main_after + flex_item->padding.main_after;
|
||||
}
|
||||
float remaining_free_space = m_available_space->main.value_or(NumericLimits<float>::max()) - used_main_space;
|
||||
if (remaining_free_space > 0) {
|
||||
float size_per_auto_margin = remaining_free_space / (float)auto_margins;
|
||||
|
||||
if (flex_line.remaining_free_space > 0) {
|
||||
float size_per_auto_margin = flex_line.remaining_free_space / (float)auto_margins;
|
||||
for (auto& flex_item : flex_line.items) {
|
||||
if (is_main_axis_margin_first_auto(flex_item->box))
|
||||
set_main_axis_first_margin(*flex_item, size_per_auto_margin);
|
||||
|
@ -1129,10 +1126,10 @@ void FlexFormattingContext::distribute_any_remaining_free_space()
|
|||
space_before_first_item = (m_available_space->main.value_or(NumericLimits<float>::max()) - used_main_space) / 2.0f;
|
||||
break;
|
||||
case CSS::JustifyContent::SpaceBetween:
|
||||
space_between_items = remaining_free_space / (number_of_items - 1);
|
||||
space_between_items = flex_line.remaining_free_space / (number_of_items - 1);
|
||||
break;
|
||||
case CSS::JustifyContent::SpaceAround:
|
||||
space_between_items = remaining_free_space / number_of_items;
|
||||
space_between_items = flex_line.remaining_free_space / number_of_items;
|
||||
space_before_first_item = space_between_items / 2.0f;
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue