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:
parent
c6e0da4bcb
commit
0981789ec7
@ -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 {
|
||||||
|
|||||||
@ -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>()
|
||||||
|
|||||||
@ -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 })
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user