add line height to TextFont
(#16614)
# Objective - Allow users to customize the line height of text. - Implements #16085 ## Solution - Add a `line_height` field to `TextFont` to feed into `cosmic_text`'s `Metrics`. ## Testing - Tested on my own game, and worked exactly as I wanted. - My game is only 2D, so I only tested `Text2d`. `Text` still needs tested, but I imagine it'll work fine. - An example is available [here](https://code.cartoon-aa.xyz/Cyborus/custom-line-height-example) --- ## Showcase <details> <summary>Click to view showcase</summary> With font: ```rust TextFont { font: /* unimportant */, font_size: 16.0, line_height: None, ..default() } ```  With font: ```rust TextFont { font: /* unimportant */, font_size: 16.0, line_height: Some(16.0), ..default() } ```  </details> ## Migration Guide `TextFont` now has a `line_height` field. Any instantiation of `TextFont` that doesn't have `..default()` will need to add this field.
This commit is contained in:
parent
27802e6975
commit
4ba09f3dd9
@ -110,6 +110,7 @@ impl Plugin for TextPlugin {
|
||||
app.init_asset::<Font>()
|
||||
.register_type::<Text2d>()
|
||||
.register_type::<TextFont>()
|
||||
.register_type::<LineHeight>()
|
||||
.register_type::<TextColor>()
|
||||
.register_type::<TextSpan>()
|
||||
.register_type::<TextBounds>()
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -286,6 +286,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::RelativeToFont(1.2)`
|
||||
pub line_height: LineHeight,
|
||||
/// The antialiasing method to use when rendering text.
|
||||
pub font_smoothing: FontSmoothing,
|
||||
}
|
||||
@ -325,11 +330,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
|
||||
RelativeToFont(f32),
|
||||
}
|
||||
|
||||
impl LineHeight {
|
||||
pub(crate) fn eval(self, font_size: f32) -> f32 {
|
||||
match self {
|
||||
LineHeight::Px(px) => px,
|
||||
LineHeight::RelativeToFont(scale) => scale * font_size,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for LineHeight {
|
||||
fn default() -> Self {
|
||||
LineHeight::RelativeToFont(1.2)
|
||||
}
|
||||
}
|
||||
|
||||
/// The color of the text for this section.
|
||||
#[derive(Component, Copy, Clone, Debug, Deref, DerefMut, Reflect)]
|
||||
#[reflect(Component, Default, Debug)]
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user