summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-05-04 13:00:16 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-05-04 18:39:31 +0200
commit9499a8f9e6f9971dedfae563cb133232aa3cebc2 (patch)
tree54074dd8b1fc17d63ad92d84b6d2b4415ad29df6 /core
parent8e8808f0e187ed6671441f5016f07bfcba426452 (diff)
downloadiced-9499a8f9e6f9971dedfae563cb133232aa3cebc2.tar.gz
iced-9499a8f9e6f9971dedfae563cb133232aa3cebc2.tar.bz2
iced-9499a8f9e6f9971dedfae563cb133232aa3cebc2.zip
Support configurable `LineHeight` in text widgets
Diffstat (limited to 'core')
-rw-r--r--core/src/length.rs8
-rw-r--r--core/src/pixels.rs6
-rw-r--r--core/src/renderer/null.rs2
-rw-r--r--core/src/text.rs73
-rw-r--r--core/src/widget/text.rs20
5 files changed, 104 insertions, 5 deletions
diff --git a/core/src/length.rs b/core/src/length.rs
index bb925c4b..3adb996e 100644
--- a/core/src/length.rs
+++ b/core/src/length.rs
@@ -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)
diff --git a/core/src/pixels.rs b/core/src/pixels.rs
index e42cd9f9..6a9e5c88 100644
--- a/core/src/pixels.rs
+++ b/core/src/pixels.rs
@@ -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
+ }
+}
diff --git a/core/src/renderer/null.rs b/core/src/renderer/null.rs
index 22afb058..f0cc952e 100644
--- a/core/src/renderer/null.rs
+++ b/core/src/renderer/null.rs
@@ -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,
diff --git a/core/src/text.rs b/core/src/text.rs
index c59d8fce..1a867be3 100644
--- a/core/src/text.rs
+++ b/core/src/text.rs
@@ -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,
diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs
index f0392168..2d86e735 100644
--- a/core/src/widget/text.rs
+++ b/core/src/widget/text.rs
@@ -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,