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
129impl<'a> MinByteRange<'a> for TrackData<'a> {
130    fn min_byte_range(&self) -> Range<usize> {
131        0..self.track_table_byte_range().end
132    }
133    fn min_table_bytes(&self) -> &'a [u8] {
134        let range = self.min_byte_range();
135        self.data.as_bytes().get(range).unwrap_or_default()
136    }
137}
138
139impl ReadArgs for TrackData<'_> {
140    type Args = ();
141}
142
143impl<'a> FontRead<'a> for TrackData<'a> {
144    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
145        #[allow(clippy::absurd_extreme_comparisons)]
146        if data.len() < Self::MIN_SIZE {
147            return Err(ReadError::OutOfBounds);
148        }
149        Ok(Self { data })
150    }
151}
152
153/// The tracking data table.
154#[derive(Clone)]
155pub struct TrackData<'a> {
156    data: FontData<'a>,
157}
158
159#[allow(clippy::needless_lifetimes)]
160impl<'a> TrackData<'a> {
161    pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
162    basic_table_impls!(impl_the_methods);
163
164    /// Number of separate tracks included in this table.
165    pub fn n_tracks(&self) -> u16 {
166        let range = self.n_tracks_byte_range();
167        self.data.read_at(range.start).ok().unwrap()
168    }
169
170    /// Number of point sizes included in this table.
171    pub fn n_sizes(&self) -> u16 {
172        let range = self.n_sizes_byte_range();
173        self.data.read_at(range.start).ok().unwrap()
174    }
175
176    /// Offset from the start of the tracking table to the start of the size subtable.
177    pub fn size_table_offset(&self) -> u32 {
178        let range = self.size_table_offset_byte_range();
179        self.data.read_at(range.start).ok().unwrap()
180    }
181
182    /// Array of TrackTableEntry records.
183    pub fn track_table(&self) -> &'a [TrackTableEntry] {
184        let range = self.track_table_byte_range();
185        self.data.read_array(range).ok().unwrap_or_default()
186    }
187
188    pub fn n_tracks_byte_range(&self) -> Range<usize> {
189        let start = 0;
190        let end = start + u16::RAW_BYTE_LEN;
191        start..end
192    }
193
194    pub fn n_sizes_byte_range(&self) -> Range<usize> {
195        let start = self.n_tracks_byte_range().end;
196        let end = start + u16::RAW_BYTE_LEN;
197        start..end
198    }
199
200    pub fn size_table_offset_byte_range(&self) -> Range<usize> {
201        let start = self.n_sizes_byte_range().end;
202        let end = start + u32::RAW_BYTE_LEN;
203        start..end
204    }
205
206    pub fn track_table_byte_range(&self) -> Range<usize> {
207        let n_tracks = self.n_tracks();
208        let start = self.size_table_offset_byte_range().end;
209        let end =
210            start + (transforms::to_usize(n_tracks)).saturating_mul(TrackTableEntry::RAW_BYTE_LEN);
211        start..end
212    }
213}
214
215const _: () = assert!(FontData::default_data_long_enough(TrackData::MIN_SIZE));
216
217impl Default for TrackData<'_> {
218    fn default() -> Self {
219        Self {
220            data: FontData::default_table_data(),
221        }
222    }
223}
224
225/// Single entry in a tracking table.
226#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
227#[repr(C)]
228#[repr(packed)]
229pub struct TrackTableEntry {
230    /// Track value for this record.
231    pub track: BigEndian<Fixed>,
232    /// 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.
233    pub name_index: BigEndian<NameId>,
234    /// Offset from the start of the tracking table to per-size tracking values for this track.
235    pub offset: BigEndian<u16>,
236}
237
238impl TrackTableEntry {
239    /// Track value for this record.
240    pub fn track(&self) -> Fixed {
241        self.track.get()
242    }
243
244    /// 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.
245    pub fn name_index(&self) -> NameId {
246        self.name_index.get()
247    }
248
249    /// Offset from the start of the tracking table to per-size tracking values for this track.
250    pub fn offset(&self) -> u16 {
251        self.offset.get()
252    }
253}
254
255impl FixedSize for TrackTableEntry {
256    const RAW_BYTE_LEN: usize = Fixed::RAW_BYTE_LEN + NameId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
257}