Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the Text2dSize component #6741

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 53 additions & 59 deletions crates/bevy_text/src/text2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use bevy_ecs::{
component::Component,
entity::Entity,
event::EventReader,
query::Changed,
query::{Changed, With},
reflect::ReflectComponent,
system::{Commands, Local, Query, Res, ResMut},
};
Expand All @@ -26,13 +26,6 @@ use crate::{
TextPipeline, TextSettings, VerticalAlign, YAxisOrientation,
};

/// The calculated size of text drawn in 2D scene.
#[derive(Component, Default, Copy, Clone, Debug, Reflect)]
#[reflect(Component)]
pub struct Text2dSize {
pub size: Vec2,
}

/// The maximum width and height of text. The text will wrap according to the specified size.
/// Characters out of the bounds after wrapping will be truncated. Text is aligned according to the
/// specified `TextAlignment`.
Expand All @@ -47,21 +40,23 @@ pub struct Text2dBounds {
}

impl Default for Text2dBounds {
#[inline]
fn default() -> Self {
Self {
size: Vec2::new(f32::MAX, f32::MAX),
}
Self::UNBOUNDED
}
}

impl Text2dBounds {
pub const UNBOUNDED: Self = Self { size: Vec2::splat(f32::MAX) };
}

/// The bundle of components needed to draw text in a 2D scene via a 2D `Camera2dBundle`.
/// [Example usage.](https://github.com/bevyengine/bevy/blob/latest/examples/2d/text2d.rs)
#[derive(Bundle, Clone, Debug, Default)]
pub struct Text2dBundle {
pub text: Text,
pub transform: Transform,
pub global_transform: GlobalTransform,
pub text_2d_size: Text2dSize,
pub text_2d_bounds: Text2dBounds,
pub visibility: Visibility,
pub computed_visibility: ComputedVisibility,
Expand All @@ -72,36 +67,40 @@ pub fn extract_text2d_sprite(
texture_atlases: Extract<Res<Assets<TextureAtlas>>>,
windows: Extract<Res<Windows>>,
text2d_query: Extract<
Query<(
Entity,
&ComputedVisibility,
&Text,
&TextLayoutInfo,
&GlobalTransform,
&Text2dSize,
)>,
Query<
(
Entity,
&ComputedVisibility,
&Text,
&TextLayoutInfo,
&GlobalTransform,
),
With<Text2dBounds>,
>,
>,
) {
let scale_factor = windows.scale_factor(WindowId::primary()) as f32;

for (entity, computed_visibility, text, text_layout_info, text_transform, calculated_size) in
text2d_query.iter()
for (entity, computed_visibility, text, text_layout_info, text_transform) in text2d_query.iter()
{
if !computed_visibility.is_visible() {
continue;
}
let (width, height) = (calculated_size.size.x, calculated_size.size.y);

let text_glyphs = &text_layout_info.glyphs;
let alignment_offset = match text.alignment.vertical {
VerticalAlign::Top => Vec3::new(0.0, -height, 0.0),
VerticalAlign::Center => Vec3::new(0.0, -height * 0.5, 0.0),
VerticalAlign::Bottom => Vec3::ZERO,
} + match text.alignment.horizontal {
HorizontalAlign::Left => Vec3::ZERO,
HorizontalAlign::Center => Vec3::new(-width * 0.5, 0.0, 0.0),
HorizontalAlign::Right => Vec3::new(-width, 0.0, 0.0),
};
let alignment_offset = -text_layout_info.size
* Vec2::new(
match text.alignment.horizontal {
HorizontalAlign::Left => 0.,
HorizontalAlign::Center => 0.5,
HorizontalAlign::Right => 1.,
},
match text.alignment.vertical {
VerticalAlign::Bottom => 0.,
VerticalAlign::Center => 0.5,
VerticalAlign::Top => 1.,
},
);

let mut color = Color::WHITE;
let mut current_section = usize::MAX;
Expand All @@ -120,10 +119,9 @@ pub fn extract_text2d_sprite(
let index = text_glyph.atlas_info.glyph_index;
let rect = Some(atlas.textures[index]);

let glyph_transform = Transform::from_translation(
alignment_offset * scale_factor + text_glyph.position.extend(0.),
);
// NOTE: Should match `bevy_ui::render::extract_text_uinodes`
let glyph_transform =
Transform::from_translation((alignment_offset + text_glyph.position).extend(0.));

let transform = *text_transform
* GlobalTransform::from_scale(Vec3::splat(scale_factor.recip()))
* glyph_transform;
Expand Down Expand Up @@ -168,26 +166,28 @@ pub fn update_text2d_layout(
Entity,
Changed<Text>,
&Text,
Option<&Text2dBounds>,
&mut Text2dSize,
&Text2dBounds,
Option<&mut TextLayoutInfo>,
)>,
) {
// We need to consume the entire iterator, hence `last`
let factor_changed = scale_factor_changed.iter().last().is_some();
let scale_factor = windows.scale_factor(WindowId::primary());

for (entity, text_changed, text, maybe_bounds, mut calculated_size, text_layout_info) in
&mut text_query
{
for (entity, text_changed, text, bounds, text_layout_info) in &mut text_query {
if factor_changed || text_changed || queue.remove(&entity) {
let text_bounds = match maybe_bounds {
Some(bounds) => Vec2::new(
scale_value(bounds.size.x, scale_factor),
scale_value(bounds.size.y, scale_factor),
),
None => Vec2::new(f32::MAX, f32::MAX),
};
let text_bounds = Vec2::new(
if bounds.size.x != f32::MAX {
scale_value(bounds.size.x, scale_factor)
} else {
f32::MAX
},
if bounds.size.x != f32::MAX {
scale_value(bounds.size.y, scale_factor)
} else {
f32::MAX
},
);

match text_pipeline.queue_text(
&fonts,
Expand All @@ -211,18 +211,12 @@ pub fn update_text2d_layout(
| Err(e @ TextError::ExceedMaxTextAtlases(_)) => {
panic!("Fatal error when processing text: {e}.");
}
Ok(info) => {
calculated_size.size = Vec2::new(
scale_value(info.size.x, 1. / scale_factor),
scale_value(info.size.y, 1. / scale_factor),
);
match text_layout_info {
Some(mut t) => *t = info,
None => {
commands.entity(entity).insert(info);
}
Ok(info) => match text_layout_info {
Some(mut t) => *t = info,
None => {
commands.entity(entity).insert(info);
}
}
},
}
}
}
Expand Down