Skip to content

Commit 64bc992

Browse files
committed
cleanup WIP
1 parent a05c971 commit 64bc992

File tree

7 files changed

+258
-162
lines changed

7 files changed

+258
-162
lines changed

crates/bevy_text/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ mod glyph;
4343
mod pipeline;
4444
mod text;
4545
mod text2d;
46+
mod text_spans;
4647

4748
pub use cosmic_text;
4849

@@ -56,13 +57,16 @@ pub use glyph::*;
5657
pub use pipeline::*;
5758
pub use text::*;
5859
pub use text2d::*;
60+
pub use text_spans::*;
5961

6062
/// The text prelude.
6163
///
6264
/// This includes the most common types in this crate, re-exported for your convenience.
6365
pub mod prelude {
6466
#[doc(hidden)]
65-
pub use crate::{Font, JustifyText, Text, Text2dBundle, TextError, TextSection, TextStyle};
67+
pub use crate::{
68+
Font, JustifyText, LineBreak, Text2d, TextBlock, TextError, TextSpan2d, TextStyle,
69+
};
6670
}
6771

6872
use bevy_app::prelude::*;

crates/bevy_text/src/text.rs

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ impl ComputedTextBlock {
6868
/// Can be used to look up [`TextStyle`] components for glyphs in [`TextLayoutInfo`] using the `span_index`
6969
/// stored there.
7070
pub fn entities(&self) -> &[TextEntity] {
71-
self.entities.iter()
71+
&self.entities
7272
}
7373

7474
/// Indicates if the text needs to be refreshed in [`TextLayoutInfo`].
@@ -112,8 +112,16 @@ pub struct TextBlock {
112112

113113
impl TextBlock {
114114
/// Makes a new [`TextBlock`].
115-
pub const fn new(justify: JustifyText, linebreak: LineBreak, font_smoothing: FontSmoothing) -> Self {
116-
Self{ justify, linebreak, font_smoothing }
115+
pub const fn new(
116+
justify: JustifyText,
117+
linebreak: LineBreak,
118+
font_smoothing: FontSmoothing,
119+
) -> Self {
120+
Self {
121+
justify,
122+
linebreak,
123+
font_smoothing,
124+
}
117125
}
118126

119127
/// Makes a new [`TextBlock`] with the specified [`JustifyText`].
@@ -277,3 +285,71 @@ pub enum FontSmoothing {
277285
// TODO: Add subpixel antialias support
278286
// SubpixelAntiAliased,
279287
}
288+
289+
/// System that detects changes to text blocks and sets `ComputedTextBlock::should_rerender`.
290+
///
291+
/// Generic over the root text component and text span component. For example, [`Text2d`]/[`TextSpan2d`] for 2d or
292+
/// `Text`/`TextSpan` for UI.
293+
pub fn detect_text_needs_rerender<Root: Component, Span: Component>(
294+
changed_roots: Query<
295+
Entity,
296+
(
297+
Or<(
298+
Changed<Root>,
299+
Changed<TextStyle>,
300+
Changed<TextBlock>,
301+
Changed<Children>,
302+
)>,
303+
With<Root>,
304+
With<TextStyle>,
305+
With<TextBlock>,
306+
),
307+
>,
308+
changed_spans: Query<
309+
&Parent,
310+
Or<(Changed<Span>, Changed<TextStyle>, Changed<Children>)>,
311+
With<Span>,
312+
With<TextStyle>,
313+
>,
314+
mut computed: Query<(Option<&Parent>, Option<&mut ComputedTextBlock>)>,
315+
) {
316+
// Root entity:
317+
// - Root component changed.
318+
// - TextStyle on root changed.
319+
// - TextBlock changed.
320+
// - Root children changed (can include additions and removals).
321+
for root in changed_roots.iter() {
322+
// TODO: ComputedTextBlock *should* be here. Log a warning?
323+
let Ok((_, Some(mut computed))) = computed.get_mut(root) else {
324+
continue;
325+
};
326+
computed.needs_rerender = true;
327+
}
328+
329+
// Span entity:
330+
// - Span component changed.
331+
// - Span TextStyle changed.
332+
// - Span children changed (can include additions and removals).
333+
for span_parent in changed_spans.iter() {
334+
let mut parent: Entity = **span_parent;
335+
336+
// Search for the nearest ancestor with ComputedTextBlock.
337+
// Note: We assume the perf cost from duplicate visits in the case that multiple spans in a block are visited
338+
// is outweighed by the expense of tracking visited spans.
339+
loop {
340+
// TODO: If this lookup fails then there is a hierarchy error. Log a warning?
341+
let Ok((maybe_parent, maybe_computed)) = computed.get_mut(parent) else {
342+
break;
343+
};
344+
if let Some(computed) = maybe_computed {
345+
computed.needs_rerender = true;
346+
break;
347+
}
348+
// TODO: If there is no parent then a span is floating without an owning TextBlock. Log a warning?
349+
let Some(next_parent) = maybe_parent else {
350+
break;
351+
};
352+
parent = **next_parent;
353+
}
354+
}
355+
}

crates/bevy_text/src/text2d.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,31 @@ use bevy_window::{PrimaryWindow, Window, WindowScaleFactorChanged};
3737
/// With `Text2d` the `justify` field of [`TextBlock`] only affects the internal alignment of a block of text and not its
3838
/// relative position, which is controlled by the [`Anchor`] component.
3939
/// This means that for a block of text consisting of only one line that doesn't wrap, the `justify` field will have no effect.
40+
///
4041
/*
4142
```
43+
# use bevy_asset::Handle;
44+
# use bevy_color::Color;
45+
# use bevy_color::palettes::basic::BLUE;
4246
# use bevy_ecs::World;
43-
# use bevy_text::{Text2d, TextBlock, JustifyText};
47+
# use bevy_text::{Font, JustifyText, Text2d, TextBlock, TextStyle};
4448
#
49+
# let font_handle: Handle<Font> = Default::default();
4550
# let mut world = World::default();
4651
#
4752
// Basic usage.
4853
world.spawn(Text2d::new("hello world!"));
4954
55+
// With non-default style.
56+
world.spawn((
57+
Text2d::new("hello world!"),
58+
TextStyle {
59+
font: font_handle.clone().into(),
60+
font_size: 60.0,
61+
color: BLUE.into(),
62+
}
63+
));
64+
5065
// With text justification.
5166
world.spawn((
5267
Text2d::new("hello world\nand bevy!"),
@@ -89,6 +104,7 @@ impl From<String> for Text2d {
89104
/// A span of 2d text in a tree of spans under an entity with [`Text2d`].
90105
///
91106
/// Spans are collected in hierarchy traversal order into a [`ComputedTextBlock`] for layout.
107+
///
92108
/*
93109
```
94110
# use bevy_asset::Handle;

crates/bevy_text/src/text_span.rs

Lines changed: 0 additions & 149 deletions
This file was deleted.

0 commit comments

Comments
 (0)