Coverage Report

Created: 2026-10-24 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/read-fonts-0.46.0/generated/generated_kerx.rs
Line
Count
Source
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)]
6
use crate::codegen_prelude::*;
7
8
impl<'a> MinByteRange<'a> for Kerx<'a> {
9
0
    fn min_byte_range(&self) -> Range<usize> {
10
0
        0..self.subtables_byte_range().end
11
0
    }
12
0
    fn min_table_bytes(&self) -> &'a [u8] {
13
0
        let range = self.min_byte_range();
14
0
        self.offset_data().as_bytes().get(range).unwrap_or_default()
15
0
    }
16
}
17
18
impl TopLevelTable for Kerx<'_> {
19
    /// `kerx`
20
    const TAG: Tag = Tag::new(b"kerx");
21
}
22
23
impl ReadArgs for Kerx<'_> {
24
    type Args = ();
25
}
26
27
impl<'a> FontRead<'a> for Kerx<'a> {
28
1.80k
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
29
        #[allow(clippy::absurd_extreme_comparisons)]
30
1.80k
        if data.len() < Self::MIN_SIZE {
31
3
            return Err(ReadError::OutOfBounds);
32
1.80k
        }
33
1.80k
        let Some(data) = TableDataRef::new(data.as_bytes()) else {
34
0
            return Err(ReadError::OutOfBounds);
35
        };
36
1.80k
        Ok(Self { data })
37
1.80k
    }
38
}
39
40
/// The fields at the start of the table, which are read directly.
41
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
42
#[repr(C, packed)]
43
#[doc(hidden)]
44
pub struct KerxFixedHeader {
45
    pub version: BigEndian<u16>,
46
    pub padding: BigEndian<u16>,
47
    pub n_tables: BigEndian<u32>,
48
}
49
50
#[allow(clippy::absurd_extreme_comparisons)]
51
const _: () = assert!(std::mem::size_of::<KerxFixedHeader>() <= Kerx::MIN_SIZE);
52
53
/// The [kerx (Extended Kerning)](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html) table.
54
#[derive(Clone)]
55
pub struct Kerx<'a> {
56
    data: TableDataRef<'a, KerxFixedHeader>,
57
}
58
59
#[allow(clippy::needless_lifetimes)]
60
impl<'a> Kerx<'a> {
61
    pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
62
    basic_table_impls!(impl_the_methods);
63
64
    /// The version number of the extended kerning table (currently 2, 3, or 4)
65
0
    pub fn version(&self) -> u16 {
66
0
        self.data.header().version.get()
67
0
    }
68
69
    /// The number of subtables included in the extended kerning table.
70
1.80k
    pub fn n_tables(&self) -> u32 {
71
1.80k
        self.data.header().n_tables.get()
72
1.80k
    }
73
74
1.80k
    pub fn subtables(&self) -> VarLenArray<'a, Subtable<'a>> {
75
1.80k
        let range = self.subtables_byte_range();
76
1.80k
        self.offset_data()
77
1.80k
            .split_off(range.start)
78
1.80k
            .and_then(|d| VarLenArray::read(d).ok())
79
1.80k
            .unwrap_or_default()
80
1.80k
    }
81
82
1.80k
    pub fn version_byte_range(&self) -> Range<usize> {
83
1.80k
        let start = 0;
84
1.80k
        let end = start + u16::RAW_BYTE_LEN;
85
1.80k
        start..end
86
1.80k
    }
87
88
1.80k
    pub fn padding_byte_range(&self) -> Range<usize> {
89
1.80k
        let start = self.version_byte_range().end;
90
1.80k
        let end = start + u16::RAW_BYTE_LEN;
91
1.80k
        start..end
92
1.80k
    }
93
94
1.80k
    pub fn n_tables_byte_range(&self) -> Range<usize> {
95
1.80k
        let start = self.padding_byte_range().end;
96
1.80k
        let end = start + u32::RAW_BYTE_LEN;
97
1.80k
        start..end
98
1.80k
    }
99
100
1.80k
    pub fn subtables_byte_range(&self) -> Range<usize> {
101
1.80k
        let n_tables = self.n_tables();
102
1.80k
        let start = self.n_tables_byte_range().end;
103
1.80k
        let end = start + {
104
1.80k
            let data = self.offset_data().split_off(start).unwrap_or_default();
105
1.80k
            <Subtable as VarSize>::total_len_for_count(data, transforms::to_usize(n_tables))
106
1.80k
                .unwrap_or(0)
107
1.80k
        };
108
1.80k
        start..end
109
1.80k
    }
110
}
111
112
const _: () = assert!(FontData::default_data_long_enough(Kerx::MIN_SIZE));
113
114
impl Default for Kerx<'_> {
115
0
    fn default() -> Self {
116
        Self {
117
0
            data: TableDataRef::new(FontData::default_table_data().as_bytes())
118
0
                .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
119
        }
120
0
    }
121
}
122
123
impl<'a> MinByteRange<'a> for Subtable<'a> {
124
0
    fn min_byte_range(&self) -> Range<usize> {
125
0
        0..self.data_byte_range().end
126
0
    }
127
0
    fn min_table_bytes(&self) -> &'a [u8] {
128
0
        let range = self.min_byte_range();
129
0
        self.offset_data().as_bytes().get(range).unwrap_or_default()
130
0
    }
131
}
132
133
impl ReadArgs for Subtable<'_> {
134
    type Args = ();
135
}
136
137
impl<'a> FontRead<'a> for Subtable<'a> {
138
3.04k
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
139
        #[allow(clippy::absurd_extreme_comparisons)]
140
3.04k
        if data.len() < Self::MIN_SIZE {
141
921
            return Err(ReadError::OutOfBounds);
142
2.11k
        }
143
2.11k
        let Some(data) = TableDataRef::new(data.as_bytes()) else {
144
0
            return Err(ReadError::OutOfBounds);
145
        };
146
2.11k
        Ok(Self { data })
147
3.04k
    }
148
}
149
150
/// The fields at the start of the table, which are read directly.
151
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
152
#[repr(C, packed)]
153
#[doc(hidden)]
154
pub struct SubtableFixedHeader {
155
    pub length: BigEndian<u32>,
156
    pub coverage: BigEndian<u32>,
157
    pub tuple_count: BigEndian<u32>,
158
}
159
160
#[allow(clippy::absurd_extreme_comparisons)]
161
const _: () = assert!(std::mem::size_of::<SubtableFixedHeader>() <= Subtable::MIN_SIZE);
162
163
/// A subtable in a `kerx` table.
164
#[derive(Clone)]
165
pub struct Subtable<'a> {
166
    data: TableDataRef<'a, SubtableFixedHeader>,
167
}
168
169
#[allow(clippy::needless_lifetimes)]
170
impl<'a> Subtable<'a> {
171
    pub const MIN_SIZE: usize = (u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
172
    basic_table_impls!(impl_the_methods);
173
174
    /// The length of this subtable in bytes, including this header.
175
0
    pub fn length(&self) -> u32 {
176
0
        self.data.header().length.get()
177
0
    }
178
179
    /// Circumstances under which this table is used.
180
20.4M
    pub fn coverage(&self) -> u32 {
181
20.4M
        self.data.header().coverage.get()
182
20.4M
    }
183
184
    /// 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.
185
20.4M
    pub fn tuple_count(&self) -> u32 {
186
20.4M
        self.data.header().tuple_count.get()
187
20.4M
    }
188
189
    /// Subtable specific data.
190
3.07k
    pub fn data(&self) -> &'a [u8] {
191
3.07k
        let range = self.data_byte_range();
192
3.07k
        self.offset_data()
193
3.07k
            .read_array(range)
194
3.07k
            .ok()
195
3.07k
            .unwrap_or_default()
196
3.07k
    }
197
198
3.07k
    pub fn length_byte_range(&self) -> Range<usize> {
199
3.07k
        let start = 0;
200
3.07k
        let end = start + u32::RAW_BYTE_LEN;
201
3.07k
        start..end
202
3.07k
    }
203
204
3.07k
    pub fn coverage_byte_range(&self) -> Range<usize> {
205
3.07k
        let start = self.length_byte_range().end;
206
3.07k
        let end = start + u32::RAW_BYTE_LEN;
207
3.07k
        start..end
208
3.07k
    }
209
210
3.07k
    pub fn tuple_count_byte_range(&self) -> Range<usize> {
211
3.07k
        let start = self.coverage_byte_range().end;
212
3.07k
        let end = start + u32::RAW_BYTE_LEN;
213
3.07k
        start..end
214
3.07k
    }
215
216
3.07k
    pub fn data_byte_range(&self) -> Range<usize> {
217
3.07k
        let start = self.tuple_count_byte_range().end;
218
3.07k
        let end = start
219
3.07k
            + self.offset_data().len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
220
3.07k
        start..end
221
3.07k
    }
222
}
223
224
const _: () = assert!(FontData::default_data_long_enough(Subtable::MIN_SIZE));
225
226
impl Default for Subtable<'_> {
227
0
    fn default() -> Self {
228
        Self {
229
0
            data: TableDataRef::new(FontData::default_table_data().as_bytes())
230
0
                .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
231
        }
232
0
    }
233
}
234
235
impl<'a> MinByteRange<'a> for Subtable0<'a> {
236
0
    fn min_byte_range(&self) -> Range<usize> {
237
0
        0..self.pairs_byte_range().end
238
0
    }
239
0
    fn min_table_bytes(&self) -> &'a [u8] {
240
0
        let range = self.min_byte_range();
241
0
        self.offset_data().as_bytes().get(range).unwrap_or_default()
242
0
    }
243
}
244
245
impl ReadArgs for Subtable0<'_> {
246
    type Args = ();
247
}
248
249
impl<'a> FontRead<'a> for Subtable0<'a> {
250
186
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
251
        #[allow(clippy::absurd_extreme_comparisons)]
252
186
        if data.len() < Self::MIN_SIZE {
253
17
            return Err(ReadError::OutOfBounds);
254
169
        }
255
169
        let Some(data) = TableDataRef::new(data.as_bytes()) else {
256
0
            return Err(ReadError::OutOfBounds);
257
        };
258
169
        Ok(Self { data })
259
186
    }
260
}
261
262
/// The fields at the start of the table, which are read directly.
263
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
264
#[repr(C, packed)]
265
#[doc(hidden)]
266
pub struct Subtable0FixedHeader {
267
    pub n_pairs: BigEndian<u32>,
268
    pub search_range: BigEndian<u32>,
269
    pub entry_selector: BigEndian<u32>,
270
    pub range_shift: BigEndian<u32>,
271
}
272
273
#[allow(clippy::absurd_extreme_comparisons)]
274
const _: () = assert!(std::mem::size_of::<Subtable0FixedHeader>() <= Subtable0::MIN_SIZE);
275
276
/// The type 0 `kerx` subtable.
277
#[derive(Clone)]
278
pub struct Subtable0<'a> {
279
    data: TableDataRef<'a, Subtable0FixedHeader>,
280
}
281
282
#[allow(clippy::needless_lifetimes)]
283
impl<'a> Subtable0<'a> {
284
    pub const MIN_SIZE: usize =
285
        (u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
286
    basic_table_impls!(impl_the_methods);
287
288
    /// The number of kerning pairs in this subtable.
289
2.21k
    pub fn n_pairs(&self) -> u32 {
290
2.21k
        self.data.header().n_pairs.get()
291
2.21k
    }
292
293
    /// 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.
294
0
    pub fn search_range(&self) -> u32 {
295
0
        self.data.header().search_range.get()
296
0
    }
297
298
    /// 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.
299
0
    pub fn entry_selector(&self) -> u32 {
300
0
        self.data.header().entry_selector.get()
301
0
    }
302
303
    /// 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.
304
0
    pub fn range_shift(&self) -> u32 {
305
0
        self.data.header().range_shift.get()
306
0
    }
307
308
    /// Kerning records.
309
2.21k
    pub fn pairs(&self) -> &'a [Subtable0Pair] {
310
2.21k
        let range = self.pairs_byte_range();
311
2.21k
        self.offset_data()
312
2.21k
            .read_array(range)
313
2.21k
            .ok()
314
2.21k
            .unwrap_or_default()
315
2.21k
    }
316
317
2.21k
    pub fn n_pairs_byte_range(&self) -> Range<usize> {
318
2.21k
        let start = 0;
319
2.21k
        let end = start + u32::RAW_BYTE_LEN;
320
2.21k
        start..end
321
2.21k
    }
322
323
2.21k
    pub fn search_range_byte_range(&self) -> Range<usize> {
324
2.21k
        let start = self.n_pairs_byte_range().end;
325
2.21k
        let end = start + u32::RAW_BYTE_LEN;
326
2.21k
        start..end
327
2.21k
    }
328
329
2.21k
    pub fn entry_selector_byte_range(&self) -> Range<usize> {
330
2.21k
        let start = self.search_range_byte_range().end;
331
2.21k
        let end = start + u32::RAW_BYTE_LEN;
332
2.21k
        start..end
333
2.21k
    }
334
335
2.21k
    pub fn range_shift_byte_range(&self) -> Range<usize> {
336
2.21k
        let start = self.entry_selector_byte_range().end;
337
2.21k
        let end = start + u32::RAW_BYTE_LEN;
338
2.21k
        start..end
339
2.21k
    }
340
341
2.21k
    pub fn pairs_byte_range(&self) -> Range<usize> {
342
2.21k
        let n_pairs = self.n_pairs();
343
2.21k
        let start = self.range_shift_byte_range().end;
344
2.21k
        let end =
345
2.21k
            start + (transforms::to_usize(n_pairs)).saturating_mul(Subtable0Pair::RAW_BYTE_LEN);
346
2.21k
        start..end
347
2.21k
    }
348
}
349
350
const _: () = assert!(FontData::default_data_long_enough(Subtable0::MIN_SIZE));
351
352
impl Default for Subtable0<'_> {
353
0
    fn default() -> Self {
354
        Self {
355
0
            data: TableDataRef::new(FontData::default_table_data().as_bytes())
356
0
                .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
357
        }
358
0
    }
359
}
360
361
/// The type 0 `kerx` subtable kerning record.
362
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
363
#[repr(C)]
364
#[repr(packed)]
365
pub struct Subtable0Pair {
366
    /// The glyph index for the lefthand glyph in the kerning pair.
367
    pub left: BigEndian<GlyphId16>,
368
    /// The glyph index for the righthand glyph in the kerning pair.
369
    pub right: BigEndian<GlyphId16>,
370
    /// Kerning value.
371
    pub value: BigEndian<i16>,
372
}
373
374
impl Subtable0Pair {
375
    /// The glyph index for the lefthand glyph in the kerning pair.
376
13.7k
    pub fn left(&self) -> GlyphId16 {
377
13.7k
        self.left.get()
378
13.7k
    }
379
380
    /// The glyph index for the righthand glyph in the kerning pair.
381
13.7k
    pub fn right(&self) -> GlyphId16 {
382
13.7k
        self.right.get()
383
13.7k
    }
384
385
    /// Kerning value.
386
2.14k
    pub fn value(&self) -> i16 {
387
2.14k
        self.value.get()
388
2.14k
    }
389
}
390
391
impl FixedSize for Subtable0Pair {
392
    const RAW_BYTE_LEN: usize =
393
        GlyphId16::RAW_BYTE_LEN + GlyphId16::RAW_BYTE_LEN + i16::RAW_BYTE_LEN;
394
}