Skip to main content

azul_core/
glyph.rs

1use crate::window::OptionChar;
2
3#[derive(Debug, Default, Copy, PartialEq, PartialOrd, Clone, Hash)]
4#[repr(C)]
5pub struct Advance {
6    pub advance_x: u16,
7    pub size_x: i32,
8    pub size_y: i32,
9    pub kerning: i16,
10}
11
12impl Advance {
13    #[inline]
14    pub const fn get_x_advance_total_unscaled(&self) -> i32 {
15        self.advance_x as i32 + self.kerning as i32
16    }
17    #[inline]
18    pub const fn get_x_advance_unscaled(&self) -> u16 {
19        self.advance_x
20    }
21    #[inline]
22    pub const fn get_x_size_unscaled(&self) -> i32 {
23        self.size_x
24    }
25    #[inline]
26    pub const fn get_y_size_unscaled(&self) -> i32 {
27        self.size_y
28    }
29    #[inline]
30    pub const fn get_kerning_unscaled(&self) -> i16 {
31        self.kerning
32    }
33
34    #[inline]
35    pub fn get_x_advance_total_scaled(&self, units_per_em: u16, target_font_size: f32) -> f32 {
36        self.get_x_advance_total_unscaled() as f32 / units_per_em as f32 * target_font_size
37    }
38    #[inline]
39    pub fn get_x_advance_scaled(&self, units_per_em: u16, target_font_size: f32) -> f32 {
40        self.get_x_advance_unscaled() as f32 / units_per_em as f32 * target_font_size
41    }
42    #[inline]
43    pub fn get_x_size_scaled(&self, units_per_em: u16, target_font_size: f32) -> f32 {
44        self.get_x_size_unscaled() as f32 / units_per_em as f32 * target_font_size
45    }
46    #[inline]
47    pub fn get_y_size_scaled(&self, units_per_em: u16, target_font_size: f32) -> f32 {
48        self.get_y_size_unscaled() as f32 / units_per_em as f32 * target_font_size
49    }
50    #[inline]
51    pub fn get_kerning_scaled(&self, units_per_em: u16, target_font_size: f32) -> f32 {
52        self.get_kerning_unscaled() as f32 / units_per_em as f32 * target_font_size
53    }
54}
55
56/// A Unicode variation selector.
57///
58/// VS04-VS14 are omitted as they aren't currently used.
59#[derive(Debug, Copy, PartialEq, PartialOrd, Clone, Hash)]
60#[repr(C)]
61pub enum VariationSelector {
62    /// VARIATION SELECTOR-1
63    VS01 = 1,
64    /// VARIATION SELECTOR-2
65    VS02 = 2,
66    /// VARIATION SELECTOR-3
67    VS03 = 3,
68    /// Text presentation
69    VS15 = 15,
70    /// Emoji presentation
71    VS16 = 16,
72}
73
74impl_option!(
75    VariationSelector,
76    OptionVariationSelector,
77    [Debug, Copy, PartialEq, PartialOrd, Clone, Hash]
78);
79
80#[derive(Debug, Copy, PartialEq, PartialOrd, Clone, Hash)]
81#[repr(C, u8)]
82pub enum GlyphOrigin {
83    Char(char),
84    Direct,
85}
86
87#[derive(Debug, Copy, PartialEq, PartialOrd, Clone, Hash)]
88#[repr(C)]
89pub struct PlacementDistance {
90    pub x: i32,
91    pub y: i32,
92}
93
94/// When not Attachment::None indicates that this glyph
95/// is an attachment with placement indicated by the variant.
96#[derive(Debug, Copy, PartialEq, PartialOrd, Clone, Hash)]
97#[repr(C, u8)]
98pub enum Placement {
99    None,
100    Distance(PlacementDistance),
101    MarkAnchor(MarkAnchorPlacement),
102    /// An overprint mark.
103    ///
104    /// This mark is shown at the same position as the base glyph.
105    ///
106    /// Fields: (base glyph index in `Vec<GlyphInfo>`)
107    MarkOverprint(usize),
108    CursiveAnchor(CursiveAnchorPlacement),
109}
110
111/// Cursive anchored placement.
112///
113/// https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#lookup-type-3-cursive-attachment-positioning-subtable
114#[derive(Debug, Copy, PartialEq, PartialOrd, Clone, Hash)]
115#[repr(C)]
116pub struct CursiveAnchorPlacement {
117    /// exit glyph index in the `Vec<GlyphInfo>`
118    pub exit_glyph_index: usize,
119    /// RIGHT_TO_LEFT flag from lookup table
120    pub right_to_left: bool,
121    /// exit glyph anchor
122    pub exit_glyph_anchor: Anchor,
123    /// entry glyph anchor
124    pub entry_glyph_anchor: Anchor,
125}
126
127/// An anchored mark.
128///
129/// This is a mark where its anchor is aligned with the base glyph anchor.
130#[derive(Debug, Copy, PartialEq, PartialOrd, Clone, Hash)]
131#[repr(C)]
132pub struct MarkAnchorPlacement {
133    /// base glyph index in `Vec<GlyphInfo>`
134    pub base_glyph_index: usize,
135    /// base glyph anchor
136    pub base_glyph_anchor: Anchor,
137    /// mark anchor
138    pub mark_anchor: Anchor,
139}
140
141#[derive(Debug, Copy, PartialEq, PartialOrd, Clone, Hash)]
142#[repr(C)]
143pub struct Anchor {
144    pub x: i16,
145    pub y: i16,
146}
147
148#[derive(Debug, Copy, PartialEq, PartialOrd, Clone, Hash)]
149#[repr(C)]
150pub struct RawGlyph {
151    pub unicode_codepoint: OptionChar, // Option<char>
152    pub glyph_index: u16,
153    pub liga_component_pos: u16,
154    pub glyph_origin: GlyphOrigin,
155    pub small_caps: bool,
156    pub multi_subst_dup: bool,
157    pub is_vert_alt: bool,
158    pub fake_bold: bool,
159    pub fake_italic: bool,
160    pub variation: OptionVariationSelector,
161}
162
163impl RawGlyph {
164    pub fn has_codepoint(&self) -> bool {
165        self.unicode_codepoint.is_some()
166    }
167
168    pub fn get_codepoint(&self) -> Option<char> {
169        self.unicode_codepoint
170            .as_ref()
171            .and_then(|u| core::char::from_u32(*u))
172    }
173}
174
175#[derive(Debug, PartialEq, PartialOrd, Clone, Hash)]
176#[repr(C)]
177pub struct GlyphInfo {
178    pub glyph: RawGlyph,
179    pub size: Advance,
180    pub kerning: i16,
181    pub placement: Placement,
182}
183
184impl_vec!(
185    GlyphInfo,
186    GlyphInfoVec,
187    GlyphInfoVecDestructor,
188    GlyphInfoVecDestructorType
189);
190impl_vec_clone!(GlyphInfo, GlyphInfoVec, GlyphInfoVecDestructor);
191impl_vec_debug!(GlyphInfo, GlyphInfoVec);
192impl_vec_partialeq!(GlyphInfo, GlyphInfoVec);
193impl_vec_partialord!(GlyphInfo, GlyphInfoVec);
194impl_vec_hash!(GlyphInfo, GlyphInfoVec);