gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 708HTML 661Markdown 12TOML 62346 Sutichaykuna

Pass cross-axis known_dimension when computing flex item min size (#545)

* 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

120bb7a2e501822b324fd48de955450ebbba1c1a · ruwaq Nico Burns · (3 wata ñawpaq) · tayta 65bedf128 · kay commitpi sach'ata qhaway

Semántico sayk'uy · 1

src/compute/flexbox.rs

2 qillqakuna · +20 −18

diff --git a/RELEASES.md b/RELEASES.md
index fe4a13471..63b59671e 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -50,6 +50,12 @@ Example usage change:
   - All types from the `node`, `data`, `layout`, `error` and `cache` modules have been moved to the  the `tree` module.
 - Fixed misspelling: `RunMode::PeformLayout` renamed into `RunMode::PerformLayout` (added missing `r`).
 
+## 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 3fff92e12..689b82717 100644
--- a/src/compute/flexbox.rs
+++ b/src/compute/flexbox.rs
@@ -628,6 +628,7 @@ 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);
@@ -638,6 +639,18 @@ fn determine_flex_base_size(
             .map_definite_value(|val| cross_axis_parent_size.unwrap_or(val))
             .maybe_clamp(child_min_cross, child_max_cross);
 
+        // Known dimensions 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.
 
@@ -679,7 +692,6 @@ 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 = Size::MAX_CONTENT
                 .with_main(
                     dir,
@@ -692,21 +704,6 @@ fn determine_flex_base_size(
                 )
                 .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 tree
                 .measure_child_size(
                     child.node,
@@ -756,12 +753,11 @@ fn determine_flex_base_size(
 
         child.resolved_minimum_main_size = style_min_main_size.unwrap_or({
             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);
 
                 tree.measure_child_size(
                     child.node,
-                    Size::NONE,
+                    child_known_dimensions,
                     child_parent_size,
                     child_available_space,
                     SizingMode::ContentSize,