diff options
Diffstat (limited to '')
| -rw-r--r-- | graphics/src/text.rs | 129 | ||||
| -rw-r--r-- | graphics/src/text/cache.rs | 16 | ||||
| -rw-r--r-- | graphics/src/text/paragraph.rs | 4 | 
3 files changed, 136 insertions, 13 deletions
| diff --git a/graphics/src/text.rs b/graphics/src/text.rs index 0310ead7..30269e69 100644 --- a/graphics/src/text.rs +++ b/graphics/src/text.rs @@ -9,14 +9,141 @@ pub use paragraph::Paragraph;  pub use cosmic_text; +use crate::core::alignment;  use crate::core::font::{self, Font};  use crate::core::text::Shaping; -use crate::core::{Color, Point, Rectangle, Size}; +use crate::core::{Color, Pixels, Point, Rectangle, Size, Transformation};  use once_cell::sync::OnceCell;  use std::borrow::Cow;  use std::sync::{Arc, RwLock, Weak}; +/// A text primitive. +#[derive(Debug, Clone, PartialEq)] +pub enum Text { +    /// A paragraph. +    #[allow(missing_docs)] +    Paragraph { +        paragraph: paragraph::Weak, +        position: Point, +        color: Color, +        clip_bounds: Rectangle, +        transformation: Transformation, +    }, +    /// An editor. +    #[allow(missing_docs)] +    Editor { +        editor: editor::Weak, +        position: Point, +        color: Color, +        clip_bounds: Rectangle, +        transformation: Transformation, +    }, +    /// Some cached text. +    Cached { +        /// The contents of the text. +        content: String, +        /// The bounds of the text. +        bounds: Rectangle, +        /// The color of the text. +        color: Color, +        /// The size of the text in logical pixels. +        size: Pixels, +        /// The line height of the text. +        line_height: Pixels, +        /// The font of the text. +        font: Font, +        /// The horizontal alignment of the text. +        horizontal_alignment: alignment::Horizontal, +        /// The vertical alignment of the text. +        vertical_alignment: alignment::Vertical, +        /// The shaping strategy of the text. +        shaping: Shaping, +        /// The clip bounds of the text. +        clip_bounds: Rectangle, +    }, +    /// Some raw text. +    #[allow(missing_docs)] +    Raw { +        raw: Raw, +        transformation: Transformation, +    }, +} + +impl Text { +    /// Returns the visible bounds of the [`Text`]. +    pub fn visible_bounds(&self) -> Option<Rectangle> { +        let (bounds, horizontal_alignment, vertical_alignment) = match self { +            Text::Paragraph { +                position, +                paragraph, +                clip_bounds, +                transformation, +                .. +            } => ( +                Rectangle::new(*position, paragraph.min_bounds) +                    .intersection(clip_bounds) +                    .map(|bounds| bounds * *transformation), +                Some(paragraph.horizontal_alignment), +                Some(paragraph.vertical_alignment), +            ), +            Text::Editor { +                editor, +                position, +                clip_bounds, +                transformation, +                .. +            } => ( +                Rectangle::new(*position, editor.bounds) +                    .intersection(clip_bounds) +                    .map(|bounds| bounds * *transformation), +                None, +                None, +            ), +            Text::Cached { +                bounds, +                clip_bounds, +                horizontal_alignment, +                vertical_alignment, +                .. +            } => ( +                bounds.intersection(clip_bounds), +                Some(*horizontal_alignment), +                Some(*vertical_alignment), +            ), +            Text::Raw { raw, .. } => (Some(raw.clip_bounds), None, None), +        }; + +        let mut bounds = bounds?; + +        if let Some(alignment) = horizontal_alignment { +            match alignment { +                alignment::Horizontal::Left => {} +                alignment::Horizontal::Center => { +                    bounds.x -= bounds.width / 2.0; +                } +                alignment::Horizontal::Right => { +                    bounds.x -= bounds.width; +                } +            } +        } + +        if let Some(alignment) = vertical_alignment { +            match alignment { +                alignment::Vertical::Top => {} +                alignment::Vertical::Center => { +                    bounds.y -= bounds.height / 2.0; +                } +                alignment::Vertical::Bottom => { +                    bounds.y -= bounds.height; +                } +            } +        } + +        Some(bounds) +    } +} +  /// The regular variant of the [Fira Sans] font.  ///  /// It is loaded as part of the default fonts in Wasm builds. diff --git a/graphics/src/text/cache.rs b/graphics/src/text/cache.rs index 7fb33567..822b61c4 100644 --- a/graphics/src/text/cache.rs +++ b/graphics/src/text/cache.rs @@ -2,22 +2,18 @@  use crate::core::{Font, Size};  use crate::text; -use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_hash::{FxHashMap, FxHashSet, FxHasher};  use std::collections::hash_map; -use std::hash::{BuildHasher, Hash, Hasher}; +use std::hash::{Hash, Hasher};  /// A store of recently used sections of text. -#[allow(missing_debug_implementations)] -#[derive(Default)] +#[derive(Debug, Default)]  pub struct Cache {      entries: FxHashMap<KeyHash, Entry>,      aliases: FxHashMap<KeyHash, KeyHash>,      recently_used: FxHashSet<KeyHash>, -    hasher: HashBuilder,  } -type HashBuilder = xxhash_rust::xxh3::Xxh3Builder; -  impl Cache {      /// Creates a new empty [`Cache`].      pub fn new() -> Self { @@ -35,7 +31,7 @@ impl Cache {          font_system: &mut cosmic_text::FontSystem,          key: Key<'_>,      ) -> (KeyHash, &mut Entry) { -        let hash = key.hash(self.hasher.build_hasher()); +        let hash = key.hash(FxHasher::default());          if let Some(hash) = self.aliases.get(&hash) {              let _ = self.recently_used.insert(*hash); @@ -77,7 +73,7 @@ impl Cache {              ] {                  if key.bounds != bounds {                      let _ = self.aliases.insert( -                        Key { bounds, ..key }.hash(self.hasher.build_hasher()), +                        Key { bounds, ..key }.hash(FxHasher::default()),                          hash,                      );                  } @@ -138,7 +134,7 @@ impl Key<'_> {  pub type KeyHash = u64;  /// A cache entry. -#[allow(missing_debug_implementations)] +#[derive(Debug)]  pub struct Entry {      /// The buffer of text, ready for drawing.      pub buffer: cosmic_text::Buffer, diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs index 5d027542..31a323ac 100644 --- a/graphics/src/text/paragraph.rs +++ b/graphics/src/text/paragraph.rs @@ -61,7 +61,7 @@ impl Paragraph {  impl core::text::Paragraph for Paragraph {      type Font = Font; -    fn with_text(text: Text<'_, Font>) -> Self { +    fn with_text(text: Text<&str>) -> Self {          log::trace!("Allocating paragraph: {}", text.content);          let mut font_system = @@ -146,7 +146,7 @@ impl core::text::Paragraph for Paragraph {          }      } -    fn compare(&self, text: Text<'_, Font>) -> core::text::Difference { +    fn compare(&self, text: Text<&str>) -> core::text::Difference {          let font_system = text::font_system().read().expect("Read font system");          let paragraph = self.internal();          let metrics = paragraph.buffer.metrics(); | 
