diff options
Diffstat (limited to '')
| -rw-r--r-- | core/src/length.rs | 8 | ||||
| -rw-r--r-- | core/src/pixels.rs | 6 | ||||
| -rw-r--r-- | core/src/renderer/null.rs | 2 | ||||
| -rw-r--r-- | core/src/text.rs | 73 | ||||
| -rw-r--r-- | core/src/widget/text.rs | 20 | 
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, | 
