Skip to main content

azul_layout/
font_traits.rs

1//! Font traits that are always available, regardless of text_layout feature.
2//!
3//! These traits define the interface between the layout solver and the font system.
4//! The actual implementations live in text3/cache.rs when text_layout feature is enabled.
5//!
6//! When `text_layout` + `font_loading` features are disabled, a stub module provides
7//! minimal placeholder types so that downstream code can still reference these names.
8
9use azul_core::geom::LogicalSize;
10
11#[cfg(all(feature = "text_layout", feature = "font_loading"))]
12pub use crate::text3::script::Language;
13#[cfg(all(feature = "text_layout", feature = "font_loading"))]
14pub use crate::text3::{
15    cache::{
16        AvailableSpace, BidiDirection, ContentIndex, FontHash, FontManager, FontSelector,
17        FontStyle, Glyph, ImageSource, InlineContent, InlineImage, InlineShape, TextShapingCache,
18        LayoutError, LayoutFontMetrics, LayoutFragment, ObjectFit, SegmentAlignment, ShapeBoundary,
19        ShapeDefinition, ShapedItem, Size, StyleProperties, StyledRun, UnifiedConstraints,
20        UnifiedLayout, VerticalMetrics,
21    },
22    script::Script,
23};
24
25/// Backwards-compat alias for the inner `TextShapingCache` type.
26/// The real struct was renamed to disambiguate it from
27/// [`crate::solver3::cache::LayoutCache`] (the per-node 9+1-slot
28/// layout cache). Internal callers that read this name continue to
29/// resolve via the alias; new code should use `TextShapingCache`.
30#[cfg(all(feature = "text_layout", feature = "font_loading"))]
31pub use crate::text3::cache::TextShapingCache as LayoutCache;
32
33#[cfg(all(feature = "text_layout", feature = "font_loading"))]
34pub type TextLayoutCache = TextShapingCache;
35
36#[cfg(not(all(feature = "text_layout", feature = "font_loading")))]
37pub use stub::TextLayoutCache;
38
39/// Trait for types that support cheap, shallow cloning (e.g., reference-counted types).
40pub trait ShallowClone {
41    /// Create a shallow clone (increment reference count, don't copy data)
42    #[must_use]
43    fn shallow_clone(&self) -> Self;
44}
45
46/// Core trait for parsed fonts that can be used for text shaping and layout.
47///
48/// This trait abstracts over the actual font parsing implementation, allowing
49/// the layout solver to work with different font backends.
50pub trait ParsedFontTrait: Send + Clone + ShallowClone {
51    /// Shape the given text into a sequence of glyphs using the font's shaping tables.
52    /// # Errors
53    ///
54    /// Returns a `LayoutError` if the text cannot be shaped.
55    fn shape_text(
56        &self,
57        text: &str,
58        script: Script,
59        language: Language,
60        direction: BidiDirection,
61        style: &StyleProperties,
62    ) -> Result<Vec<Glyph>, LayoutError>;
63
64    /// Hash of the font, necessary for breaking layouted glyphs into glyph runs
65    fn get_hash(&self) -> u64;
66
67    /// Returns the size of a glyph at the given font size, or `None` if the glyph is missing.
68    fn get_glyph_size(&self, glyph_id: u16, font_size: f32) -> Option<LogicalSize>;
69
70    /// Returns the glyph ID and horizontal advance of the hyphen character at the given font size.
71    fn get_hyphen_glyph_and_advance(&self, font_size: f32) -> Option<(u16, f32)>;
72
73    /// Returns the glyph ID and horizontal advance of the kashida (tatweel) character.
74    fn get_kashida_glyph_and_advance(&self, font_size: f32) -> Option<(u16, f32)>;
75
76    /// Returns whether the font contains a glyph for the given Unicode codepoint.
77    fn has_glyph(&self, codepoint: u32) -> bool;
78
79    /// Returns vertical metrics (ascent, descent, line gap) for a specific glyph.
80    fn get_vertical_metrics(&self, glyph_id: u16) -> Option<VerticalMetrics>;
81
82    /// Returns the global font metrics (ascent, descent, units per em, etc.).
83    fn get_font_metrics(&self) -> LayoutFontMetrics;
84
85    /// Returns the total number of glyphs in the font.
86    fn num_glyphs(&self) -> u16;
87
88    /// Returns the advance width of the space character (U+0020) in font units,
89    /// or None if the font doesn't have a space glyph.
90    fn get_space_width(&self) -> Option<usize>;
91}
92
93/// Trait for loading fonts from raw bytes.
94///
95/// This allows different font loading strategies (e.g., allsorts, freetype, mock)
96/// to be used with the layout engine.
97pub trait FontLoaderTrait<T>: Send + core::fmt::Debug {
98    /// # Errors
99    ///
100    /// Returns a `LayoutError` if the font cannot be loaded.
101    fn load_font(&self, font_bytes: &[u8], font_index: usize) -> Result<T, LayoutError>;
102}
103
104// When text_layout or font_loading is disabled, provide minimal stub types
105#[cfg(not(all(feature = "text_layout", feature = "font_loading")))]
106pub use stub::*;
107
108#[cfg(not(all(feature = "text_layout", feature = "font_loading")))]
109mod stub {
110    use super::*;
111
112    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
113    pub struct Script;
114
115    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
116    pub struct Language;
117
118    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
119    pub enum FontStyle {
120        Normal,
121        Italic,
122        Oblique,
123    }
124
125    /// Stub for BidiDirection when text_layout is disabled
126    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
127    pub enum BidiDirection {
128        Ltr,
129        Rtl,
130    }
131
132    #[derive(Debug, Clone)]
133    pub struct StyleProperties;
134
135    #[derive(Debug, Clone)]
136    pub struct Glyph;
137
138    #[derive(Debug, Clone, Copy)]
139    pub struct VerticalMetrics {
140        pub ascent: f32,
141        pub descent: f32,
142        pub line_gap: f32,
143    }
144
145    #[derive(Debug, Clone, Copy)]
146    pub struct LayoutFontMetrics {
147        pub ascent: f32,
148        pub descent: f32,
149        pub line_gap: f32,
150        pub units_per_em: u16,
151        pub x_height: Option<f32>,
152        pub cap_height: Option<f32>,
153    }
154
155    #[derive(Debug, Clone)]
156    pub struct LayoutError;
157
158    #[derive(Debug, Clone)]
159    pub struct FontSelector;
160
161    #[derive(Debug)]
162    pub struct FontManager;
163
164    #[derive(Debug)]
165    pub struct LayoutCache;
166
167    // Additional stub types needed by solver3
168    pub type ContentIndex = usize;
169    pub type FontHash = u64;
170
171    #[derive(Debug, Clone)]
172    pub struct InlineContent;
173
174    #[derive(Debug, Clone)]
175    pub struct StyledRun;
176
177    #[derive(Debug, Clone)]
178    pub struct LayoutFragment;
179
180    #[derive(Debug, Clone)]
181    pub struct UnifiedConstraints;
182
183    #[derive(Debug, Clone)]
184    pub struct InlineImage;
185
186    #[derive(Debug, Clone)]
187    pub struct InlineShape;
188
189    #[derive(Debug, Clone)]
190    pub struct ShapeDefinition;
191
192    #[derive(Debug, Clone)]
193    pub struct ShapeBoundary;
194
195    #[derive(Debug, Clone)]
196    pub struct ShapedItem;
197
198    #[derive(Debug, Clone)]
199    pub enum ImageSource {
200        Ref(azul_core::resources::ImageRef),
201        Url(String),
202        Data(std::sync::Arc<[u8]>),
203        Svg(std::sync::Arc<str>),
204        Placeholder(Size),
205    }
206
207    #[derive(Debug, Clone, Copy)]
208    pub enum ObjectFit {
209        Contain,
210        Cover,
211        Fill,
212        None,
213        ScaleDown,
214    }
215
216    #[derive(Debug, Clone, Copy)]
217    pub enum SegmentAlignment {
218        Start,
219        Center,
220        End,
221    }
222
223    #[derive(Debug, Clone)]
224    pub struct UnifiedLayout;
225
226    pub type TextLayoutCache = LayoutCache;
227
228    pub type Size = azul_core::geom::LogicalSize;
229}