Jelajahi Sumber

LibWeb: Improve min/max content contribution calculations for flex items

Follow the spec more closely.
Andreas Kling 3 tahun lalu
induk
melakukan
3def9e47f6
1 mengubah file dengan 43 tambahan dan 61 penghapusan
  1. 43 61
      Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp

+ 43 - 61
Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp

@@ -1541,92 +1541,74 @@ float FlexFormattingContext::calculate_main_min_content_contribution(FlexItem co
     // The main-size min-content contribution of a flex item is
     // The main-size min-content contribution of a flex item is
     // the larger of its outer min-content size and outer preferred size if that is not auto,
     // the larger of its outer min-content size and outer preferred size if that is not auto,
     // clamped by its min/max main size.
     // clamped by its min/max main size.
-    auto outer_min_content_size = [&]() -> float {
-        auto inner_main_size = calculate_min_content_main_size(item);
-        auto outer_main_size = inner_main_size
-            + item.margins.main_before + item.margins.main_after
-            + item.borders.main_before + item.borders.main_after
-            + item.padding.main_before + item.padding.main_after;
-        return outer_main_size;
+    auto larger_size = [&] {
+        auto inner_min_content_size = calculate_min_content_main_size(item);
+        if (computed_main_size(item.box).is_auto())
+            return inner_min_content_size;
+        auto inner_preferred_size = is_row_layout() ? get_pixel_width(item.box, computed_main_size(item.box)) : get_pixel_height(item.box, computed_main_size(item.box));
+        return max(inner_min_content_size, inner_preferred_size);
     }();
     }();
 
 
-    if (!has_definite_main_size(item.box)) {
-        return outer_min_content_size;
-    }
-
     auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box) : automatic_minimum_size(item);
     auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box) : automatic_minimum_size(item);
     auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : NumericLimits<float>::max();
     auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : NumericLimits<float>::max();
-    auto unclamped_preferred_size = resolved_definite_main_size(item.box);
-    auto clamped_preferred_size = css_clamp(unclamped_preferred_size, clamp_min, clamp_max);
-    return max(outer_min_content_size, clamped_preferred_size);
+    auto clamped_inner_size = css_clamp(larger_size, clamp_min, clamp_max);
+
+    return item.add_main_margin_box_sizes(clamped_inner_size);
 }
 }
 
 
 // https://drafts.csswg.org/css-flexbox-1/#intrinsic-item-contributions
 // https://drafts.csswg.org/css-flexbox-1/#intrinsic-item-contributions
 float FlexFormattingContext::calculate_main_max_content_contribution(FlexItem const& item) const
 float FlexFormattingContext::calculate_main_max_content_contribution(FlexItem const& item) const
 {
 {
-    // The main-size max-content contribution of a flex item is the larger of its outer max-content size and outer preferred size if that is not auto, clamped by its min/max main size.
-    auto outer_max_content_size = [&]() -> float {
-        auto inner_main_size = calculate_max_content_main_size(item);
-        auto outer_main_size = inner_main_size
-            + item.margins.main_before + item.margins.main_after
-            + item.borders.main_before + item.borders.main_after
-            + item.padding.main_before + item.padding.main_after;
-        return outer_main_size;
+    // The main-size max-content contribution of a flex item is
+    // the larger of its outer max-content size and outer preferred size if that is not auto,
+    // clamped by its min/max main size.
+    auto larger_size = [&] {
+        auto inner_max_content_size = calculate_max_content_main_size(item);
+        if (computed_main_size(item.box).is_auto())
+            return inner_max_content_size;
+        auto inner_preferred_size = is_row_layout() ? get_pixel_width(item.box, computed_main_size(item.box)) : get_pixel_height(item.box, computed_main_size(item.box));
+        return max(inner_max_content_size, inner_preferred_size);
     }();
     }();
 
 
-    if (!has_definite_main_size(item.box)) {
-        return outer_max_content_size;
-    }
-
     auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box) : automatic_minimum_size(item);
     auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box) : automatic_minimum_size(item);
     auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : NumericLimits<float>::max();
     auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : NumericLimits<float>::max();
-    auto unclamped_preferred_size = resolved_definite_main_size(item.box);
-    auto clamped_preferred_size = css_clamp(unclamped_preferred_size, clamp_min, clamp_max);
-    return max(outer_max_content_size, clamped_preferred_size);
+    auto clamped_inner_size = css_clamp(larger_size, clamp_min, clamp_max);
+
+    return item.add_main_margin_box_sizes(clamped_inner_size);
 }
 }
 
 
-float FlexFormattingContext::calculate_cross_min_content_contribution(FlexItem const& flex_item) const
+float FlexFormattingContext::calculate_cross_min_content_contribution(FlexItem const& item) const
 {
 {
-    auto outer_min_cross_size = [&] {
-        auto inner_cross_size = calculate_min_content_cross_size(flex_item);
-        auto outer_cross_size = inner_cross_size
-            + flex_item.margins.cross_before + flex_item.margins.cross_after
-            + flex_item.borders.cross_before + flex_item.borders.cross_after
-            + flex_item.padding.cross_before + flex_item.padding.cross_after;
-        return outer_cross_size;
+    auto larger_size = [&] {
+        auto inner_min_content_size = calculate_min_content_cross_size(item);
+        if (computed_cross_size(item.box).is_auto())
+            return inner_min_content_size;
+        auto inner_preferred_size = !is_row_layout() ? get_pixel_width(item.box, computed_cross_size(item.box)) : get_pixel_height(item.box, computed_cross_size(item.box));
+        return max(inner_min_content_size, inner_preferred_size);
     }();
     }();
 
 
-    if (!has_definite_cross_size(flex_item.box)) {
-        return outer_min_cross_size;
-    }
+    auto clamp_min = has_cross_min_size(item.box) ? specified_cross_min_size(item.box) : 0;
+    auto clamp_max = has_cross_max_size(item.box) ? specified_cross_max_size(item.box) : NumericLimits<float>::max();
+    auto clamped_inner_size = css_clamp(larger_size, clamp_min, clamp_max);
 
 
-    auto clamp_min = has_cross_min_size(flex_item.box) ? specified_cross_min_size(flex_item.box) : 0;
-    auto clamp_max = has_cross_max_size(flex_item.box) ? specified_cross_max_size(flex_item.box) : NumericLimits<float>::max();
-    auto unclamped_preferred_size = resolved_definite_cross_size(flex_item.box);
-    auto clamped_preferred_size = css_clamp(unclamped_preferred_size, clamp_min, clamp_max);
-    return max(outer_min_cross_size, clamped_preferred_size);
+    return item.add_cross_margin_box_sizes(clamped_inner_size);
 }
 }
 
 
-float FlexFormattingContext::calculate_cross_max_content_contribution(FlexItem const& flex_item) const
+float FlexFormattingContext::calculate_cross_max_content_contribution(FlexItem const& item) const
 {
 {
-    auto outer_max_content_size = [&] {
-        auto inner_cross_size = calculate_max_content_cross_size(flex_item);
-        auto outer_cross_size = inner_cross_size
-            + flex_item.margins.cross_before + flex_item.margins.cross_after
-            + flex_item.borders.cross_before + flex_item.borders.cross_after
-            + flex_item.padding.cross_before + flex_item.padding.cross_after;
-        return outer_cross_size;
+    auto larger_size = [&] {
+        auto inner_max_content_size = calculate_max_content_cross_size(item);
+        if (computed_cross_size(item.box).is_auto())
+            return inner_max_content_size;
+        auto inner_preferred_size = !is_row_layout() ? get_pixel_width(item.box, computed_cross_size(item.box)) : get_pixel_height(item.box, computed_cross_size(item.box));
+        return max(inner_max_content_size, inner_preferred_size);
     }();
     }();
 
 
-    if (!has_definite_cross_size(flex_item.box)) {
-        return outer_max_content_size;
-    }
+    auto clamp_min = has_cross_min_size(item.box) ? specified_cross_min_size(item.box) : 0;
+    auto clamp_max = has_cross_max_size(item.box) ? specified_cross_max_size(item.box) : NumericLimits<float>::max();
+    auto clamped_inner_size = css_clamp(larger_size, clamp_min, clamp_max);
 
 
-    auto clamp_min = has_cross_min_size(flex_item.box) ? specified_cross_min_size(flex_item.box) : 0;
-    auto clamp_max = has_cross_max_size(flex_item.box) ? specified_cross_max_size(flex_item.box) : NumericLimits<float>::max();
-    auto unclamped_preferred_size = resolved_definite_cross_size(flex_item.box);
-    auto clamped_preferred_size = css_clamp(unclamped_preferred_size, clamp_min, clamp_max);
-    return max(outer_max_content_size, clamped_preferred_size);
+    return item.add_cross_margin_box_sizes(clamped_inner_size);
 }
 }
 
 
 float FlexFormattingContext::calculate_min_content_main_size(FlexItem const& item) const
 float FlexFormattingContext::calculate_min_content_main_size(FlexItem const& item) const