@@ -6,7 +6,7 @@ use bevy_ecs::{
6
6
event:: EventReader ,
7
7
query:: Changed ,
8
8
reflect:: ReflectComponent ,
9
- system:: { Local , Query , Res , ResMut } ,
9
+ system:: { Commands , Local , Query , Res , ResMut } ,
10
10
} ;
11
11
use bevy_math:: { Vec2 , Vec3 } ;
12
12
use bevy_reflect:: Reflect ;
@@ -22,7 +22,8 @@ use bevy_utils::HashSet;
22
22
use bevy_window:: { WindowId , WindowScaleFactorChanged , Windows } ;
23
23
24
24
use crate :: {
25
- DefaultTextPipeline , Font , FontAtlasSet , HorizontalAlign , Text , TextError , VerticalAlign ,
25
+ Font , FontAtlasSet , HorizontalAlign , Text , TextError , TextLayoutInfo , TextPipeline ,
26
+ VerticalAlign ,
26
27
} ;
27
28
28
29
/// The calculated size of text drawn in 2D scene.
@@ -69,76 +70,75 @@ pub struct Text2dBundle {
69
70
pub fn extract_text2d_sprite (
70
71
mut extracted_sprites : ResMut < ExtractedSprites > ,
71
72
texture_atlases : Extract < Res < Assets < TextureAtlas > > > ,
72
- text_pipeline : Extract < Res < DefaultTextPipeline > > ,
73
73
windows : Extract < Res < Windows > > ,
74
74
text2d_query : Extract <
75
75
Query < (
76
76
Entity ,
77
77
& ComputedVisibility ,
78
78
& Text ,
79
+ & TextLayoutInfo ,
79
80
& GlobalTransform ,
80
81
& Text2dSize ,
81
82
) > ,
82
83
> ,
83
84
) {
84
85
let scale_factor = windows. scale_factor ( WindowId :: primary ( ) ) as f32 ;
85
86
86
- for ( entity, computed_visibility, text, text_transform, calculated_size) in text2d_query. iter ( )
87
+ for ( entity, computed_visibility, text, text_layout_info, text_transform, calculated_size) in
88
+ text2d_query. iter ( )
87
89
{
88
90
if !computed_visibility. is_visible ( ) {
89
91
continue ;
90
92
}
91
93
let ( width, height) = ( calculated_size. size . x , calculated_size. size . y ) ;
92
94
93
- if let Some ( text_layout) = text_pipeline. get_glyphs ( & entity) {
94
- let text_glyphs = & text_layout. glyphs ;
95
- let alignment_offset = match text. alignment . vertical {
96
- VerticalAlign :: Top => Vec3 :: new ( 0.0 , -height, 0.0 ) ,
97
- VerticalAlign :: Center => Vec3 :: new ( 0.0 , -height * 0.5 , 0.0 ) ,
98
- VerticalAlign :: Bottom => Vec3 :: ZERO ,
99
- } + match text. alignment . horizontal {
100
- HorizontalAlign :: Left => Vec3 :: ZERO ,
101
- HorizontalAlign :: Center => Vec3 :: new ( -width * 0.5 , 0.0 , 0.0 ) ,
102
- HorizontalAlign :: Right => Vec3 :: new ( -width, 0.0 , 0.0 ) ,
103
- } ;
95
+ let text_glyphs = & text_layout_info. glyphs ;
96
+ let alignment_offset = match text. alignment . vertical {
97
+ VerticalAlign :: Top => Vec3 :: new ( 0.0 , -height, 0.0 ) ,
98
+ VerticalAlign :: Center => Vec3 :: new ( 0.0 , -height * 0.5 , 0.0 ) ,
99
+ VerticalAlign :: Bottom => Vec3 :: ZERO ,
100
+ } + match text. alignment . horizontal {
101
+ HorizontalAlign :: Left => Vec3 :: ZERO ,
102
+ HorizontalAlign :: Center => Vec3 :: new ( -width * 0.5 , 0.0 , 0.0 ) ,
103
+ HorizontalAlign :: Right => Vec3 :: new ( -width, 0.0 , 0.0 ) ,
104
+ } ;
104
105
105
- let mut color = Color :: WHITE ;
106
- let mut current_section = usize:: MAX ;
107
- for text_glyph in text_glyphs {
108
- if text_glyph. section_index != current_section {
109
- color = text. sections [ text_glyph. section_index ]
110
- . style
111
- . color
112
- . as_rgba_linear ( ) ;
113
- current_section = text_glyph. section_index ;
114
- }
115
- let atlas = texture_atlases
116
- . get ( & text_glyph. atlas_info . texture_atlas )
117
- . unwrap ( ) ;
118
- let handle = atlas. texture . clone_weak ( ) ;
119
- let index = text_glyph. atlas_info . glyph_index as usize ;
120
- let rect = Some ( atlas. textures [ index] ) ;
106
+ let mut color = Color :: WHITE ;
107
+ let mut current_section = usize:: MAX ;
108
+ for text_glyph in text_glyphs {
109
+ if text_glyph. section_index != current_section {
110
+ color = text. sections [ text_glyph. section_index ]
111
+ . style
112
+ . color
113
+ . as_rgba_linear ( ) ;
114
+ current_section = text_glyph. section_index ;
115
+ }
116
+ let atlas = texture_atlases
117
+ . get ( & text_glyph. atlas_info . texture_atlas )
118
+ . unwrap ( ) ;
119
+ let handle = atlas. texture . clone_weak ( ) ;
120
+ let index = text_glyph. atlas_info . glyph_index as usize ;
121
+ let rect = Some ( atlas. textures [ index] ) ;
121
122
122
- let glyph_transform = Transform :: from_translation (
123
- alignment_offset * scale_factor + text_glyph. position . extend ( 0. ) ,
124
- ) ;
125
- // NOTE: Should match `bevy_ui::render::extract_text_uinodes`
126
- let transform = * text_transform
127
- * GlobalTransform :: from_scale ( Vec3 :: splat ( scale_factor. recip ( ) ) )
128
- * glyph_transform;
123
+ let glyph_transform = Transform :: from_translation (
124
+ alignment_offset * scale_factor + text_glyph. position . extend ( 0. ) ,
125
+ ) ;
126
+ // NOTE: Should match `bevy_ui::render::extract_text_uinodes`
127
+ let transform = * text_transform
128
+ * GlobalTransform :: from_scale ( Vec3 :: splat ( scale_factor. recip ( ) ) )
129
+ * glyph_transform;
129
130
130
- extracted_sprites. sprites . push ( ExtractedSprite {
131
- entity,
132
- transform,
133
- color,
134
- rect,
135
- custom_size : None ,
136
- image_handle_id : handle. id ,
137
- flip_x : false ,
138
- flip_y : false ,
139
- anchor : Anchor :: Center . as_vec ( ) ,
140
- } ) ;
141
- }
131
+ extracted_sprites. sprites . push ( ExtractedSprite {
132
+ entity,
133
+ transform,
134
+ color,
135
+ rect,
136
+ custom_size : None ,
137
+ image_handle_id : handle. id ,
138
+ flip_x : false ,
139
+ flip_y : false ,
140
+ anchor : Anchor :: Center . as_vec ( ) ,
141
+ } ) ;
142
142
}
143
143
}
144
144
}
@@ -147,6 +147,7 @@ pub fn extract_text2d_sprite(
147
147
/// This information is computed by the `TextPipeline` on insertion, then stored.
148
148
#[ allow( clippy:: too_many_arguments) ]
149
149
pub fn update_text2d_layout (
150
+ mut commands : Commands ,
150
151
// Text items which should be reprocessed again, generally when the font hasn't loaded yet.
151
152
mut queue : Local < HashSet < Entity > > ,
152
153
mut textures : ResMut < Assets < Image > > ,
@@ -155,20 +156,23 @@ pub fn update_text2d_layout(
155
156
mut scale_factor_changed : EventReader < WindowScaleFactorChanged > ,
156
157
mut texture_atlases : ResMut < Assets < TextureAtlas > > ,
157
158
mut font_atlas_set_storage : ResMut < Assets < FontAtlasSet > > ,
158
- mut text_pipeline : ResMut < DefaultTextPipeline > ,
159
+ mut text_pipeline : ResMut < TextPipeline > ,
159
160
mut text_query : Query < (
160
161
Entity ,
161
162
Changed < Text > ,
162
163
& Text ,
163
164
Option < & Text2dBounds > ,
164
165
& mut Text2dSize ,
166
+ Option < & mut TextLayoutInfo > ,
165
167
) > ,
166
168
) {
167
169
// We need to consume the entire iterator, hence `last`
168
170
let factor_changed = scale_factor_changed. iter ( ) . last ( ) . is_some ( ) ;
169
171
let scale_factor = windows. scale_factor ( WindowId :: primary ( ) ) ;
170
172
171
- for ( entity, text_changed, text, maybe_bounds, mut calculated_size) in & mut text_query {
173
+ for ( entity, text_changed, text, maybe_bounds, mut calculated_size, text_layout_info) in
174
+ & mut text_query
175
+ {
172
176
if factor_changed || text_changed || queue. remove ( & entity) {
173
177
let text_bounds = match maybe_bounds {
174
178
Some ( bounds) => Vec2 :: new (
@@ -178,7 +182,6 @@ pub fn update_text2d_layout(
178
182
None => Vec2 :: new ( f32:: MAX , f32:: MAX ) ,
179
183
} ;
180
184
match text_pipeline. queue_text (
181
- entity,
182
185
& fonts,
183
186
& text. sections ,
184
187
scale_factor,
@@ -196,14 +199,17 @@ pub fn update_text2d_layout(
196
199
Err ( e @ TextError :: FailedToAddGlyph ( _) ) => {
197
200
panic ! ( "Fatal error when processing text: {}." , e) ;
198
201
}
199
- Ok ( ( ) ) => {
200
- let text_layout_info = text_pipeline. get_glyphs ( & entity) . expect (
201
- "Failed to get glyphs from the pipeline that have just been computed" ,
202
- ) ;
202
+ Ok ( info) => {
203
203
calculated_size. size = Vec2 :: new (
204
- scale_value ( text_layout_info . size . x , 1. / scale_factor) ,
205
- scale_value ( text_layout_info . size . y , 1. / scale_factor) ,
204
+ scale_value ( info . size . x , 1. / scale_factor) ,
205
+ scale_value ( info . size . y , 1. / scale_factor) ,
206
206
) ;
207
+ match text_layout_info {
208
+ Some ( mut t) => * t = info,
209
+ None => {
210
+ commands. entity ( entity) . insert ( info) ;
211
+ }
212
+ }
207
213
}
208
214
}
209
215
}
0 commit comments