diff --git a/crates/bevy_text/src/glyph.rs b/crates/bevy_text/src/glyph.rs index ebae713af4856..fb590d1719166 100644 --- a/crates/bevy_text/src/glyph.rs +++ b/crates/bevy_text/src/glyph.rs @@ -9,7 +9,7 @@ use bevy_reflect::Reflect; /// /// Contains information about how and where to render a glyph. /// -/// Used in [`TextPipeline::queue_text`](crate::TextPipeline::queue_text) and [`crate::TextLayoutInfo`] for rendering glyphs. +/// Used in [`TextPipeline::queue_text`](crate::TextPipeline::queue_text) and [`crate::ComputedTextLayout`] for rendering glyphs. #[derive(Debug, Clone, Reflect)] #[reflect(Clone)] pub struct PositionedGlyph { @@ -19,7 +19,7 @@ pub struct PositionedGlyph { pub size: Vec2, /// Information about the glyph's atlas. pub atlas_info: GlyphAtlasInfo, - /// The index of the glyph in the [`ComputedTextBlock`](crate::ComputedTextBlock)'s tracked spans. + /// The index of the glyph in the [`TextBuffer`](crate::TextBuffer)'s tracked spans. pub span_index: usize, /// The index of the glyph's line. pub line_index: usize, diff --git a/crates/bevy_text/src/lib.rs b/crates/bevy_text/src/lib.rs index 2bc74a1aa7acf..0cd4256a35809 100644 --- a/crates/bevy_text/src/lib.rs +++ b/crates/bevy_text/src/lib.rs @@ -26,7 +26,7 @@ //! 1. updates a [`Buffer`](cosmic_text::Buffer) from the [`TextSpan`]s, generating new [`FontAtlasSet`]s if necessary. //! 2. iterates over each glyph in the [`Buffer`](cosmic_text::Buffer) to create a [`PositionedGlyph`], //! retrieving glyphs from the cache, or rasterizing to a [`FontAtlas`] if necessary. -//! 3. [`PositionedGlyph`]s are stored in a [`TextLayoutInfo`], +//! 3. [`PositionedGlyph`]s are stored in a [`ComputedTextLayout`], //! which contains all the information that downstream systems need for rendering. extern crate alloc; @@ -62,7 +62,7 @@ pub mod prelude { #[doc(hidden)] pub use crate::{ Font, JustifyText, LineBreak, Text2d, Text2dReader, Text2dWriter, TextColor, TextError, - TextFont, TextLayout, TextSpan, + TextFont, TextSpan, }; } @@ -105,8 +105,9 @@ impl Plugin for TextPlugin { .register_type::() .register_type::() .register_type::() - .register_type::() - .register_type::() + .register_type::() + .register_type::() + .register_type::() .register_type::() .init_asset_loader::() .init_resource::() diff --git a/crates/bevy_text/src/pipeline.rs b/crates/bevy_text/src/pipeline.rs index 50b983f9293c0..8681fa2714e98 100644 --- a/crates/bevy_text/src/pipeline.rs +++ b/crates/bevy_text/src/pipeline.rs @@ -16,8 +16,8 @@ use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use cosmic_text::{Attrs, Buffer, Family, Metrics, Shaping, Wrap}; use crate::{ - error::TextError, ComputedTextBlock, Font, FontAtlasSets, FontSmoothing, JustifyText, - LineBreak, PositionedGlyph, TextBounds, TextEntity, TextFont, TextLayout, + error::TextError, Font, FontAtlasSets, FontSmoothing, JustifyText, LineBreak, PositionedGlyph, + TextBounds, TextBuffer, TextEntity, TextFont, }; /// A wrapper resource around a [`cosmic_text::FontSystem`] @@ -91,7 +91,7 @@ impl TextPipeline { justify: JustifyText, bounds: TextBounds, scale_factor: f64, - computed: &mut ComputedTextBlock, + text_buffer: &mut TextBuffer, font_system: &mut CosmicFontSystem, ) -> Result<(), TextError> { let font_system = &mut font_system.0; @@ -106,11 +106,11 @@ impl TextPipeline { .map(|_| -> (usize, &str, &TextFont, FontFaceInfo, Color) { unreachable!() }) .collect(); - computed.entities.clear(); + text_buffer.entities.clear(); for (span_index, (entity, depth, span, text_font, color)) in text_spans.enumerate() { // Save this span entity in the computed text block. - computed.entities.push(TextEntity { entity, depth }); + text_buffer.entities.push(TextEntity { entity, depth }); if span.is_empty() { continue; @@ -176,7 +176,7 @@ impl TextPipeline { }); // Update the buffer. - let buffer = &mut computed.buffer; + let buffer = &mut text_buffer.buffer; buffer.set_metrics_and_size(font_system, metrics, bounds.width, bounds.height); buffer.set_wrap( @@ -219,20 +219,21 @@ impl TextPipeline { /// Queues text for rendering /// - /// Produces a [`TextLayoutInfo`], containing [`PositionedGlyph`]s + /// Produces a [`ComputedTextLayout`], containing [`PositionedGlyph`]s /// which contain information for rendering the text. pub fn queue_text<'a>( &mut self, - layout_info: &mut TextLayoutInfo, + layout_info: &mut ComputedTextLayout, fonts: &Assets, text_spans: impl Iterator, scale_factor: f64, - layout: &TextLayout, + linebreak: LineBreak, + justify: JustifyText, bounds: TextBounds, font_atlas_sets: &mut FontAtlasSets, texture_atlases: &mut Assets, textures: &mut Assets, - computed: &mut ComputedTextBlock, + computed: &mut TextBuffer, font_system: &mut CosmicFontSystem, swash_cache: &mut SwashCache, ) -> Result<(), TextError> { @@ -253,8 +254,8 @@ impl TextPipeline { let update_result = self.update_buffer( fonts, text_spans, - layout.linebreak, - layout.justify, + linebreak, + justify, bounds, scale_factor, computed, @@ -396,8 +397,9 @@ impl TextPipeline { fonts: &Assets, text_spans: impl Iterator, scale_factor: f64, - layout: &TextLayout, - computed: &mut ComputedTextBlock, + linebreak: LineBreak, + justify: JustifyText, + computed: &mut TextBuffer, font_system: &mut CosmicFontSystem, ) -> Result { const MIN_WIDTH_CONTENT_BOUNDS: TextBounds = TextBounds::new_horizontal(0.0); @@ -409,8 +411,8 @@ impl TextPipeline { self.update_buffer( fonts, text_spans, - layout.linebreak, - layout.justify, + linebreak, + justify, MIN_WIDTH_CONTENT_BOUNDS, scale_factor, computed, @@ -445,10 +447,10 @@ impl TextPipeline { /// Render information for a corresponding text block. /// /// Contains scaled glyphs and their size. Generated via [`TextPipeline::queue_text`] when an entity has -/// [`TextLayout`] and [`ComputedTextBlock`] components. +/// [`JustifyText`], [`LineBreak`] and [`TextBuffer`] components. #[derive(Component, Clone, Default, Debug, Reflect)] #[reflect(Component, Default, Debug, Clone)] -pub struct TextLayoutInfo { +pub struct ComputedTextLayout { /// Scaled and positioned glyphs in screenspace pub glyphs: Vec, /// Rects bounding the text block's text sections. @@ -458,7 +460,7 @@ pub struct TextLayoutInfo { pub size: Vec2, } -/// Size information for a corresponding [`ComputedTextBlock`] component. +/// Size information for a corresponding [`TextBuffer`] component. /// /// Generated via [`TextPipeline::create_text_measure`]. #[derive(Debug)] @@ -476,7 +478,7 @@ impl TextMeasureInfo { pub fn compute_size( &mut self, bounds: TextBounds, - computed: &mut ComputedTextBlock, + computed: &mut TextBuffer, font_system: &mut CosmicFontSystem, ) -> Vec2 { // Note that this arbitrarily adjusts the buffer layout. We assume the buffer is always 'refreshed' diff --git a/crates/bevy_text/src/text.rs b/crates/bevy_text/src/text.rs index debf9cc3756c8..e5f6df8f4cab7 100644 --- a/crates/bevy_text/src/text.rs +++ b/crates/bevy_text/src/text.rs @@ -1,4 +1,4 @@ -use crate::{Font, TextLayoutInfo, TextSpanAccess, TextSpanComponent}; +use crate::{Font, TextSpanAccess, TextSpanComponent}; use bevy_asset::Handle; use bevy_color::Color; use bevy_derive::{Deref, DerefMut}; @@ -20,32 +20,31 @@ impl Default for CosmicBuffer { } } -/// A sub-entity of a [`ComputedTextBlock`]. +/// A sub-entity of a [`TextBuffer`]. /// -/// Returned by [`ComputedTextBlock::entities`]. +/// Returned by [`TextBuffer::entities`]. #[derive(Debug, Copy, Clone, Reflect)] #[reflect(Debug, Clone)] pub struct TextEntity { /// The entity. pub entity: Entity, - /// Records the hierarchy depth of the entity within a `TextLayout`. + /// Records the hierarchy depth of the entity within a `TextBuffer`. pub depth: usize, } /// Computed information for a text block. /// -/// See [`TextLayout`]. +/// See [`ComputedTextLayout`](crate::ComputedTextLayout). /// /// Automatically updated by 2d and UI text systems. #[derive(Component, Debug, Clone, Reflect)] #[reflect(Component, Debug, Default, Clone)] -pub struct ComputedTextBlock { - /// Buffer for managing text layout and creating [`TextLayoutInfo`]. +pub struct TextBuffer { + /// Buffer for managing text layout and creating [`ComputedTextLayout`](crate::ComputedTextLayout). /// /// This is private because buffer contents are always refreshed from ECS state when writing glyphs to - /// `TextLayoutInfo`. If you want to control the buffer contents manually or use the `cosmic-text` - /// editor, then you need to not use `TextLayout` and instead manually implement the conversion to - /// `TextLayoutInfo`. + /// `ComputedTextLayout`. If you want to control the buffer contents manually or use the `cosmic-text` + /// editor, then you need to manually implement the conversion to `ComputedTextLayout`. #[reflect(ignore, clone)] pub(crate) buffer: CosmicBuffer, /// Entities for all text spans in the block, including the root-level text. @@ -55,7 +54,7 @@ pub struct ComputedTextBlock { /// Flag set when any change has been made to this block that should cause it to be rerendered. /// /// Includes: - /// - [`TextLayout`] changes. + /// - Changes to [`JustifyText`] and [`LineBreak`]. /// - [`TextFont`] or `Text2d`/`Text`/`TextSpan` changes anywhere in the block's entity hierarchy. // TODO: This encompasses both structural changes like font size or justification and non-structural // changes like text color and font smoothing. This field currently causes UI to 'remeasure' text, even if @@ -65,16 +64,16 @@ pub struct ComputedTextBlock { pub(crate) needs_rerender: bool, } -impl ComputedTextBlock { +impl TextBuffer { /// Accesses entities in this block. /// - /// Can be used to look up [`TextFont`] components for glyphs in [`TextLayoutInfo`] using the `span_index` + /// Can be used to look up [`TextFont`] components for glyphs in [`ComputedTextLayout`](crate::ComputedTextLayout) using the `span_index` /// stored there. pub fn entities(&self) -> &[TextEntity] { &self.entities } - /// Indicates if the text needs to be refreshed in [`TextLayoutInfo`]. + /// Indicates if the text needs to be refreshed in [`ComputedTextLayout`](crate::ComputedTextLayout). /// /// Updated automatically by [`detect_text_needs_rerender`] and cleared /// by [`TextPipeline`](crate::TextPipeline) methods. @@ -86,14 +85,14 @@ impl ComputedTextBlock { /// /// Mutable access is not offered because changes would be overwritten during the automated layout calculation. /// If you want to control the buffer contents manually or use the `cosmic-text` - /// editor, then you need to not use `TextLayout` and instead manually implement the conversion to - /// `TextLayoutInfo`. + /// editor, then you need to not use `TextBuffer` and instead manually implement the conversion to + /// `ComputedTextLayout`. pub fn buffer(&self) -> &CosmicBuffer { &self.buffer } } -impl Default for ComputedTextBlock { +impl Default for TextBuffer { fn default() -> Self { Self { buffer: CosmicBuffer::default(), @@ -103,79 +102,19 @@ impl Default for ComputedTextBlock { } } -/// Component with text format settings for a block of text. -/// -/// A block of text is composed of text spans, which each have a separate string value and [`TextFont`]. Text -/// spans associated with a text block are collected into [`ComputedTextBlock`] for layout, and then inserted -/// to [`TextLayoutInfo`] for rendering. -/// -/// See [`Text2d`](crate::Text2d) for the core component of 2d text, and `Text` in `bevy_ui` for UI text. -#[derive(Component, Debug, Copy, Clone, Default, Reflect)] -#[reflect(Component, Default, Debug, Clone)] -#[require(ComputedTextBlock, TextLayoutInfo)] -pub struct TextLayout { - /// The text's internal alignment. - /// Should not affect its position within a container. - pub justify: JustifyText, - /// How the text should linebreak when running out of the bounds determined by `max_size`. - pub linebreak: LineBreak, -} - -impl TextLayout { - /// Makes a new [`TextLayout`]. - pub const fn new(justify: JustifyText, linebreak: LineBreak) -> Self { - Self { justify, linebreak } - } - - /// Makes a new [`TextLayout`] with the specified [`JustifyText`]. - pub fn new_with_justify(justify: JustifyText) -> Self { - Self::default().with_justify(justify) - } - - /// Makes a new [`TextLayout`] with the specified [`LineBreak`]. - pub fn new_with_linebreak(linebreak: LineBreak) -> Self { - Self::default().with_linebreak(linebreak) - } - - /// Makes a new [`TextLayout`] with soft wrapping disabled. - /// Hard wrapping, where text contains an explicit linebreak such as the escape sequence `\n`, will still occur. - pub fn new_with_no_wrap() -> Self { - Self::default().with_no_wrap() - } - - /// Returns this [`TextLayout`] with the specified [`JustifyText`]. - pub const fn with_justify(mut self, justify: JustifyText) -> Self { - self.justify = justify; - self - } - - /// Returns this [`TextLayout`] with the specified [`LineBreak`]. - pub const fn with_linebreak(mut self, linebreak: LineBreak) -> Self { - self.linebreak = linebreak; - self - } - - /// Returns this [`TextLayout`] with soft wrapping disabled. - /// Hard wrapping, where text contains an explicit linebreak such as the escape sequence `\n`, will still occur. - pub const fn with_no_wrap(mut self) -> Self { - self.linebreak = LineBreak::NoWrap; - self - } -} - /// A span of text in a tree of spans. /// -/// `TextSpan` is only valid as a child of an entity with [`TextLayout`], which is provided by `Text` +/// `TextSpan` is only valid as a child of an entity with [`TextBuffer`], which is provided by `Text` /// for text in `bevy_ui` or `Text2d` for text in 2d world-space. /// -/// Spans are collected in hierarchy traversal order into a [`ComputedTextBlock`] for layout. +/// Spans are collected in hierarchy traversal order into a [`TextBuffer`] for layout. /// /// ``` /// # use bevy_asset::Handle; /// # use bevy_color::Color; /// # use bevy_color::palettes::basic::{RED, BLUE}; /// # use bevy_ecs::world::World; -/// # use bevy_text::{Font, TextLayout, TextFont, TextSpan, TextColor}; +/// # use bevy_text::{Font, TextFont, JustifyText, LineBreak, TextSpan, TextColor}; /// /// # let font_handle: Handle = Default::default(); /// # let mut world = World::default(); @@ -183,7 +122,8 @@ impl TextLayout { /// world.spawn(( /// // `Text` or `Text2d` are needed, and will provide default instances /// // of the following components. -/// TextLayout::default(), +/// JustifyText::default(), +/// LineBreak::default(), /// TextFont { /// font: font_handle.clone().into(), /// font_size: 60.0, @@ -244,7 +184,9 @@ impl From for TextSpan { /// /// _Has no affect on a single line text entity_, unless used together with a /// [`TextBounds`](super::bounds::TextBounds) component with an explicit `width` value. -#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Reflect, Serialize, Deserialize)] +#[derive( + Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Reflect, Serialize, Deserialize, Component, +)] #[reflect(Serialize, Deserialize, Clone, PartialEq, Hash)] pub enum JustifyText { /// Leftmost character is immediately to the right of the render position. @@ -274,7 +216,7 @@ impl From for cosmic_text::Align { } } -/// `TextFont` determines the style of a text span within a [`ComputedTextBlock`], specifically +/// `TextFont` determines the style of a text span within a [`ComputedTextLayout`](crate::ComputedTextLayout), specifically /// the font face, the font size, and the color. #[derive(Component, Clone, Debug, Reflect)] #[reflect(Component, Default, Debug, Clone)] @@ -427,7 +369,9 @@ impl TextBackgroundColor { } /// Determines how lines will be broken when preventing text from running out of bounds. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Reflect, Serialize, Deserialize)] +#[derive( + Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Reflect, Serialize, Deserialize, Component, +)] #[reflect(Serialize, Deserialize, Clone, PartialEq, Hash, Default)] pub enum LineBreak { /// Uses the [Unicode Line Breaking Algorithm](https://www.unicode.org/reports/tr14/). @@ -470,7 +414,7 @@ pub enum FontSmoothing { // SubpixelAntiAliased, } -/// System that detects changes to text blocks and sets `ComputedTextBlock::should_rerender`. +/// System that detects changes to text blocks and sets `TextBuffer::should_rerender`. /// /// Generic over the root text component and text span component. For example, [`Text2d`](crate::Text2d)/[`TextSpan`] for /// 2d or `Text`/[`TextSpan`] for UI. @@ -481,33 +425,32 @@ pub fn detect_text_needs_rerender( Or<( Changed, Changed, - Changed, + Changed, + Changed, Changed, )>, With, With, - With, + With, + With, ), >, changed_spans: Query< - (Entity, Option<&ChildOf>, Has), + (Entity, Option<&ChildOf>, Has, Has), ( Or<( Changed, Changed, Changed, Changed, // Included to detect broken text block hierarchies. - Added, + Added, + Added, )>, With, With, ), >, - mut computed: Query<( - Option<&ChildOf>, - Option<&mut ComputedTextBlock>, - Has, - )>, + mut buffers: Query<(Option<&ChildOf>, Option<&mut TextBuffer>, Has)>, ) { // Root entity: // - Root component changed. @@ -515,8 +458,8 @@ pub fn detect_text_needs_rerender( // - TextLayout changed. // - Root children changed (can include additions and removals). for root in changed_roots.iter() { - let Ok((_, Some(mut computed), _)) = computed.get_mut(root) else { - once!(warn!("found entity {} with a root text component ({}) but no ComputedTextBlock; this warning only \ + let Ok((_, Some(mut computed), _)) = buffers.get_mut(root) else { + once!(warn!("found entity {} with a root text component ({}) but no ComputedTextLayout; this warning only \ prints once", root, core::any::type_name::())); continue; }; @@ -527,9 +470,15 @@ pub fn detect_text_needs_rerender( // - Span component changed. // - Span TextFont changed. // - Span children changed (can include additions and removals). - for (entity, maybe_span_child_of, has_text_block) in changed_spans.iter() { - if has_text_block { - once!(warn!("found entity {} with a TextSpan that has a TextLayout, which should only be on root \ + for (entity, maybe_span_child_of, has_justify_text, has_line_break) in changed_spans.iter() { + if has_justify_text { + once!(warn!("found entity {} with a TextSpan that has a JustifyText, which should only be on root \ + text entities (that have {}); this warning only prints once", + entity, core::any::type_name::())); + } + + if has_line_break { + once!(warn!("found entity {} with a TextSpan that has a LineBreak, which should only be on root \ text entities (that have {}); this warning only prints once", entity, core::any::type_name::())); } @@ -545,11 +494,11 @@ pub fn detect_text_needs_rerender( }; let mut parent: Entity = span_child_of.parent(); - // Search for the nearest ancestor with ComputedTextBlock. + // Search for the nearest ancestor with TextBuffer. // Note: We assume the perf cost from duplicate visits in the case that multiple spans in a block are visited // is outweighed by the expense of tracking visited spans. loop { - let Ok((maybe_child_of, maybe_computed, has_span)) = computed.get_mut(parent) else { + let Ok((maybe_child_of, maybe_computed, has_span)) = buffers.get_mut(parent) else { once!(warn!("found entity {} with a TextSpan that is part of a broken hierarchy with a ChildOf \ component that points at non-existent entity {}; this warning only prints once", entity, parent)); @@ -561,7 +510,7 @@ pub fn detect_text_needs_rerender( } if !has_span { once!(warn!("found entity {} with a TextSpan that has an ancestor ({}) that does not have a text \ - span component or a ComputedTextBlock component; this warning only prints once", + span component or a TextBuffer component; this warning only prints once", entity, parent)); break; } diff --git a/crates/bevy_text/src/text2d.rs b/crates/bevy_text/src/text2d.rs index 5069804df8672..507fdbc3552f9 100644 --- a/crates/bevy_text/src/text2d.rs +++ b/crates/bevy_text/src/text2d.rs @@ -1,7 +1,7 @@ use crate::pipeline::CosmicFontSystem; use crate::{ - ComputedTextBlock, Font, FontAtlasSets, LineBreak, PositionedGlyph, SwashCache, TextBounds, - TextColor, TextError, TextFont, TextLayout, TextLayoutInfo, TextPipeline, TextReader, TextRoot, + ComputedTextLayout, Font, FontAtlasSets, JustifyText, LineBreak, PositionedGlyph, SwashCache, + TextBounds, TextBuffer, TextColor, TextError, TextFont, TextPipeline, TextReader, TextRoot, TextSpanAccess, TextWriter, }; use bevy_asset::Assets; @@ -39,11 +39,11 @@ use bevy_window::{PrimaryWindow, Window}; /// [Example usage.](https://github.com/bevyengine/bevy/blob/latest/examples/2d/text2d.rs) /// /// The string in this component is the first 'text span' in a hierarchy of text spans that are collected into -/// a [`ComputedTextBlock`]. See [`TextSpan`](crate::TextSpan) for the component used by children of entities with [`Text2d`]. +/// a [`ComputedTextLayout`]. See [`TextSpan`](crate::TextSpan) for the component used by children of entities with [`Text2d`]. /// -/// With `Text2d` the `justify` field of [`TextLayout`] only affects the internal alignment of a block of text and not its +/// With `Text2d` `JustifyText` only affects the internal alignment of a block of text and not its /// relative position, which is controlled by the [`Anchor`] component. -/// This means that for a block of text consisting of only one line that doesn't wrap, the `justify` field will have no effect. +/// This means that for a block of text consisting of only one line that doesn't wrap, the `JustifyText` component will have no effect. /// /// /// ``` @@ -51,7 +51,7 @@ use bevy_window::{PrimaryWindow, Window}; /// # use bevy_color::Color; /// # use bevy_color::palettes::basic::BLUE; /// # use bevy_ecs::world::World; -/// # use bevy_text::{Font, JustifyText, Text2d, TextLayout, TextFont, TextColor, TextSpan}; +/// # use bevy_text::{Font, JustifyText, Text2d, TextFont, TextColor, TextSpan}; /// # /// # let font_handle: Handle = Default::default(); /// # let mut world = World::default(); @@ -73,7 +73,7 @@ use bevy_window::{PrimaryWindow, Window}; /// // With text justification. /// world.spawn(( /// Text2d::new("hello world\nand bevy!"), -/// TextLayout::new_with_justify(JustifyText::Center) +/// JustifyText::Center /// )); /// /// // With spans @@ -85,10 +85,13 @@ use bevy_window::{PrimaryWindow, Window}; #[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect)] #[reflect(Component, Default, Debug, Clone)] #[require( - TextLayout, + TextBuffer, + ComputedTextLayout, TextFont, TextColor, TextBounds, + JustifyText, + LineBreak, Anchor, Visibility, VisibilityClass, @@ -145,8 +148,8 @@ pub fn extract_text2d_sprite( Query<( Entity, &ViewVisibility, - &ComputedTextBlock, - &TextLayoutInfo, + &TextBuffer, + &ComputedTextLayout, &TextBounds, &Anchor, &GlobalTransform, @@ -266,10 +269,11 @@ pub fn update_text2d_layout( mut text_pipeline: ResMut, mut text_query: Query<( Entity, - Ref, + &LineBreak, + &JustifyText, Ref, - &mut TextLayoutInfo, - &mut ComputedTextBlock, + &mut ComputedTextLayout, + &mut TextBuffer, )>, mut text_reader: Text2dReader, mut font_system: ResMut, @@ -288,14 +292,14 @@ pub fn update_text2d_layout( let factor_changed = *last_scale_factor != Some(scale_factor); *last_scale_factor = Some(scale_factor); - for (entity, block, bounds, text_layout_info, mut computed) in &mut text_query { + for (entity, linebreak, justify, bounds, text_layout_info, mut computed) in &mut text_query { if factor_changed || computed.needs_rerender() || bounds.is_changed() || (!queue.is_empty() && queue.remove(&entity)) { let text_bounds = TextBounds { - width: if block.linebreak == LineBreak::NoWrap { + width: if *linebreak == LineBreak::NoWrap { None } else { bounds.width.map(|width| scale_value(width, scale_factor)) @@ -311,7 +315,8 @@ pub fn update_text2d_layout( &fonts, text_reader.iter(entity), scale_factor.into(), - &block, + *linebreak, + *justify, text_bounds, &mut font_atlas_sets, &mut texture_atlases, @@ -345,7 +350,7 @@ pub fn scale_value(value: f32, factor: f32) -> f32 { } /// System calculating and inserting an [`Aabb`] component to entities with some -/// [`TextLayoutInfo`] and [`Anchor`] components, and without a [`NoFrustumCulling`] component. +/// [`ComputedTextLayout`] and [`Anchor`] components, and without a [`NoFrustumCulling`] component. /// /// Used in system set [`VisibilitySystems::CalculateBounds`](bevy_render::view::VisibilitySystems::CalculateBounds). pub fn calculate_bounds_text2d( @@ -353,12 +358,12 @@ pub fn calculate_bounds_text2d( mut text_to_update_aabb: Query< ( Entity, - &TextLayoutInfo, + &ComputedTextLayout, &Anchor, &TextBounds, Option<&mut Aabb>, ), - (Changed, Without), + (Changed, Without), >, ) { for (entity, layout_info, anchor, text_bounds, aabb) in &mut text_to_update_aabb { diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index b38241a95a942..d789c881a6e54 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -19,7 +19,7 @@ use thiserror::Error; use tracing::warn; use ui_surface::UiSurface; -use bevy_text::ComputedTextBlock; +use bevy_text::TextBuffer; use bevy_text::CosmicFontSystem; @@ -90,7 +90,7 @@ pub fn ui_layout_system( Option<&Outline>, Option<&ScrollPosition>, )>, - mut buffer_query: Query<&mut ComputedTextBlock>, + mut buffer_query: Query<&mut TextBuffer>, mut font_system: ResMut, mut removed_children: RemovedComponents, mut removed_content_sizes: RemovedComponents, @@ -1050,7 +1050,7 @@ mod tests { fn test_system( params: In, mut ui_surface: ResMut, - mut computed_text_block_query: Query<&mut bevy_text::ComputedTextBlock>, + mut computed_text_block_query: Query<&mut bevy_text::TextBuffer>, mut font_system: ResMut, ) { ui_surface.upsert_node( diff --git a/crates/bevy_ui/src/layout/ui_surface.rs b/crates/bevy_ui/src/layout/ui_surface.rs index 2df6afa947dac..46b5926189399 100644 --- a/crates/bevy_ui/src/layout/ui_surface.rs +++ b/crates/bevy_ui/src/layout/ui_surface.rs @@ -185,7 +185,7 @@ impl UiSurface { &mut self, ui_root_entity: Entity, render_target_resolution: UVec2, - buffer_query: &'a mut bevy_ecs::prelude::Query<&mut bevy_text::ComputedTextBlock>, + buffer_query: &'a mut bevy_ecs::prelude::Query<&mut bevy_text::TextBuffer>, font_system: &'a mut CosmicFontSystem, ) { let implicit_viewport_node = self.get_or_insert_taffy_viewport_node(ui_root_entity); @@ -286,8 +286,8 @@ impl UiSurface { pub fn get_text_buffer<'a>( needs_buffer: bool, ctx: &mut NodeMeasure, - query: &'a mut bevy_ecs::prelude::Query<&mut bevy_text::ComputedTextBlock>, -) -> Option<&'a mut bevy_text::ComputedTextBlock> { + query: &'a mut bevy_ecs::prelude::Query<&mut bevy_text::TextBuffer>, +) -> Option<&'a mut bevy_text::TextBuffer> { // We avoid a query lookup whenever the buffer is not required. if !needs_buffer { return None; diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index 4ce635920652c..1eef0ea8e6d5c 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -278,10 +278,10 @@ impl Plugin for UiPlugin { fn build_text_interop(app: &mut App) { use crate::widget::TextNodeFlags; - use bevy_text::TextLayoutInfo; + use bevy_text::ComputedTextLayout; use widget::Text; - app.register_type::() + app.register_type::() .register_type::() .register_type::(); diff --git a/crates/bevy_ui/src/measurement.rs b/crates/bevy_ui/src/measurement.rs index 029498ab8de9d..700892bd7a717 100644 --- a/crates/bevy_ui/src/measurement.rs +++ b/crates/bevy_ui/src/measurement.rs @@ -21,7 +21,7 @@ pub struct MeasureArgs<'a> { pub available_width: AvailableSpace, pub available_height: AvailableSpace, pub font_system: &'a mut CosmicFontSystem, - pub buffer: Option<&'a mut bevy_text::ComputedTextBlock>, + pub buffer: Option<&'a mut bevy_text::TextBuffer>, } /// A `Measure` is used to compute the size of a ui node diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index 83140d0f3b9cb..9d1414fac2ab8 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -54,9 +54,7 @@ use gradient::GradientPlugin; use crate::{Display, Node}; use bevy_platform::collections::{HashMap, HashSet}; -use bevy_text::{ - ComputedTextBlock, PositionedGlyph, TextBackgroundColor, TextColor, TextLayoutInfo, -}; +use bevy_text::{ComputedTextLayout, PositionedGlyph, TextBackgroundColor, TextBuffer, TextColor}; use bevy_transform::components::GlobalTransform; use box_shadow::BoxShadowPlugin; use bytemuck::{Pod, Zeroable}; @@ -816,8 +814,8 @@ pub fn extract_text_sections( &InheritedVisibility, Option<&CalculatedClip>, &ComputedNodeTarget, - &ComputedTextBlock, - &TextLayoutInfo, + &TextBuffer, + &ComputedTextLayout, )>, >, text_styles: Extract>, @@ -914,7 +912,7 @@ pub fn extract_text_shadows( &GlobalTransform, &InheritedVisibility, Option<&CalculatedClip>, - &TextLayoutInfo, + &ComputedTextLayout, &TextShadow, )>, >, @@ -1002,7 +1000,7 @@ pub fn extract_text_background_colors( &InheritedVisibility, Option<&CalculatedClip>, &ComputedNodeTarget, - &TextLayoutInfo, + &ComputedTextLayout, )>, >, text_background_colors_query: Extract>, diff --git a/crates/bevy_ui/src/widget/text.rs b/crates/bevy_ui/src/widget/text.rs index 785040c1e9057..9476925994c2c 100644 --- a/crates/bevy_ui/src/widget/text.rs +++ b/crates/bevy_ui/src/widget/text.rs @@ -18,8 +18,8 @@ use bevy_image::prelude::*; use bevy_math::Vec2; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_text::{ - scale_value, ComputedTextBlock, CosmicFontSystem, Font, FontAtlasSets, LineBreak, SwashCache, - TextBounds, TextColor, TextError, TextFont, TextLayout, TextLayoutInfo, TextMeasureInfo, + scale_value, ComputedTextLayout, CosmicFontSystem, Font, FontAtlasSets, JustifyText, LineBreak, + SwashCache, TextBounds, TextBuffer, TextColor, TextError, TextFont, TextMeasureInfo, TextPipeline, TextReader, TextRoot, TextSpanAccess, TextWriter, }; use taffy::style::AvailableSpace; @@ -51,7 +51,7 @@ impl Default for TextNodeFlags { /// Adding [`Text`] to an entity will pull in required components for setting up a UI text node. /// /// The string in this component is the first 'text span' in a hierarchy of text spans that are collected into -/// a [`ComputedTextBlock`]. See [`TextSpan`](bevy_text::TextSpan) for the component used by children of entities with [`Text`]. +/// a [`ComputedTextLayout`]. See [`TextSpan`](bevy_text::TextSpan) for the component used by children of entities with [`Text`]. /// /// Note that [`Transform`](bevy_transform::components::Transform) on this entity is managed automatically by the UI layout system. /// @@ -61,7 +61,7 @@ impl Default for TextNodeFlags { /// # use bevy_color::Color; /// # use bevy_color::palettes::basic::BLUE; /// # use bevy_ecs::world::World; -/// # use bevy_text::{Font, JustifyText, TextLayout, TextFont, TextColor, TextSpan}; +/// # use bevy_text::{Font, JustifyText, TextFont, TextColor, TextSpan}; /// # use bevy_ui::prelude::Text; /// # /// # let font_handle: Handle = Default::default(); @@ -84,7 +84,7 @@ impl Default for TextNodeFlags { /// // With text justification. /// world.spawn(( /// Text::new("hello world\nand bevy!"), -/// TextLayout::new_with_justify(JustifyText::Center) +/// JustifyText::Center /// )); /// /// // With spans @@ -95,7 +95,17 @@ impl Default for TextNodeFlags { /// ``` #[derive(Component, Debug, Default, Clone, Deref, DerefMut, Reflect, PartialEq)] #[reflect(Component, Default, Debug, PartialEq, Clone)] -#[require(Node, TextLayout, TextFont, TextColor, TextNodeFlags, ContentSize)] +#[require( + Node, + TextBuffer, + ComputedTextLayout, + LineBreak, + JustifyText, + TextFont, + TextColor, + TextNodeFlags, + ContentSize +)] pub struct Text(pub String); impl Text { @@ -198,11 +208,12 @@ fn create_text_measure<'a>( fonts: &Assets, scale_factor: f64, spans: impl Iterator, - block: Ref, + linebreak: LineBreak, + justify: JustifyText, text_pipeline: &mut TextPipeline, mut content_size: Mut, mut text_flags: Mut, - mut computed: Mut, + mut computed: Mut, font_system: &mut CosmicFontSystem, ) { match text_pipeline.create_text_measure( @@ -210,12 +221,13 @@ fn create_text_measure<'a>( fonts, spans, scale_factor, - &block, + linebreak, + justify, computed.as_mut(), font_system, ) { Ok(measure) => { - if block.linebreak == LineBreak::NoWrap { + if linebreak == LineBreak::NoWrap { content_size.set(NodeMeasure::Fixed(FixedMeasure { size: measure.max })); } else { content_size.set(NodeMeasure::Text(TextMeasure { info: measure })); @@ -240,7 +252,7 @@ fn create_text_measure<'a>( /// A `Measure` is used by the UI's layout algorithm to determine the appropriate amount of space /// to provide for the text given the fonts, the text itself and the constraints of the layout. /// -/// * Measures are regenerated on changes to either [`ComputedTextBlock`] or [`ComputedNodeTarget`]. +/// * Measures are regenerated on changes to either [`ComputedTextLayout`] or [`ComputedNodeTarget`]. /// * Changes that only modify the colors of a `Text` do not require a new `Measure`. This system /// is only able to detect that a `Text` component has changed and will regenerate the `Measure` on /// color changes. This can be expensive, particularly for large blocks of text, and the [`bypass_change_detection`](bevy_ecs::change_detection::DetectChangesMut::bypass_change_detection) @@ -250,10 +262,11 @@ pub fn measure_text_system( mut text_query: Query< ( Entity, - Ref, + &LineBreak, + &JustifyText, &mut ContentSize, &mut TextNodeFlags, - &mut ComputedTextBlock, + &mut TextBuffer, Ref, ), With, @@ -262,8 +275,10 @@ pub fn measure_text_system( mut text_pipeline: ResMut, mut font_system: ResMut, ) { - for (entity, block, content_size, text_flags, computed, computed_target) in &mut text_query { - // Note: the ComputedTextBlock::needs_rerender bool is cleared in create_text_measure(). + for (entity, linebreak, justify, content_size, text_flags, computed, computed_target) in + &mut text_query + { + // Note: the ComputedTextLayout::needs_rerender bool is cleared in create_text_measure(). if computed_target.is_changed() || computed.needs_rerender() || text_flags.needs_measure_fn @@ -274,7 +289,8 @@ pub fn measure_text_system( &fonts, computed_target.scale_factor.into(), text_reader.iter(entity), - block, + *linebreak, + *justify, &mut text_pipeline, content_size, text_flags, @@ -295,11 +311,12 @@ fn queue_text( textures: &mut Assets, scale_factor: f32, inverse_scale_factor: f32, - block: &TextLayout, + linebreak: LineBreak, + justify: JustifyText, node: Ref, mut text_flags: Mut, - text_layout_info: Mut, - computed: &mut ComputedTextBlock, + text_layout_info: Mut, + computed: &mut TextBuffer, text_reader: &mut TextUiReader, font_system: &mut CosmicFontSystem, swash_cache: &mut SwashCache, @@ -309,7 +326,7 @@ fn queue_text( return; } - let physical_node_size = if block.linebreak == LineBreak::NoWrap { + let physical_node_size = if linebreak == LineBreak::NoWrap { // With `NoWrap` set, no constraints are placed on the width of the text. TextBounds::UNBOUNDED } else { @@ -323,7 +340,8 @@ fn queue_text( fonts, text_reader.iter(entity), scale_factor.into(), - block, + linebreak, + justify, physical_node_size, font_atlas_sets, texture_atlases, @@ -349,7 +367,7 @@ fn queue_text( /// Updates the layout and size information for a UI text node on changes to the size value of its [`Node`] component, /// or when the `needs_recompute` field of [`TextNodeFlags`] is set to true. -/// This information is computed by the [`TextPipeline`] and then stored in [`TextLayoutInfo`]. +/// This information is computed by the [`TextPipeline`] and then stored in [`ComputedTextLayout`]. /// /// ## World Resources /// @@ -364,16 +382,19 @@ pub fn text_system( mut text_query: Query<( Entity, Ref, - &TextLayout, - &mut TextLayoutInfo, + &LineBreak, + &JustifyText, + &mut ComputedTextLayout, &mut TextNodeFlags, - &mut ComputedTextBlock, + &mut TextBuffer, )>, mut text_reader: TextUiReader, mut font_system: ResMut, mut swash_cache: ResMut, ) { - for (entity, node, block, text_layout_info, text_flags, mut computed) in &mut text_query { + for (entity, node, linebreak, justify, text_layout_info, text_flags, mut computed) in + &mut text_query + { if node.is_changed() || text_flags.needs_recompute { queue_text( entity, @@ -384,7 +405,8 @@ pub fn text_system( &mut textures, node.inverse_scale_factor.recip(), node.inverse_scale_factor, - block, + *linebreak, + *justify, node, text_flags, text_layout_info, diff --git a/examples/2d/sprite_scale.rs b/examples/2d/sprite_scale.rs index c549134419388..2089569893d5e 100644 --- a/examples/2d/sprite_scale.rs +++ b/examples/2d/sprite_scale.rs @@ -129,7 +129,7 @@ fn setup_sprites(mut commands: Commands, asset_server: Res) { cmd.with_children(|builder| { builder.spawn(( Text2d::new(rect.text), - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, TextFont::from_font_size(15.), Transform::from_xyz(0., -0.5 * rect.size.y - 10., 0.), bevy::sprite::Anchor::TOP_CENTER, @@ -275,7 +275,7 @@ fn setup_texture_atlas( cmd.with_children(|builder| { builder.spawn(( Text2d::new(sprite_sheet.text), - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, TextFont::from_font_size(15.), Transform::from_xyz(0., -0.5 * sprite_sheet.size.y - 10., 0.), bevy::sprite::Anchor::TOP_CENTER, diff --git a/examples/2d/sprite_slice.rs b/examples/2d/sprite_slice.rs index 94f4fe809f8e9..f289dfe914c96 100644 --- a/examples/2d/sprite_slice.rs +++ b/examples/2d/sprite_slice.rs @@ -94,7 +94,7 @@ fn spawn_sprites( children![( Text2d::new(label), text_style, - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, Transform::from_xyz(0., -0.5 * size.y - 10., 0.0), bevy::sprite::Anchor::TOP_CENTER, )], diff --git a/examples/2d/text2d.rs b/examples/2d/text2d.rs index 7b1abfd8dabf7..dec5008397c7e 100644 --- a/examples/2d/text2d.rs +++ b/examples/2d/text2d.rs @@ -46,21 +46,21 @@ fn setup(mut commands: Commands, asset_server: Res) { commands.spawn(( Text2d::new("translation"), text_font.clone(), - TextLayout::new_with_justify(text_justification), + text_justification, AnimateTranslation, )); // Demonstrate changing rotation commands.spawn(( Text2d::new("rotation"), text_font.clone(), - TextLayout::new_with_justify(text_justification), + text_justification, AnimateRotation, )); // Demonstrate changing scale commands.spawn(( Text2d::new("scale"), text_font, - TextLayout::new_with_justify(text_justification), + text_justification, Transform::from_translation(Vec3::new(400.0, 0.0, 0.0)), AnimateScale, )); @@ -78,7 +78,8 @@ fn setup(mut commands: Commands, asset_server: Res) { children![( Text2d::new("this text wraps in the box\n(Unicode linebreaks)"), slightly_smaller_text_font.clone(), - TextLayout::new(JustifyText::Left, LineBreak::WordBoundary), + JustifyText::Left, + LineBreak::WordBoundary, // Wrap text in the rectangle TextBounds::from(box_size), // Ensure the text is drawn on top of the box @@ -94,7 +95,8 @@ fn setup(mut commands: Commands, asset_server: Res) { children![( Text2d::new("this text wraps in the box\n(AnyCharacter linebreaks)"), slightly_smaller_text_font.clone(), - TextLayout::new(JustifyText::Left, LineBreak::AnyCharacter), + JustifyText::Left, + LineBreak::AnyCharacter, // Wrap text in the rectangle TextBounds::from(other_box_size), // Ensure the text is drawn on top of the box @@ -108,7 +110,7 @@ fn setup(mut commands: Commands, asset_server: Res) { slightly_smaller_text_font .clone() .with_font_smoothing(FontSmoothing::None), - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, Transform::from_translation(Vec3::new(-400.0, -250.0, 0.0)), )); diff --git a/examples/2d/texture_atlas.rs b/examples/2d/texture_atlas.rs index 7510afbceea74..798dcaaa15efc 100644 --- a/examples/2d/texture_atlas.rs +++ b/examples/2d/texture_atlas.rs @@ -279,7 +279,7 @@ fn create_label( commands.spawn(( Text2d::new(text), text_style, - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, Transform { translation: Vec3::new(translation.0, translation.1, translation.2), ..default() diff --git a/examples/3d/blend_modes.rs b/examples/3d/blend_modes.rs index 95fe522cf0ba8..5bc6d69cc3691 100644 --- a/examples/3d/blend_modes.rs +++ b/examples/3d/blend_modes.rs @@ -207,7 +207,7 @@ fn setup( bottom: Val::ZERO, ..default() }, - TextLayout::default().with_no_wrap(), + LineBreak::NoWrap, )); }); }; diff --git a/examples/3d/tonemapping.rs b/examples/3d/tonemapping.rs index 0808776e2be7b..be05e1b49eb8b 100644 --- a/examples/3d/tonemapping.rs +++ b/examples/3d/tonemapping.rs @@ -180,7 +180,7 @@ fn setup_image_viewer_scene( ..default() }, TextColor(Color::BLACK), - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, Node { align_self: AlignSelf::Center, margin: UiRect::all(Val::Auto), diff --git a/examples/animation/animated_ui.rs b/examples/animation/animated_ui.rs index f31b2ccd5eb4b..eb030a80f27af 100644 --- a/examples/animation/animated_ui.rs +++ b/examples/animation/animated_ui.rs @@ -151,7 +151,7 @@ fn setup( ..default() }, TextColor(Color::Srgba(Srgba::RED)), - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, )) // Mark as an animation target. .insert(AnimationTarget { diff --git a/examples/animation/animation_graph.rs b/examples/animation/animation_graph.rs index 610074744f901..775e9259bd16d 100644 --- a/examples/animation/animation_graph.rs +++ b/examples/animation/animation_graph.rs @@ -277,7 +277,7 @@ fn setup_node_rects(commands: &mut Commands) { ..default() }, TextColor(ANTIQUE_WHITE.into()), - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, )) .id(); diff --git a/examples/animation/animation_masks.rs b/examples/animation/animation_masks.rs index 07261b40df630..cc11406f267a0 100644 --- a/examples/animation/animation_masks.rs +++ b/examples/animation/animation_masks.rs @@ -334,7 +334,7 @@ fn add_mask_group_control( } else { selected_button_text_style.clone() }, - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, Node { flex_grow: 1.0, margin: UiRect::vertical(Val::Px(3.0)), diff --git a/examples/async_tasks/external_source_external_thread.rs b/examples/async_tasks/external_source_external_thread.rs index 1b7bb27b16dab..e9e2d16069fdd 100644 --- a/examples/async_tasks/external_source_external_thread.rs +++ b/examples/async_tasks/external_source_external_thread.rs @@ -54,7 +54,7 @@ fn spawn_text(mut commands: Commands, mut reader: EventReader) { for (per_frame, event) in reader.read().enumerate() { commands.spawn(( Text2d::new(event.0.to_string()), - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, Transform::from_xyz(per_frame as f32 * 100.0, 300.0, 0.0), )); } diff --git a/examples/ecs/one_shot_systems.rs b/examples/ecs/one_shot_systems.rs index 8dfb90f175cb3..cf055527b2526 100644 --- a/examples/ecs/one_shot_systems.rs +++ b/examples/ecs/one_shot_systems.rs @@ -94,7 +94,7 @@ fn setup_ui(mut commands: Commands) { commands .spawn(( Text::default(), - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, Node { align_self: AlignSelf::Center, justify_self: JustifySelf::Center, diff --git a/examples/math/render_primitives.rs b/examples/math/render_primitives.rs index 7d1e3aca97f32..da7cc8ed9ff8e 100644 --- a/examples/math/render_primitives.rs +++ b/examples/math/render_primitives.rs @@ -379,7 +379,7 @@ fn setup_text(mut commands: Commands, cameras: Query<(Entity, &Camera)>) { children![( Text::default(), HeaderText, - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, children![ TextSpan::new("Primitive: "), TextSpan(format!("{text}", text = PrimitiveSelected::default())), diff --git a/examples/mobile/src/lib.rs b/examples/mobile/src/lib.rs index ba93268e86a93..9eea81b2950e0 100644 --- a/examples/mobile/src/lib.rs +++ b/examples/mobile/src/lib.rs @@ -158,7 +158,7 @@ fn setup_scene( ..default() }, TextColor::BLACK, - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, )); } diff --git a/examples/stress_tests/many_glyphs.rs b/examples/stress_tests/many_glyphs.rs index d6629fa80c7a0..dac3ea4cacf4a 100644 --- a/examples/stress_tests/many_glyphs.rs +++ b/examples/stress_tests/many_glyphs.rs @@ -73,10 +73,7 @@ fn setup(mut commands: Commands, args: Res) { font_size: 4., ..Default::default() }; - let text_block = TextLayout { - justify: JustifyText::Left, - linebreak: LineBreak::AnyCharacter, - }; + let text_block = (JustifyText::Left, LineBreak::AnyCharacter); if !args.no_ui { commands @@ -108,7 +105,7 @@ fn setup(mut commands: Commands, args: Res) { } } -fn force_text_recomputation(mut text_query: Query<&mut TextLayout>) { +fn force_text_recomputation(mut text_query: Query<&mut JustifyText>) { for mut block in &mut text_query { block.set_changed(); } diff --git a/examples/stress_tests/many_text2d.rs b/examples/stress_tests/many_text2d.rs index c05ce00a47158..327885ed506a8 100644 --- a/examples/stress_tests/many_text2d.rs +++ b/examples/stress_tests/many_text2d.rs @@ -131,11 +131,11 @@ fn setup(mut commands: Commands, font: Res, args: Res) { Text2d(random_text(&mut rng, &args)), random_text_font(&mut rng, &args, font.0.clone()), TextColor(color.into()), - TextLayout::new_with_justify(if args.center { + if args.center { JustifyText::Center } else { JustifyText::Left - }), + }, Transform { translation, rotation, diff --git a/examples/stress_tests/text_pipeline.rs b/examples/stress_tests/text_pipeline.rs index acb0b0e804f2b..c1a23d09f943a 100644 --- a/examples/stress_tests/text_pipeline.rs +++ b/examples/stress_tests/text_pipeline.rs @@ -68,10 +68,8 @@ fn spawn(mut commands: Commands, asset_server: Res) { commands .spawn(( Text2d::default(), - TextLayout { - justify: JustifyText::Center, - linebreak: LineBreak::AnyCharacter, - }, + JustifyText::Center, + LineBreak::AnyCharacter, TextBounds::default(), )) .with_children(|p| { diff --git a/examples/testbed/2d.rs b/examples/testbed/2d.rs index c812157899fb7..713f9a58ddd69 100644 --- a/examples/testbed/2d.rs +++ b/examples/testbed/2d.rs @@ -217,7 +217,7 @@ mod text { ] { let mut text = commands.spawn(( Text2d::new("L R\n"), - TextLayout::new_with_justify(justify), + justify, Transform::from_translation(dest + Vec3::Z), anchor, DespawnOnExitState(super::Scene::Text), diff --git a/examples/testbed/ui.rs b/examples/testbed/ui.rs index eba2afb40906a..b4361402da26b 100644 --- a/examples/testbed/ui.rs +++ b/examples/testbed/ui.rs @@ -372,7 +372,8 @@ mod text_wrap { for (j, message) in messages.into_iter().enumerate() { commands.entity(root).with_child(( Text(message.clone()), - TextLayout::new(JustifyText::Left, linebreak), + JustifyText::Left, + linebreak, BackgroundColor(Color::srgb(0.8 - j as f32 * 0.3, 0., 0.)), )); } diff --git a/examples/time/virtual_time.rs b/examples/time/virtual_time.rs index 09923da7b7fac..524a15ecd5d27 100644 --- a/examples/time/virtual_time.rs +++ b/examples/time/virtual_time.rs @@ -102,7 +102,7 @@ fn setup(mut commands: Commands, asset_server: Res, mut time: ResMu ..default() }, TextColor(Color::srgb(0.85, 0.85, 0.85)), - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, ), ( Text::default(), @@ -111,7 +111,7 @@ fn setup(mut commands: Commands, asset_server: Res, mut time: ResMu ..default() }, TextColor(virtual_color), - TextLayout::new_with_justify(JustifyText::Right), + JustifyText::Right, VirtualTime, ), ], diff --git a/examples/ui/directional_navigation.rs b/examples/ui/directional_navigation.rs index 41b0a4b012c0a..27ae73a0fa08b 100644 --- a/examples/ui/directional_navigation.rs +++ b/examples/ui/directional_navigation.rs @@ -185,10 +185,7 @@ fn setup_ui( .with_child(( Text::new(button_name), // And center the text if it flows onto multiple lines - TextLayout { - justify: JustifyText::Center, - ..default() - }, + JustifyText::Center, )) .id(); diff --git a/examples/ui/display_and_visibility.rs b/examples/ui/display_and_visibility.rs index 239b9814dbcc5..6fd1511766607 100644 --- a/examples/ui/display_and_visibility.rs +++ b/examples/ui/display_and_visibility.rs @@ -99,7 +99,7 @@ fn setup(mut commands: Commands, asset_server: Res) { parent.spawn(( Text::new("Use the panel on the right to change the Display and Visibility properties for the respective nodes of the panel on the left"), text_font.clone(), - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, Node { margin: UiRect::bottom(Val::Px(10.)), ..Default::default() @@ -153,13 +153,13 @@ fn setup(mut commands: Commands, asset_server: Res) { Text::new("Display::None\nVisibility::Hidden\nVisibility::Inherited"), text_font.clone(), TextColor(HIDDEN_COLOR), - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, )); builder.spawn(( Text::new("-\n-\n-"), text_font.clone(), TextColor(DARK_GRAY.into()), - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, )); builder.spawn((Text::new("The UI Node and its descendants will not be visible and will not be allotted any space in the UI layout.\nThe UI Node will not be visible but will still occupy space in the UI layout.\nThe UI node will inherit the visibility property of its parent. If it has no parent it will be visible."), text_font)); }); @@ -396,7 +396,7 @@ where builder.spawn(( Text(format!("{}::{:?}", Target::::NAME, T::default())), text_font, - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, )); }); } diff --git a/examples/ui/size_constraints.rs b/examples/ui/size_constraints.rs index 72a072d788465..ff3324223cd1d 100644 --- a/examples/ui/size_constraints.rs +++ b/examples/ui/size_constraints.rs @@ -251,7 +251,7 @@ fn spawn_button( } else { UNHOVERED_TEXT_COLOR }), - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, )); }); } diff --git a/examples/ui/text.rs b/examples/ui/text.rs index 8bf34cc96ee7c..b91ed5b5b06e5 100644 --- a/examples/ui/text.rs +++ b/examples/ui/text.rs @@ -40,7 +40,7 @@ fn setup(mut commands: Commands, asset_server: Res) { }, TextShadow::default(), // Set the justification of the Text - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, // Set the style of the Node itself. Node { position_type: PositionType::Absolute, diff --git a/examples/ui/text_background_colors.rs b/examples/ui/text_background_colors.rs index caf0b60e85097..80a55f998b389 100644 --- a/examples/ui/text_background_colors.rs +++ b/examples/ui/text_background_colors.rs @@ -40,13 +40,7 @@ fn setup(mut commands: Commands) { }) .with_children(|commands| { commands - .spawn(( - Text::default(), - TextLayout { - justify: JustifyText::Center, - ..Default::default() - }, - )) + .spawn((Text::default(), JustifyText::Center)) .with_children(|commands| { for (i, section_str) in message_text.iter().enumerate() { commands.spawn(( diff --git a/examples/ui/text_debug.rs b/examples/ui/text_debug.rs index 10ba7040b7109..ad7e32d42488d 100644 --- a/examples/ui/text_debug.rs +++ b/examples/ui/text_debug.rs @@ -72,7 +72,7 @@ fn infotext_system(mut commands: Commands, asset_server: Res) { ..default() }, TextColor(YELLOW.into()), - TextLayout::new_with_justify(JustifyText::Right), + JustifyText::Right, Node { max_width: Val::Px(300.), ..default() @@ -114,7 +114,7 @@ fn infotext_system(mut commands: Commands, asset_server: Res) { ..default() }, TextColor(Color::srgb(0.8, 0.2, 0.7)), - TextLayout::new_with_justify(JustifyText::Center), + JustifyText::Center, Node { max_width: Val::Px(400.), ..default() @@ -130,7 +130,7 @@ fn infotext_system(mut commands: Commands, asset_server: Res) { ..default() }, TextColor(YELLOW.into()), - TextLayout::new_with_justify(JustifyText::Left), + JustifyText::Left, Node { max_width: Val::Px(300.), ..default() @@ -145,7 +145,7 @@ fn infotext_system(mut commands: Commands, asset_server: Res) { font_size: 29.0, ..default() }, - TextLayout::new_with_justify(JustifyText::Justified), + JustifyText::Justified, TextColor(GREEN_YELLOW.into()), Node { max_width: Val::Px(300.), diff --git a/examples/ui/text_wrap_debug.rs b/examples/ui/text_wrap_debug.rs index 227fb15116eb0..cd409c6e295c2 100644 --- a/examples/ui/text_wrap_debug.rs +++ b/examples/ui/text_wrap_debug.rs @@ -117,7 +117,8 @@ fn spawn(mut commands: Commands, asset_server: Res) { commands.entity(column_id).with_child(( Text(message.clone()), text_font.clone(), - TextLayout::new(JustifyText::Left, linebreak), + JustifyText::Left, + linebreak, BackgroundColor(Color::srgb(0.8 - j as f32 * 0.2, 0., 0.)), )); } diff --git a/release-content/migration-guides/TextLayout-renamed-to-TextLayoutSettings.md b/release-content/migration-guides/TextLayout-renamed-to-TextLayoutSettings.md new file mode 100644 index 0000000000000..e3188fe1dd9b8 --- /dev/null +++ b/release-content/migration-guides/TextLayout-renamed-to-TextLayoutSettings.md @@ -0,0 +1,14 @@ +--- +title: `bevy_text` components refactor +pull_requests: [19444] +--- + +Renamed `TextLayoutInfo` to `ComputedTextLayout`. +It contains the finalized text layout, the `-Info` suffix is redundant and potentially confusing. + +Renamed `ComputedTextBlock` to `TextBuffer`. +This component wraps the cosmic-text buffer. The name `ComputedTextBlock` suggests that it contains the final result of a text relayout, but the buffer can be out-of-date until it is updated during the text schedule. + +Removed `TextLayout`. Contains the linebreak and justification settings, not the text layout. + +`JustifyText` and `Linebreak` are now components required by `Text` and `Text2d`.