TextLayoutInfo::size should hold the drawn size of the text, and not a scaled value. (#7794)

# Objective

`TextLayoutInfo::size` isn't the drawn size of the text, but a scaled
value. This is fragile, counter-intuitive and makes it awkward to
retrieve the correct value.

## Solution

Multiply `TextLayoutInfo::size` by the reciprocal of the window's scale
factor after generating the text layout in `update_text2d_layout` and
`bevy_ui::widget::text_system`.

---

fixes: #7787

## Changelog

* Multiply `TextLayoutInfo::size` by the reciprocal of the scale factor
after text computation to reflect the actual size of the text as drawn.
* Reorder the operations in `extract_text2d_sprite` to apply the
alignment offset before the scale factor scaling.

## Migration Guide

The `size` value of `TextLayoutInfo` is stored in logical pixels and has
been renamed to `logical_size`. There is no longer any need to divide by
the window's scale factor to get the logical size.
This commit is contained in:
ickshonpe 2023-09-11 19:56:16 +01:00 committed by GitHub
parent f3ab38a802
commit 9d9750b928
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 11 deletions

View file

@ -25,7 +25,7 @@ pub struct TextPipeline {
#[derive(Component, Clone, Default, Debug)]
pub struct TextLayoutInfo {
pub glyphs: Vec<PositionedGlyph>,
pub size: Vec2,
pub logical_size: Vec2,
}
impl TextPipeline {
@ -97,7 +97,10 @@ impl TextPipeline {
y_axis_orientation,
)?;
Ok(TextLayoutInfo { glyphs, size })
Ok(TextLayoutInfo {
glyphs,
logical_size: size,
})
}
}

View file

@ -36,6 +36,7 @@ use bevy_window::{PrimaryWindow, Window, WindowScaleFactorChanged};
#[derive(Component, Copy, Clone, Debug, Reflect)]
#[reflect(Component)]
pub struct Text2dBounds {
/// The maximum width and height of text in logical pixels.
pub size: Vec2,
}
@ -105,10 +106,10 @@ pub fn extract_text2d_sprite(
}
let text_anchor = -(anchor.as_vec() + 0.5);
let alignment_translation = text_layout_info.size * text_anchor;
let alignment_translation = text_layout_info.logical_size * text_anchor;
let transform = *global_transform
* scaling
* GlobalTransform::from_translation(alignment_translation.extend(0.));
* GlobalTransform::from_translation(alignment_translation.extend(0.))
* scaling;
let mut color = Color::WHITE;
let mut current_section = usize::MAX;
for PositionedGlyph {
@ -172,6 +173,8 @@ pub fn update_text2d_layout(
.map(|window| window.resolution.scale_factor())
.unwrap_or(1.0);
let inverse_scale_factor = scale_factor.recip();
for (entity, text, bounds, mut text_layout_info) in &mut text_query {
if factor_changed || text.is_changed() || bounds.is_changed() || queue.remove(&entity) {
let text_bounds = Vec2::new(
@ -182,7 +185,6 @@ pub fn update_text2d_layout(
},
scale_value(bounds.size.y, scale_factor),
);
match text_pipeline.queue_text(
&fonts,
&text.sections,
@ -205,7 +207,11 @@ pub fn update_text2d_layout(
Err(e @ TextError::FailedToAddGlyph(_)) => {
panic!("Fatal error when processing text: {e}.");
}
Ok(info) => *text_layout_info = info,
Ok(mut info) => {
info.logical_size.x = scale_value(info.logical_size.x, inverse_scale_factor);
info.logical_size.y = scale_value(info.logical_size.y, inverse_scale_factor);
*text_layout_info = info;
}
}
}
}

View file

@ -12,8 +12,8 @@ use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use bevy_render::texture::Image;
use bevy_sprite::TextureAtlas;
use bevy_text::{
BreakLineOn, Font, FontAtlasSets, FontAtlasWarning, Text, TextError, TextLayoutInfo,
TextMeasureInfo, TextPipeline, TextSettings, YAxisOrientation,
scale_value, BreakLineOn, Font, FontAtlasSets, FontAtlasWarning, Text, TextError,
TextLayoutInfo, TextMeasureInfo, TextPipeline, TextSettings, YAxisOrientation,
};
use bevy_window::{PrimaryWindow, Window};
use taffy::style::AvailableSpace;
@ -153,6 +153,7 @@ fn queue_text(
textures: &mut Assets<Image>,
text_settings: &TextSettings,
scale_factor: f64,
inverse_scale_factor: f64,
text: &Text,
node: Ref<Node>,
mut text_flags: Mut<TextFlags>,
@ -189,7 +190,9 @@ fn queue_text(
Err(e @ TextError::FailedToAddGlyph(_)) => {
panic!("Fatal error when processing text: {e}.");
}
Ok(info) => {
Ok(mut info) => {
info.logical_size.x = scale_value(info.logical_size.x, inverse_scale_factor);
info.logical_size.y = scale_value(info.logical_size.y, inverse_scale_factor);
*text_layout_info = info;
text_flags.needs_recompute = false;
}
@ -226,7 +229,7 @@ pub fn text_system(
.unwrap_or(1.);
let scale_factor = ui_scale.0 * window_scale_factor;
let inverse_scale_factor = scale_factor.recip();
if *last_scale_factor == scale_factor {
// Scale factor unchanged, only recompute text for modified text nodes
for (node, text, text_layout_info, text_flags) in text_query.iter_mut() {
@ -240,6 +243,7 @@ pub fn text_system(
&mut textures,
&text_settings,
scale_factor,
inverse_scale_factor,
text,
node,
text_flags,
@ -261,6 +265,7 @@ pub fn text_system(
&mut textures,
&text_settings,
scale_factor,
inverse_scale_factor,
text,
node,
text_flags,