tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 231Rust 9TOML 3CSS 1345 Sutichaykuna

Pass cross-axis known_dimension when computing flex item min size (0.3.x) (#544)

* Pass cross-axis known_dimension when computing flex item min size

(fixes sizing of children that have inherent aspect ratio (e.g. images))

* Update changelog for inherent aspect ratio fix

83ea1eab8b724c37f4d77cce0f40e04c219a5378 · ruwaq Nico Burns · (3 wata ñawpaq) · tayta a0344e273 · kay commitpi sach'ata qhaway

Semántico sayk'uy · 3

src/compute/flexbox.rs

tests/caching.rs

3 qillqakuna · +24 −21

diff --git a/RELEASES.md b/RELEASES.md
index 77c4b193b..d7c635ccc 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,5 +1,11 @@
 # Release Notes
 
+## 0.3.14
+
+### Fixes
+
+- Flex: Fix issue where constraints were not being propagated, causing nodes with inherent aspect-ratio (typically images) to not apply that aspect-ratio (#545) (Fixes bevyengine/bevy#9841)
+
 ## 0.3.13
 
 ### Fixes
diff --git a/src/compute/flexbox.rs b/src/compute/flexbox.rs
index 55eb0b927..88b326f78 100644
--- a/src/compute/flexbox.rs
+++ b/src/compute/flexbox.rs
@@ -602,12 +602,26 @@ fn determine_flex_base_size(
 
         // Parent size for child sizing
         let cross_axis_parent_size = constants.node_inner_size.cross(dir);
+        let child_parent_size = Size::NONE.with_cross(dir, cross_axis_parent_size);
 
         // Available space for child sizing
         let cross_axis_margin_sum = constants.margin.cross_axis_sum(dir);
         let child_min_cross = child.min_size.cross(dir).maybe_add(cross_axis_margin_sum);
         let child_max_cross = child.max_size.cross(dir).maybe_add(cross_axis_margin_sum);
-        let cross_axis_available_space = cross_axis_parent_size.maybe_clamp(child_min_cross, child_max_cross).into();
+        let cross_axis_available_space: AvailableSpace =
+            cross_axis_parent_size.maybe_clamp(child_min_cross, child_max_cross).into();
+
+        // Known dimension for child sizing
+        let child_known_dimensions = {
+            let mut ckd = child.size.with_main(dir, None);
+            if child.align_self == AlignSelf::Stretch && ckd.cross(dir).is_none() {
+                ckd.set_cross(
+                    dir,
+                    cross_axis_available_space.into_option().maybe_sub(child.margin.cross_axis_sum(dir)),
+                );
+            }
+            ckd
+        };
 
         child.flex_basis = 'flex_basis: {
             // A. If the item has a definite used flex basis, that’s the flex base size.
@@ -650,24 +664,8 @@ fn determine_flex_base_size(
             //    is auto and not definite, in this calculation use fit-content as the
             //    flex item’s cross size. The flex base size is the item’s resulting main size.
 
-            let child_parent_size = Size::NONE.with_cross(dir, cross_axis_parent_size);
             let child_available_space = available_space.with_cross(dir, cross_axis_available_space);
 
-            let child_known_dimensions = {
-                let mut ckd = child.size;
-                if child.align_self == AlignSelf::Stretch && ckd.cross(dir).is_none() {
-                    ckd.set_cross(
-                        dir,
-                        child_available_space
-                            .cross(dir)
-                            .into_option()
-                            .maybe_clamp(child_min_cross, child_max_cross)
-                            .maybe_sub(child.margin.cross_axis_sum(dir)),
-                    );
-                }
-                ckd
-            };
-
             break 'flex_basis GenericAlgorithm::measure_size(
                 tree,
                 child.node,
@@ -712,13 +710,12 @@ fn determine_flex_base_size(
         //
         // See https://drafts.csswg.org/css-sizing-3/#min-percentage-contribution
         let min_content_size = {
-            let child_parent_size = Size::NONE.with_cross(dir, cross_axis_parent_size);
             let child_available_space = Size::MIN_CONTENT.with_cross(dir, cross_axis_available_space);
 
             GenericAlgorithm::measure_size(
                 tree,
                 child.node,
-                Size::NONE,
+                child_known_dimensions,
                 child_parent_size,
                 child_available_space,
                 SizingMode::ContentSize,
diff --git a/tests/caching.rs b/tests/caching.rs
index 581ce43e9..d52185824 100644
--- a/tests/caching.rs
+++ b/tests/caching.rs
@@ -30,7 +30,7 @@ mod caching {
 
         taffy.compute_layout(node, Size::MAX_CONTENT).unwrap();
 
-        assert_eq!(NUM_MEASURES.load(Ordering::SeqCst), 8);
+        assert_eq!(NUM_MEASURES.load(Ordering::SeqCst), 5);
     }
 
     #[test]
@@ -62,6 +62,6 @@ mod caching {
         }
 
         taffy.compute_layout(node, Size::MAX_CONTENT).unwrap();
-        assert_eq!(NUM_MEASURES.load(Ordering::SeqCst), 8);
+        assert_eq!(NUM_MEASURES.load(Ordering::SeqCst), 5);
     }
 }