Coverage Report

Created: 2025-09-27 07:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fontations/read-fonts/generated/generated_postscript.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
/// An array of variable-sized objects in a `CFF` table.
9
#[derive(Debug, Clone, Copy)]
10
#[doc(hidden)]
11
pub struct Index1Marker {
12
    offsets_byte_len: usize,
13
    data_byte_len: usize,
14
}
15
16
impl Index1Marker {
17
484M
    pub fn count_byte_range(&self) -> Range<usize> {
18
484M
        let start = 0;
19
484M
        start..start + u16::RAW_BYTE_LEN
20
484M
    }
21
22
333M
    pub fn off_size_byte_range(&self) -> Range<usize> {
23
333M
        let start = self.count_byte_range().end;
24
333M
        start..start + u8::RAW_BYTE_LEN
25
333M
    }
26
27
202M
    pub fn offsets_byte_range(&self) -> Range<usize> {
28
202M
        let start = self.off_size_byte_range().end;
29
202M
        start..start + self.offsets_byte_len
30
202M
    }
31
32
72.4M
    pub fn data_byte_range(&self) -> Range<usize> {
33
72.4M
        let start = self.offsets_byte_range().end;
34
72.4M
        start..start + self.data_byte_len
35
72.4M
    }
36
}
37
38
impl MinByteRange for Index1Marker {
39
0
    fn min_byte_range(&self) -> Range<usize> {
40
0
        0..self.data_byte_range().end
41
0
    }
42
}
43
44
impl<'a> FontRead<'a> for Index1<'a> {
45
4.68M
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
46
4.68M
        let mut cursor = data.cursor();
47
4.68M
        let count: u16 = cursor.read()?;
48
4.32M
        let off_size: u8 = cursor.read()?;
49
4.32M
        let offsets_byte_len = (transforms::add_multiply(count, 1_usize, off_size))
50
4.32M
            .checked_mul(u8::RAW_BYTE_LEN)
51
4.32M
            .ok_or(ReadError::OutOfBounds)?;
52
4.32M
        cursor.advance_by(offsets_byte_len);
53
4.32M
        let data_byte_len = cursor.remaining_bytes() / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
54
4.32M
        cursor.advance_by(data_byte_len);
55
4.32M
        cursor.finish(Index1Marker {
56
4.32M
            offsets_byte_len,
57
4.32M
            data_byte_len,
58
4.32M
        })
59
4.68M
    }
60
}
61
62
/// An array of variable-sized objects in a `CFF` table.
63
pub type Index1<'a> = TableRef<'a, Index1Marker>;
64
65
#[allow(clippy::needless_lifetimes)]
66
impl<'a> Index1<'a> {
67
    /// Number of objects stored in INDEX.
68
151M
    pub fn count(&self) -> u16 {
69
151M
        let range = self.shape.count_byte_range();
70
151M
        self.data.read_at(range.start).unwrap()
71
151M
    }
72
73
    /// Object array element size.
74
130M
    pub fn off_size(&self) -> u8 {
75
130M
        let range = self.shape.off_size_byte_range();
76
130M
        self.data.read_at(range.start).unwrap()
77
130M
    }
78
79
    /// Bytes containing `count + 1` offsets each of `off_size`.
80
130M
    pub fn offsets(&self) -> &'a [u8] {
81
130M
        let range = self.shape.offsets_byte_range();
82
130M
        self.data.read_array(range).unwrap()
83
130M
    }
84
85
    /// Array containing the object data.
86
72.4M
    pub fn data(&self) -> &'a [u8] {
87
72.4M
        let range = self.shape.data_byte_range();
88
72.4M
        self.data.read_array(range).unwrap()
89
72.4M
    }
90
}
91
92
#[cfg(feature = "experimental_traverse")]
93
impl<'a> SomeTable<'a> for Index1<'a> {
94
    fn type_name(&self) -> &str {
95
        "Index1"
96
    }
97
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
98
        match idx {
99
            0usize => Some(Field::new("count", self.count())),
100
            1usize => Some(Field::new("off_size", self.off_size())),
101
            2usize => Some(Field::new("offsets", self.offsets())),
102
            3usize => Some(Field::new("data", self.data())),
103
            _ => None,
104
        }
105
    }
106
}
107
108
#[cfg(feature = "experimental_traverse")]
109
#[allow(clippy::needless_lifetimes)]
110
impl<'a> std::fmt::Debug for Index1<'a> {
111
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112
        (self as &dyn SomeTable<'a>).fmt(f)
113
    }
114
}
115
116
/// An array of variable-sized objects in a `CFF2` table.
117
#[derive(Debug, Clone, Copy)]
118
#[doc(hidden)]
119
pub struct Index2Marker {
120
    offsets_byte_len: usize,
121
    data_byte_len: usize,
122
}
123
124
impl Index2Marker {
125
25.1M
    pub fn count_byte_range(&self) -> Range<usize> {
126
25.1M
        let start = 0;
127
25.1M
        start..start + u32::RAW_BYTE_LEN
128
25.1M
    }
129
130
15.8M
    pub fn off_size_byte_range(&self) -> Range<usize> {
131
15.8M
        let start = self.count_byte_range().end;
132
15.8M
        start..start + u8::RAW_BYTE_LEN
133
15.8M
    }
134
135
9.52M
    pub fn offsets_byte_range(&self) -> Range<usize> {
136
9.52M
        let start = self.off_size_byte_range().end;
137
9.52M
        start..start + self.offsets_byte_len
138
9.52M
    }
139
140
3.20M
    pub fn data_byte_range(&self) -> Range<usize> {
141
3.20M
        let start = self.offsets_byte_range().end;
142
3.20M
        start..start + self.data_byte_len
143
3.20M
    }
144
}
145
146
impl MinByteRange for Index2Marker {
147
0
    fn min_byte_range(&self) -> Range<usize> {
148
0
        0..self.data_byte_range().end
149
0
    }
150
}
151
152
impl<'a> FontRead<'a> for Index2<'a> {
153
679k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
154
679k
        let mut cursor = data.cursor();
155
679k
        let count: u32 = cursor.read()?;
156
678k
        let off_size: u8 = cursor.read()?;
157
678k
        let offsets_byte_len = (transforms::add_multiply(count, 1_usize, off_size))
158
678k
            .checked_mul(u8::RAW_BYTE_LEN)
159
678k
            .ok_or(ReadError::OutOfBounds)?;
160
678k
        cursor.advance_by(offsets_byte_len);
161
678k
        let data_byte_len = cursor.remaining_bytes() / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
162
678k
        cursor.advance_by(data_byte_len);
163
678k
        cursor.finish(Index2Marker {
164
678k
            offsets_byte_len,
165
678k
            data_byte_len,
166
678k
        })
167
679k
    }
168
}
169
170
/// An array of variable-sized objects in a `CFF2` table.
171
pub type Index2<'a> = TableRef<'a, Index2Marker>;
172
173
#[allow(clippy::needless_lifetimes)]
174
impl<'a> Index2<'a> {
175
    /// Number of objects stored in INDEX.
176
9.34M
    pub fn count(&self) -> u32 {
177
9.34M
        let range = self.shape.count_byte_range();
178
9.34M
        self.data.read_at(range.start).unwrap()
179
9.34M
    }
180
181
    /// Object array element size.
182
6.32M
    pub fn off_size(&self) -> u8 {
183
6.32M
        let range = self.shape.off_size_byte_range();
184
6.32M
        self.data.read_at(range.start).unwrap()
185
6.32M
    }
186
187
    /// Bytes containing `count + 1` offsets each of `off_size`.
188
6.32M
    pub fn offsets(&self) -> &'a [u8] {
189
6.32M
        let range = self.shape.offsets_byte_range();
190
6.32M
        self.data.read_array(range).unwrap()
191
6.32M
    }
192
193
    /// Array containing the object data.
194
3.20M
    pub fn data(&self) -> &'a [u8] {
195
3.20M
        let range = self.shape.data_byte_range();
196
3.20M
        self.data.read_array(range).unwrap()
197
3.20M
    }
198
}
199
200
#[cfg(feature = "experimental_traverse")]
201
impl<'a> SomeTable<'a> for Index2<'a> {
202
    fn type_name(&self) -> &str {
203
        "Index2"
204
    }
205
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
206
        match idx {
207
            0usize => Some(Field::new("count", self.count())),
208
            1usize => Some(Field::new("off_size", self.off_size())),
209
            2usize => Some(Field::new("offsets", self.offsets())),
210
            3usize => Some(Field::new("data", self.data())),
211
            _ => None,
212
        }
213
    }
214
}
215
216
#[cfg(feature = "experimental_traverse")]
217
#[allow(clippy::needless_lifetimes)]
218
impl<'a> std::fmt::Debug for Index2<'a> {
219
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
220
        (self as &dyn SomeTable<'a>).fmt(f)
221
    }
222
}
223
224
/// Associates a glyph identifier with a Font DICT.
225
#[derive(Clone)]
226
pub enum FdSelect<'a> {
227
    Format0(FdSelectFormat0<'a>),
228
    Format3(FdSelectFormat3<'a>),
229
    Format4(FdSelectFormat4<'a>),
230
}
231
232
impl<'a> FdSelect<'a> {
233
    ///Return the `FontData` used to resolve offsets for this table.
234
0
    pub fn offset_data(&self) -> FontData<'a> {
235
0
        match self {
236
0
            Self::Format0(item) => item.offset_data(),
237
0
            Self::Format3(item) => item.offset_data(),
238
0
            Self::Format4(item) => item.offset_data(),
239
        }
240
0
    }
241
242
    /// Format = 0.
243
0
    pub fn format(&self) -> u8 {
244
0
        match self {
245
0
            Self::Format0(item) => item.format(),
246
0
            Self::Format3(item) => item.format(),
247
0
            Self::Format4(item) => item.format(),
248
        }
249
0
    }
250
}
251
252
impl<'a> FontRead<'a> for FdSelect<'a> {
253
19.2k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
254
19.2k
        let format: u8 = data.read_at(0usize)?;
255
19.1k
        match format {
256
1.53k
            FdSelectFormat0Marker::FORMAT => Ok(Self::Format0(FontRead::read(data)?)),
257
17.3k
            FdSelectFormat3Marker::FORMAT => Ok(Self::Format3(FontRead::read(data)?)),
258
96
            FdSelectFormat4Marker::FORMAT => Ok(Self::Format4(FontRead::read(data)?)),
259
96
            other => Err(ReadError::InvalidFormat(other.into())),
260
        }
261
19.2k
    }
262
}
263
264
impl MinByteRange for FdSelect<'_> {
265
0
    fn min_byte_range(&self) -> Range<usize> {
266
0
        match self {
267
0
            Self::Format0(item) => item.min_byte_range(),
268
0
            Self::Format3(item) => item.min_byte_range(),
269
0
            Self::Format4(item) => item.min_byte_range(),
270
        }
271
0
    }
272
}
273
274
#[cfg(feature = "experimental_traverse")]
275
impl<'a> FdSelect<'a> {
276
    fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
277
        match self {
278
            Self::Format0(table) => table,
279
            Self::Format3(table) => table,
280
            Self::Format4(table) => table,
281
        }
282
    }
283
}
284
285
#[cfg(feature = "experimental_traverse")]
286
impl std::fmt::Debug for FdSelect<'_> {
287
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
288
        self.dyn_inner().fmt(f)
289
    }
290
}
291
292
#[cfg(feature = "experimental_traverse")]
293
impl<'a> SomeTable<'a> for FdSelect<'a> {
294
    fn type_name(&self) -> &str {
295
        self.dyn_inner().type_name()
296
    }
297
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
298
        self.dyn_inner().get_field(idx)
299
    }
300
}
301
302
impl Format<u8> for FdSelectFormat0Marker {
303
    const FORMAT: u8 = 0;
304
}
305
306
/// FdSelect format 0.
307
#[derive(Debug, Clone, Copy)]
308
#[doc(hidden)]
309
pub struct FdSelectFormat0Marker {
310
    fds_byte_len: usize,
311
}
312
313
impl FdSelectFormat0Marker {
314
79.6k
    pub fn format_byte_range(&self) -> Range<usize> {
315
79.6k
        let start = 0;
316
79.6k
        start..start + u8::RAW_BYTE_LEN
317
79.6k
    }
318
319
79.6k
    pub fn fds_byte_range(&self) -> Range<usize> {
320
79.6k
        let start = self.format_byte_range().end;
321
79.6k
        start..start + self.fds_byte_len
322
79.6k
    }
323
}
324
325
impl MinByteRange for FdSelectFormat0Marker {
326
0
    fn min_byte_range(&self) -> Range<usize> {
327
0
        0..self.fds_byte_range().end
328
0
    }
329
}
330
331
impl<'a> FontRead<'a> for FdSelectFormat0<'a> {
332
1.53k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
333
1.53k
        let mut cursor = data.cursor();
334
1.53k
        cursor.advance::<u8>();
335
1.53k
        let fds_byte_len = cursor.remaining_bytes() / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
336
1.53k
        cursor.advance_by(fds_byte_len);
337
1.53k
        cursor.finish(FdSelectFormat0Marker { fds_byte_len })
338
1.53k
    }
339
}
340
341
/// FdSelect format 0.
342
pub type FdSelectFormat0<'a> = TableRef<'a, FdSelectFormat0Marker>;
343
344
#[allow(clippy::needless_lifetimes)]
345
impl<'a> FdSelectFormat0<'a> {
346
    /// Format = 0.
347
0
    pub fn format(&self) -> u8 {
348
0
        let range = self.shape.format_byte_range();
349
0
        self.data.read_at(range.start).unwrap()
350
0
    }
351
352
    /// FD selector array (one entry for each glyph).
353
79.6k
    pub fn fds(&self) -> &'a [u8] {
354
79.6k
        let range = self.shape.fds_byte_range();
355
79.6k
        self.data.read_array(range).unwrap()
356
79.6k
    }
357
}
358
359
#[cfg(feature = "experimental_traverse")]
360
impl<'a> SomeTable<'a> for FdSelectFormat0<'a> {
361
    fn type_name(&self) -> &str {
362
        "FdSelectFormat0"
363
    }
364
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
365
        match idx {
366
            0usize => Some(Field::new("format", self.format())),
367
            1usize => Some(Field::new("fds", self.fds())),
368
            _ => None,
369
        }
370
    }
371
}
372
373
#[cfg(feature = "experimental_traverse")]
374
#[allow(clippy::needless_lifetimes)]
375
impl<'a> std::fmt::Debug for FdSelectFormat0<'a> {
376
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
377
        (self as &dyn SomeTable<'a>).fmt(f)
378
    }
379
}
380
381
impl Format<u8> for FdSelectFormat3Marker {
382
    const FORMAT: u8 = 3;
383
}
384
385
/// FdSelect format 3.
386
#[derive(Debug, Clone, Copy)]
387
#[doc(hidden)]
388
pub struct FdSelectFormat3Marker {
389
    ranges_byte_len: usize,
390
}
391
392
impl FdSelectFormat3Marker {
393
3.87M
    pub fn format_byte_range(&self) -> Range<usize> {
394
3.87M
        let start = 0;
395
3.87M
        start..start + u8::RAW_BYTE_LEN
396
3.87M
    }
397
398
3.87M
    pub fn n_ranges_byte_range(&self) -> Range<usize> {
399
3.87M
        let start = self.format_byte_range().end;
400
3.87M
        start..start + u16::RAW_BYTE_LEN
401
3.87M
    }
402
403
3.87M
    pub fn ranges_byte_range(&self) -> Range<usize> {
404
3.87M
        let start = self.n_ranges_byte_range().end;
405
3.87M
        start..start + self.ranges_byte_len
406
3.87M
    }
407
408
0
    pub fn sentinel_byte_range(&self) -> Range<usize> {
409
0
        let start = self.ranges_byte_range().end;
410
0
        start..start + u16::RAW_BYTE_LEN
411
0
    }
412
}
413
414
impl MinByteRange for FdSelectFormat3Marker {
415
0
    fn min_byte_range(&self) -> Range<usize> {
416
0
        0..self.sentinel_byte_range().end
417
0
    }
418
}
419
420
impl<'a> FontRead<'a> for FdSelectFormat3<'a> {
421
17.3k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
422
17.3k
        let mut cursor = data.cursor();
423
17.3k
        cursor.advance::<u8>();
424
17.3k
        let n_ranges: u16 = cursor.read()?;
425
17.3k
        let ranges_byte_len = (n_ranges as usize)
426
17.3k
            .checked_mul(FdSelectRange3::RAW_BYTE_LEN)
427
17.3k
            .ok_or(ReadError::OutOfBounds)?;
428
17.3k
        cursor.advance_by(ranges_byte_len);
429
17.3k
        cursor.advance::<u16>();
430
17.3k
        cursor.finish(FdSelectFormat3Marker { ranges_byte_len })
431
17.3k
    }
432
}
433
434
/// FdSelect format 3.
435
pub type FdSelectFormat3<'a> = TableRef<'a, FdSelectFormat3Marker>;
436
437
#[allow(clippy::needless_lifetimes)]
438
impl<'a> FdSelectFormat3<'a> {
439
    /// Format = 3.
440
0
    pub fn format(&self) -> u8 {
441
0
        let range = self.shape.format_byte_range();
442
0
        self.data.read_at(range.start).unwrap()
443
0
    }
444
445
    /// Number of ranges.
446
0
    pub fn n_ranges(&self) -> u16 {
447
0
        let range = self.shape.n_ranges_byte_range();
448
0
        self.data.read_at(range.start).unwrap()
449
0
    }
450
451
    /// Range3 array.
452
3.87M
    pub fn ranges(&self) -> &'a [FdSelectRange3] {
453
3.87M
        let range = self.shape.ranges_byte_range();
454
3.87M
        self.data.read_array(range).unwrap()
455
3.87M
    }
456
457
    /// Sentinel GID. Set equal to the number of glyphs in the font.
458
0
    pub fn sentinel(&self) -> u16 {
459
0
        let range = self.shape.sentinel_byte_range();
460
0
        self.data.read_at(range.start).unwrap()
461
0
    }
462
}
463
464
#[cfg(feature = "experimental_traverse")]
465
impl<'a> SomeTable<'a> for FdSelectFormat3<'a> {
466
    fn type_name(&self) -> &str {
467
        "FdSelectFormat3"
468
    }
469
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
470
        match idx {
471
            0usize => Some(Field::new("format", self.format())),
472
            1usize => Some(Field::new("n_ranges", self.n_ranges())),
473
            2usize => Some(Field::new(
474
                "ranges",
475
                traversal::FieldType::array_of_records(
476
                    stringify!(FdSelectRange3),
477
                    self.ranges(),
478
                    self.offset_data(),
479
                ),
480
            )),
481
            3usize => Some(Field::new("sentinel", self.sentinel())),
482
            _ => None,
483
        }
484
    }
485
}
486
487
#[cfg(feature = "experimental_traverse")]
488
#[allow(clippy::needless_lifetimes)]
489
impl<'a> std::fmt::Debug for FdSelectFormat3<'a> {
490
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
491
        (self as &dyn SomeTable<'a>).fmt(f)
492
    }
493
}
494
495
/// Range struct for FdSelect format 3.
496
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
497
#[repr(C)]
498
#[repr(packed)]
499
pub struct FdSelectRange3 {
500
    /// First glyph index in range.
501
    pub first: BigEndian<u16>,
502
    /// FD index for all glyphs in range.
503
    pub fd: u8,
504
}
505
506
impl FdSelectRange3 {
507
    /// First glyph index in range.
508
11.6M
    pub fn first(&self) -> u16 {
509
11.6M
        self.first.get()
510
11.6M
    }
511
512
    /// FD index for all glyphs in range.
513
3.87M
    pub fn fd(&self) -> u8 {
514
3.87M
        self.fd
515
3.87M
    }
516
}
517
518
impl FixedSize for FdSelectRange3 {
519
    const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u8::RAW_BYTE_LEN;
520
}
521
522
#[cfg(feature = "experimental_traverse")]
523
impl<'a> SomeRecord<'a> for FdSelectRange3 {
524
    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
525
        RecordResolver {
526
            name: "FdSelectRange3",
527
            get_field: Box::new(move |idx, _data| match idx {
528
                0usize => Some(Field::new("first", self.first())),
529
                1usize => Some(Field::new("fd", self.fd())),
530
                _ => None,
531
            }),
532
            data,
533
        }
534
    }
535
}
536
537
impl Format<u8> for FdSelectFormat4Marker {
538
    const FORMAT: u8 = 4;
539
}
540
541
/// FdSelect format 4.
542
#[derive(Debug, Clone, Copy)]
543
#[doc(hidden)]
544
pub struct FdSelectFormat4Marker {
545
    ranges_byte_len: usize,
546
}
547
548
impl FdSelectFormat4Marker {
549
0
    pub fn format_byte_range(&self) -> Range<usize> {
550
0
        let start = 0;
551
0
        start..start + u8::RAW_BYTE_LEN
552
0
    }
553
554
0
    pub fn n_ranges_byte_range(&self) -> Range<usize> {
555
0
        let start = self.format_byte_range().end;
556
0
        start..start + u32::RAW_BYTE_LEN
557
0
    }
558
559
0
    pub fn ranges_byte_range(&self) -> Range<usize> {
560
0
        let start = self.n_ranges_byte_range().end;
561
0
        start..start + self.ranges_byte_len
562
0
    }
563
564
0
    pub fn sentinel_byte_range(&self) -> Range<usize> {
565
0
        let start = self.ranges_byte_range().end;
566
0
        start..start + u32::RAW_BYTE_LEN
567
0
    }
568
}
569
570
impl MinByteRange for FdSelectFormat4Marker {
571
0
    fn min_byte_range(&self) -> Range<usize> {
572
0
        0..self.sentinel_byte_range().end
573
0
    }
574
}
575
576
impl<'a> FontRead<'a> for FdSelectFormat4<'a> {
577
96
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
578
96
        let mut cursor = data.cursor();
579
96
        cursor.advance::<u8>();
580
96
        let n_ranges: u32 = cursor.read()?;
581
96
        let ranges_byte_len = (n_ranges as usize)
582
96
            .checked_mul(FdSelectRange4::RAW_BYTE_LEN)
583
96
            .ok_or(ReadError::OutOfBounds)?;
584
96
        cursor.advance_by(ranges_byte_len);
585
96
        cursor.advance::<u32>();
586
96
        cursor.finish(FdSelectFormat4Marker { ranges_byte_len })
587
96
    }
588
}
589
590
/// FdSelect format 4.
591
pub type FdSelectFormat4<'a> = TableRef<'a, FdSelectFormat4Marker>;
592
593
#[allow(clippy::needless_lifetimes)]
594
impl<'a> FdSelectFormat4<'a> {
595
    /// Format = 4.
596
0
    pub fn format(&self) -> u8 {
597
0
        let range = self.shape.format_byte_range();
598
0
        self.data.read_at(range.start).unwrap()
599
0
    }
600
601
    /// Number of ranges.
602
0
    pub fn n_ranges(&self) -> u32 {
603
0
        let range = self.shape.n_ranges_byte_range();
604
0
        self.data.read_at(range.start).unwrap()
605
0
    }
606
607
    /// Range4 array.
608
0
    pub fn ranges(&self) -> &'a [FdSelectRange4] {
609
0
        let range = self.shape.ranges_byte_range();
610
0
        self.data.read_array(range).unwrap()
611
0
    }
612
613
    /// Sentinel GID. Set equal to the number of glyphs in the font.
614
0
    pub fn sentinel(&self) -> u32 {
615
0
        let range = self.shape.sentinel_byte_range();
616
0
        self.data.read_at(range.start).unwrap()
617
0
    }
618
}
619
620
#[cfg(feature = "experimental_traverse")]
621
impl<'a> SomeTable<'a> for FdSelectFormat4<'a> {
622
    fn type_name(&self) -> &str {
623
        "FdSelectFormat4"
624
    }
625
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
626
        match idx {
627
            0usize => Some(Field::new("format", self.format())),
628
            1usize => Some(Field::new("n_ranges", self.n_ranges())),
629
            2usize => Some(Field::new(
630
                "ranges",
631
                traversal::FieldType::array_of_records(
632
                    stringify!(FdSelectRange4),
633
                    self.ranges(),
634
                    self.offset_data(),
635
                ),
636
            )),
637
            3usize => Some(Field::new("sentinel", self.sentinel())),
638
            _ => None,
639
        }
640
    }
641
}
642
643
#[cfg(feature = "experimental_traverse")]
644
#[allow(clippy::needless_lifetimes)]
645
impl<'a> std::fmt::Debug for FdSelectFormat4<'a> {
646
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
647
        (self as &dyn SomeTable<'a>).fmt(f)
648
    }
649
}
650
651
/// Range struct for FdSelect format 4.
652
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
653
#[repr(C)]
654
#[repr(packed)]
655
pub struct FdSelectRange4 {
656
    /// First glyph index in range.
657
    pub first: BigEndian<u32>,
658
    /// FD index for all glyphs in range.
659
    pub fd: BigEndian<u16>,
660
}
661
662
impl FdSelectRange4 {
663
    /// First glyph index in range.
664
0
    pub fn first(&self) -> u32 {
665
0
        self.first.get()
666
0
    }
667
668
    /// FD index for all glyphs in range.
669
0
    pub fn fd(&self) -> u16 {
670
0
        self.fd.get()
671
0
    }
672
}
673
674
impl FixedSize for FdSelectRange4 {
675
    const RAW_BYTE_LEN: usize = u32::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
676
}
677
678
#[cfg(feature = "experimental_traverse")]
679
impl<'a> SomeRecord<'a> for FdSelectRange4 {
680
    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
681
        RecordResolver {
682
            name: "FdSelectRange4",
683
            get_field: Box::new(move |idx, _data| match idx {
684
                0usize => Some(Field::new("first", self.first())),
685
                1usize => Some(Field::new("fd", self.fd())),
686
                _ => None,
687
            }),
688
            data,
689
        }
690
    }
691
}
692
693
/// Charset with custom glyph id to string id mappings.
694
#[derive(Clone)]
695
pub enum CustomCharset<'a> {
696
    Format0(CharsetFormat0<'a>),
697
    Format1(CharsetFormat1<'a>),
698
    Format2(CharsetFormat2<'a>),
699
}
700
701
impl<'a> CustomCharset<'a> {
702
    ///Return the `FontData` used to resolve offsets for this table.
703
0
    pub fn offset_data(&self) -> FontData<'a> {
704
0
        match self {
705
0
            Self::Format0(item) => item.offset_data(),
706
0
            Self::Format1(item) => item.offset_data(),
707
0
            Self::Format2(item) => item.offset_data(),
708
        }
709
0
    }
710
711
    /// Format; =0
712
0
    pub fn format(&self) -> u8 {
713
0
        match self {
714
0
            Self::Format0(item) => item.format(),
715
0
            Self::Format1(item) => item.format(),
716
0
            Self::Format2(item) => item.format(),
717
        }
718
0
    }
719
}
720
721
impl<'a> FontRead<'a> for CustomCharset<'a> {
722
17.6k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
723
17.6k
        let format: u8 = data.read_at(0usize)?;
724
17.6k
        match format {
725
5.85k
            CharsetFormat0Marker::FORMAT => Ok(Self::Format0(FontRead::read(data)?)),
726
11.5k
            CharsetFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
727
0
            CharsetFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
728
288
            other => Err(ReadError::InvalidFormat(other.into())),
729
        }
730
17.6k
    }
731
}
732
733
impl MinByteRange for CustomCharset<'_> {
734
0
    fn min_byte_range(&self) -> Range<usize> {
735
0
        match self {
736
0
            Self::Format0(item) => item.min_byte_range(),
737
0
            Self::Format1(item) => item.min_byte_range(),
738
0
            Self::Format2(item) => item.min_byte_range(),
739
        }
740
0
    }
741
}
742
743
#[cfg(feature = "experimental_traverse")]
744
impl<'a> CustomCharset<'a> {
745
    fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
746
        match self {
747
            Self::Format0(table) => table,
748
            Self::Format1(table) => table,
749
            Self::Format2(table) => table,
750
        }
751
    }
752
}
753
754
#[cfg(feature = "experimental_traverse")]
755
impl std::fmt::Debug for CustomCharset<'_> {
756
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
757
        self.dyn_inner().fmt(f)
758
    }
759
}
760
761
#[cfg(feature = "experimental_traverse")]
762
impl<'a> SomeTable<'a> for CustomCharset<'a> {
763
    fn type_name(&self) -> &str {
764
        self.dyn_inner().type_name()
765
    }
766
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
767
        self.dyn_inner().get_field(idx)
768
    }
769
}
770
771
impl Format<u8> for CharsetFormat0Marker {
772
    const FORMAT: u8 = 0;
773
}
774
775
/// Charset format 0.
776
#[derive(Debug, Clone, Copy)]
777
#[doc(hidden)]
778
pub struct CharsetFormat0Marker {
779
    glyph_byte_len: usize,
780
}
781
782
impl CharsetFormat0Marker {
783
11.7k
    pub fn format_byte_range(&self) -> Range<usize> {
784
11.7k
        let start = 0;
785
11.7k
        start..start + u8::RAW_BYTE_LEN
786
11.7k
    }
787
788
11.7k
    pub fn glyph_byte_range(&self) -> Range<usize> {
789
11.7k
        let start = self.format_byte_range().end;
790
11.7k
        start..start + self.glyph_byte_len
791
11.7k
    }
792
}
793
794
impl MinByteRange for CharsetFormat0Marker {
795
0
    fn min_byte_range(&self) -> Range<usize> {
796
0
        0..self.glyph_byte_range().end
797
0
    }
798
}
799
800
impl<'a> FontRead<'a> for CharsetFormat0<'a> {
801
5.85k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
802
5.85k
        let mut cursor = data.cursor();
803
5.85k
        cursor.advance::<u8>();
804
5.85k
        let glyph_byte_len = cursor.remaining_bytes() / u16::RAW_BYTE_LEN * u16::RAW_BYTE_LEN;
805
5.85k
        cursor.advance_by(glyph_byte_len);
806
5.85k
        cursor.finish(CharsetFormat0Marker { glyph_byte_len })
807
5.85k
    }
808
}
809
810
/// Charset format 0.
811
pub type CharsetFormat0<'a> = TableRef<'a, CharsetFormat0Marker>;
812
813
#[allow(clippy::needless_lifetimes)]
814
impl<'a> CharsetFormat0<'a> {
815
    /// Format; =0
816
0
    pub fn format(&self) -> u8 {
817
0
        let range = self.shape.format_byte_range();
818
0
        self.data.read_at(range.start).unwrap()
819
0
    }
820
821
    /// Glyph name array.
822
11.7k
    pub fn glyph(&self) -> &'a [BigEndian<u16>] {
823
11.7k
        let range = self.shape.glyph_byte_range();
824
11.7k
        self.data.read_array(range).unwrap()
825
11.7k
    }
826
}
827
828
#[cfg(feature = "experimental_traverse")]
829
impl<'a> SomeTable<'a> for CharsetFormat0<'a> {
830
    fn type_name(&self) -> &str {
831
        "CharsetFormat0"
832
    }
833
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
834
        match idx {
835
            0usize => Some(Field::new("format", self.format())),
836
            1usize => Some(Field::new("glyph", self.glyph())),
837
            _ => None,
838
        }
839
    }
840
}
841
842
#[cfg(feature = "experimental_traverse")]
843
#[allow(clippy::needless_lifetimes)]
844
impl<'a> std::fmt::Debug for CharsetFormat0<'a> {
845
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
846
        (self as &dyn SomeTable<'a>).fmt(f)
847
    }
848
}
849
850
impl Format<u8> for CharsetFormat1Marker {
851
    const FORMAT: u8 = 1;
852
}
853
854
/// Charset format 1.
855
#[derive(Debug, Clone, Copy)]
856
#[doc(hidden)]
857
pub struct CharsetFormat1Marker {
858
    ranges_byte_len: usize,
859
}
860
861
impl CharsetFormat1Marker {
862
11.7k
    pub fn format_byte_range(&self) -> Range<usize> {
863
11.7k
        let start = 0;
864
11.7k
        start..start + u8::RAW_BYTE_LEN
865
11.7k
    }
866
867
11.7k
    pub fn ranges_byte_range(&self) -> Range<usize> {
868
11.7k
        let start = self.format_byte_range().end;
869
11.7k
        start..start + self.ranges_byte_len
870
11.7k
    }
871
}
872
873
impl MinByteRange for CharsetFormat1Marker {
874
0
    fn min_byte_range(&self) -> Range<usize> {
875
0
        0..self.ranges_byte_range().end
876
0
    }
877
}
878
879
impl<'a> FontRead<'a> for CharsetFormat1<'a> {
880
11.5k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
881
11.5k
        let mut cursor = data.cursor();
882
11.5k
        cursor.advance::<u8>();
883
11.5k
        let ranges_byte_len =
884
11.5k
            cursor.remaining_bytes() / CharsetRange1::RAW_BYTE_LEN * CharsetRange1::RAW_BYTE_LEN;
885
11.5k
        cursor.advance_by(ranges_byte_len);
886
11.5k
        cursor.finish(CharsetFormat1Marker { ranges_byte_len })
887
11.5k
    }
888
}
889
890
/// Charset format 1.
891
pub type CharsetFormat1<'a> = TableRef<'a, CharsetFormat1Marker>;
892
893
#[allow(clippy::needless_lifetimes)]
894
impl<'a> CharsetFormat1<'a> {
895
    /// Format; =1
896
0
    pub fn format(&self) -> u8 {
897
0
        let range = self.shape.format_byte_range();
898
0
        self.data.read_at(range.start).unwrap()
899
0
    }
900
901
    /// Range1 array.
902
11.7k
    pub fn ranges(&self) -> &'a [CharsetRange1] {
903
11.7k
        let range = self.shape.ranges_byte_range();
904
11.7k
        self.data.read_array(range).unwrap()
905
11.7k
    }
906
}
907
908
#[cfg(feature = "experimental_traverse")]
909
impl<'a> SomeTable<'a> for CharsetFormat1<'a> {
910
    fn type_name(&self) -> &str {
911
        "CharsetFormat1"
912
    }
913
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
914
        match idx {
915
            0usize => Some(Field::new("format", self.format())),
916
            1usize => Some(Field::new(
917
                "ranges",
918
                traversal::FieldType::array_of_records(
919
                    stringify!(CharsetRange1),
920
                    self.ranges(),
921
                    self.offset_data(),
922
                ),
923
            )),
924
            _ => None,
925
        }
926
    }
927
}
928
929
#[cfg(feature = "experimental_traverse")]
930
#[allow(clippy::needless_lifetimes)]
931
impl<'a> std::fmt::Debug for CharsetFormat1<'a> {
932
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
933
        (self as &dyn SomeTable<'a>).fmt(f)
934
    }
935
}
936
937
/// Range struct for Charset format 1.
938
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
939
#[repr(C)]
940
#[repr(packed)]
941
pub struct CharsetRange1 {
942
    /// First glyph in range.
943
    pub first: BigEndian<u16>,
944
    /// Glyphs left in range (excluding first).
945
    pub n_left: u8,
946
}
947
948
impl CharsetRange1 {
949
    /// First glyph in range.
950
0
    pub fn first(&self) -> u16 {
951
0
        self.first.get()
952
0
    }
953
954
    /// Glyphs left in range (excluding first).
955
0
    pub fn n_left(&self) -> u8 {
956
0
        self.n_left
957
0
    }
958
}
959
960
impl FixedSize for CharsetRange1 {
961
    const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u8::RAW_BYTE_LEN;
962
}
963
964
#[cfg(feature = "experimental_traverse")]
965
impl<'a> SomeRecord<'a> for CharsetRange1 {
966
    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
967
        RecordResolver {
968
            name: "CharsetRange1",
969
            get_field: Box::new(move |idx, _data| match idx {
970
                0usize => Some(Field::new("first", self.first())),
971
                1usize => Some(Field::new("n_left", self.n_left())),
972
                _ => None,
973
            }),
974
            data,
975
        }
976
    }
977
}
978
979
impl Format<u8> for CharsetFormat2Marker {
980
    const FORMAT: u8 = 2;
981
}
982
983
/// Charset format 2.
984
#[derive(Debug, Clone, Copy)]
985
#[doc(hidden)]
986
pub struct CharsetFormat2Marker {
987
    ranges_byte_len: usize,
988
}
989
990
impl CharsetFormat2Marker {
991
0
    pub fn format_byte_range(&self) -> Range<usize> {
992
0
        let start = 0;
993
0
        start..start + u8::RAW_BYTE_LEN
994
0
    }
995
996
0
    pub fn ranges_byte_range(&self) -> Range<usize> {
997
0
        let start = self.format_byte_range().end;
998
0
        start..start + self.ranges_byte_len
999
0
    }
1000
}
1001
1002
impl MinByteRange for CharsetFormat2Marker {
1003
0
    fn min_byte_range(&self) -> Range<usize> {
1004
0
        0..self.ranges_byte_range().end
1005
0
    }
1006
}
1007
1008
impl<'a> FontRead<'a> for CharsetFormat2<'a> {
1009
0
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1010
0
        let mut cursor = data.cursor();
1011
0
        cursor.advance::<u8>();
1012
0
        let ranges_byte_len =
1013
0
            cursor.remaining_bytes() / CharsetRange2::RAW_BYTE_LEN * CharsetRange2::RAW_BYTE_LEN;
1014
0
        cursor.advance_by(ranges_byte_len);
1015
0
        cursor.finish(CharsetFormat2Marker { ranges_byte_len })
1016
0
    }
1017
}
1018
1019
/// Charset format 2.
1020
pub type CharsetFormat2<'a> = TableRef<'a, CharsetFormat2Marker>;
1021
1022
#[allow(clippy::needless_lifetimes)]
1023
impl<'a> CharsetFormat2<'a> {
1024
    /// Format; =2
1025
0
    pub fn format(&self) -> u8 {
1026
0
        let range = self.shape.format_byte_range();
1027
0
        self.data.read_at(range.start).unwrap()
1028
0
    }
1029
1030
    /// Range2 array.
1031
0
    pub fn ranges(&self) -> &'a [CharsetRange2] {
1032
0
        let range = self.shape.ranges_byte_range();
1033
0
        self.data.read_array(range).unwrap()
1034
0
    }
1035
}
1036
1037
#[cfg(feature = "experimental_traverse")]
1038
impl<'a> SomeTable<'a> for CharsetFormat2<'a> {
1039
    fn type_name(&self) -> &str {
1040
        "CharsetFormat2"
1041
    }
1042
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1043
        match idx {
1044
            0usize => Some(Field::new("format", self.format())),
1045
            1usize => Some(Field::new(
1046
                "ranges",
1047
                traversal::FieldType::array_of_records(
1048
                    stringify!(CharsetRange2),
1049
                    self.ranges(),
1050
                    self.offset_data(),
1051
                ),
1052
            )),
1053
            _ => None,
1054
        }
1055
    }
1056
}
1057
1058
#[cfg(feature = "experimental_traverse")]
1059
#[allow(clippy::needless_lifetimes)]
1060
impl<'a> std::fmt::Debug for CharsetFormat2<'a> {
1061
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1062
        (self as &dyn SomeTable<'a>).fmt(f)
1063
    }
1064
}
1065
1066
/// Range struct for Charset format 2.
1067
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
1068
#[repr(C)]
1069
#[repr(packed)]
1070
pub struct CharsetRange2 {
1071
    /// First glyph in range.
1072
    pub first: BigEndian<u16>,
1073
    /// Glyphs left in range (excluding first).
1074
    pub n_left: BigEndian<u16>,
1075
}
1076
1077
impl CharsetRange2 {
1078
    /// First glyph in range.
1079
0
    pub fn first(&self) -> u16 {
1080
0
        self.first.get()
1081
0
    }
1082
1083
    /// Glyphs left in range (excluding first).
1084
0
    pub fn n_left(&self) -> u16 {
1085
0
        self.n_left.get()
1086
0
    }
1087
}
1088
1089
impl FixedSize for CharsetRange2 {
1090
    const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
1091
}
1092
1093
#[cfg(feature = "experimental_traverse")]
1094
impl<'a> SomeRecord<'a> for CharsetRange2 {
1095
    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
1096
        RecordResolver {
1097
            name: "CharsetRange2",
1098
            get_field: Box::new(move |idx, _data| match idx {
1099
                0usize => Some(Field::new("first", self.first())),
1100
                1usize => Some(Field::new("n_left", self.n_left())),
1101
                _ => None,
1102
            }),
1103
            data,
1104
        }
1105
    }
1106
}