1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8#[derive(Debug, Clone, Copy)]
10#[doc(hidden)]
11pub struct Index1Marker {
12 offsets_byte_len: usize,
13 data_byte_len: usize,
14}
15
16impl Index1Marker {
17 pub fn count_byte_range(&self) -> Range<usize> {
18 let start = 0;
19 start..start + u16::RAW_BYTE_LEN
20 }
21
22 pub fn off_size_byte_range(&self) -> Range<usize> {
23 let start = self.count_byte_range().end;
24 start..start + u8::RAW_BYTE_LEN
25 }
26
27 pub fn offsets_byte_range(&self) -> Range<usize> {
28 let start = self.off_size_byte_range().end;
29 start..start + self.offsets_byte_len
30 }
31
32 pub fn data_byte_range(&self) -> Range<usize> {
33 let start = self.offsets_byte_range().end;
34 start..start + self.data_byte_len
35 }
36}
37
38impl MinByteRange for Index1Marker {
39 fn min_byte_range(&self) -> Range<usize> {
40 0..self.data_byte_range().end
41 }
42}
43
44impl<'a> FontRead<'a> for Index1<'a> {
45 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
46 let mut cursor = data.cursor();
47 let count: u16 = cursor.read()?;
48 let off_size: u8 = cursor.read()?;
49 let offsets_byte_len = (transforms::add_multiply(count, 1_usize, off_size))
50 .checked_mul(u8::RAW_BYTE_LEN)
51 .ok_or(ReadError::OutOfBounds)?;
52 cursor.advance_by(offsets_byte_len);
53 let data_byte_len = cursor.remaining_bytes() / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
54 cursor.advance_by(data_byte_len);
55 cursor.finish(Index1Marker {
56 offsets_byte_len,
57 data_byte_len,
58 })
59 }
60}
61
62pub type Index1<'a> = TableRef<'a, Index1Marker>;
64
65#[allow(clippy::needless_lifetimes)]
66impl<'a> Index1<'a> {
67 pub fn count(&self) -> u16 {
69 let range = self.shape.count_byte_range();
70 self.data.read_at(range.start).unwrap()
71 }
72
73 pub fn off_size(&self) -> u8 {
75 let range = self.shape.off_size_byte_range();
76 self.data.read_at(range.start).unwrap()
77 }
78
79 pub fn offsets(&self) -> &'a [u8] {
81 let range = self.shape.offsets_byte_range();
82 self.data.read_array(range).unwrap()
83 }
84
85 pub fn data(&self) -> &'a [u8] {
87 let range = self.shape.data_byte_range();
88 self.data.read_array(range).unwrap()
89 }
90}
91
92#[cfg(feature = "experimental_traverse")]
93impl<'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)]
110impl<'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#[derive(Debug, Clone, Copy)]
118#[doc(hidden)]
119pub struct Index2Marker {
120 offsets_byte_len: usize,
121 data_byte_len: usize,
122}
123
124impl Index2Marker {
125 pub fn count_byte_range(&self) -> Range<usize> {
126 let start = 0;
127 start..start + u32::RAW_BYTE_LEN
128 }
129
130 pub fn off_size_byte_range(&self) -> Range<usize> {
131 let start = self.count_byte_range().end;
132 start..start + u8::RAW_BYTE_LEN
133 }
134
135 pub fn offsets_byte_range(&self) -> Range<usize> {
136 let start = self.off_size_byte_range().end;
137 start..start + self.offsets_byte_len
138 }
139
140 pub fn data_byte_range(&self) -> Range<usize> {
141 let start = self.offsets_byte_range().end;
142 start..start + self.data_byte_len
143 }
144}
145
146impl MinByteRange for Index2Marker {
147 fn min_byte_range(&self) -> Range<usize> {
148 0..self.data_byte_range().end
149 }
150}
151
152impl<'a> FontRead<'a> for Index2<'a> {
153 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
154 let mut cursor = data.cursor();
155 let count: u32 = cursor.read()?;
156 let off_size: u8 = cursor.read()?;
157 let offsets_byte_len = (transforms::add_multiply(count, 1_usize, off_size))
158 .checked_mul(u8::RAW_BYTE_LEN)
159 .ok_or(ReadError::OutOfBounds)?;
160 cursor.advance_by(offsets_byte_len);
161 let data_byte_len = cursor.remaining_bytes() / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
162 cursor.advance_by(data_byte_len);
163 cursor.finish(Index2Marker {
164 offsets_byte_len,
165 data_byte_len,
166 })
167 }
168}
169
170pub type Index2<'a> = TableRef<'a, Index2Marker>;
172
173#[allow(clippy::needless_lifetimes)]
174impl<'a> Index2<'a> {
175 pub fn count(&self) -> u32 {
177 let range = self.shape.count_byte_range();
178 self.data.read_at(range.start).unwrap()
179 }
180
181 pub fn off_size(&self) -> u8 {
183 let range = self.shape.off_size_byte_range();
184 self.data.read_at(range.start).unwrap()
185 }
186
187 pub fn offsets(&self) -> &'a [u8] {
189 let range = self.shape.offsets_byte_range();
190 self.data.read_array(range).unwrap()
191 }
192
193 pub fn data(&self) -> &'a [u8] {
195 let range = self.shape.data_byte_range();
196 self.data.read_array(range).unwrap()
197 }
198}
199
200#[cfg(feature = "experimental_traverse")]
201impl<'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)]
218impl<'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#[derive(Clone)]
226pub enum FdSelect<'a> {
227 Format0(FdSelectFormat0<'a>),
228 Format3(FdSelectFormat3<'a>),
229 Format4(FdSelectFormat4<'a>),
230}
231
232impl<'a> FdSelect<'a> {
233 pub fn offset_data(&self) -> FontData<'a> {
235 match self {
236 Self::Format0(item) => item.offset_data(),
237 Self::Format3(item) => item.offset_data(),
238 Self::Format4(item) => item.offset_data(),
239 }
240 }
241
242 pub fn format(&self) -> u8 {
244 match self {
245 Self::Format0(item) => item.format(),
246 Self::Format3(item) => item.format(),
247 Self::Format4(item) => item.format(),
248 }
249 }
250}
251
252impl<'a> FontRead<'a> for FdSelect<'a> {
253 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
254 let format: u8 = data.read_at(0usize)?;
255 match format {
256 FdSelectFormat0Marker::FORMAT => Ok(Self::Format0(FontRead::read(data)?)),
257 FdSelectFormat3Marker::FORMAT => Ok(Self::Format3(FontRead::read(data)?)),
258 FdSelectFormat4Marker::FORMAT => Ok(Self::Format4(FontRead::read(data)?)),
259 other => Err(ReadError::InvalidFormat(other.into())),
260 }
261 }
262}
263
264impl MinByteRange for FdSelect<'_> {
265 fn min_byte_range(&self) -> Range<usize> {
266 match self {
267 Self::Format0(item) => item.min_byte_range(),
268 Self::Format3(item) => item.min_byte_range(),
269 Self::Format4(item) => item.min_byte_range(),
270 }
271 }
272}
273
274#[cfg(feature = "experimental_traverse")]
275impl<'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")]
286impl 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")]
293impl<'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
302impl Format<u8> for FdSelectFormat0Marker {
303 const FORMAT: u8 = 0;
304}
305
306#[derive(Debug, Clone, Copy)]
308#[doc(hidden)]
309pub struct FdSelectFormat0Marker {
310 fds_byte_len: usize,
311}
312
313impl FdSelectFormat0Marker {
314 pub fn format_byte_range(&self) -> Range<usize> {
315 let start = 0;
316 start..start + u8::RAW_BYTE_LEN
317 }
318
319 pub fn fds_byte_range(&self) -> Range<usize> {
320 let start = self.format_byte_range().end;
321 start..start + self.fds_byte_len
322 }
323}
324
325impl MinByteRange for FdSelectFormat0Marker {
326 fn min_byte_range(&self) -> Range<usize> {
327 0..self.fds_byte_range().end
328 }
329}
330
331impl<'a> FontRead<'a> for FdSelectFormat0<'a> {
332 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
333 let mut cursor = data.cursor();
334 cursor.advance::<u8>();
335 let fds_byte_len = cursor.remaining_bytes() / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
336 cursor.advance_by(fds_byte_len);
337 cursor.finish(FdSelectFormat0Marker { fds_byte_len })
338 }
339}
340
341pub type FdSelectFormat0<'a> = TableRef<'a, FdSelectFormat0Marker>;
343
344#[allow(clippy::needless_lifetimes)]
345impl<'a> FdSelectFormat0<'a> {
346 pub fn format(&self) -> u8 {
348 let range = self.shape.format_byte_range();
349 self.data.read_at(range.start).unwrap()
350 }
351
352 pub fn fds(&self) -> &'a [u8] {
354 let range = self.shape.fds_byte_range();
355 self.data.read_array(range).unwrap()
356 }
357}
358
359#[cfg(feature = "experimental_traverse")]
360impl<'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)]
375impl<'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
381impl Format<u8> for FdSelectFormat3Marker {
382 const FORMAT: u8 = 3;
383}
384
385#[derive(Debug, Clone, Copy)]
387#[doc(hidden)]
388pub struct FdSelectFormat3Marker {
389 ranges_byte_len: usize,
390}
391
392impl FdSelectFormat3Marker {
393 pub fn format_byte_range(&self) -> Range<usize> {
394 let start = 0;
395 start..start + u8::RAW_BYTE_LEN
396 }
397
398 pub fn n_ranges_byte_range(&self) -> Range<usize> {
399 let start = self.format_byte_range().end;
400 start..start + u16::RAW_BYTE_LEN
401 }
402
403 pub fn ranges_byte_range(&self) -> Range<usize> {
404 let start = self.n_ranges_byte_range().end;
405 start..start + self.ranges_byte_len
406 }
407
408 pub fn sentinel_byte_range(&self) -> Range<usize> {
409 let start = self.ranges_byte_range().end;
410 start..start + u16::RAW_BYTE_LEN
411 }
412}
413
414impl MinByteRange for FdSelectFormat3Marker {
415 fn min_byte_range(&self) -> Range<usize> {
416 0..self.sentinel_byte_range().end
417 }
418}
419
420impl<'a> FontRead<'a> for FdSelectFormat3<'a> {
421 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
422 let mut cursor = data.cursor();
423 cursor.advance::<u8>();
424 let n_ranges: u16 = cursor.read()?;
425 let ranges_byte_len = (n_ranges as usize)
426 .checked_mul(FdSelectRange3::RAW_BYTE_LEN)
427 .ok_or(ReadError::OutOfBounds)?;
428 cursor.advance_by(ranges_byte_len);
429 cursor.advance::<u16>();
430 cursor.finish(FdSelectFormat3Marker { ranges_byte_len })
431 }
432}
433
434pub type FdSelectFormat3<'a> = TableRef<'a, FdSelectFormat3Marker>;
436
437#[allow(clippy::needless_lifetimes)]
438impl<'a> FdSelectFormat3<'a> {
439 pub fn format(&self) -> u8 {
441 let range = self.shape.format_byte_range();
442 self.data.read_at(range.start).unwrap()
443 }
444
445 pub fn n_ranges(&self) -> u16 {
447 let range = self.shape.n_ranges_byte_range();
448 self.data.read_at(range.start).unwrap()
449 }
450
451 pub fn ranges(&self) -> &'a [FdSelectRange3] {
453 let range = self.shape.ranges_byte_range();
454 self.data.read_array(range).unwrap()
455 }
456
457 pub fn sentinel(&self) -> u16 {
459 let range = self.shape.sentinel_byte_range();
460 self.data.read_at(range.start).unwrap()
461 }
462}
463
464#[cfg(feature = "experimental_traverse")]
465impl<'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)]
489impl<'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#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
497#[repr(C)]
498#[repr(packed)]
499pub struct FdSelectRange3 {
500 pub first: BigEndian<u16>,
502 pub fd: u8,
504}
505
506impl FdSelectRange3 {
507 pub fn first(&self) -> u16 {
509 self.first.get()
510 }
511
512 pub fn fd(&self) -> u8 {
514 self.fd
515 }
516}
517
518impl FixedSize for FdSelectRange3 {
519 const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u8::RAW_BYTE_LEN;
520}
521
522#[cfg(feature = "experimental_traverse")]
523impl<'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
537impl Format<u8> for FdSelectFormat4Marker {
538 const FORMAT: u8 = 4;
539}
540
541#[derive(Debug, Clone, Copy)]
543#[doc(hidden)]
544pub struct FdSelectFormat4Marker {
545 ranges_byte_len: usize,
546}
547
548impl FdSelectFormat4Marker {
549 pub fn format_byte_range(&self) -> Range<usize> {
550 let start = 0;
551 start..start + u8::RAW_BYTE_LEN
552 }
553
554 pub fn n_ranges_byte_range(&self) -> Range<usize> {
555 let start = self.format_byte_range().end;
556 start..start + u32::RAW_BYTE_LEN
557 }
558
559 pub fn ranges_byte_range(&self) -> Range<usize> {
560 let start = self.n_ranges_byte_range().end;
561 start..start + self.ranges_byte_len
562 }
563
564 pub fn sentinel_byte_range(&self) -> Range<usize> {
565 let start = self.ranges_byte_range().end;
566 start..start + u32::RAW_BYTE_LEN
567 }
568}
569
570impl MinByteRange for FdSelectFormat4Marker {
571 fn min_byte_range(&self) -> Range<usize> {
572 0..self.sentinel_byte_range().end
573 }
574}
575
576impl<'a> FontRead<'a> for FdSelectFormat4<'a> {
577 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
578 let mut cursor = data.cursor();
579 cursor.advance::<u8>();
580 let n_ranges: u32 = cursor.read()?;
581 let ranges_byte_len = (n_ranges as usize)
582 .checked_mul(FdSelectRange4::RAW_BYTE_LEN)
583 .ok_or(ReadError::OutOfBounds)?;
584 cursor.advance_by(ranges_byte_len);
585 cursor.advance::<u32>();
586 cursor.finish(FdSelectFormat4Marker { ranges_byte_len })
587 }
588}
589
590pub type FdSelectFormat4<'a> = TableRef<'a, FdSelectFormat4Marker>;
592
593#[allow(clippy::needless_lifetimes)]
594impl<'a> FdSelectFormat4<'a> {
595 pub fn format(&self) -> u8 {
597 let range = self.shape.format_byte_range();
598 self.data.read_at(range.start).unwrap()
599 }
600
601 pub fn n_ranges(&self) -> u32 {
603 let range = self.shape.n_ranges_byte_range();
604 self.data.read_at(range.start).unwrap()
605 }
606
607 pub fn ranges(&self) -> &'a [FdSelectRange4] {
609 let range = self.shape.ranges_byte_range();
610 self.data.read_array(range).unwrap()
611 }
612
613 pub fn sentinel(&self) -> u32 {
615 let range = self.shape.sentinel_byte_range();
616 self.data.read_at(range.start).unwrap()
617 }
618}
619
620#[cfg(feature = "experimental_traverse")]
621impl<'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)]
645impl<'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#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
653#[repr(C)]
654#[repr(packed)]
655pub struct FdSelectRange4 {
656 pub first: BigEndian<u32>,
658 pub fd: BigEndian<u16>,
660}
661
662impl FdSelectRange4 {
663 pub fn first(&self) -> u32 {
665 self.first.get()
666 }
667
668 pub fn fd(&self) -> u16 {
670 self.fd.get()
671 }
672}
673
674impl FixedSize for FdSelectRange4 {
675 const RAW_BYTE_LEN: usize = u32::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
676}
677
678#[cfg(feature = "experimental_traverse")]
679impl<'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#[derive(Clone)]
695pub enum CustomCharset<'a> {
696 Format0(CharsetFormat0<'a>),
697 Format1(CharsetFormat1<'a>),
698 Format2(CharsetFormat2<'a>),
699}
700
701impl<'a> CustomCharset<'a> {
702 pub fn offset_data(&self) -> FontData<'a> {
704 match self {
705 Self::Format0(item) => item.offset_data(),
706 Self::Format1(item) => item.offset_data(),
707 Self::Format2(item) => item.offset_data(),
708 }
709 }
710
711 pub fn format(&self) -> u8 {
713 match self {
714 Self::Format0(item) => item.format(),
715 Self::Format1(item) => item.format(),
716 Self::Format2(item) => item.format(),
717 }
718 }
719}
720
721impl<'a> FontRead<'a> for CustomCharset<'a> {
722 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
723 let format: u8 = data.read_at(0usize)?;
724 match format {
725 CharsetFormat0Marker::FORMAT => Ok(Self::Format0(FontRead::read(data)?)),
726 CharsetFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
727 CharsetFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
728 other => Err(ReadError::InvalidFormat(other.into())),
729 }
730 }
731}
732
733impl MinByteRange for CustomCharset<'_> {
734 fn min_byte_range(&self) -> Range<usize> {
735 match self {
736 Self::Format0(item) => item.min_byte_range(),
737 Self::Format1(item) => item.min_byte_range(),
738 Self::Format2(item) => item.min_byte_range(),
739 }
740 }
741}
742
743#[cfg(feature = "experimental_traverse")]
744impl<'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")]
755impl 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")]
762impl<'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
771impl Format<u8> for CharsetFormat0Marker {
772 const FORMAT: u8 = 0;
773}
774
775#[derive(Debug, Clone, Copy)]
777#[doc(hidden)]
778pub struct CharsetFormat0Marker {
779 glyph_byte_len: usize,
780}
781
782impl CharsetFormat0Marker {
783 pub fn format_byte_range(&self) -> Range<usize> {
784 let start = 0;
785 start..start + u8::RAW_BYTE_LEN
786 }
787
788 pub fn glyph_byte_range(&self) -> Range<usize> {
789 let start = self.format_byte_range().end;
790 start..start + self.glyph_byte_len
791 }
792}
793
794impl MinByteRange for CharsetFormat0Marker {
795 fn min_byte_range(&self) -> Range<usize> {
796 0..self.glyph_byte_range().end
797 }
798}
799
800impl<'a> FontRead<'a> for CharsetFormat0<'a> {
801 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
802 let mut cursor = data.cursor();
803 cursor.advance::<u8>();
804 let glyph_byte_len = cursor.remaining_bytes() / u16::RAW_BYTE_LEN * u16::RAW_BYTE_LEN;
805 cursor.advance_by(glyph_byte_len);
806 cursor.finish(CharsetFormat0Marker { glyph_byte_len })
807 }
808}
809
810pub type CharsetFormat0<'a> = TableRef<'a, CharsetFormat0Marker>;
812
813#[allow(clippy::needless_lifetimes)]
814impl<'a> CharsetFormat0<'a> {
815 pub fn format(&self) -> u8 {
817 let range = self.shape.format_byte_range();
818 self.data.read_at(range.start).unwrap()
819 }
820
821 pub fn glyph(&self) -> &'a [BigEndian<u16>] {
823 let range = self.shape.glyph_byte_range();
824 self.data.read_array(range).unwrap()
825 }
826}
827
828#[cfg(feature = "experimental_traverse")]
829impl<'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)]
844impl<'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
850impl Format<u8> for CharsetFormat1Marker {
851 const FORMAT: u8 = 1;
852}
853
854#[derive(Debug, Clone, Copy)]
856#[doc(hidden)]
857pub struct CharsetFormat1Marker {
858 ranges_byte_len: usize,
859}
860
861impl CharsetFormat1Marker {
862 pub fn format_byte_range(&self) -> Range<usize> {
863 let start = 0;
864 start..start + u8::RAW_BYTE_LEN
865 }
866
867 pub fn ranges_byte_range(&self) -> Range<usize> {
868 let start = self.format_byte_range().end;
869 start..start + self.ranges_byte_len
870 }
871}
872
873impl MinByteRange for CharsetFormat1Marker {
874 fn min_byte_range(&self) -> Range<usize> {
875 0..self.ranges_byte_range().end
876 }
877}
878
879impl<'a> FontRead<'a> for CharsetFormat1<'a> {
880 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
881 let mut cursor = data.cursor();
882 cursor.advance::<u8>();
883 let ranges_byte_len =
884 cursor.remaining_bytes() / CharsetRange1::RAW_BYTE_LEN * CharsetRange1::RAW_BYTE_LEN;
885 cursor.advance_by(ranges_byte_len);
886 cursor.finish(CharsetFormat1Marker { ranges_byte_len })
887 }
888}
889
890pub type CharsetFormat1<'a> = TableRef<'a, CharsetFormat1Marker>;
892
893#[allow(clippy::needless_lifetimes)]
894impl<'a> CharsetFormat1<'a> {
895 pub fn format(&self) -> u8 {
897 let range = self.shape.format_byte_range();
898 self.data.read_at(range.start).unwrap()
899 }
900
901 pub fn ranges(&self) -> &'a [CharsetRange1] {
903 let range = self.shape.ranges_byte_range();
904 self.data.read_array(range).unwrap()
905 }
906}
907
908#[cfg(feature = "experimental_traverse")]
909impl<'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)]
931impl<'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#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
939#[repr(C)]
940#[repr(packed)]
941pub struct CharsetRange1 {
942 pub first: BigEndian<u16>,
944 pub n_left: u8,
946}
947
948impl CharsetRange1 {
949 pub fn first(&self) -> u16 {
951 self.first.get()
952 }
953
954 pub fn n_left(&self) -> u8 {
956 self.n_left
957 }
958}
959
960impl FixedSize for CharsetRange1 {
961 const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u8::RAW_BYTE_LEN;
962}
963
964#[cfg(feature = "experimental_traverse")]
965impl<'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
979impl Format<u8> for CharsetFormat2Marker {
980 const FORMAT: u8 = 2;
981}
982
983#[derive(Debug, Clone, Copy)]
985#[doc(hidden)]
986pub struct CharsetFormat2Marker {
987 ranges_byte_len: usize,
988}
989
990impl CharsetFormat2Marker {
991 pub fn format_byte_range(&self) -> Range<usize> {
992 let start = 0;
993 start..start + u8::RAW_BYTE_LEN
994 }
995
996 pub fn ranges_byte_range(&self) -> Range<usize> {
997 let start = self.format_byte_range().end;
998 start..start + self.ranges_byte_len
999 }
1000}
1001
1002impl MinByteRange for CharsetFormat2Marker {
1003 fn min_byte_range(&self) -> Range<usize> {
1004 0..self.ranges_byte_range().end
1005 }
1006}
1007
1008impl<'a> FontRead<'a> for CharsetFormat2<'a> {
1009 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1010 let mut cursor = data.cursor();
1011 cursor.advance::<u8>();
1012 let ranges_byte_len =
1013 cursor.remaining_bytes() / CharsetRange2::RAW_BYTE_LEN * CharsetRange2::RAW_BYTE_LEN;
1014 cursor.advance_by(ranges_byte_len);
1015 cursor.finish(CharsetFormat2Marker { ranges_byte_len })
1016 }
1017}
1018
1019pub type CharsetFormat2<'a> = TableRef<'a, CharsetFormat2Marker>;
1021
1022#[allow(clippy::needless_lifetimes)]
1023impl<'a> CharsetFormat2<'a> {
1024 pub fn format(&self) -> u8 {
1026 let range = self.shape.format_byte_range();
1027 self.data.read_at(range.start).unwrap()
1028 }
1029
1030 pub fn ranges(&self) -> &'a [CharsetRange2] {
1032 let range = self.shape.ranges_byte_range();
1033 self.data.read_array(range).unwrap()
1034 }
1035}
1036
1037#[cfg(feature = "experimental_traverse")]
1038impl<'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)]
1060impl<'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#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
1068#[repr(C)]
1069#[repr(packed)]
1070pub struct CharsetRange2 {
1071 pub first: BigEndian<u16>,
1073 pub n_left: BigEndian<u16>,
1075}
1076
1077impl CharsetRange2 {
1078 pub fn first(&self) -> u16 {
1080 self.first.get()
1081 }
1082
1083 pub fn n_left(&self) -> u16 {
1085 self.n_left.get()
1086 }
1087}
1088
1089impl FixedSize for CharsetRange2 {
1090 const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
1091}
1092
1093#[cfg(feature = "experimental_traverse")]
1094impl<'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}