Skip to main content

read_fonts/generated/
generated_mort.rs

1// THIS FILE IS AUTOGENERATED.
2// Any changes to this file will be overwritten.
3// For more information about how codegen works, see font-codegen/README.md
4
5#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8impl<'a> MinByteRange<'a> for Mort<'a> {
9    fn min_byte_range(&self) -> Range<usize> {
10        0..self.chains_byte_range().end
11    }
12    fn min_table_bytes(&self) -> &'a [u8] {
13        let range = self.min_byte_range();
14        self.data.as_bytes().get(range).unwrap_or_default()
15    }
16}
17
18impl TopLevelTable for Mort<'_> {
19    /// `mort`
20    const TAG: Tag = Tag::new(b"mort");
21}
22
23impl ReadArgs for Mort<'_> {
24    type Args = ();
25}
26
27impl<'a> FontRead<'a> for Mort<'a> {
28    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
29        #[allow(clippy::absurd_extreme_comparisons)]
30        if data.len() < Self::MIN_SIZE {
31            return Err(ReadError::OutOfBounds);
32        }
33        Ok(Self { data })
34    }
35}
36
37/// The [mort (Glyph Metamorphosis)](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6mort.html) table.
38#[derive(Clone)]
39pub struct Mort<'a> {
40    data: FontData<'a>,
41}
42
43#[allow(clippy::needless_lifetimes)]
44impl<'a> Mort<'a> {
45    pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
46    basic_table_impls!(impl_the_methods);
47
48    /// Version number of the glyph metamorphosis table.
49    pub fn version(&self) -> u16 {
50        let range = self.version_byte_range();
51        self.data.read_at(range.start).ok().unwrap()
52    }
53
54    /// Number of metamorphosis chains contained in this table.
55    pub fn n_chains(&self) -> u32 {
56        let range = self.n_chains_byte_range();
57        self.data.read_at(range.start).ok().unwrap()
58    }
59
60    pub fn chains(&self) -> VarLenArray<'a, Chain<'a>> {
61        let range = self.chains_byte_range();
62        self.data
63            .split_off(range.start)
64            .and_then(|d| VarLenArray::read(d).ok())
65            .unwrap_or_default()
66    }
67
68    pub fn version_byte_range(&self) -> Range<usize> {
69        let start = 0;
70        let end = start + u16::RAW_BYTE_LEN;
71        start..end
72    }
73
74    pub fn unused_byte_range(&self) -> Range<usize> {
75        let start = self.version_byte_range().end;
76        let end = start + u16::RAW_BYTE_LEN;
77        start..end
78    }
79
80    pub fn n_chains_byte_range(&self) -> Range<usize> {
81        let start = self.unused_byte_range().end;
82        let end = start + u32::RAW_BYTE_LEN;
83        start..end
84    }
85
86    pub fn chains_byte_range(&self) -> Range<usize> {
87        let n_chains = self.n_chains();
88        let start = self.n_chains_byte_range().end;
89        let end = start + {
90            let data = self.data.split_off(start).unwrap_or_default();
91            <Chain as VarSize>::total_len_for_count(data, transforms::to_usize(n_chains))
92                .unwrap_or(0)
93        };
94        start..end
95    }
96}
97
98const _: () = assert!(FontData::default_data_long_enough(Mort::MIN_SIZE));
99
100impl Default for Mort<'_> {
101    fn default() -> Self {
102        Self {
103            data: FontData::default_table_data(),
104        }
105    }
106}
107
108impl<'a> MinByteRange<'a> for Chain<'a> {
109    fn min_byte_range(&self) -> Range<usize> {
110        0..self.subtables_byte_range().end
111    }
112    fn min_table_bytes(&self) -> &'a [u8] {
113        let range = self.min_byte_range();
114        self.data.as_bytes().get(range).unwrap_or_default()
115    }
116}
117
118impl ReadArgs for Chain<'_> {
119    type Args = ();
120}
121
122impl<'a> FontRead<'a> for Chain<'a> {
123    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
124        #[allow(clippy::absurd_extreme_comparisons)]
125        if data.len() < Self::MIN_SIZE {
126            return Err(ReadError::OutOfBounds);
127        }
128        Ok(Self { data })
129    }
130}
131
132/// A chain in a `mort` table.
133#[derive(Clone)]
134pub struct Chain<'a> {
135    data: FontData<'a>,
136}
137
138#[allow(clippy::needless_lifetimes)]
139impl<'a> Chain<'a> {
140    pub const MIN_SIZE: usize =
141        (u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
142    basic_table_impls!(impl_the_methods);
143
144    /// The default specification for subtables.
145    pub fn default_flags(&self) -> u32 {
146        let range = self.default_flags_byte_range();
147        self.data.read_at(range.start).ok().unwrap()
148    }
149
150    /// Total byte count, including this header.
151    pub fn chain_length(&self) -> u32 {
152        let range = self.chain_length_byte_range();
153        self.data.read_at(range.start).ok().unwrap()
154    }
155
156    /// Number of feature subtable entries.
157    pub fn n_feature_entries(&self) -> u16 {
158        let range = self.n_feature_entries_byte_range();
159        self.data.read_at(range.start).ok().unwrap()
160    }
161
162    /// The number of subtables in the chain.
163    pub fn n_subtables(&self) -> u16 {
164        let range = self.n_subtables_byte_range();
165        self.data.read_at(range.start).ok().unwrap()
166    }
167
168    /// Feature entries for this chain.
169    pub fn features(&self) -> &'a [Feature] {
170        let range = self.features_byte_range();
171        self.data.read_array(range).ok().unwrap_or_default()
172    }
173
174    /// Array of chain subtables.
175    pub fn subtables(&self) -> VarLenArray<'a, Subtable<'a>> {
176        let range = self.subtables_byte_range();
177        self.data
178            .split_off(range.start)
179            .and_then(|d| VarLenArray::read(d).ok())
180            .unwrap_or_default()
181    }
182
183    pub fn default_flags_byte_range(&self) -> Range<usize> {
184        let start = 0;
185        let end = start + u32::RAW_BYTE_LEN;
186        start..end
187    }
188
189    pub fn chain_length_byte_range(&self) -> Range<usize> {
190        let start = self.default_flags_byte_range().end;
191        let end = start + u32::RAW_BYTE_LEN;
192        start..end
193    }
194
195    pub fn n_feature_entries_byte_range(&self) -> Range<usize> {
196        let start = self.chain_length_byte_range().end;
197        let end = start + u16::RAW_BYTE_LEN;
198        start..end
199    }
200
201    pub fn n_subtables_byte_range(&self) -> Range<usize> {
202        let start = self.n_feature_entries_byte_range().end;
203        let end = start + u16::RAW_BYTE_LEN;
204        start..end
205    }
206
207    pub fn features_byte_range(&self) -> Range<usize> {
208        let n_feature_entries = self.n_feature_entries();
209        let start = self.n_subtables_byte_range().end;
210        let end =
211            start + (transforms::to_usize(n_feature_entries)).saturating_mul(Feature::RAW_BYTE_LEN);
212        start..end
213    }
214
215    pub fn subtables_byte_range(&self) -> Range<usize> {
216        let n_subtables = self.n_subtables();
217        let start = self.features_byte_range().end;
218        let end = start + {
219            let data = self.data.split_off(start).unwrap_or_default();
220            <Subtable as VarSize>::total_len_for_count(data, transforms::to_usize(n_subtables))
221                .unwrap_or(0)
222        };
223        start..end
224    }
225}
226
227const _: () = assert!(FontData::default_data_long_enough(Chain::MIN_SIZE));
228
229impl Default for Chain<'_> {
230    fn default() -> Self {
231        Self {
232            data: FontData::default_table_data(),
233        }
234    }
235}
236
237/// Used to compute the sub-feature flags for a list of requested features and settings.
238#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
239#[repr(C)]
240#[repr(packed)]
241pub struct Feature {
242    /// The type of feature.
243    pub feature_type: BigEndian<u16>,
244    /// The feature's setting (aka selector).
245    pub feature_settings: BigEndian<u16>,
246    /// Flags for the settings that this feature and setting enables.
247    pub enable_flags: BigEndian<u32>,
248    /// Complement of flags for the settings that this feature and setting disable.
249    pub disable_flags: BigEndian<u32>,
250}
251
252impl Feature {
253    /// The type of feature.
254    pub fn feature_type(&self) -> u16 {
255        self.feature_type.get()
256    }
257
258    /// The feature's setting (aka selector).
259    pub fn feature_settings(&self) -> u16 {
260        self.feature_settings.get()
261    }
262
263    /// Flags for the settings that this feature and setting enables.
264    pub fn enable_flags(&self) -> u32 {
265        self.enable_flags.get()
266    }
267
268    /// Complement of flags for the settings that this feature and setting disable.
269    pub fn disable_flags(&self) -> u32 {
270        self.disable_flags.get()
271    }
272}
273
274impl FixedSize for Feature {
275    const RAW_BYTE_LEN: usize =
276        u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN;
277}
278
279impl<'a> MinByteRange<'a> for Subtable<'a> {
280    fn min_byte_range(&self) -> Range<usize> {
281        0..self.data_byte_range().end
282    }
283    fn min_table_bytes(&self) -> &'a [u8] {
284        let range = self.min_byte_range();
285        self.data.as_bytes().get(range).unwrap_or_default()
286    }
287}
288
289impl ReadArgs for Subtable<'_> {
290    type Args = ();
291}
292
293impl<'a> FontRead<'a> for Subtable<'a> {
294    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
295        #[allow(clippy::absurd_extreme_comparisons)]
296        if data.len() < Self::MIN_SIZE {
297            return Err(ReadError::OutOfBounds);
298        }
299        Ok(Self { data })
300    }
301}
302
303/// A subtable in a `mort` chain.
304#[derive(Clone)]
305pub struct Subtable<'a> {
306    data: FontData<'a>,
307}
308
309#[allow(clippy::needless_lifetimes)]
310impl<'a> Subtable<'a> {
311    pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
312    basic_table_impls!(impl_the_methods);
313
314    /// Total subtable length, including this header.
315    pub fn length(&self) -> u16 {
316        let range = self.length_byte_range();
317        self.data.read_at(range.start).ok().unwrap()
318    }
319
320    /// Coverage flags and subtable type.
321    pub fn coverage(&self) -> u16 {
322        let range = self.coverage_byte_range();
323        self.data.read_at(range.start).ok().unwrap()
324    }
325
326    /// The 32-bit mask identifying which subtable this is.
327    pub fn sub_feature_flags(&self) -> u32 {
328        let range = self.sub_feature_flags_byte_range();
329        self.data.read_at(range.start).ok().unwrap()
330    }
331
332    /// Data for the specific subtable type.
333    pub fn data(&self) -> &'a [u8] {
334        let range = self.data_byte_range();
335        self.data.read_array(range).ok().unwrap_or_default()
336    }
337
338    pub fn length_byte_range(&self) -> Range<usize> {
339        let start = 0;
340        let end = start + u16::RAW_BYTE_LEN;
341        start..end
342    }
343
344    pub fn coverage_byte_range(&self) -> Range<usize> {
345        let start = self.length_byte_range().end;
346        let end = start + u16::RAW_BYTE_LEN;
347        start..end
348    }
349
350    pub fn sub_feature_flags_byte_range(&self) -> Range<usize> {
351        let start = self.coverage_byte_range().end;
352        let end = start + u32::RAW_BYTE_LEN;
353        start..end
354    }
355
356    pub fn data_byte_range(&self) -> Range<usize> {
357        let start = self.sub_feature_flags_byte_range().end;
358        let end =
359            start + self.data.len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
360        start..end
361    }
362}
363
364const _: () = assert!(FontData::default_data_long_enough(Subtable::MIN_SIZE));
365
366impl Default for Subtable<'_> {
367    fn default() -> Self {
368        Self {
369            data: FontData::default_table_data(),
370        }
371    }
372}
373
374/// Entry payload in a contextual subtable state machine.
375#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
376#[repr(C)]
377#[repr(packed)]
378pub struct ContextualEntryData {
379    /// Signed word offset of the substitution array for the marked glyph (0 for none).
380    pub mark_offset: BigEndian<i16>,
381    /// Signed word offset of the substitution array for the current glyph (0 for none).
382    pub current_offset: BigEndian<i16>,
383}
384
385impl ContextualEntryData {
386    /// Signed word offset of the substitution array for the marked glyph (0 for none).
387    pub fn mark_offset(&self) -> i16 {
388        self.mark_offset.get()
389    }
390
391    /// Signed word offset of the substitution array for the current glyph (0 for none).
392    pub fn current_offset(&self) -> i16 {
393        self.current_offset.get()
394    }
395}
396
397impl FixedSize for ContextualEntryData {
398    const RAW_BYTE_LEN: usize = i16::RAW_BYTE_LEN + i16::RAW_BYTE_LEN;
399}
400
401/// Entry payload in an insertion subtable state machine.
402#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
403#[repr(C)]
404#[repr(packed)]
405pub struct InsertionEntryData {
406    /// Zero-based index into the insertion glyph table (0xFFFF for none).
407    pub current_insert_index: BigEndian<u16>,
408    /// Zero-based index into the insertion glyph table (0xFFFF for none).
409    pub marked_insert_index: BigEndian<u16>,
410}
411
412impl InsertionEntryData {
413    /// Zero-based index into the insertion glyph table (0xFFFF for none).
414    pub fn current_insert_index(&self) -> u16 {
415        self.current_insert_index.get()
416    }
417
418    /// Zero-based index into the insertion glyph table (0xFFFF for none).
419    pub fn marked_insert_index(&self) -> u16 {
420        self.marked_insert_index.get()
421    }
422}
423
424impl FixedSize for InsertionEntryData {
425    const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
426}