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    fn shallow_clone(&self) -> Self;
43}
44
45/// Core trait for parsed fonts that can be used for text shaping and layout.
46///
47/// This trait abstracts over the actual font parsing implementation, allowing
48/// the layout solver to work with different font backends.
49pub trait ParsedFontTrait: Send + Clone + ShallowClone {
50    /// Shape the given text into a sequence of glyphs using the font's shaping tables.
51    fn shape_text(
52        &self,
53        text: &str,
54        script: Script,
55        language: Language,
56        direction: BidiDirection,
57        style: &StyleProperties,
58    ) -> Result<Vec<Glyph>, LayoutError>;
59
60    /// Hash of the font, necessary for breaking layouted glyphs into glyph runs
61    fn get_hash(&self) -> u64;
62
63    /// Returns the size of a glyph at the given font size, or `None` if the glyph is missing.
64    fn get_glyph_size(&self, glyph_id: u16, font_size: f32) -> Option<LogicalSize>;
65
66    /// Returns the glyph ID and horizontal advance of the hyphen character at the given font size.
67    fn get_hyphen_glyph_and_advance(&self, font_size: f32) -> Option<(u16, f32)>;
68
69    /// Returns the glyph ID and horizontal advance of the kashida (tatweel) character.
70    fn get_kashida_glyph_and_advance(&self, font_size: f32) -> Option<(u16, f32)>;
71
72    /// Returns whether the font contains a glyph for the given Unicode codepoint.
73    fn has_glyph(&self, codepoint: u32) -> bool;
74
75    /// Returns vertical metrics (ascent, descent, line gap) for a specific glyph.
76    fn get_vertical_metrics(&self, glyph_id: u16) -> Option<VerticalMetrics>;
77
78    /// Returns the global font metrics (ascent, descent, units per em, etc.).
79    fn get_font_metrics(&self) -> LayoutFontMetrics;
80
81    /// Returns the total number of glyphs in the font.
82    fn num_glyphs(&self) -> u16;
83
84    /// Returns the advance width of the space character (U+0020) in font units,
85    /// or None if the font doesn't have a space glyph.
86    fn get_space_width(&self) -> Option<usize>;
87}
88
89/// Trait for loading fonts from raw bytes.
90///
91/// This allows different font loading strategies (e.g., allsorts, freetype, mock)
92/// to be used with the layout engine.
93pub trait FontLoaderTrait<T>: Send + core::fmt::Debug {
94    fn load_font(&self, font_bytes: &[u8], font_index: usize) -> Result<T, LayoutError>;
95}
96
97/// Opaque font identifier - wraps the underlying font system's ID type
98#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
99pub struct FontId(pub u64);
100
101/// Trait for font system abstraction (font discovery, fallback chains).
102///
103/// This abstracts over the underlying font system (e.g., rust_fontconfig, fontdb)
104/// allowing text3 to work with or without system font discovery.
105pub trait FontSystemTrait: Send + Sync {
106    /// The type of font fallback chain this system uses
107    type FallbackChain: FontFallbackChainTrait;
108
109    /// Resolve a character to a font ID using the fallback chain
110    fn resolve_char(&self, chain: &Self::FallbackChain, c: char) -> Option<FontId>;
111
112    /// Get the font data (bytes) for a font ID
113    fn get_font_data(&self, font_id: FontId) -> Option<alloc::vec::Vec<u8>>;
114
115    /// Get the font index within the font file
116    fn get_font_index(&self, font_id: FontId) -> usize;
117}
118
119/// Trait for font fallback chains
120pub trait FontFallbackChainTrait: Clone + Send + Sync {
121    /// Check if the chain is empty
122    fn is_empty(&self) -> bool;
123
124    /// Get the primary font ID (if any)
125    fn primary_font_id(&self) -> Option<FontId>;
126}
127
128// When text_layout or font_loading is disabled, provide minimal stub types
129#[cfg(not(all(feature = "text_layout", feature = "font_loading")))]
130pub use stub::*;
131
132#[cfg(not(all(feature = "text_layout", feature = "font_loading")))]
133mod stub {
134    use super::*;
135
136    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
137    pub struct Script;
138
139    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
140    pub struct Language;
141
142    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
143    pub enum FontStyle {
144        Normal,
145        Italic,
146        Oblique,
147    }
148
149    /// Stub for BidiDirection when text_layout is disabled
150    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
151    pub enum BidiDirection {
152        Ltr,
153        Rtl,
154    }
155
156    #[derive(Debug, Clone)]
157    pub struct StyleProperties;
158
159    #[derive(Debug, Clone)]
160    pub struct Glyph;
161
162    #[derive(Debug, Clone, Copy)]
163    pub struct VerticalMetrics {
164        pub ascent: f32,
165        pub descent: f32,
166        pub line_gap: f32,
167    }
168
169    #[derive(Debug, Clone, Copy)]
170    pub struct LayoutFontMetrics {
171        pub ascent: f32,
172        pub descent: f32,
173        pub line_gap: f32,
174        pub units_per_em: u16,
175        pub x_height: Option<f32>,
176        pub cap_height: Option<f32>,
177    }
178
179    #[derive(Debug, Clone)]
180    pub struct LayoutError;
181
182    #[derive(Debug, Clone)]
183    pub struct FontSelector;
184
185    #[derive(Debug)]
186    pub struct FontManager;
187
188    #[derive(Debug)]
189    pub struct LayoutCache;
190
191    // Additional stub types needed by solver3
192    pub type ContentIndex = usize;
193    pub type FontHash = u64;
194
195    #[derive(Debug, Clone)]
196    pub struct InlineContent;
197
198    #[derive(Debug, Clone)]
199    pub struct StyledRun;
200
201    #[derive(Debug, Clone)]
202    pub struct LayoutFragment;
203
204    #[derive(Debug, Clone)]
205    pub struct UnifiedConstraints;
206
207    #[derive(Debug, Clone)]
208    pub struct InlineImage;
209
210    #[derive(Debug, Clone)]
211    pub struct InlineShape;
212
213    #[derive(Debug, Clone)]
214    pub struct ShapeDefinition;
215
216    #[derive(Debug, Clone)]
217    pub struct ShapeBoundary;
218
219    #[derive(Debug, Clone)]
220    pub struct ShapedItem;
221
222    #[derive(Debug, Clone)]
223    pub enum ImageSource {
224        Ref(azul_core::resources::ImageRef),
225        Url(String),
226        Data(std::sync::Arc<[u8]>),
227        Svg(std::sync::Arc<str>),
228        Placeholder(Size),
229    }
230
231    #[derive(Debug, Clone, Copy)]
232    pub enum ObjectFit {
233        Contain,
234        Cover,
235        Fill,
236        None,
237        ScaleDown,
238    }
239
240    #[derive(Debug, Clone, Copy)]
241    pub enum SegmentAlignment {
242        Start,
243        Center,
244        End,
245    }
246
247    #[derive(Debug, Clone)]
248    pub struct UnifiedLayout;
249
250    pub type TextLayoutCache = LayoutCache;
251
252    pub type Size = azul_core::geom::LogicalSize;
253}