read_fonts/generated/
generated_postscript.rs

1// THIS FILE IS AUTOGENERATED.
2// Any changes to this file will be overwritten.
3// For more information about how codegen works, see font-codegen/README.md
4
5#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8/// An array of variable-sized objects in a `CFF` table.
9#[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
62/// An array of variable-sized objects in a `CFF` table.
63pub type Index1<'a> = TableRef<'a, Index1Marker>;
64
65#[allow(clippy::needless_lifetimes)]
66impl<'a> Index1<'a> {
67    /// Number of objects stored in INDEX.
68    pub fn count(&self) -> u16 {
69        let range = self.shape.count_byte_range();
70        self.data.read_at(range.start).unwrap()
71    }
72
73    /// Object array element size.
74    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    /// Bytes containing `count + 1` offsets each of `off_size`.
80    pub fn offsets(&self) -> &'a [u8] {
81        let range = self.shape.offsets_byte_range();
82        self.data.read_array(range).unwrap()
83    }
84
85    /// Array containing the object data.
86    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/// An array of variable-sized objects in a `CFF2` table.
117#[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
170/// An array of variable-sized objects in a `CFF2` table.
171pub type Index2<'a> = TableRef<'a, Index2Marker>;
172
173#[allow(clippy::needless_lifetimes)]
174impl<'a> Index2<'a> {
175    /// Number of objects stored in INDEX.
176    pub fn count(&self) -> u32 {
177        let range = self.shape.count_byte_range();
178        self.data.read_at(range.start).unwrap()
179    }
180
181    /// Object array element size.
182    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    /// Bytes containing `count + 1` offsets each of `off_size`.
188    pub fn offsets(&self) -> &'a [u8] {
189        let range = self.shape.offsets_byte_range();
190        self.data.read_array(range).unwrap()
191    }
192
193    /// Array containing the object data.
194    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/// Associates a glyph identifier with a Font DICT.
225#[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    ///Return the `FontData` used to resolve offsets for this table.
234    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    /// Format = 0.
243    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/// FdSelect format 0.
307#[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
341/// FdSelect format 0.
342pub type FdSelectFormat0<'a> = TableRef<'a, FdSelectFormat0Marker>;
343
344#[allow(clippy::needless_lifetimes)]
345impl<'a> FdSelectFormat0<'a> {
346    /// Format = 0.
347    pub fn format(&self) -> u8 {
348        let range = self.shape.format_byte_range();
349        self.data.read_at(range.start).unwrap()
350    }
351
352    /// FD selector array (one entry for each glyph).
353    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/// FdSelect format 3.
386#[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
434/// FdSelect format 3.
435pub type FdSelectFormat3<'a> = TableRef<'a, FdSelectFormat3Marker>;
436
437#[allow(clippy::needless_lifetimes)]
438impl<'a> FdSelectFormat3<'a> {
439    /// Format = 3.
440    pub fn format(&self) -> u8 {
441        let range = self.shape.format_byte_range();
442        self.data.read_at(range.start).unwrap()
443    }
444
445    /// Number of ranges.
446    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    /// Range3 array.
452    pub fn ranges(&self) -> &'a [FdSelectRange3] {
453        let range = self.shape.ranges_byte_range();
454        self.data.read_array(range).unwrap()
455    }
456
457    /// Sentinel GID. Set equal to the number of glyphs in the font.
458    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/// Range struct for FdSelect format 3.
496#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
497#[repr(C)]
498#[repr(packed)]
499pub 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
506impl FdSelectRange3 {
507    /// First glyph index in range.
508    pub fn first(&self) -> u16 {
509        self.first.get()
510    }
511
512    /// FD index for all glyphs in range.
513    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/// FdSelect format 4.
542#[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
590/// FdSelect format 4.
591pub type FdSelectFormat4<'a> = TableRef<'a, FdSelectFormat4Marker>;
592
593#[allow(clippy::needless_lifetimes)]
594impl<'a> FdSelectFormat4<'a> {
595    /// Format = 4.
596    pub fn format(&self) -> u8 {
597        let range = self.shape.format_byte_range();
598        self.data.read_at(range.start).unwrap()
599    }
600
601    /// Number of ranges.
602    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    /// Range4 array.
608    pub fn ranges(&self) -> &'a [FdSelectRange4] {
609        let range = self.shape.ranges_byte_range();
610        self.data.read_array(range).unwrap()
611    }
612
613    /// Sentinel GID. Set equal to the number of glyphs in the font.
614    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/// Range struct for FdSelect format 4.
652#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
653#[repr(C)]
654#[repr(packed)]
655pub 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
662impl FdSelectRange4 {
663    /// First glyph index in range.
664    pub fn first(&self) -> u32 {
665        self.first.get()
666    }
667
668    /// FD index for all glyphs in range.
669    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/// Charset with custom glyph id to string id mappings.
694#[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    ///Return the `FontData` used to resolve offsets for this table.
703    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    /// Format; =0
712    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/// Charset format 0.
776#[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
810/// Charset format 0.
811pub type CharsetFormat0<'a> = TableRef<'a, CharsetFormat0Marker>;
812
813#[allow(clippy::needless_lifetimes)]
814impl<'a> CharsetFormat0<'a> {
815    /// Format; =0
816    pub fn format(&self) -> u8 {
817        let range = self.shape.format_byte_range();
818        self.data.read_at(range.start).unwrap()
819    }
820
821    /// Glyph name array.
822    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/// Charset format 1.
855#[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
890/// Charset format 1.
891pub type CharsetFormat1<'a> = TableRef<'a, CharsetFormat1Marker>;
892
893#[allow(clippy::needless_lifetimes)]
894impl<'a> CharsetFormat1<'a> {
895    /// Format; =1
896    pub fn format(&self) -> u8 {
897        let range = self.shape.format_byte_range();
898        self.data.read_at(range.start).unwrap()
899    }
900
901    /// Range1 array.
902    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/// Range struct for Charset format 1.
938#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
939#[repr(C)]
940#[repr(packed)]
941pub 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
948impl CharsetRange1 {
949    /// First glyph in range.
950    pub fn first(&self) -> u16 {
951        self.first.get()
952    }
953
954    /// Glyphs left in range (excluding first).
955    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/// Charset format 2.
984#[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
1019/// Charset format 2.
1020pub type CharsetFormat2<'a> = TableRef<'a, CharsetFormat2Marker>;
1021
1022#[allow(clippy::needless_lifetimes)]
1023impl<'a> CharsetFormat2<'a> {
1024    /// Format; =2
1025    pub fn format(&self) -> u8 {
1026        let range = self.shape.format_byte_range();
1027        self.data.read_at(range.start).unwrap()
1028    }
1029
1030    /// Range2 array.
1031    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/// Range struct for Charset format 2.
1067#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
1068#[repr(C)]
1069#[repr(packed)]
1070pub 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
1077impl CharsetRange2 {
1078    /// First glyph in range.
1079    pub fn first(&self) -> u16 {
1080        self.first.get()
1081    }
1082
1083    /// Glyphs left in range (excluding first).
1084    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}