Support configurable LineHeight in text widgets
This commit is contained in:
parent
8e8808f0e1
commit
9499a8f9e6
24 changed files with 337 additions and 42 deletions
|
|
@ -1,3 +1,5 @@
|
|||
use crate::Pixels;
|
||||
|
||||
/// The strategy used to fill space in a specific dimension.
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum Length {
|
||||
|
|
@ -36,6 +38,12 @@ impl Length {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<Pixels> for Length {
|
||||
fn from(amount: Pixels) -> Self {
|
||||
Length::Fixed(f32::from(amount))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f32> for Length {
|
||||
fn from(amount: f32) -> Self {
|
||||
Length::Fixed(amount)
|
||||
|
|
|
|||
|
|
@ -20,3 +20,9 @@ impl From<u16> for Pixels {
|
|||
Self(f32::from(amount))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Pixels> for f32 {
|
||||
fn from(pixels: Pixels) -> Self {
|
||||
pixels.0
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ impl text::Renderer for Null {
|
|||
&self,
|
||||
_content: &str,
|
||||
_size: f32,
|
||||
_line_height: text::LineHeight,
|
||||
_font: Font,
|
||||
_bounds: Size,
|
||||
_shaping: text::Shaping,
|
||||
|
|
@ -71,6 +72,7 @@ impl text::Renderer for Null {
|
|||
&self,
|
||||
_contents: &str,
|
||||
_size: f32,
|
||||
_line_height: text::LineHeight,
|
||||
_font: Self::Font,
|
||||
_bounds: Size,
|
||||
_shaping: text::Shaping,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ where
|
|||
{
|
||||
content: Cow<'a, str>,
|
||||
size: Option<f32>,
|
||||
line_height: text::LineHeight,
|
||||
width: Length,
|
||||
height: Length,
|
||||
horizontal_alignment: alignment::Horizontal,
|
||||
|
|
@ -38,6 +39,7 @@ where
|
|||
Text {
|
||||
content: content.into(),
|
||||
size: None,
|
||||
line_height: text::LineHeight::default(),
|
||||
font: None,
|
||||
width: Length::Shrink,
|
||||
height: Length::Shrink,
|
||||
|
|
@ -54,6 +56,15 @@ where
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets the [`LineHeight`] of the [`Text`].
|
||||
pub fn line_height(
|
||||
mut self,
|
||||
line_height: impl Into<text::LineHeight>,
|
||||
) -> Self {
|
||||
self.line_height = line_height.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the [`Font`] of the [`Text`].
|
||||
///
|
||||
/// [`Font`]: crate::text::Renderer::Font
|
||||
|
|
@ -135,6 +146,7 @@ where
|
|||
let (width, height) = renderer.measure(
|
||||
&self.content,
|
||||
size,
|
||||
self.line_height,
|
||||
self.font.unwrap_or_else(|| renderer.default_font()),
|
||||
bounds,
|
||||
self.shaping,
|
||||
|
|
@ -161,6 +173,7 @@ where
|
|||
layout,
|
||||
&self.content,
|
||||
self.size,
|
||||
self.line_height,
|
||||
self.font,
|
||||
theme.appearance(self.style.clone()),
|
||||
self.horizontal_alignment,
|
||||
|
|
@ -186,6 +199,7 @@ pub fn draw<Renderer>(
|
|||
layout: Layout<'_>,
|
||||
content: &str,
|
||||
size: Option<f32>,
|
||||
line_height: text::LineHeight,
|
||||
font: Option<Renderer::Font>,
|
||||
appearance: Appearance,
|
||||
horizontal_alignment: alignment::Horizontal,
|
||||
|
|
@ -208,9 +222,12 @@ pub fn draw<Renderer>(
|
|||
alignment::Vertical::Bottom => bounds.y + bounds.height,
|
||||
};
|
||||
|
||||
let size = size.unwrap_or_else(|| renderer.default_size());
|
||||
|
||||
renderer.fill_text(crate::Text {
|
||||
content,
|
||||
size: size.unwrap_or_else(|| renderer.default_size()),
|
||||
size,
|
||||
line_height,
|
||||
bounds: Rectangle { x, y, ..bounds },
|
||||
color: appearance.color.unwrap_or(style.text_color),
|
||||
font: font.unwrap_or_else(|| renderer.default_font()),
|
||||
|
|
@ -240,6 +257,7 @@ where
|
|||
Self {
|
||||
content: self.content.clone(),
|
||||
size: self.size,
|
||||
line_height: self.line_height,
|
||||
width: self.width,
|
||||
height: self.height,
|
||||
horizontal_alignment: self.horizontal_alignment,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue