Skip to content

Commit

Permalink
TextLayoutInfo::size should hold the drawn size of the text, and no…
Browse files Browse the repository at this point in the history
…t 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.
  • Loading branch information
ickshonpe authored Sep 11, 2023
1 parent f3ab38a commit 9d9750b
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 11 deletions.
7 changes: 5 additions & 2 deletions crates/bevy_text/src/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -97,7 +97,10 @@ impl TextPipeline {
y_axis_orientation,
)?;

Ok(TextLayoutInfo { glyphs, size })
Ok(TextLayoutInfo {
glyphs,
logical_size: size,
})
}
}

Expand Down
16 changes: 11 additions & 5 deletions crates/bevy_text/src/text2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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(
Expand All @@ -182,7 +185,6 @@ pub fn update_text2d_layout(
},
scale_value(bounds.size.y, scale_factor),
);

match text_pipeline.queue_text(
&fonts,
&text.sections,
Expand All @@ -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;
}
}
}
}
Expand Down
13 changes: 9 additions & 4 deletions crates/bevy_ui/src/widget/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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>,
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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() {
Expand All @@ -240,6 +243,7 @@ pub fn text_system(
&mut textures,
&text_settings,
scale_factor,
inverse_scale_factor,
text,
node,
text_flags,
Expand All @@ -261,6 +265,7 @@ pub fn text_system(
&mut textures,
&text_settings,
scale_factor,
inverse_scale_factor,
text,
node,
text_flags,
Expand Down

0 comments on commit 9d9750b

Please sign in to comment.