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        start..start + MajorMinor::RAW_BYTE_LEN
87    }
88
89    pub fn format_byte_range(&self) -> Range<usize> {
90        let start = self.version_byte_range().end;
91        start..start + u16::RAW_BYTE_LEN
92    }
93
94    pub fn horiz_offset_byte_range(&self) -> Range<usize> {
95        let start = self.format_byte_range().end;
96        start..start + Offset16::RAW_BYTE_LEN
97    }
98
99    pub fn vert_offset_byte_range(&self) -> Range<usize> {
100        let start = self.horiz_offset_byte_range().end;
101        start..start + Offset16::RAW_BYTE_LEN
102    }
103
104    pub fn reserved_byte_range(&self) -> Range<usize> {
105        let start = self.vert_offset_byte_range().end;
106        start..start + u16::RAW_BYTE_LEN
107    }
108}
109
110#[cfg(feature = "experimental_traverse")]
111impl<'a> SomeTable<'a> for Trak<'a> {
112    fn type_name(&self) -> &str {
113        "Trak"
114    }
115    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
116        match idx {
117            0usize => Some(Field::new("version", self.version())),
118            1usize => Some(Field::new("format", self.format())),
119            2usize => Some(Field::new(
120                "horiz_offset",
121                FieldType::offset(self.horiz_offset(), self.horiz()),
122            )),
123            3usize => Some(Field::new(
124                "vert_offset",
125                FieldType::offset(self.vert_offset(), self.vert()),
126            )),
127            _ => None,
128        }
129    }
130}
131
132#[cfg(feature = "experimental_traverse")]
133#[allow(clippy::needless_lifetimes)]
134impl<'a> std::fmt::Debug for Trak<'a> {
135    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136        (self as &dyn SomeTable<'a>).fmt(f)
137    }
138}
139
140impl<'a> MinByteRange<'a> for TrackData<'a> {
141    fn min_byte_range(&self) -> Range<usize> {
142        0..self.track_table_byte_range().end
143    }
144    fn min_table_bytes(&self) -> &'a [u8] {
145        let range = self.min_byte_range();
146        self.data.as_bytes().get(range).unwrap_or_default()
147    }
148}
149
150impl<'a> FontRead<'a> for TrackData<'a> {
151    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
152        #[allow(clippy::absurd_extreme_comparisons)]
153        if data.len() < Self::MIN_SIZE {
154            return Err(ReadError::OutOfBounds);
155        }
156        Ok(Self { data })
157    }
158}
159
160/// The tracking data table.
161#[derive(Clone)]
162pub struct TrackData<'a> {
163    data: FontData<'a>,
164}
165
166#[allow(clippy::needless_lifetimes)]
167impl<'a> TrackData<'a> {
168    pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
169    basic_table_impls!(impl_the_methods);
170
171    /// Number of separate tracks included in this table.
172    pub fn n_tracks(&self) -> u16 {
173        let range = self.n_tracks_byte_range();
174        self.data.read_at(range.start).ok().unwrap()
175    }
176
177    /// Number of point sizes included in this table.
178    pub fn n_sizes(&self) -> u16 {
179        let range = self.n_sizes_byte_range();
180        self.data.read_at(range.start).ok().unwrap()
181    }
182
183    /// Offset from the start of the tracking table to the start of the size subtable.
184    pub fn size_table_offset(&self) -> u32 {
185        let range = self.size_table_offset_byte_range();
186        self.data.read_at(range.start).ok().unwrap()
187    }
188
189    /// Array of TrackTableEntry records.
190    pub fn track_table(&self) -> &'a [TrackTableEntry] {
191        let range = self.track_table_byte_range();
192        self.data.read_array(range).ok().unwrap_or_default()
193    }
194
195    pub fn n_tracks_byte_range(&self) -> Range<usize> {
196        let start = 0;
197        start..start + u16::RAW_BYTE_LEN
198    }
199
200    pub fn n_sizes_byte_range(&self) -> Range<usize> {
201        let start = self.n_tracks_byte_range().end;
202        start..start + u16::RAW_BYTE_LEN
203    }
204
205    pub fn size_table_offset_byte_range(&self) -> Range<usize> {
206        let start = self.n_sizes_byte_range().end;
207        start..start + u32::RAW_BYTE_LEN
208    }
209
210    pub fn track_table_byte_range(&self) -> Range<usize> {
211        let n_tracks = self.n_tracks();
212        let start = self.size_table_offset_byte_range().end;
213        start..start + (n_tracks as usize).saturating_mul(TrackTableEntry::RAW_BYTE_LEN)
214    }
215}
216
217#[cfg(feature = "experimental_traverse")]
218impl<'a> SomeTable<'a> for TrackData<'a> {
219    fn type_name(&self) -> &str {
220        "TrackData"
221    }
222    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
223        match idx {
224            0usize => Some(Field::new("n_tracks", self.n_tracks())),
225            1usize => Some(Field::new("n_sizes", self.n_sizes())),
226            2usize => Some(Field::new("size_table_offset", self.size_table_offset())),
227            3usize => Some(Field::new(
228                "track_table",
229                traversal::FieldType::array_of_records(
230                    stringify!(TrackTableEntry),
231                    self.track_table(),
232                    self.offset_data(),
233                ),
234            )),
235            _ => None,
236        }
237    }
238}
239
240#[cfg(feature = "experimental_traverse")]
241#[allow(clippy::needless_lifetimes)]
242impl<'a> std::fmt::Debug for TrackData<'a> {
243    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
244        (self as &dyn SomeTable<'a>).fmt(f)
245    }
246}
247
248/// Single entry in a tracking table.
249#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
250#[repr(C)]
251#[repr(packed)]
252pub struct TrackTableEntry {
253    /// Track value for this record.
254    pub track: BigEndian<Fixed>,
255    /// 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.
256    pub name_index: BigEndian<NameId>,
257    /// Offset from the start of the tracking table to per-size tracking values for this track.
258    pub offset: BigEndian<u16>,
259}
260
261impl TrackTableEntry {
262    /// Track value for this record.
263    pub fn track(&self) -> Fixed {
264        self.track.get()
265    }
266
267    /// 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.
268    pub fn name_index(&self) -> NameId {
269        self.name_index.get()
270    }
271
272    /// Offset from the start of the tracking table to per-size tracking values for this track.
273    pub fn offset(&self) -> u16 {
274        self.offset.get()
275    }
276}
277
278impl FixedSize for TrackTableEntry {
279    const RAW_BYTE_LEN: usize = Fixed::RAW_BYTE_LEN + NameId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
280}
281
282#[cfg(feature = "experimental_traverse")]
283impl<'a> SomeRecord<'a> for TrackTableEntry {
284    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
285        RecordResolver {
286            name: "TrackTableEntry",
287            get_field: Box::new(move |idx, _data| match idx {
288                0usize => Some(Field::new("track", self.track())),
289                1usize => Some(Field::new("name_index", self.name_index())),
290                2usize => Some(Field::new("offset", self.offset())),
291                _ => None,
292            }),
293            data,
294        }
295    }
296}