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 · 2023-10-02T22:36:20Z (3 wata ñawpaq) · tayta a0344e273 · kay commitpi sach'ata qhaway
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);
}
}