diff --git a/crates/bevy_ui/src/widget/text.rs b/crates/bevy_ui/src/widget/text.rs index a84a6689f1f47..0bad77d4eeb1d 100644 --- a/crates/bevy_ui/src/widget/text.rs +++ b/crates/bevy_ui/src/widget/text.rs @@ -12,7 +12,7 @@ use bevy_ecs::{ query::With, reflect::ReflectComponent, system::{Query, Res, ResMut}, - world::{Mut, Ref}, + world::Ref, }; use bevy_image::prelude::*; use bevy_math::Vec2; @@ -215,49 +215,6 @@ impl Measure for TextMeasure { } } -#[inline] -fn create_text_measure<'a>( - entity: Entity, - fonts: &Assets, - scale_factor: f64, - spans: impl Iterator, - block: Ref, - text_pipeline: &mut TextPipeline, - mut content_size: Mut, - mut text_flags: Mut, - mut computed: Mut, - font_system: &mut CosmicFontSystem, -) { - match text_pipeline.create_text_measure( - entity, - fonts, - spans, - scale_factor, - &block, - computed.as_mut(), - font_system, - ) { - Ok(measure) => { - if block.linebreak == LineBreak::NoWrap { - content_size.set(NodeMeasure::Fixed(FixedMeasure { size: measure.max })); - } else { - content_size.set(NodeMeasure::Text(TextMeasure { info: measure })); - } - - // Text measure func created successfully, so set `TextNodeFlags` to schedule a recompute - text_flags.needs_measure_fn = false; - text_flags.needs_recompute = true; - } - Err(TextError::NoSuchFont) => { - // Try again next frame - text_flags.needs_measure_fn = true; - } - Err(e @ (TextError::FailedToAddGlyph(_) | TextError::FailedToGetGlyphImage(_))) => { - panic!("Fatal error when processing text: {e}."); - } - }; -} - /// Generates a new [`Measure`] for a text node on changes to its [`Text`] component. /// /// A `Measure` is used by the UI's layout algorithm to determine the appropriate amount of space @@ -286,92 +243,55 @@ pub fn measure_text_system( mut text_pipeline: ResMut, mut font_system: ResMut, ) { - for (entity, block, content_size, text_flags, computed, computed_target, computed_node) in - &mut text_query + for ( + entity, + block, + mut content_size, + mut text_flags, + mut computed, + computed_target, + computed_node, + ) in &mut text_query { // Note: the ComputedTextBlock::needs_rerender bool is cleared in create_text_measure(). // 1e-5 epsilon to ignore tiny scale factor float errors - if 1e-5 + if !(1e-5 < (computed_target.scale_factor() - computed_node.inverse_scale_factor.recip()).abs() || computed.needs_rerender() || text_flags.needs_measure_fn - || content_size.is_added() + || content_size.is_added()) { - create_text_measure( - entity, - &fonts, - computed_target.scale_factor.into(), - text_reader.iter(entity), - block, - &mut text_pipeline, - content_size, - text_flags, - computed, - &mut font_system, - ); + continue; } - } -} - -#[inline] -fn queue_text( - entity: Entity, - fonts: &Assets, - text_pipeline: &mut TextPipeline, - font_atlas_set: &mut FontAtlasSet, - texture_atlases: &mut Assets, - textures: &mut Assets, - scale_factor: f32, - inverse_scale_factor: f32, - block: &TextLayout, - node: Ref, - mut text_flags: Mut, - text_layout_info: Mut, - computed: &mut ComputedTextBlock, - text_reader: &mut TextUiReader, - font_system: &mut CosmicFontSystem, - swash_cache: &mut SwashCache, -) { - // Skip the text node if it is waiting for a new measure func - if text_flags.needs_measure_fn { - return; - } - let physical_node_size = if block.linebreak == LineBreak::NoWrap { - // With `NoWrap` set, no constraints are placed on the width of the text. - TextBounds::UNBOUNDED - } else { - // `scale_factor` is already multiplied by `UiScale` - TextBounds::new(node.unrounded_size.x, node.unrounded_size.y) - }; + match text_pipeline.create_text_measure( + entity, + fonts.as_ref(), + text_reader.iter(entity), + computed_target.scale_factor.into(), + &block, + computed.as_mut(), + &mut font_system, + ) { + Ok(measure) => { + if block.linebreak == LineBreak::NoWrap { + content_size.set(NodeMeasure::Fixed(FixedMeasure { size: measure.max })); + } else { + content_size.set(NodeMeasure::Text(TextMeasure { info: measure })); + } - let text_layout_info = text_layout_info.into_inner(); - match text_pipeline.queue_text( - text_layout_info, - fonts, - text_reader.iter(entity), - scale_factor.into(), - block, - physical_node_size, - font_atlas_set, - texture_atlases, - textures, - computed, - font_system, - swash_cache, - ) { - Err(TextError::NoSuchFont) => { - // There was an error processing the text layout, try again next frame - text_flags.needs_recompute = true; - } - Err(e @ (TextError::FailedToAddGlyph(_) | TextError::FailedToGetGlyphImage(_))) => { - panic!("Fatal error when processing text: {e}."); - } - Ok(()) => { - text_layout_info.scale_factor = scale_factor; - text_layout_info.size *= inverse_scale_factor; - text_flags.needs_recompute = false; - } + // Text measure func created successfully, so set `TextNodeFlags` to schedule a recompute + text_flags.needs_measure_fn = false; + text_flags.needs_recompute = true; + } + Err(TextError::NoSuchFont) => { + // Try again next frame + text_flags.needs_measure_fn = true; + } + Err(e @ (TextError::FailedToAddGlyph(_) | TextError::FailedToGetGlyphImage(_))) => { + panic!("Fatal error when processing text: {e}."); + } + }; } } @@ -401,26 +321,51 @@ pub fn text_system( mut font_system: ResMut, mut swash_cache: ResMut, ) { - for (entity, node, block, text_layout_info, text_flags, mut computed) in &mut text_query { - if node.is_changed() || text_flags.needs_recompute { - queue_text( - entity, - &fonts, - &mut text_pipeline, - &mut font_atlas_set, - &mut texture_atlases, - &mut textures, - node.inverse_scale_factor.recip(), - node.inverse_scale_factor, - block, - node, - text_flags, - text_layout_info, - computed.as_mut(), - &mut text_reader, - &mut font_system, - &mut swash_cache, - ); + for (entity, node, block, text_layout_info, mut text_flags, mut computed) in &mut text_query { + // Skip the text node if it is waiting for a new measure func + if text_flags.needs_measure_fn { + continue; + } + + if !(node.is_changed() || text_flags.needs_recompute) { + continue; + } + + let physical_node_size = if block.linebreak == LineBreak::NoWrap { + // With `NoWrap` set, no constraints are placed on the width of the text. + TextBounds::UNBOUNDED + } else { + // `scale_factor` is already multiplied by `UiScale` + TextBounds::new(node.unrounded_size.x, node.unrounded_size.y) + }; + + let text_layout_info = text_layout_info.into_inner(); + match text_pipeline.queue_text( + text_layout_info, + &fonts, + text_reader.iter(entity), + node.inverse_scale_factor.recip() as f64, + block, + physical_node_size, + &mut font_atlas_set, + &mut texture_atlases, + &mut textures, + &mut computed, + &mut font_system, + &mut swash_cache, + ) { + Err(TextError::NoSuchFont) => { + // There was an error processing the text layout, try again next frame + text_flags.needs_recompute = true; + } + Err(e @ (TextError::FailedToAddGlyph(_) | TextError::FailedToGetGlyphImage(_))) => { + panic!("Fatal error when processing text: {e}."); + } + Ok(()) => { + text_layout_info.scale_factor = node.inverse_scale_factor.recip(); + text_layout_info.size *= node.inverse_scale_factor; + text_flags.needs_recompute = false; + } } } }