1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8#[derive(Debug, Clone, Copy)]
10#[doc(hidden)]
11pub struct OtKernMarker {
12 subtable_data_byte_len: usize,
13}
14
15impl OtKernMarker {
16 pub fn version_byte_range(&self) -> Range<usize> {
17 let start = 0;
18 start..start + u16::RAW_BYTE_LEN
19 }
20
21 pub fn n_tables_byte_range(&self) -> Range<usize> {
22 let start = self.version_byte_range().end;
23 start..start + u16::RAW_BYTE_LEN
24 }
25
26 pub fn subtable_data_byte_range(&self) -> Range<usize> {
27 let start = self.n_tables_byte_range().end;
28 start..start + self.subtable_data_byte_len
29 }
30}
31
32impl MinByteRange for OtKernMarker {
33 fn min_byte_range(&self) -> Range<usize> {
34 0..self.subtable_data_byte_range().end
35 }
36}
37
38impl<'a> FontRead<'a> for OtKern<'a> {
39 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
40 let mut cursor = data.cursor();
41 cursor.advance::<u16>();
42 cursor.advance::<u16>();
43 let subtable_data_byte_len = cursor.remaining_bytes() / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
44 cursor.advance_by(subtable_data_byte_len);
45 cursor.finish(OtKernMarker {
46 subtable_data_byte_len,
47 })
48 }
49}
50
51pub type OtKern<'a> = TableRef<'a, OtKernMarker>;
53
54#[allow(clippy::needless_lifetimes)]
55impl<'a> OtKern<'a> {
56 pub fn version(&self) -> u16 {
58 let range = self.shape.version_byte_range();
59 self.data.read_at(range.start).unwrap()
60 }
61
62 pub fn n_tables(&self) -> u16 {
64 let range = self.shape.n_tables_byte_range();
65 self.data.read_at(range.start).unwrap()
66 }
67
68 pub fn subtable_data(&self) -> &'a [u8] {
70 let range = self.shape.subtable_data_byte_range();
71 self.data.read_array(range).unwrap()
72 }
73}
74
75#[cfg(feature = "experimental_traverse")]
76impl<'a> SomeTable<'a> for OtKern<'a> {
77 fn type_name(&self) -> &str {
78 "OtKern"
79 }
80 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
81 match idx {
82 0usize => Some(Field::new("version", self.version())),
83 1usize => Some(Field::new("n_tables", self.n_tables())),
84 2usize => Some(Field::new("subtable_data", self.subtable_data())),
85 _ => None,
86 }
87 }
88}
89
90#[cfg(feature = "experimental_traverse")]
91#[allow(clippy::needless_lifetimes)]
92impl<'a> std::fmt::Debug for OtKern<'a> {
93 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94 (self as &dyn SomeTable<'a>).fmt(f)
95 }
96}
97
98#[derive(Debug, Clone, Copy)]
100#[doc(hidden)]
101pub struct AatKernMarker {
102 subtable_data_byte_len: usize,
103}
104
105impl AatKernMarker {
106 pub fn version_byte_range(&self) -> Range<usize> {
107 let start = 0;
108 start..start + MajorMinor::RAW_BYTE_LEN
109 }
110
111 pub fn n_tables_byte_range(&self) -> Range<usize> {
112 let start = self.version_byte_range().end;
113 start..start + u32::RAW_BYTE_LEN
114 }
115
116 pub fn subtable_data_byte_range(&self) -> Range<usize> {
117 let start = self.n_tables_byte_range().end;
118 start..start + self.subtable_data_byte_len
119 }
120}
121
122impl MinByteRange for AatKernMarker {
123 fn min_byte_range(&self) -> Range<usize> {
124 0..self.subtable_data_byte_range().end
125 }
126}
127
128impl<'a> FontRead<'a> for AatKern<'a> {
129 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
130 let mut cursor = data.cursor();
131 cursor.advance::<MajorMinor>();
132 cursor.advance::<u32>();
133 let subtable_data_byte_len = cursor.remaining_bytes() / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
134 cursor.advance_by(subtable_data_byte_len);
135 cursor.finish(AatKernMarker {
136 subtable_data_byte_len,
137 })
138 }
139}
140
141pub type AatKern<'a> = TableRef<'a, AatKernMarker>;
143
144#[allow(clippy::needless_lifetimes)]
145impl<'a> AatKern<'a> {
146 pub fn version(&self) -> MajorMinor {
148 let range = self.shape.version_byte_range();
149 self.data.read_at(range.start).unwrap()
150 }
151
152 pub fn n_tables(&self) -> u32 {
154 let range = self.shape.n_tables_byte_range();
155 self.data.read_at(range.start).unwrap()
156 }
157
158 pub fn subtable_data(&self) -> &'a [u8] {
160 let range = self.shape.subtable_data_byte_range();
161 self.data.read_array(range).unwrap()
162 }
163}
164
165#[cfg(feature = "experimental_traverse")]
166impl<'a> SomeTable<'a> for AatKern<'a> {
167 fn type_name(&self) -> &str {
168 "AatKern"
169 }
170 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
171 match idx {
172 0usize => Some(Field::new("version", self.version())),
173 1usize => Some(Field::new("n_tables", self.n_tables())),
174 2usize => Some(Field::new("subtable_data", self.subtable_data())),
175 _ => None,
176 }
177 }
178}
179
180#[cfg(feature = "experimental_traverse")]
181#[allow(clippy::needless_lifetimes)]
182impl<'a> std::fmt::Debug for AatKern<'a> {
183 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
184 (self as &dyn SomeTable<'a>).fmt(f)
185 }
186}
187
188#[derive(Debug, Clone, Copy)]
190#[doc(hidden)]
191pub struct OtSubtableMarker {
192 data_byte_len: usize,
193}
194
195impl OtSubtableMarker {
196 pub fn version_byte_range(&self) -> Range<usize> {
197 let start = 0;
198 start..start + u16::RAW_BYTE_LEN
199 }
200
201 pub fn length_byte_range(&self) -> Range<usize> {
202 let start = self.version_byte_range().end;
203 start..start + u16::RAW_BYTE_LEN
204 }
205
206 pub fn coverage_byte_range(&self) -> Range<usize> {
207 let start = self.length_byte_range().end;
208 start..start + u16::RAW_BYTE_LEN
209 }
210
211 pub fn data_byte_range(&self) -> Range<usize> {
212 let start = self.coverage_byte_range().end;
213 start..start + self.data_byte_len
214 }
215}
216
217impl MinByteRange for OtSubtableMarker {
218 fn min_byte_range(&self) -> Range<usize> {
219 0..self.data_byte_range().end
220 }
221}
222
223impl<'a> FontRead<'a> for OtSubtable<'a> {
224 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
225 let mut cursor = data.cursor();
226 cursor.advance::<u16>();
227 cursor.advance::<u16>();
228 cursor.advance::<u16>();
229 let data_byte_len = cursor.remaining_bytes() / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
230 cursor.advance_by(data_byte_len);
231 cursor.finish(OtSubtableMarker { data_byte_len })
232 }
233}
234
235pub type OtSubtable<'a> = TableRef<'a, OtSubtableMarker>;
237
238#[allow(clippy::needless_lifetimes)]
239impl<'a> OtSubtable<'a> {
240 pub fn version(&self) -> u16 {
242 let range = self.shape.version_byte_range();
243 self.data.read_at(range.start).unwrap()
244 }
245
246 pub fn length(&self) -> u16 {
248 let range = self.shape.length_byte_range();
249 self.data.read_at(range.start).unwrap()
250 }
251
252 pub fn coverage(&self) -> u16 {
254 let range = self.shape.coverage_byte_range();
255 self.data.read_at(range.start).unwrap()
256 }
257
258 pub fn data(&self) -> &'a [u8] {
260 let range = self.shape.data_byte_range();
261 self.data.read_array(range).unwrap()
262 }
263}
264
265#[cfg(feature = "experimental_traverse")]
266impl<'a> SomeTable<'a> for OtSubtable<'a> {
267 fn type_name(&self) -> &str {
268 "OtSubtable"
269 }
270 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
271 match idx {
272 0usize => Some(Field::new("version", self.version())),
273 1usize => Some(Field::new("length", self.length())),
274 2usize => Some(Field::new("coverage", self.coverage())),
275 3usize => Some(Field::new("data", self.data())),
276 _ => None,
277 }
278 }
279}
280
281#[cfg(feature = "experimental_traverse")]
282#[allow(clippy::needless_lifetimes)]
283impl<'a> std::fmt::Debug for OtSubtable<'a> {
284 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
285 (self as &dyn SomeTable<'a>).fmt(f)
286 }
287}
288
289#[derive(Debug, Clone, Copy)]
291#[doc(hidden)]
292pub struct AatSubtableMarker {
293 data_byte_len: usize,
294}
295
296impl AatSubtableMarker {
297 pub fn length_byte_range(&self) -> Range<usize> {
298 let start = 0;
299 start..start + u32::RAW_BYTE_LEN
300 }
301
302 pub fn coverage_byte_range(&self) -> Range<usize> {
303 let start = self.length_byte_range().end;
304 start..start + u16::RAW_BYTE_LEN
305 }
306
307 pub fn tuple_index_byte_range(&self) -> Range<usize> {
308 let start = self.coverage_byte_range().end;
309 start..start + u16::RAW_BYTE_LEN
310 }
311
312 pub fn data_byte_range(&self) -> Range<usize> {
313 let start = self.tuple_index_byte_range().end;
314 start..start + self.data_byte_len
315 }
316}
317
318impl MinByteRange for AatSubtableMarker {
319 fn min_byte_range(&self) -> Range<usize> {
320 0..self.data_byte_range().end
321 }
322}
323
324impl<'a> FontRead<'a> for AatSubtable<'a> {
325 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
326 let mut cursor = data.cursor();
327 cursor.advance::<u32>();
328 cursor.advance::<u16>();
329 cursor.advance::<u16>();
330 let data_byte_len = cursor.remaining_bytes() / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
331 cursor.advance_by(data_byte_len);
332 cursor.finish(AatSubtableMarker { data_byte_len })
333 }
334}
335
336pub type AatSubtable<'a> = TableRef<'a, AatSubtableMarker>;
338
339#[allow(clippy::needless_lifetimes)]
340impl<'a> AatSubtable<'a> {
341 pub fn length(&self) -> u32 {
343 let range = self.shape.length_byte_range();
344 self.data.read_at(range.start).unwrap()
345 }
346
347 pub fn coverage(&self) -> u16 {
349 let range = self.shape.coverage_byte_range();
350 self.data.read_at(range.start).unwrap()
351 }
352
353 pub fn tuple_index(&self) -> u16 {
355 let range = self.shape.tuple_index_byte_range();
356 self.data.read_at(range.start).unwrap()
357 }
358
359 pub fn data(&self) -> &'a [u8] {
361 let range = self.shape.data_byte_range();
362 self.data.read_array(range).unwrap()
363 }
364}
365
366#[cfg(feature = "experimental_traverse")]
367impl<'a> SomeTable<'a> for AatSubtable<'a> {
368 fn type_name(&self) -> &str {
369 "AatSubtable"
370 }
371 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
372 match idx {
373 0usize => Some(Field::new("length", self.length())),
374 1usize => Some(Field::new("coverage", self.coverage())),
375 2usize => Some(Field::new("tuple_index", self.tuple_index())),
376 3usize => Some(Field::new("data", self.data())),
377 _ => None,
378 }
379 }
380}
381
382#[cfg(feature = "experimental_traverse")]
383#[allow(clippy::needless_lifetimes)]
384impl<'a> std::fmt::Debug for AatSubtable<'a> {
385 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
386 (self as &dyn SomeTable<'a>).fmt(f)
387 }
388}
389
390#[derive(Debug, Clone, Copy)]
392#[doc(hidden)]
393pub struct Subtable0Marker {
394 pairs_byte_len: usize,
395}
396
397impl Subtable0Marker {
398 pub fn n_pairs_byte_range(&self) -> Range<usize> {
399 let start = 0;
400 start..start + u16::RAW_BYTE_LEN
401 }
402
403 pub fn search_range_byte_range(&self) -> Range<usize> {
404 let start = self.n_pairs_byte_range().end;
405 start..start + u16::RAW_BYTE_LEN
406 }
407
408 pub fn entry_selector_byte_range(&self) -> Range<usize> {
409 let start = self.search_range_byte_range().end;
410 start..start + u16::RAW_BYTE_LEN
411 }
412
413 pub fn range_shift_byte_range(&self) -> Range<usize> {
414 let start = self.entry_selector_byte_range().end;
415 start..start + u16::RAW_BYTE_LEN
416 }
417
418 pub fn pairs_byte_range(&self) -> Range<usize> {
419 let start = self.range_shift_byte_range().end;
420 start..start + self.pairs_byte_len
421 }
422}
423
424impl MinByteRange for Subtable0Marker {
425 fn min_byte_range(&self) -> Range<usize> {
426 0..self.pairs_byte_range().end
427 }
428}
429
430impl<'a> FontRead<'a> for Subtable0<'a> {
431 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
432 let mut cursor = data.cursor();
433 let n_pairs: u16 = cursor.read()?;
434 cursor.advance::<u16>();
435 cursor.advance::<u16>();
436 cursor.advance::<u16>();
437 let pairs_byte_len = (n_pairs as usize)
438 .checked_mul(Subtable0Pair::RAW_BYTE_LEN)
439 .ok_or(ReadError::OutOfBounds)?;
440 cursor.advance_by(pairs_byte_len);
441 cursor.finish(Subtable0Marker { pairs_byte_len })
442 }
443}
444
445pub type Subtable0<'a> = TableRef<'a, Subtable0Marker>;
447
448#[allow(clippy::needless_lifetimes)]
449impl<'a> Subtable0<'a> {
450 pub fn n_pairs(&self) -> u16 {
452 let range = self.shape.n_pairs_byte_range();
453 self.data.read_at(range.start).unwrap()
454 }
455
456 pub fn search_range(&self) -> u16 {
458 let range = self.shape.search_range_byte_range();
459 self.data.read_at(range.start).unwrap()
460 }
461
462 pub fn entry_selector(&self) -> u16 {
464 let range = self.shape.entry_selector_byte_range();
465 self.data.read_at(range.start).unwrap()
466 }
467
468 pub fn range_shift(&self) -> u16 {
470 let range = self.shape.range_shift_byte_range();
471 self.data.read_at(range.start).unwrap()
472 }
473
474 pub fn pairs(&self) -> &'a [Subtable0Pair] {
476 let range = self.shape.pairs_byte_range();
477 self.data.read_array(range).unwrap()
478 }
479}
480
481#[cfg(feature = "experimental_traverse")]
482impl<'a> SomeTable<'a> for Subtable0<'a> {
483 fn type_name(&self) -> &str {
484 "Subtable0"
485 }
486 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
487 match idx {
488 0usize => Some(Field::new("n_pairs", self.n_pairs())),
489 1usize => Some(Field::new("search_range", self.search_range())),
490 2usize => Some(Field::new("entry_selector", self.entry_selector())),
491 3usize => Some(Field::new("range_shift", self.range_shift())),
492 4usize => Some(Field::new(
493 "pairs",
494 traversal::FieldType::array_of_records(
495 stringify!(Subtable0Pair),
496 self.pairs(),
497 self.offset_data(),
498 ),
499 )),
500 _ => None,
501 }
502 }
503}
504
505#[cfg(feature = "experimental_traverse")]
506#[allow(clippy::needless_lifetimes)]
507impl<'a> std::fmt::Debug for Subtable0<'a> {
508 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
509 (self as &dyn SomeTable<'a>).fmt(f)
510 }
511}
512
513#[derive(Debug, Clone, Copy)]
515#[doc(hidden)]
516pub struct Subtable2ClassTableMarker {
517 offsets_byte_len: usize,
518}
519
520impl Subtable2ClassTableMarker {
521 pub fn first_glyph_byte_range(&self) -> Range<usize> {
522 let start = 0;
523 start..start + GlyphId16::RAW_BYTE_LEN
524 }
525
526 pub fn n_glyphs_byte_range(&self) -> Range<usize> {
527 let start = self.first_glyph_byte_range().end;
528 start..start + u16::RAW_BYTE_LEN
529 }
530
531 pub fn offsets_byte_range(&self) -> Range<usize> {
532 let start = self.n_glyphs_byte_range().end;
533 start..start + self.offsets_byte_len
534 }
535}
536
537impl MinByteRange for Subtable2ClassTableMarker {
538 fn min_byte_range(&self) -> Range<usize> {
539 0..self.offsets_byte_range().end
540 }
541}
542
543impl<'a> FontRead<'a> for Subtable2ClassTable<'a> {
544 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
545 let mut cursor = data.cursor();
546 cursor.advance::<GlyphId16>();
547 let n_glyphs: u16 = cursor.read()?;
548 let offsets_byte_len = (n_glyphs as usize)
549 .checked_mul(u16::RAW_BYTE_LEN)
550 .ok_or(ReadError::OutOfBounds)?;
551 cursor.advance_by(offsets_byte_len);
552 cursor.finish(Subtable2ClassTableMarker { offsets_byte_len })
553 }
554}
555
556pub type Subtable2ClassTable<'a> = TableRef<'a, Subtable2ClassTableMarker>;
558
559#[allow(clippy::needless_lifetimes)]
560impl<'a> Subtable2ClassTable<'a> {
561 pub fn first_glyph(&self) -> GlyphId16 {
563 let range = self.shape.first_glyph_byte_range();
564 self.data.read_at(range.start).unwrap()
565 }
566
567 pub fn n_glyphs(&self) -> u16 {
569 let range = self.shape.n_glyphs_byte_range();
570 self.data.read_at(range.start).unwrap()
571 }
572
573 pub fn offsets(&self) -> &'a [BigEndian<u16>] {
575 let range = self.shape.offsets_byte_range();
576 self.data.read_array(range).unwrap()
577 }
578}
579
580#[cfg(feature = "experimental_traverse")]
581impl<'a> SomeTable<'a> for Subtable2ClassTable<'a> {
582 fn type_name(&self) -> &str {
583 "Subtable2ClassTable"
584 }
585 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
586 match idx {
587 0usize => Some(Field::new("first_glyph", self.first_glyph())),
588 1usize => Some(Field::new("n_glyphs", self.n_glyphs())),
589 2usize => Some(Field::new("offsets", self.offsets())),
590 _ => None,
591 }
592 }
593}
594
595#[cfg(feature = "experimental_traverse")]
596#[allow(clippy::needless_lifetimes)]
597impl<'a> std::fmt::Debug for Subtable2ClassTable<'a> {
598 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
599 (self as &dyn SomeTable<'a>).fmt(f)
600 }
601}
602
603#[derive(Debug, Clone, Copy)]
605#[doc(hidden)]
606pub struct Subtable3Marker {
607 kern_value_byte_len: usize,
608 left_class_byte_len: usize,
609 right_class_byte_len: usize,
610 kern_index_byte_len: usize,
611}
612
613impl Subtable3Marker {
614 pub fn glyph_count_byte_range(&self) -> Range<usize> {
615 let start = 0;
616 start..start + u16::RAW_BYTE_LEN
617 }
618
619 pub fn kern_value_count_byte_range(&self) -> Range<usize> {
620 let start = self.glyph_count_byte_range().end;
621 start..start + u8::RAW_BYTE_LEN
622 }
623
624 pub fn left_class_count_byte_range(&self) -> Range<usize> {
625 let start = self.kern_value_count_byte_range().end;
626 start..start + u8::RAW_BYTE_LEN
627 }
628
629 pub fn right_class_count_byte_range(&self) -> Range<usize> {
630 let start = self.left_class_count_byte_range().end;
631 start..start + u8::RAW_BYTE_LEN
632 }
633
634 pub fn flags_byte_range(&self) -> Range<usize> {
635 let start = self.right_class_count_byte_range().end;
636 start..start + u8::RAW_BYTE_LEN
637 }
638
639 pub fn kern_value_byte_range(&self) -> Range<usize> {
640 let start = self.flags_byte_range().end;
641 start..start + self.kern_value_byte_len
642 }
643
644 pub fn left_class_byte_range(&self) -> Range<usize> {
645 let start = self.kern_value_byte_range().end;
646 start..start + self.left_class_byte_len
647 }
648
649 pub fn right_class_byte_range(&self) -> Range<usize> {
650 let start = self.left_class_byte_range().end;
651 start..start + self.right_class_byte_len
652 }
653
654 pub fn kern_index_byte_range(&self) -> Range<usize> {
655 let start = self.right_class_byte_range().end;
656 start..start + self.kern_index_byte_len
657 }
658}
659
660impl MinByteRange for Subtable3Marker {
661 fn min_byte_range(&self) -> Range<usize> {
662 0..self.kern_index_byte_range().end
663 }
664}
665
666impl<'a> FontRead<'a> for Subtable3<'a> {
667 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
668 let mut cursor = data.cursor();
669 let glyph_count: u16 = cursor.read()?;
670 let kern_value_count: u8 = cursor.read()?;
671 let left_class_count: u8 = cursor.read()?;
672 let right_class_count: u8 = cursor.read()?;
673 cursor.advance::<u8>();
674 let kern_value_byte_len = (kern_value_count as usize)
675 .checked_mul(i16::RAW_BYTE_LEN)
676 .ok_or(ReadError::OutOfBounds)?;
677 cursor.advance_by(kern_value_byte_len);
678 let left_class_byte_len = (glyph_count as usize)
679 .checked_mul(u8::RAW_BYTE_LEN)
680 .ok_or(ReadError::OutOfBounds)?;
681 cursor.advance_by(left_class_byte_len);
682 let right_class_byte_len = (glyph_count as usize)
683 .checked_mul(u8::RAW_BYTE_LEN)
684 .ok_or(ReadError::OutOfBounds)?;
685 cursor.advance_by(right_class_byte_len);
686 let kern_index_byte_len =
687 (transforms::add_multiply(left_class_count, 0_usize, right_class_count))
688 .checked_mul(u8::RAW_BYTE_LEN)
689 .ok_or(ReadError::OutOfBounds)?;
690 cursor.advance_by(kern_index_byte_len);
691 cursor.finish(Subtable3Marker {
692 kern_value_byte_len,
693 left_class_byte_len,
694 right_class_byte_len,
695 kern_index_byte_len,
696 })
697 }
698}
699
700pub type Subtable3<'a> = TableRef<'a, Subtable3Marker>;
702
703#[allow(clippy::needless_lifetimes)]
704impl<'a> Subtable3<'a> {
705 pub fn glyph_count(&self) -> u16 {
707 let range = self.shape.glyph_count_byte_range();
708 self.data.read_at(range.start).unwrap()
709 }
710
711 pub fn kern_value_count(&self) -> u8 {
713 let range = self.shape.kern_value_count_byte_range();
714 self.data.read_at(range.start).unwrap()
715 }
716
717 pub fn left_class_count(&self) -> u8 {
719 let range = self.shape.left_class_count_byte_range();
720 self.data.read_at(range.start).unwrap()
721 }
722
723 pub fn right_class_count(&self) -> u8 {
725 let range = self.shape.right_class_count_byte_range();
726 self.data.read_at(range.start).unwrap()
727 }
728
729 pub fn flags(&self) -> u8 {
731 let range = self.shape.flags_byte_range();
732 self.data.read_at(range.start).unwrap()
733 }
734
735 pub fn kern_value(&self) -> &'a [BigEndian<i16>] {
737 let range = self.shape.kern_value_byte_range();
738 self.data.read_array(range).unwrap()
739 }
740
741 pub fn left_class(&self) -> &'a [u8] {
743 let range = self.shape.left_class_byte_range();
744 self.data.read_array(range).unwrap()
745 }
746
747 pub fn right_class(&self) -> &'a [u8] {
749 let range = self.shape.right_class_byte_range();
750 self.data.read_array(range).unwrap()
751 }
752
753 pub fn kern_index(&self) -> &'a [u8] {
755 let range = self.shape.kern_index_byte_range();
756 self.data.read_array(range).unwrap()
757 }
758}
759
760#[cfg(feature = "experimental_traverse")]
761impl<'a> SomeTable<'a> for Subtable3<'a> {
762 fn type_name(&self) -> &str {
763 "Subtable3"
764 }
765 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
766 match idx {
767 0usize => Some(Field::new("glyph_count", self.glyph_count())),
768 1usize => Some(Field::new("kern_value_count", self.kern_value_count())),
769 2usize => Some(Field::new("left_class_count", self.left_class_count())),
770 3usize => Some(Field::new("right_class_count", self.right_class_count())),
771 4usize => Some(Field::new("flags", self.flags())),
772 5usize => Some(Field::new("kern_value", self.kern_value())),
773 6usize => Some(Field::new("left_class", self.left_class())),
774 7usize => Some(Field::new("right_class", self.right_class())),
775 8usize => Some(Field::new("kern_index", self.kern_index())),
776 _ => None,
777 }
778 }
779}
780
781#[cfg(feature = "experimental_traverse")]
782#[allow(clippy::needless_lifetimes)]
783impl<'a> std::fmt::Debug for Subtable3<'a> {
784 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
785 (self as &dyn SomeTable<'a>).fmt(f)
786 }
787}