From b3a01973c6c726e6539be959659f4306ef3234c6 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 31 Oct 2021 16:13:03 +0700 Subject: Introduce first-class `text` module in `iced_native` --- native/src/text.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 native/src/text.rs (limited to 'native/src/text.rs') diff --git a/native/src/text.rs b/native/src/text.rs new file mode 100644 index 00000000..f112a8f3 --- /dev/null +++ b/native/src/text.rs @@ -0,0 +1,71 @@ +use crate::alignment; +use crate::{Color, Point, Rectangle, Size}; + +pub use iced_core::text::Hit; + +#[derive(Debug, Clone, Copy)] +pub struct Text<'a, Font> { + pub content: &'a str, + pub bounds: Rectangle, + pub size: f32, + pub color: Color, + pub font: Font, + pub horizontal_alignment: alignment::Horizontal, + pub vertical_alignment: alignment::Vertical, +} + +pub trait Renderer: crate::Renderer { + /// The font type used. + type Font: Default + Copy; + + /// The icon font of the backend. + const ICON_FONT: Self::Font; + + /// The `char` representing a ✔ icon in the [`ICON_FONT`]. + /// + /// [`ICON_FONT`]: Self::ICON_FONT + const CHECKMARK_ICON: char; + + /// The `char` representing a ▼ icon in the built-in [`ICON_FONT`]. + /// + /// [`ICON_FONT`]: Self::ICON_FONT + const ARROW_DOWN_ICON: char; + + /// Returns the default size of [`Text`]. + fn default_size(&self) -> u16; + + /// Measures the text in the given bounds and returns the minimum boundaries + /// that can fit the contents. + fn measure( + &self, + content: &str, + size: u16, + font: Self::Font, + bounds: Size, + ) -> (f32, f32); + + fn measure_width(&self, content: &str, size: u16, font: Self::Font) -> f32 { + let (width, _) = self.measure(content, size, font, Size::INFINITY); + + width + } + + /// Tests whether the provided point is within the boundaries of [`Text`] + /// laid out with the given parameters, returning information about + /// the nearest character. + /// + /// If `nearest_only` is true, the hit test does not consider whether the + /// the point is interior to any glyph bounds, returning only the character + /// with the nearest centeroid. + fn hit_test( + &self, + contents: &str, + size: f32, + font: Self::Font, + bounds: Size, + point: Point, + nearest_only: bool, + ) -> Option; + + fn fill_text(&mut self, text: Text<'_, Self::Font>); +} -- cgit From 343f9b7e2e594bd1fef1ed511d71e81f9c44e3d9 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 4 Nov 2021 18:28:06 +0700 Subject: Merge `iced_core::text` with `iced_native::text` --- native/src/text.rs | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'native/src/text.rs') diff --git a/native/src/text.rs b/native/src/text.rs index f112a8f3..81419481 100644 --- a/native/src/text.rs +++ b/native/src/text.rs @@ -1,7 +1,5 @@ use crate::alignment; -use crate::{Color, Point, Rectangle, Size}; - -pub use iced_core::text::Hit; +use crate::{Color, Point, Rectangle, Size, Vector}; #[derive(Debug, Clone, Copy)] pub struct Text<'a, Font> { @@ -14,6 +12,33 @@ pub struct Text<'a, Font> { pub vertical_alignment: alignment::Vertical, } +/// The result of hit testing on text. +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum Hit { + /// The point was within the bounds of the returned character index. + CharOffset(usize), + /// The provided point was not within the bounds of a glyph. The index + /// of the character with the closest centeroid position is returned, + /// as well as its delta. + NearestCharOffset(usize, Vector), +} + +impl Hit { + /// Computes the cursor position corresponding to this [`HitTestResult`] . + pub fn cursor(self) -> usize { + match self { + Self::CharOffset(i) => i, + Self::NearestCharOffset(i, delta) => { + if delta.x > f32::EPSILON { + i + 1 + } else { + i + } + } + } + } +} + pub trait Renderer: crate::Renderer { /// The font type used. type Font: Default + Copy; -- cgit From d5f4067defcc033c5963676c872d9245d494db69 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 4 Nov 2021 19:24:52 +0700 Subject: Write documentation for `iced_native::text` --- native/src/text.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'native/src/text.rs') diff --git a/native/src/text.rs b/native/src/text.rs index 81419481..8b9205e3 100644 --- a/native/src/text.rs +++ b/native/src/text.rs @@ -1,14 +1,29 @@ +//! Draw and interact with text. use crate::alignment; use crate::{Color, Point, Rectangle, Size, Vector}; +/// A paragraph. #[derive(Debug, Clone, Copy)] pub struct Text<'a, Font> { + /// The content of the paragraph. pub content: &'a str, + + /// The bounds of the paragraph. pub bounds: Rectangle, + + /// The size of the [`Text`]. pub size: f32, + + /// The color of the [`Text`]. pub color: Color, + + /// The font of the [`Text`]. pub font: Font, + + /// The horizontal alignment of the [`Text`]. pub horizontal_alignment: alignment::Horizontal, + + /// The vertical alignment of the [`Text`]. pub vertical_alignment: alignment::Vertical, } @@ -39,6 +54,7 @@ impl Hit { } } +/// A renderer capable of measuring and drawing [`Text`]. pub trait Renderer: crate::Renderer { /// The font type used. type Font: Default + Copy; @@ -69,13 +85,14 @@ pub trait Renderer: crate::Renderer { bounds: Size, ) -> (f32, f32); + /// Measures the width of the text as if it were laid out in a single line. fn measure_width(&self, content: &str, size: u16, font: Self::Font) -> f32 { let (width, _) = self.measure(content, size, font, Size::INFINITY); width } - /// Tests whether the provided point is within the boundaries of [`Text`] + /// Tests whether the provided point is within the boundaries of text /// laid out with the given parameters, returning information about /// the nearest character. /// @@ -92,5 +109,6 @@ pub trait Renderer: crate::Renderer { nearest_only: bool, ) -> Option; + /// Draws the given [`Text`]. fn fill_text(&mut self, text: Text<'_, Self::Font>); } -- cgit