Support configurable LineHeight in text widgets

This commit is contained in:
Héctor Ramón Jiménez 2023-05-04 13:00:16 +02:00
parent 8e8808f0e1
commit 9499a8f9e6
No known key found for this signature in database
GPG key ID: 140CC052C94F138E
24 changed files with 337 additions and 42 deletions

View file

@ -1,8 +1,9 @@
//! Draw and interact with text.
use crate::alignment;
use crate::{Color, Point, Rectangle, Size};
use crate::{Color, Pixels, Point, Rectangle, Size};
use std::borrow::Cow;
use std::hash::{Hash, Hasher};
/// A paragraph.
#[derive(Debug, Clone, Copy)]
@ -13,9 +14,12 @@ pub struct Text<'a, Font> {
/// The bounds of the paragraph.
pub bounds: Rectangle,
/// The size of the [`Text`].
/// The size of the [`Text`] in logical pixels.
pub size: f32,
/// The line height of the [`Text`].
pub line_height: LineHeight,
/// The color of the [`Text`].
pub color: Color,
@ -56,6 +60,59 @@ pub enum Shaping {
Advanced,
}
/// The height of a line of text in a paragraph.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum LineHeight {
/// A factor of the size of the text.
Relative(f32),
/// An absolute height in logical pixels.
Absolute(Pixels),
}
impl LineHeight {
/// Returns the [`LineHeight`] in absolute logical pixels.
pub fn to_absolute(self, text_size: Pixels) -> Pixels {
match self {
Self::Relative(factor) => Pixels(factor * text_size.0),
Self::Absolute(pixels) => pixels,
}
}
}
impl Default for LineHeight {
fn default() -> Self {
Self::Relative(1.2)
}
}
impl From<f32> for LineHeight {
fn from(factor: f32) -> Self {
Self::Relative(factor)
}
}
impl From<Pixels> for LineHeight {
fn from(pixels: Pixels) -> Self {
Self::Absolute(pixels)
}
}
impl Hash for LineHeight {
fn hash<H: Hasher>(&self, state: &mut H) {
match self {
Self::Relative(factor) => {
state.write_u8(0);
factor.to_bits().hash(state);
}
Self::Absolute(pixels) => {
state.write_u8(1);
f32::from(*pixels).to_bits().hash(state);
}
}
}
}
/// The result of hit testing on text.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Hit {
@ -102,6 +159,7 @@ pub trait Renderer: crate::Renderer {
&self,
content: &str,
size: f32,
line_height: LineHeight,
font: Self::Font,
bounds: Size,
shaping: Shaping,
@ -115,8 +173,14 @@ pub trait Renderer: crate::Renderer {
font: Self::Font,
shaping: Shaping,
) -> f32 {
let (width, _) =
self.measure(content, size, font, Size::INFINITY, shaping);
let (width, _) = self.measure(
content,
size,
LineHeight::Absolute(Pixels(size)),
font,
Size::INFINITY,
shaping,
);
width
}
@ -132,6 +196,7 @@ pub trait Renderer: crate::Renderer {
&self,
contents: &str,
size: f32,
line_height: LineHeight,
font: Self::Font,
bounds: Size,
shaping: Shaping,