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