Skip to main content

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