Fixes incorrect glyph positioning for text2d (#6273)

# Objective
Fixes #6272

## Solution
Revert to old way of positioning text for Text2D rendered text.


Co-authored-by: Michel van der Hulst <hulstmichel@gmail.com>
This commit is contained in:
Michel van der Hulst 2022-10-18 13:28:34 +00:00
parent c6e0da4bcb
commit 0981789ec7
6 changed files with 35 additions and 5 deletions

View File

@ -7,7 +7,10 @@ use glyph_brush_layout::{
FontId, GlyphPositioner, Layout, SectionGeometry, SectionGlyph, SectionText, ToSectionText, FontId, GlyphPositioner, Layout, SectionGeometry, SectionGlyph, SectionText, ToSectionText,
}; };
use crate::{error::TextError, Font, FontAtlasSet, GlyphAtlasInfo, TextAlignment, TextSettings}; use crate::{
error::TextError, Font, FontAtlasSet, GlyphAtlasInfo, TextAlignment, TextSettings,
YAxisOrientation,
};
pub struct GlyphBrush { pub struct GlyphBrush {
fonts: Vec<FontArc>, fonts: Vec<FontArc>,
@ -53,6 +56,7 @@ impl GlyphBrush {
texture_atlases: &mut Assets<TextureAtlas>, texture_atlases: &mut Assets<TextureAtlas>,
textures: &mut Assets<Image>, textures: &mut Assets<Image>,
text_settings: &TextSettings, text_settings: &TextSettings,
y_axis_orientation: YAxisOrientation,
) -> Result<Vec<PositionedGlyph>, TextError> { ) -> Result<Vec<PositionedGlyph>, TextError> {
if glyphs.is_empty() { if glyphs.is_empty() {
return Ok(Vec::new()); return Ok(Vec::new());
@ -75,15 +79,18 @@ impl GlyphBrush {
let mut min_x = std::f32::MAX; let mut min_x = std::f32::MAX;
let mut min_y = std::f32::MAX; let mut min_y = std::f32::MAX;
let mut max_y = std::f32::MIN;
for sg in &glyphs { for sg in &glyphs {
let glyph = &sg.glyph; let glyph = &sg.glyph;
let scaled_font = sections_data[sg.section_index].3; let scaled_font = sections_data[sg.section_index].3;
min_x = min_x.min(glyph.position.x); min_x = min_x.min(glyph.position.x);
min_y = min_y.min(glyph.position.y - scaled_font.ascent()); min_y = min_y.min(glyph.position.y - scaled_font.ascent());
max_y = max_y.max(glyph.position.y - scaled_font.descent());
} }
min_x = min_x.floor(); min_x = min_x.floor();
min_y = min_y.floor(); min_y = min_y.floor();
max_y = max_y.floor();
let mut positioned_glyphs = Vec::new(); let mut positioned_glyphs = Vec::new();
for sg in glyphs { for sg in glyphs {
@ -120,7 +127,12 @@ impl GlyphBrush {
let size = Vec2::new(glyph_rect.width(), glyph_rect.height()); let size = Vec2::new(glyph_rect.width(), glyph_rect.height());
let x = bounds.min.x + size.x / 2.0 - min_x; let x = bounds.min.x + size.x / 2.0 - min_x;
let y = bounds.min.y + size.y / 2.0 - min_y;
let y = match y_axis_orientation {
YAxisOrientation::BottomToTop => max_y - bounds.max.y + size.y / 2.0,
YAxisOrientation::TopToBottom => bounds.min.y + size.y / 2.0 - min_y,
};
let position = adjust.position(Vec2::new(x, y)); let position = adjust.position(Vec2::new(x, y));
positioned_glyphs.push(PositionedGlyph { positioned_glyphs.push(PositionedGlyph {

View File

@ -56,6 +56,14 @@ impl Default for TextSettings {
} }
} }
/// Text is rendered for two different view projections, normal `Text2DBundle` is rendered with a
/// `BottomToTop` y axis, and UI is rendered with a `TopToBottom` y axis. This matters for text because
/// the glyph positioning is different in either layout.
pub enum YAxisOrientation {
TopToBottom,
BottomToTop,
}
impl Plugin for TextPlugin { impl Plugin for TextPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_asset::<Font>() app.add_asset::<Font>()

View File

@ -11,7 +11,7 @@ use glyph_brush_layout::{FontId, SectionText};
use crate::{ use crate::{
error::TextError, glyph_brush::GlyphBrush, scale_value, Font, FontAtlasSet, PositionedGlyph, error::TextError, glyph_brush::GlyphBrush, scale_value, Font, FontAtlasSet, PositionedGlyph,
TextAlignment, TextSection, TextSettings, TextAlignment, TextSection, TextSettings, YAxisOrientation,
}; };
#[derive(Default, Resource)] #[derive(Default, Resource)]
@ -50,6 +50,7 @@ impl TextPipeline {
texture_atlases: &mut Assets<TextureAtlas>, texture_atlases: &mut Assets<TextureAtlas>,
textures: &mut Assets<Image>, textures: &mut Assets<Image>,
text_settings: &TextSettings, text_settings: &TextSettings,
y_axis_orientation: YAxisOrientation,
) -> Result<TextLayoutInfo, TextError> { ) -> Result<TextLayoutInfo, TextError> {
let mut scaled_fonts = Vec::new(); let mut scaled_fonts = Vec::new();
let sections = sections let sections = sections
@ -105,6 +106,7 @@ impl TextPipeline {
texture_atlases, texture_atlases,
textures, textures,
text_settings, text_settings,
y_axis_orientation,
)?; )?;
Ok(TextLayoutInfo { glyphs, size }) Ok(TextLayoutInfo { glyphs, size })

View File

@ -23,7 +23,7 @@ use bevy_window::{WindowId, WindowScaleFactorChanged, Windows};
use crate::{ use crate::{
Font, FontAtlasSet, HorizontalAlign, Text, TextError, TextLayoutInfo, TextPipeline, Font, FontAtlasSet, HorizontalAlign, Text, TextError, TextLayoutInfo, TextPipeline,
TextSettings, VerticalAlign, TextSettings, VerticalAlign, YAxisOrientation,
}; };
/// The calculated size of text drawn in 2D scene. /// The calculated size of text drawn in 2D scene.
@ -182,6 +182,7 @@ pub fn update_text2d_layout(
), ),
None => Vec2::new(f32::MAX, f32::MAX), None => Vec2::new(f32::MAX, f32::MAX),
}; };
match text_pipeline.queue_text( match text_pipeline.queue_text(
&fonts, &fonts,
&text.sections, &text.sections,
@ -192,6 +193,7 @@ pub fn update_text2d_layout(
&mut *texture_atlases, &mut *texture_atlases,
&mut *textures, &mut *textures,
text_settings.as_ref(), text_settings.as_ref(),
YAxisOrientation::BottomToTop,
) { ) {
Err(TextError::NoSuchFont) => { Err(TextError::NoSuchFont) => {
// There was an error processing the text layout, let's add this entity to the // There was an error processing the text layout, let's add this entity to the

View File

@ -8,7 +8,10 @@ use bevy_ecs::{
use bevy_math::Vec2; use bevy_math::Vec2;
use bevy_render::texture::Image; use bevy_render::texture::Image;
use bevy_sprite::TextureAtlas; use bevy_sprite::TextureAtlas;
use bevy_text::{Font, FontAtlasSet, Text, TextError, TextLayoutInfo, TextPipeline, TextSettings}; use bevy_text::{
Font, FontAtlasSet, Text, TextError, TextLayoutInfo, TextPipeline, TextSettings,
YAxisOrientation,
};
use bevy_window::Windows; use bevy_window::Windows;
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -118,6 +121,7 @@ pub fn text_system(
&mut *texture_atlases, &mut *texture_atlases,
&mut *textures, &mut *textures,
text_settings.as_ref(), text_settings.as_ref(),
YAxisOrientation::TopToBottom,
) { ) {
Err(TextError::NoSuchFont) => { Err(TextError::NoSuchFont) => {
// There was an error processing the text layout, let's add this entity to the // There was an error processing the text layout, let's add this entity to the

View File

@ -19,8 +19,10 @@ fn main() {
#[derive(Component)] #[derive(Component)]
struct AnimateTranslation; struct AnimateTranslation;
#[derive(Component)] #[derive(Component)]
struct AnimateRotation; struct AnimateRotation;
#[derive(Component)] #[derive(Component)]
struct AnimateScale; struct AnimateScale;