mirror of
https://github.com/bevyengine/bevy
synced 2024-11-21 20:23:28 +00:00
Text2d scalefactor change detection fix (#16264)
# Objective Text2d doesn't respond to changes to the window scalefactor. Fixes #16223 ## Solution In `update_text2d_layout` store the previous scale factor in a `Local` instead and check against the current scale factor to detect changes. It seems like previously the text wasn't updated because of a bug with the `WindowScaleFactorChanged` event and it isn't emitted after changes to the scale factor. That needs to be looked into, but this will work for now. ## Testing Really simple app that draws a big message in the middle of the window: ``` use bevy::prelude::*; fn main() { App::new() .add_plugins(DefaultPlugins) .add_systems(Startup, setup) .run(); } fn setup(mut commands: Commands) { commands.spawn(Camera2d); commands.spawn(( Text2d::new("Hello"), TextFont { font_size: 400., ..Default::default() }, )); } ``` Looks fine: <img width="500" alt="hello1" src="https://github.com/user-attachments/assets/5320746b-687e-4682-9e4c-bc43ab7ff9d3"> On main, after changing the monitor's scale factor: <img width="500" alt="hello2" src="https://github.com/user-attachments/assets/486cea16-fc44-4d66-9468-6f68905d4196"> With this PR the text maintains the same size and position after the scale factor is changed.
This commit is contained in:
parent
bf9971f239
commit
c0fbadbc4c
1 changed files with 6 additions and 8 deletions
|
@ -11,7 +11,6 @@ use bevy_ecs::component::Component;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
change_detection::{DetectChanges, Ref},
|
change_detection::{DetectChanges, Ref},
|
||||||
entity::Entity,
|
entity::Entity,
|
||||||
event::EventReader,
|
|
||||||
prelude::{ReflectComponent, With},
|
prelude::{ReflectComponent, With},
|
||||||
query::{Changed, Without},
|
query::{Changed, Without},
|
||||||
system::{Commands, Local, Query, Res, ResMut},
|
system::{Commands, Local, Query, Res, ResMut},
|
||||||
|
@ -30,7 +29,7 @@ use bevy_sprite::{Anchor, ExtractedSprite, ExtractedSprites, SpriteSource, Textu
|
||||||
use bevy_transform::components::Transform;
|
use bevy_transform::components::Transform;
|
||||||
use bevy_transform::prelude::GlobalTransform;
|
use bevy_transform::prelude::GlobalTransform;
|
||||||
use bevy_utils::HashSet;
|
use bevy_utils::HashSet;
|
||||||
use bevy_window::{PrimaryWindow, Window, WindowScaleFactorChanged};
|
use bevy_window::{PrimaryWindow, Window};
|
||||||
|
|
||||||
/// [`Text2dBundle`] was removed in favor of required components.
|
/// [`Text2dBundle`] was removed in favor of required components.
|
||||||
/// The core component is now [`Text2d`] which can contain a single text segment.
|
/// The core component is now [`Text2d`] which can contain a single text segment.
|
||||||
|
@ -235,12 +234,12 @@ pub fn extract_text2d_sprite(
|
||||||
/// It does not modify or observe existing ones.
|
/// It does not modify or observe existing ones.
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn update_text2d_layout(
|
pub fn update_text2d_layout(
|
||||||
|
mut last_scale_factor: Local<f32>,
|
||||||
// Text items which should be reprocessed again, generally when the font hasn't loaded yet.
|
// Text items which should be reprocessed again, generally when the font hasn't loaded yet.
|
||||||
mut queue: Local<HashSet<Entity>>,
|
mut queue: Local<HashSet<Entity>>,
|
||||||
mut textures: ResMut<Assets<Image>>,
|
mut textures: ResMut<Assets<Image>>,
|
||||||
fonts: Res<Assets<Font>>,
|
fonts: Res<Assets<Font>>,
|
||||||
windows: Query<&Window, With<PrimaryWindow>>,
|
windows: Query<&Window, With<PrimaryWindow>>,
|
||||||
mut scale_factor_changed: EventReader<WindowScaleFactorChanged>,
|
|
||||||
mut texture_atlases: ResMut<Assets<TextureAtlasLayout>>,
|
mut texture_atlases: ResMut<Assets<TextureAtlasLayout>>,
|
||||||
mut font_atlas_sets: ResMut<FontAtlasSets>,
|
mut font_atlas_sets: ResMut<FontAtlasSets>,
|
||||||
mut text_pipeline: ResMut<TextPipeline>,
|
mut text_pipeline: ResMut<TextPipeline>,
|
||||||
|
@ -255,9 +254,6 @@ pub fn update_text2d_layout(
|
||||||
mut font_system: ResMut<CosmicFontSystem>,
|
mut font_system: ResMut<CosmicFontSystem>,
|
||||||
mut swash_cache: ResMut<SwashCache>,
|
mut swash_cache: ResMut<SwashCache>,
|
||||||
) {
|
) {
|
||||||
// We need to consume the entire iterator, hence `last`
|
|
||||||
let factor_changed = scale_factor_changed.read().last().is_some();
|
|
||||||
|
|
||||||
// TODO: Support window-independent scaling: https://github.com/bevyengine/bevy/issues/5621
|
// TODO: Support window-independent scaling: https://github.com/bevyengine/bevy/issues/5621
|
||||||
let scale_factor = windows
|
let scale_factor = windows
|
||||||
.get_single()
|
.get_single()
|
||||||
|
@ -266,6 +262,9 @@ pub fn update_text2d_layout(
|
||||||
|
|
||||||
let inverse_scale_factor = scale_factor.recip();
|
let inverse_scale_factor = scale_factor.recip();
|
||||||
|
|
||||||
|
let factor_changed = *last_scale_factor != scale_factor;
|
||||||
|
*last_scale_factor = scale_factor;
|
||||||
|
|
||||||
for (entity, block, bounds, text_layout_info, mut computed) in &mut text_query {
|
for (entity, block, bounds, text_layout_info, mut computed) in &mut text_query {
|
||||||
if factor_changed
|
if factor_changed
|
||||||
|| computed.needs_rerender()
|
|| computed.needs_rerender()
|
||||||
|
@ -359,7 +358,7 @@ mod tests {
|
||||||
|
|
||||||
use bevy_app::{App, Update};
|
use bevy_app::{App, Update};
|
||||||
use bevy_asset::{load_internal_binary_asset, Handle};
|
use bevy_asset::{load_internal_binary_asset, Handle};
|
||||||
use bevy_ecs::{event::Events, schedule::IntoSystemConfigs};
|
use bevy_ecs::schedule::IntoSystemConfigs;
|
||||||
|
|
||||||
use crate::{detect_text_needs_rerender, TextIterScratch};
|
use crate::{detect_text_needs_rerender, TextIterScratch};
|
||||||
|
|
||||||
|
@ -374,7 +373,6 @@ mod tests {
|
||||||
.init_resource::<Assets<Image>>()
|
.init_resource::<Assets<Image>>()
|
||||||
.init_resource::<Assets<TextureAtlasLayout>>()
|
.init_resource::<Assets<TextureAtlasLayout>>()
|
||||||
.init_resource::<FontAtlasSets>()
|
.init_resource::<FontAtlasSets>()
|
||||||
.init_resource::<Events<WindowScaleFactorChanged>>()
|
|
||||||
.init_resource::<TextPipeline>()
|
.init_resource::<TextPipeline>()
|
||||||
.init_resource::<CosmicFontSystem>()
|
.init_resource::<CosmicFontSystem>()
|
||||||
.init_resource::<SwashCache>()
|
.init_resource::<SwashCache>()
|
||||||
|
|
Loading…
Reference in a new issue