Skip to main content

read_fonts/generated/
generated_trak.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 Trak<'a> {
9    fn min_byte_range(&self) -> Range<usize> {
10        0..self.reserved_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 Trak<'_> {
19    /// `trak`
20    const TAG: Tag = Tag::new(b"trak");
21}
22
23impl ReadArgs for Trak<'_> {
24    type Args = ();
25}
26
27impl<'a> FontRead<'a> for Trak<'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 [tracking (trak)](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6trak.html) table.
38#[derive(Clone)]
39pub struct Trak<'a> {
40    data: FontData<'a>,
41}
42
43#[allow(clippy::needless_lifetimes)]
44impl<'a> Trak<'a> {
45    pub const MIN_SIZE: usize = (MajorMinor::RAW_BYTE_LEN
46        + u16::RAW_BYTE_LEN
47        + Offset16::RAW_BYTE_LEN
48        + Offset16::RAW_BYTE_LEN
49        + u16::RAW_BYTE_LEN);
50    basic_table_impls!(impl_the_methods);
51
52    /// Version number of the tracking table (0x00010000 for the current version).
53    pub fn version(&self) -> MajorMinor {
54        let range = self.version_byte_range();
55        self.data.read_at(range.start).ok().unwrap()
56    }
57
58    /// Format of the tracking table (set to 0).
59    pub fn format(&self) -> u16 {
60        let range = self.format_byte_range();
61        self.data.read_at(range.start).ok().unwrap()
62    }
63
64    /// Offset from start of tracking table to TrackData for horizontal text (or 0 if none).
65    pub fn horiz_offset(&self) -> Nullable<Offset16> {
66        let range = self.horiz_offset_byte_range();
67        self.data.read_at(range.start).ok().unwrap()
68    }
69
70    /// Attempt to resolve [`horiz_offset`][Self::horiz_offset].
71    pub fn horiz(&self) -> Option<Result<TrackData<'a>, ReadError>> {
72        let data = self.data;
73        self.horiz_offset().resolve(data)
74    }
75
76    /// Offset from start of tracking table to TrackData for vertical text (or 0 if none).
77    pub fn vert_offset(&self) -> Nullable<Offset16> {
78        let range = self.vert_offset_byte_range();
79        self.data.read_at(range.start).ok().unwrap()
80    }
81
82    /// Attempt to resolve [`vert_offset`][Self::vert_offset].
83    pub fn vert(&self) -> Option<Result<TrackData<'a>, ReadError>> {
84        let data = self.data;
85        self.vert_offset().resolve(data)
86    }
87
88    pub fn version_byte_range(&self) -> Range<usize> {
89        let start = 0;
90        let end = start + MajorMinor::RAW_BYTE_LEN;
91        start..end
92    }
93
94    pub fn format_byte_range(&self) -> Range<usize> {
95        let start = self.version_byte_range().end;
96        let end = start + u16::RAW_BYTE_LEN;
97        start..end
98    }
99
100    pub fn horiz_offset_byte_range(&self) -> Range<usize> {
101        let start = self.format_byte_range().end;
102        let end = start + Offset16::RAW_BYTE_LEN;
103        start..end
104    }
105
106    pub fn vert_offset_byte_range(&self) -> Range<usize> {
107        let start = self.horiz_offset_byte_range().end;
108        let end = start + Offset16::RAW_BYTE_LEN;
109        start..end
110    }
111
112    pub fn reserved_byte_range(&self) -> Range<usize> {
113        let start = self.vert_offset_byte_range().end;
114        let end = start + u16::RAW_BYTE_LEN;
115        start..end
116    }
117}
118
119const _: () = assert!(FontData::default_data_long_enough(Trak::MIN_SIZE));
120
121impl Default for Trak<'_> {
122    fn default() -> Self {
123        Self {
124            data: FontData::default_table_data(),
125        }
126    }
127}
128
129#[cfg(feature = "experimental_traverse")]
130impl<'a> SomeTable<'a> for Trak<'a> {
131    fn type_name(&self) -> &str {
132        "Trak"
133    }
134    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
135        match idx {
136            0usize => Some(Field::new("version", self.version())),
137            1usize => Some(Field::new("format", self.format())),
138            2usize => Some(Field::new(
139                "horiz_offset",
140                FieldType::offset(self.horiz_offset(), self.horiz()),
141            )),
142            3usize => Some(Field::new(
143                "vert_offset",
144                FieldType::offset(self.vert_offset(), self.vert()),
145            )),
146            _ => None,
147        }
148    }
149}
150
151#[cfg(feature = "experimental_traverse")]
152#[allow(clippy::needless_lifetimes)]
153impl<'a> std::fmt::Debug for Trak<'a> {
154    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
155        (self as &dyn SomeTable<'a>).fmt(f)
156    }
157}
158
159impl<'a> MinByteRange<'a> for TrackData<'a> {
160    fn min_byte_range(&self) -> Range<usize> {
161        0..self.track_table_byte_range().end
162    }
163    fn min_table_bytes(&self) -> &'a [u8] {
164        let range = self.min_byte_range();
165        self.data.as_bytes().get(range).unwrap_or_default()
166    }
167}
168
169impl ReadArgs for TrackData<'_> {
170    type Args = ();
171}
172
173impl<'a> FontRead<'a> for TrackData<'a> {
174    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
175        #[allow(clippy::absurd_extreme_comparisons)]
176        if data.len() < Self::MIN_SIZE {
177            return Err(ReadError::OutOfBounds);
178        }
179        Ok(Self { data })
180    }
181}
182
183/// The tracking data table.
184#[derive(Clone)]
185pub struct TrackData<'a> {
186    data: FontData<'a>,
187}
188
189#[allow(clippy::needless_lifetimes)]
190impl<'a> TrackData<'a> {
191    pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
192    basic_table_impls!(impl_the_methods);
193
194    /// Number of separate tracks included in this table.
195    pub fn n_tracks(&self) -> u16 {
196        let range = self.n_tracks_byte_range();
197        self.data.read_at(range.start).ok().unwrap()
198    }
199
200    /// Number of point sizes included in this table.
201    pub fn n_sizes(&self) -> u16 {
202        let range = self.n_sizes_byte_range();
203        self.data.read_at(range.start).ok().unwrap()
204    }
205
206    /// Offset from the start of the tracking table to the start of the size subtable.
207    pub fn size_table_offset(&self) -> u32 {
208        let range = self.size_table_offset_byte_range();
209        self.data.read_at(range.start).ok().unwrap()
210    }
211
212    /// Array of TrackTableEntry records.
213    pub fn track_table(&self) -> &'a [TrackTableEntry] {
214        let range = self.track_table_byte_range();
215        self.data.read_array(range).ok().unwrap_or_default()
216    }
217
218    pub fn n_tracks_byte_range(&self) -> Range<usize> {
219        let start = 0;
220        let end = start + u16::RAW_BYTE_LEN;
221        start..end
222    }
223
224    pub fn n_sizes_byte_range(&self) -> Range<usize> {
225        let start = self.n_tracks_byte_range().end;
226        let end = start + u16::RAW_BYTE_LEN;
227        start..end
228    }
229
230    pub fn size_table_offset_byte_range(&self) -> Range<usize> {
231        let start = self.n_sizes_byte_range().end;
232        let end = start + u32::RAW_BYTE_LEN;
233        start..end
234    }
235
236    pub fn track_table_byte_range(&self) -> Range<usize> {
237        let n_tracks = self.n_tracks();
238        let start = self.size_table_offset_byte_range().end;
239        let end =
240            start + (transforms::to_usize(n_tracks)).saturating_mul(TrackTableEntry::RAW_BYTE_LEN);
241        start..end
242    }
243}
244
245const _: () = assert!(FontData::default_data_long_enough(TrackData::MIN_SIZE));
246
247impl Default for TrackData<'_> {
248    fn default() -> Self {
249        Self {
250            data: FontData::default_table_data(),
251        }
252    }
253}
254
255#[cfg(feature = "experimental_traverse")]
256impl<'a> SomeTable<'a> for TrackData<'a> {
257    fn type_name(&self) -> &str {
258        "TrackData"
259    }
260    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
261        match idx {
262            0usize => Some(Field::new("n_tracks", self.n_tracks())),
263            1usize => Some(Field::new("n_sizes", self.n_sizes())),
264            2usize => Some(Field::new("size_table_offset", self.size_table_offset())),
265            3usize => Some(Field::new(
266                "track_table",
267                traversal::FieldType::array_of_records(
268                    stringify!(TrackTableEntry),
269                    self.track_table(),
270                    self.offset_data(),
271                ),
272            )),
273            _ => None,
274        }
275    }
276}
277
278#[cfg(feature = "experimental_traverse")]
279#[allow(clippy::needless_lifetimes)]
280impl<'a> std::fmt::Debug for TrackData<'a> {
281    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
282        (self as &dyn SomeTable<'a>).fmt(f)
283    }
284}
285
286/// Single entry in a tracking table.
287#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
288#[repr(C)]
289#[repr(packed)]
290pub struct TrackTableEntry {
291    /// Track value for this record.
292    pub track: BigEndian<Fixed>,
293    /// The 'name' table index for this track (a short word or phrase like \"loose\" or \"very tight\"). NameIndex has a value greater than 255 and less than 32768.
294    pub name_index: BigEndian<NameId>,
295    /// Offset from the start of the tracking table to per-size tracking values for this track.
296    pub offset: BigEndian<u16>,
297}
298
299impl TrackTableEntry {
300    /// Track value for this record.
301    pub fn track(&self) -> Fixed {
302        self.track.get()
303    }
304
305    /// The 'name' table index for this track (a short word or phrase like \"loose\" or \"very tight\"). NameIndex has a value greater than 255 and less than 32768.
306    pub fn name_index(&self) -> NameId {
307        self.name_index.get()
308    }
309
310    /// Offset from the start of the tracking table to per-size tracking values for this track.
311    pub fn offset(&self) -> u16 {
312        self.offset.get()
313    }
314}
315
316impl FixedSize for TrackTableEntry {
317    const RAW_BYTE_LEN: usize = Fixed::RAW_BYTE_LEN + NameId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
318}
319
320#[cfg(feature = "experimental_traverse")]
321impl<'a> SomeRecord<'a> for TrackTableEntry {
322    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
323        RecordResolver {
324            name: "TrackTableEntry",
325            get_field: Box::new(move |idx, _data| match idx {
326                0usize => Some(Field::new("track", self.track())),
327                1usize => Some(Field::new("name_index", self.name_index())),
328                2usize => Some(Field::new("offset", self.offset())),
329                _ => None,
330            }),
331            data,
332        }
333    }
334}