From ff661ea694428468a716e9a094f9fb188217b084 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Tue, 20 Dec 2022 16:44:12 +0000 Subject: [PATCH] text aspect ratio bug fix (#6825) ## Objective Bevy UI uses a `MeasureFunc` that preserves the aspect ratio of text, not just images. This means that the extent of flex-items containing text may be calculated incorrectly depending on the ratio of the text size compared to the size of its containing node. Fixes #6748 Related to #6724 with Bevy 0.9: ![Capture_cols_0 9](https://user-images.githubusercontent.com/27962798/205435999-386d3400-fe9b-475a-aab1-18e61c4c074f.PNG) with this PR (accurately matching the behavior of Flexbox): ![Capture_fixed](https://user-images.githubusercontent.com/27962798/205436005-6bafbcc2-cd87-4eb7-b5c6-9dbcb30fc795.PNG) ## Solution Only perform the aspect ratio calculations if the uinode contains an image. ## Changelog * Added a field `preserve_aspect_ratio` to `CalculatedSize` * The `MeasureFunc` only preserves the aspect ratio when `preserve_aspect_ratio` is true. * `update_image_calculated_size_system` sets `preserve_aspect_ratio` to true for nodes with images. --- crates/bevy_ui/src/flex/mod.rs | 20 ++++++++++++-------- crates/bevy_ui/src/ui_node.rs | 2 ++ crates/bevy_ui/src/widget/image.rs | 1 + 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/crates/bevy_ui/src/flex/mod.rs b/crates/bevy_ui/src/flex/mod.rs index ebe6e1ad4d394..da31a692d5630 100644 --- a/crates/bevy_ui/src/flex/mod.rs +++ b/crates/bevy_ui/src/flex/mod.rs @@ -86,11 +86,15 @@ impl FlexSurface { match (constraints.width, constraints.height) { (Number::Undefined, Number::Undefined) => {} (Number::Defined(width), Number::Undefined) => { - size.height = width * size.height / size.width; + if calculated_size.preserve_aspect_ratio { + size.height = width * size.height / size.width; + } size.width = width; } (Number::Undefined, Number::Defined(height)) => { - size.width = height * size.width / size.height; + if calculated_size.preserve_aspect_ratio { + size.width = height * size.width / size.height; + } size.height = height; } (Number::Defined(width), Number::Defined(height)) => { @@ -236,12 +240,6 @@ pub fn flex_node_system( let logical_to_physical_factor = windows.scale_factor(WindowId::primary()); let scale_factor = logical_to_physical_factor * ui_scale.scale; - if scale_factor_events.iter().next_back().is_some() || ui_scale.is_changed() { - update_changed(&mut flex_surface, scale_factor, full_node_query); - } else { - update_changed(&mut flex_surface, scale_factor, node_query); - } - fn update_changed( flex_surface: &mut FlexSurface, scaling_factor: f64, @@ -258,6 +256,12 @@ pub fn flex_node_system( } } + if scale_factor_events.iter().next_back().is_some() || ui_scale.is_changed() { + update_changed(&mut flex_surface, scale_factor, full_node_query); + } else { + update_changed(&mut flex_surface, scale_factor, node_query); + } + for (entity, style, calculated_size) in &changed_size_query { flex_surface.upsert_leaf(entity, style, *calculated_size, scale_factor); } diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 738d578d6e5a3..bc6661b2ed81c 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -434,6 +434,8 @@ pub enum FlexWrap { pub struct CalculatedSize { /// The size of the node pub size: Size, + /// Whether to attempt to preserve the aspect ratio when determing the layout for this item + pub preserve_aspect_ratio: bool, } /// The background color of the node diff --git a/crates/bevy_ui/src/widget/image.rs b/crates/bevy_ui/src/widget/image.rs index 2916a6295223a..fa2e011232cec 100644 --- a/crates/bevy_ui/src/widget/image.rs +++ b/crates/bevy_ui/src/widget/image.rs @@ -21,6 +21,7 @@ pub fn update_image_calculated_size_system( // Update only if size has changed to avoid needless layout calculations if size != calculated_size.size { calculated_size.size = size; + calculated_size.preserve_aspect_ratio = true; } } }