Skip to main content

read_fonts/generated/
generated_kerx.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 Kerx<'a> {
9    fn min_byte_range(&self) -> Range<usize> {
10        0..self.subtables_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 Kerx<'_> {
19    /// `kerx`
20    const TAG: Tag = Tag::new(b"kerx");
21}
22
23impl ReadArgs for Kerx<'_> {
24    type Args = ();
25}
26
27impl<'a> FontRead<'a> for Kerx<'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 [kerx (Extended Kerning)](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html) table.
38#[derive(Clone)]
39pub struct Kerx<'a> {
40    data: FontData<'a>,
41}
42
43#[allow(clippy::needless_lifetimes)]
44impl<'a> Kerx<'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    /// The version number of the extended kerning table (currently 2, 3, or 4)
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    /// The number of subtables included in the extended kerning table.
55    pub fn n_tables(&self) -> u32 {
56        let range = self.n_tables_byte_range();
57        self.data.read_at(range.start).ok().unwrap()
58    }
59
60    pub fn subtables(&self) -> VarLenArray<'a, Subtable<'a>> {
61        let range = self.subtables_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 padding_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_tables_byte_range(&self) -> Range<usize> {
81        let start = self.padding_byte_range().end;
82        let end = start + u32::RAW_BYTE_LEN;
83        start..end
84    }
85
86    pub fn subtables_byte_range(&self) -> Range<usize> {
87        let n_tables = self.n_tables();
88        let start = self.n_tables_byte_range().end;
89        let end = start + {
90            let data = self.data.split_off(start).unwrap_or_default();
91            <Subtable as VarSize>::total_len_for_count(data, transforms::to_usize(n_tables))
92                .unwrap_or(0)
93        };
94        start..end
95    }
96}
97
98const _: () = assert!(FontData::default_data_long_enough(Kerx::MIN_SIZE));
99
100impl Default for Kerx<'_> {
101    fn default() -> Self {
102        Self {
103            data: FontData::default_table_data(),
104        }
105    }
106}
107
108impl<'a> MinByteRange<'a> for Subtable<'a> {
109    fn min_byte_range(&self) -> Range<usize> {
110        0..self.data_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 Subtable<'_> {
119    type Args = ();
120}
121
122impl<'a> FontRead<'a> for Subtable<'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 subtable in a `kerx` table.
133#[derive(Clone)]
134pub struct Subtable<'a> {
135    data: FontData<'a>,
136}
137
138#[allow(clippy::needless_lifetimes)]
139impl<'a> Subtable<'a> {
140    pub const MIN_SIZE: usize = (u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
141    basic_table_impls!(impl_the_methods);
142
143    /// The length of this subtable in bytes, including this header.
144    pub fn length(&self) -> u32 {
145        let range = self.length_byte_range();
146        self.data.read_at(range.start).ok().unwrap()
147    }
148
149    /// Circumstances under which this table is used.
150    pub fn coverage(&self) -> u32 {
151        let range = self.coverage_byte_range();
152        self.data.read_at(range.start).ok().unwrap()
153    }
154
155    /// The tuple count. This value is only used with variation fonts and should be 0 for all other fonts. The subtable's tupleCount will be ignored if the 'kerx' table version is less than 4.
156    pub fn tuple_count(&self) -> u32 {
157        let range = self.tuple_count_byte_range();
158        self.data.read_at(range.start).ok().unwrap()
159    }
160
161    /// Subtable specific data.
162    pub fn data(&self) -> &'a [u8] {
163        let range = self.data_byte_range();
164        self.data.read_array(range).ok().unwrap_or_default()
165    }
166
167    pub fn length_byte_range(&self) -> Range<usize> {
168        let start = 0;
169        let end = start + u32::RAW_BYTE_LEN;
170        start..end
171    }
172
173    pub fn coverage_byte_range(&self) -> Range<usize> {
174        let start = self.length_byte_range().end;
175        let end = start + u32::RAW_BYTE_LEN;
176        start..end
177    }
178
179    pub fn tuple_count_byte_range(&self) -> Range<usize> {
180        let start = self.coverage_byte_range().end;
181        let end = start + u32::RAW_BYTE_LEN;
182        start..end
183    }
184
185    pub fn data_byte_range(&self) -> Range<usize> {
186        let start = self.tuple_count_byte_range().end;
187        let end =
188            start + self.data.len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
189        start..end
190    }
191}
192
193const _: () = assert!(FontData::default_data_long_enough(Subtable::MIN_SIZE));
194
195impl Default for Subtable<'_> {
196    fn default() -> Self {
197        Self {
198            data: FontData::default_table_data(),
199        }
200    }
201}
202
203impl<'a> MinByteRange<'a> for Subtable0<'a> {
204    fn min_byte_range(&self) -> Range<usize> {
205        0..self.pairs_byte_range().end
206    }
207    fn min_table_bytes(&self) -> &'a [u8] {
208        let range = self.min_byte_range();
209        self.data.as_bytes().get(range).unwrap_or_default()
210    }
211}
212
213impl ReadArgs for Subtable0<'_> {
214    type Args = ();
215}
216
217impl<'a> FontRead<'a> for Subtable0<'a> {
218    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
219        #[allow(clippy::absurd_extreme_comparisons)]
220        if data.len() < Self::MIN_SIZE {
221            return Err(ReadError::OutOfBounds);
222        }
223        Ok(Self { data })
224    }
225}
226
227/// The type 0 `kerx` subtable.
228#[derive(Clone)]
229pub struct Subtable0<'a> {
230    data: FontData<'a>,
231}
232
233#[allow(clippy::needless_lifetimes)]
234impl<'a> Subtable0<'a> {
235    pub const MIN_SIZE: usize =
236        (u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
237    basic_table_impls!(impl_the_methods);
238
239    /// The number of kerning pairs in this subtable.
240    pub fn n_pairs(&self) -> u32 {
241        let range = self.n_pairs_byte_range();
242        self.data.read_at(range.start).ok().unwrap()
243    }
244
245    /// The largest power of two less than or equal to the value of nPairs, multiplied by the size in bytes of an entry in the subtable.
246    pub fn search_range(&self) -> u32 {
247        let range = self.search_range_byte_range();
248        self.data.read_at(range.start).ok().unwrap()
249    }
250
251    /// This is calculated as log2 of the largest power of two less than or equal to the value of nPairs. This value indicates how many iterations of the search loop have to be made. For example, in a list of eight items, there would be three iterations of the loop.
252    pub fn entry_selector(&self) -> u32 {
253        let range = self.entry_selector_byte_range();
254        self.data.read_at(range.start).ok().unwrap()
255    }
256
257    /// The value of nPairs minus the largest power of two less than or equal to nPairs. This is multiplied by the size in bytes of an entry in the table.
258    pub fn range_shift(&self) -> u32 {
259        let range = self.range_shift_byte_range();
260        self.data.read_at(range.start).ok().unwrap()
261    }
262
263    /// Kerning records.
264    pub fn pairs(&self) -> &'a [Subtable0Pair] {
265        let range = self.pairs_byte_range();
266        self.data.read_array(range).ok().unwrap_or_default()
267    }
268
269    pub fn n_pairs_byte_range(&self) -> Range<usize> {
270        let start = 0;
271        let end = start + u32::RAW_BYTE_LEN;
272        start..end
273    }
274
275    pub fn search_range_byte_range(&self) -> Range<usize> {
276        let start = self.n_pairs_byte_range().end;
277        let end = start + u32::RAW_BYTE_LEN;
278        start..end
279    }
280
281    pub fn entry_selector_byte_range(&self) -> Range<usize> {
282        let start = self.search_range_byte_range().end;
283        let end = start + u32::RAW_BYTE_LEN;
284        start..end
285    }
286
287    pub fn range_shift_byte_range(&self) -> Range<usize> {
288        let start = self.entry_selector_byte_range().end;
289        let end = start + u32::RAW_BYTE_LEN;
290        start..end
291    }
292
293    pub fn pairs_byte_range(&self) -> Range<usize> {
294        let n_pairs = self.n_pairs();
295        let start = self.range_shift_byte_range().end;
296        let end =
297            start + (transforms::to_usize(n_pairs)).saturating_mul(Subtable0Pair::RAW_BYTE_LEN);
298        start..end
299    }
300}
301
302const _: () = assert!(FontData::default_data_long_enough(Subtable0::MIN_SIZE));
303
304impl Default for Subtable0<'_> {
305    fn default() -> Self {
306        Self {
307            data: FontData::default_table_data(),
308        }
309    }
310}
311
312/// The type 0 `kerx` subtable kerning record.
313#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
314#[repr(C)]
315#[repr(packed)]
316pub struct Subtable0Pair {
317    /// The glyph index for the lefthand glyph in the kerning pair.
318    pub left: BigEndian<GlyphId16>,
319    /// The glyph index for the righthand glyph in the kerning pair.
320    pub right: BigEndian<GlyphId16>,
321    /// Kerning value.
322    pub value: BigEndian<i16>,
323}
324
325impl Subtable0Pair {
326    /// The glyph index for the lefthand glyph in the kerning pair.
327    pub fn left(&self) -> GlyphId16 {
328        self.left.get()
329    }
330
331    /// The glyph index for the righthand glyph in the kerning pair.
332    pub fn right(&self) -> GlyphId16 {
333        self.right.get()
334    }
335
336    /// Kerning value.
337    pub fn value(&self) -> i16 {
338        self.value.get()
339    }
340}
341
342impl FixedSize for Subtable0Pair {
343    const RAW_BYTE_LEN: usize =
344        GlyphId16::RAW_BYTE_LEN + GlyphId16::RAW_BYTE_LEN + i16::RAW_BYTE_LEN;
345}