Skip to content

Commit

Permalink
feat: add line height to TextFont
Browse files Browse the repository at this point in the history
  • Loading branch information
Cyborus04 committed Dec 2, 2024
1 parent 793e2f2 commit 2344bdb
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
17 changes: 15 additions & 2 deletions crates/bevy_text/src/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ 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.;
// We can't know the font size until the end, so keep track of both
let mut line_height_pixel: f32 = 0.0;
let mut line_height_scalar: f32 = 0.0;
let mut spans: Vec<(usize, &str, &TextFont, FontFaceInfo, Color)> =
core::mem::take(&mut self.spans_buffer)
.into_iter()
Expand Down Expand Up @@ -130,6 +133,10 @@ impl TextPipeline {

// Get max font size for use in cosmic Metrics.
font_size = font_size.max(text_font.font_size);
match text_font.line_height {
crate::LineHeight::Pixels(px) => line_height_pixel = line_height_pixel.max(px),
crate::LineHeight::Scalar(s) => line_height_scalar = line_height_scalar.max(s),
}

// Load Bevy fonts into cosmic-text's font system.
let face_info = load_font_to_fontdb(
Expand All @@ -146,7 +153,7 @@ impl TextPipeline {
spans.push((span_index, span, text_font, face_info, color));
}

let line_height = font_size * 1.2;
let line_height = line_height_pixel.max(line_height_scalar * font_size);
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
Expand Down Expand Up @@ -486,7 +493,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
}
Expand Down
32 changes: 32 additions & 0 deletions crates/bevy_text/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 in pixels, 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,
}
Expand Down Expand Up @@ -323,11 +328,38 @@ 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)]
pub enum LineHeight {
/// Set line height to a specific number of pixels
Pixels(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::Pixels(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)]
Expand Down
1 change: 1 addition & 0 deletions examples/dev_tools/fps_overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 2344bdb

Please sign in to comment.