From bb381747711866c8f9da089c2d5b9498d9c4b076 Mon Sep 17 00:00:00 2001 From: Cyborus Date: Mon, 2 Dec 2024 14:00:29 -0500 Subject: [PATCH] feat: add line height to `TextFont` --- crates/bevy_text/src/lib.rs | 1 + crates/bevy_text/src/pipeline.rs | 11 +++++++++-- crates/bevy_text/src/text.rs | 33 +++++++++++++++++++++++++++++++ examples/dev_tools/fps_overlay.rs | 1 + 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/crates/bevy_text/src/lib.rs b/crates/bevy_text/src/lib.rs index ad9feb7fdcf0f..d039d9941123e 100644 --- a/crates/bevy_text/src/lib.rs +++ b/crates/bevy_text/src/lib.rs @@ -113,6 +113,7 @@ impl Plugin for TextPlugin { app.init_asset::() .register_type::() .register_type::() + .register_type::() .register_type::() .register_type::() .register_type::() diff --git a/crates/bevy_text/src/pipeline.rs b/crates/bevy_text/src/pipeline.rs index f8e7274ef31f2..6ff1e306dbdb8 100644 --- a/crates/bevy_text/src/pipeline.rs +++ b/crates/bevy_text/src/pipeline.rs @@ -98,6 +98,7 @@ impl TextPipeline { // Collect span information into a vec. This is necessary because font loading requires mut access // to FontSystem, which the cosmic-text Buffer also needs. let mut font_size: f32 = 0.; + let mut line_height: f32 = 0.0; let mut spans: Vec<(usize, &str, &TextFont, FontFaceInfo, Color)> = core::mem::take(&mut self.spans_buffer) .into_iter() @@ -130,6 +131,7 @@ impl TextPipeline { // Get max font size for use in cosmic Metrics. font_size = font_size.max(text_font.font_size); + line_height = line_height.max(text_font.line_height.eval(text_font.font_size)); // Load Bevy fonts into cosmic-text's font system. let face_info = load_font_to_fontdb( @@ -146,7 +148,6 @@ impl TextPipeline { spans.push((span_index, span, text_font, face_info, color)); } - let line_height = font_size * 1.2; let mut metrics = Metrics::new(font_size, line_height).scale(scale_factor as f32); // Metrics of 0.0 cause `Buffer::set_metrics` to panic. We hack around this by 'falling // through' to call `Buffer::set_rich_text` with zero spans so any cached text will be cleared without @@ -486,7 +487,13 @@ fn get_attrs<'a>( .stretch(face_info.stretch) .style(face_info.style) .weight(face_info.weight) - .metrics(Metrics::relative(text_font.font_size, 1.2).scale(scale_factor as f32)) + .metrics( + Metrics { + font_size: text_font.font_size, + line_height: text_font.line_height.eval(text_font.font_size), + } + .scale(scale_factor as f32), + ) .color(cosmic_text::Color(color.to_linear().as_u32())); attrs } diff --git a/crates/bevy_text/src/text.rs b/crates/bevy_text/src/text.rs index 0effb361aa302..7b9d5bfd10924 100644 --- a/crates/bevy_text/src/text.rs +++ b/crates/bevy_text/src/text.rs @@ -284,6 +284,11 @@ pub struct TextFont { /// A new font atlas is generated for every combination of font handle and scaled font size /// which can have a strong performance impact. pub font_size: f32, + /// The vertical height of a line of text, from the top of one line to the top of the + /// next. + /// + /// Defaults to `LineHeight::Scalar(1.2)` + pub line_height: LineHeight, /// The antialiasing method to use when rendering text. pub font_smoothing: FontSmoothing, } @@ -323,11 +328,39 @@ impl Default for TextFont { Self { font: Default::default(), font_size: 20.0, + line_height: LineHeight::default(), font_smoothing: Default::default(), } } } +/// Specifies the height of each line of text for `Text` and `Text2d` +/// +/// Default is 1.2x the font size +#[derive(Debug, Clone, Copy, Reflect)] +#[reflect(Debug)] +pub enum LineHeight { + /// Set line height to a specific number of pixels + Px(f32), + /// Set line height to a multiple of the font size + Scalar(f32), +} + +impl LineHeight { + pub(crate) fn eval(self, font_size: f32) -> f32 { + match self { + LineHeight::Px(px) => px, + LineHeight::Scalar(scale) => scale * font_size, + } + } +} + +impl Default for LineHeight { + fn default() -> Self { + LineHeight::Scalar(1.2) + } +} + /// The color of the text for this section. #[derive(Component, Copy, Clone, Debug, Deref, DerefMut, Reflect)] #[reflect(Component, Default, Debug)] diff --git a/examples/dev_tools/fps_overlay.rs b/examples/dev_tools/fps_overlay.rs index 0dcc5e5218be5..a1c11bb3ce026 100644 --- a/examples/dev_tools/fps_overlay.rs +++ b/examples/dev_tools/fps_overlay.rs @@ -26,6 +26,7 @@ fn main() { font: default(), // We could also disable font smoothing, font_smoothing: FontSmoothing::default(), + ..default() }, // We can also change color of the overlay text_color: OverlayColor::GREEN,