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.
This commit is contained in:
ickshonpe 2022-12-20 16:44:12 +00:00
parent a5106c841f
commit 8545580214
3 changed files with 15 additions and 8 deletions

View file

@ -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<F: ReadOnlyWorldQuery>(
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);
}

View file

@ -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

View file

@ -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;
}
}
}