1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8impl<'a> MinByteRange<'a> for Cmap<'a> {
9 fn min_byte_range(&self) -> Range<usize> {
10 0..self.encoding_records_byte_range().end
11 }
12 fn min_table_bytes(&self) -> &'a [u8] {
13 let range = self.min_byte_range();
14 self.offset_data().as_bytes().get(range).unwrap_or_default()
15 }
16}
17
18impl TopLevelTable for Cmap<'_> {
19 const TAG: Tag = Tag::new(b"cmap");
21}
22
23impl ReadArgs for Cmap<'_> {
24 type Args = ();
25}
26
27impl<'a> FontRead<'a> for Cmap<'a> {
28 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
29 #[allow(clippy::absurd_extreme_comparisons)]
30 if data.len() < Self::MIN_SIZE {
31 return Err(ReadError::OutOfBounds);
32 }
33 let Some(data) = TableDataRef::new(data.as_bytes()) else {
34 return Err(ReadError::OutOfBounds);
35 };
36 Ok(Self { data })
37 }
38}
39
40#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
42#[repr(C, packed)]
43#[doc(hidden)]
44pub struct CmapFixedHeader {
45 pub version: BigEndian<u16>,
46 pub num_tables: BigEndian<u16>,
47}
48
49#[allow(clippy::absurd_extreme_comparisons)]
50const _: () = assert!(std::mem::size_of::<CmapFixedHeader>() <= Cmap::MIN_SIZE);
51
52#[derive(Clone)]
54pub struct Cmap<'a> {
55 data: TableDataRef<'a, CmapFixedHeader>,
56}
57
58#[allow(clippy::needless_lifetimes)]
59impl<'a> Cmap<'a> {
60 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
61 basic_table_impls!(impl_the_methods);
62
63 pub fn version(&self) -> u16 {
65 self.data.header().version.get()
66 }
67
68 pub fn num_tables(&self) -> u16 {
70 self.data.header().num_tables.get()
71 }
72
73 pub fn encoding_records(&self) -> &'a [EncodingRecord] {
74 let range = self.encoding_records_byte_range();
75 self.offset_data()
76 .read_array(range)
77 .ok()
78 .unwrap_or_default()
79 }
80
81 pub fn version_byte_range(&self) -> Range<usize> {
82 let start = 0;
83 let end = start + u16::RAW_BYTE_LEN;
84 start..end
85 }
86
87 pub fn num_tables_byte_range(&self) -> Range<usize> {
88 let start = self.version_byte_range().end;
89 let end = start + u16::RAW_BYTE_LEN;
90 start..end
91 }
92
93 pub fn encoding_records_byte_range(&self) -> Range<usize> {
94 let num_tables = self.num_tables();
95 let start = self.num_tables_byte_range().end;
96 let end =
97 start + (transforms::to_usize(num_tables)).saturating_mul(EncodingRecord::RAW_BYTE_LEN);
98 start..end
99 }
100}
101
102const _: () = assert!(FontData::default_data_long_enough(Cmap::MIN_SIZE));
103
104impl Default for Cmap<'_> {
105 fn default() -> Self {
106 Self {
107 data: TableDataRef::new(FontData::default_table_data().as_bytes())
108 .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
109 }
110 }
111}
112
113impl<'a> MinByteRange<'a> for Dmap<'a> {
114 fn min_byte_range(&self) -> Range<usize> {
115 0..self.encoding_records_byte_range().end
116 }
117 fn min_table_bytes(&self) -> &'a [u8] {
118 let range = self.min_byte_range();
119 self.offset_data().as_bytes().get(range).unwrap_or_default()
120 }
121}
122
123impl TopLevelTable for Dmap<'_> {
124 const TAG: Tag = Tag::new(b"DMAP");
126}
127
128impl ReadArgs for Dmap<'_> {
129 type Args = ();
130}
131
132impl<'a> FontRead<'a> for Dmap<'a> {
133 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
134 #[allow(clippy::absurd_extreme_comparisons)]
135 if data.len() < Self::MIN_SIZE {
136 return Err(ReadError::OutOfBounds);
137 }
138 let Some(data) = TableDataRef::new(data.as_bytes()) else {
139 return Err(ReadError::OutOfBounds);
140 };
141 Ok(Self { data })
142 }
143}
144
145#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
147#[repr(C, packed)]
148#[doc(hidden)]
149pub struct DmapFixedHeader {
150 pub version: BigEndian<u16>,
151 pub num_tables: BigEndian<u16>,
152}
153
154#[allow(clippy::absurd_extreme_comparisons)]
155const _: () = assert!(std::mem::size_of::<DmapFixedHeader>() <= Dmap::MIN_SIZE);
156
157#[derive(Clone)]
159pub struct Dmap<'a> {
160 data: TableDataRef<'a, DmapFixedHeader>,
161}
162
163#[allow(clippy::needless_lifetimes)]
164impl<'a> Dmap<'a> {
165 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
166 basic_table_impls!(impl_the_methods);
167
168 pub fn version(&self) -> u16 {
170 self.data.header().version.get()
171 }
172
173 pub fn num_tables(&self) -> u16 {
175 self.data.header().num_tables.get()
176 }
177
178 pub fn encoding_records(&self) -> &'a [EncodingRecord] {
179 let range = self.encoding_records_byte_range();
180 self.offset_data()
181 .read_array(range)
182 .ok()
183 .unwrap_or_default()
184 }
185
186 pub fn version_byte_range(&self) -> Range<usize> {
187 let start = 0;
188 let end = start + u16::RAW_BYTE_LEN;
189 start..end
190 }
191
192 pub fn num_tables_byte_range(&self) -> Range<usize> {
193 let start = self.version_byte_range().end;
194 let end = start + u16::RAW_BYTE_LEN;
195 start..end
196 }
197
198 pub fn encoding_records_byte_range(&self) -> Range<usize> {
199 let num_tables = self.num_tables();
200 let start = self.num_tables_byte_range().end;
201 let end =
202 start + (transforms::to_usize(num_tables)).saturating_mul(EncodingRecord::RAW_BYTE_LEN);
203 start..end
204 }
205}
206
207const _: () = assert!(FontData::default_data_long_enough(Dmap::MIN_SIZE));
208
209impl Default for Dmap<'_> {
210 fn default() -> Self {
211 Self {
212 data: TableDataRef::new(FontData::default_table_data().as_bytes())
213 .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
214 }
215 }
216}
217
218#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
220#[repr(C)]
221#[repr(packed)]
222pub struct EncodingRecord {
223 pub platform_id: BigEndian<PlatformId>,
225 pub encoding_id: BigEndian<u16>,
227 pub subtable_offset: BigEndian<Offset32>,
230}
231
232impl EncodingRecord {
233 pub fn platform_id(&self) -> PlatformId {
235 self.platform_id.get()
236 }
237
238 pub fn encoding_id(&self) -> u16 {
240 self.encoding_id.get()
241 }
242
243 pub fn subtable_offset(&self) -> Offset32 {
246 self.subtable_offset.get()
247 }
248
249 pub fn subtable<'a>(&self, data: FontData<'a>) -> Result<CmapSubtable<'a>, ReadError> {
255 self.subtable_offset().resolve(data)
256 }
257}
258
259impl FixedSize for EncodingRecord {
260 const RAW_BYTE_LEN: usize =
261 PlatformId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN;
262}
263
264#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
266#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
267#[repr(u16)]
268#[allow(clippy::manual_non_exhaustive)]
269pub enum PlatformId {
270 #[default]
271 Unicode = 0,
272 Macintosh = 1,
273 ISO = 2,
274 Windows = 3,
275 Custom = 4,
276 #[doc(hidden)]
277 Unknown,
279}
280
281impl PlatformId {
282 pub fn new(raw: u16) -> Self {
286 match raw {
287 0 => Self::Unicode,
288 1 => Self::Macintosh,
289 2 => Self::ISO,
290 3 => Self::Windows,
291 4 => Self::Custom,
292 _ => Self::Unknown,
293 }
294 }
295}
296
297impl font_types::Scalar for PlatformId {
298 type Raw = <u16 as font_types::Scalar>::Raw;
299 fn to_raw(self) -> Self::Raw {
300 (self as u16).to_raw()
301 }
302 fn from_raw(raw: Self::Raw) -> Self {
303 let t = <u16>::from_raw(raw);
304 Self::new(t)
305 }
306}
307
308#[derive(Clone)]
310pub enum CmapSubtable<'a> {
311 Format0(Cmap0<'a>),
312 Format2(Cmap2<'a>),
313 Format4(Cmap4<'a>),
314 Format6(Cmap6<'a>),
315 Format8(Cmap8<'a>),
316 Format10(Cmap10<'a>),
317 Format12(Cmap12<'a>),
318 Format13(Cmap13<'a>),
319 Format14(Cmap14<'a>),
320 Format15(Cmap15<'a>),
321}
322
323impl Default for CmapSubtable<'_> {
324 fn default() -> Self {
325 Self::Format0(Default::default())
326 }
327}
328
329impl<'a> CmapSubtable<'a> {
330 pub fn offset_data(&self) -> FontData<'a> {
332 match self {
333 Self::Format0(item) => item.offset_data(),
334 Self::Format2(item) => item.offset_data(),
335 Self::Format4(item) => item.offset_data(),
336 Self::Format6(item) => item.offset_data(),
337 Self::Format8(item) => item.offset_data(),
338 Self::Format10(item) => item.offset_data(),
339 Self::Format12(item) => item.offset_data(),
340 Self::Format13(item) => item.offset_data(),
341 Self::Format14(item) => item.offset_data(),
342 Self::Format15(item) => item.offset_data(),
343 }
344 }
345
346 pub fn format(&self) -> u16 {
348 match self {
349 Self::Format0(item) => item.format(),
350 Self::Format2(item) => item.format(),
351 Self::Format4(item) => item.format(),
352 Self::Format6(item) => item.format(),
353 Self::Format8(item) => item.format(),
354 Self::Format10(item) => item.format(),
355 Self::Format12(item) => item.format(),
356 Self::Format13(item) => item.format(),
357 Self::Format14(item) => item.format(),
358 Self::Format15(item) => item.format(),
359 }
360 }
361}
362
363impl ReadArgs for CmapSubtable<'_> {
364 type Args = ();
365}
366
367impl<'a> FontRead<'a> for CmapSubtable<'a> {
368 #[inline]
369 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
370 let format: u16 = data.read_at(0usize)?;
371 match format {
372 Cmap0::FORMAT => Ok(Self::Format0(FontRead::read(data)?)),
373 Cmap2::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
374 Cmap4::FORMAT => Ok(Self::Format4(FontRead::read(data)?)),
375 Cmap6::FORMAT => Ok(Self::Format6(FontRead::read(data)?)),
376 Cmap8::FORMAT => Ok(Self::Format8(FontRead::read(data)?)),
377 Cmap10::FORMAT => Ok(Self::Format10(FontRead::read(data)?)),
378 Cmap12::FORMAT => Ok(Self::Format12(FontRead::read(data)?)),
379 Cmap13::FORMAT => Ok(Self::Format13(FontRead::read(data)?)),
380 Cmap14::FORMAT => Ok(Self::Format14(FontRead::read(data)?)),
381 Cmap15::FORMAT => Ok(Self::Format15(FontRead::read(data)?)),
382 other => Err(ReadError::InvalidFormat(other.into())),
383 }
384 }
385}
386
387impl<'a> MinByteRange<'a> for CmapSubtable<'a> {
388 fn min_byte_range(&self) -> Range<usize> {
389 match self {
390 Self::Format0(item) => item.min_byte_range(),
391 Self::Format2(item) => item.min_byte_range(),
392 Self::Format4(item) => item.min_byte_range(),
393 Self::Format6(item) => item.min_byte_range(),
394 Self::Format8(item) => item.min_byte_range(),
395 Self::Format10(item) => item.min_byte_range(),
396 Self::Format12(item) => item.min_byte_range(),
397 Self::Format13(item) => item.min_byte_range(),
398 Self::Format14(item) => item.min_byte_range(),
399 Self::Format15(item) => item.min_byte_range(),
400 }
401 }
402 fn min_table_bytes(&self) -> &'a [u8] {
403 match self {
404 Self::Format0(item) => item.min_table_bytes(),
405 Self::Format2(item) => item.min_table_bytes(),
406 Self::Format4(item) => item.min_table_bytes(),
407 Self::Format6(item) => item.min_table_bytes(),
408 Self::Format8(item) => item.min_table_bytes(),
409 Self::Format10(item) => item.min_table_bytes(),
410 Self::Format12(item) => item.min_table_bytes(),
411 Self::Format13(item) => item.min_table_bytes(),
412 Self::Format14(item) => item.min_table_bytes(),
413 Self::Format15(item) => item.min_table_bytes(),
414 }
415 }
416}
417
418impl Format<u16> for Cmap0<'_> {
419 const FORMAT: u16 = 0;
420}
421
422impl<'a> MinByteRange<'a> for Cmap0<'a> {
423 fn min_byte_range(&self) -> Range<usize> {
424 0..self.glyph_id_array_byte_range().end
425 }
426 fn min_table_bytes(&self) -> &'a [u8] {
427 let range = self.min_byte_range();
428 self.offset_data().as_bytes().get(range).unwrap_or_default()
429 }
430}
431
432impl ReadArgs for Cmap0<'_> {
433 type Args = ();
434}
435
436impl<'a> FontRead<'a> for Cmap0<'a> {
437 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
438 #[allow(clippy::absurd_extreme_comparisons)]
439 if data.len() < Self::MIN_SIZE {
440 return Err(ReadError::OutOfBounds);
441 }
442 let Some(data) = TableDataRef::new(data.as_bytes()) else {
443 return Err(ReadError::OutOfBounds);
444 };
445 Ok(Self { data })
446 }
447}
448
449#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
451#[repr(C, packed)]
452#[doc(hidden)]
453pub struct Cmap0FixedHeader {
454 pub format: BigEndian<u16>,
455 pub length: BigEndian<u16>,
456 pub language: BigEndian<u16>,
457}
458
459#[allow(clippy::absurd_extreme_comparisons)]
460const _: () = assert!(std::mem::size_of::<Cmap0FixedHeader>() <= Cmap0::MIN_SIZE);
461
462#[derive(Clone)]
464pub struct Cmap0<'a> {
465 data: TableDataRef<'a, Cmap0FixedHeader>,
466}
467
468#[allow(clippy::needless_lifetimes)]
469impl<'a> Cmap0<'a> {
470 pub const MIN_SIZE: usize =
471 (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u8::RAW_BYTE_LEN * 256_usize);
472 basic_table_impls!(impl_the_methods);
473
474 pub fn format(&self) -> u16 {
476 self.data.header().format.get()
477 }
478
479 pub fn length(&self) -> u16 {
481 self.data.header().length.get()
482 }
483
484 pub fn language(&self) -> u16 {
487 self.data.header().language.get()
488 }
489
490 pub fn glyph_id_array(&self) -> &'a [u8] {
492 let range = self.glyph_id_array_byte_range();
493 self.offset_data()
494 .read_array(range)
495 .ok()
496 .unwrap_or_default()
497 }
498
499 pub fn format_byte_range(&self) -> Range<usize> {
500 let start = 0;
501 let end = start + u16::RAW_BYTE_LEN;
502 start..end
503 }
504
505 pub fn length_byte_range(&self) -> Range<usize> {
506 let start = self.format_byte_range().end;
507 let end = start + u16::RAW_BYTE_LEN;
508 start..end
509 }
510
511 pub fn language_byte_range(&self) -> Range<usize> {
512 let start = self.length_byte_range().end;
513 let end = start + u16::RAW_BYTE_LEN;
514 start..end
515 }
516
517 pub fn glyph_id_array_byte_range(&self) -> Range<usize> {
518 let start = self.language_byte_range().end;
519 let end = start + (256_usize).saturating_mul(u8::RAW_BYTE_LEN);
520 start..end
521 }
522}
523
524const _: () = assert!(FontData::default_data_long_enough(Cmap0::MIN_SIZE));
525
526impl Default for Cmap0<'_> {
527 fn default() -> Self {
528 Self {
529 data: TableDataRef::new(FontData::default_table_data().as_bytes())
530 .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
531 }
532 }
533}
534
535impl Format<u16> for Cmap2<'_> {
536 const FORMAT: u16 = 2;
537}
538
539impl<'a> MinByteRange<'a> for Cmap2<'a> {
540 fn min_byte_range(&self) -> Range<usize> {
541 0..self.sub_header_keys_byte_range().end
542 }
543 fn min_table_bytes(&self) -> &'a [u8] {
544 let range = self.min_byte_range();
545 self.offset_data().as_bytes().get(range).unwrap_or_default()
546 }
547}
548
549impl ReadArgs for Cmap2<'_> {
550 type Args = ();
551}
552
553impl<'a> FontRead<'a> for Cmap2<'a> {
554 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
555 #[allow(clippy::absurd_extreme_comparisons)]
556 if data.len() < Self::MIN_SIZE {
557 return Err(ReadError::OutOfBounds);
558 }
559 let Some(data) = TableDataRef::new(data.as_bytes()) else {
560 return Err(ReadError::OutOfBounds);
561 };
562 Ok(Self { data })
563 }
564}
565
566#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
568#[repr(C, packed)]
569#[doc(hidden)]
570pub struct Cmap2FixedHeader {
571 pub format: BigEndian<u16>,
572 pub length: BigEndian<u16>,
573 pub language: BigEndian<u16>,
574}
575
576#[allow(clippy::absurd_extreme_comparisons)]
577const _: () = assert!(std::mem::size_of::<Cmap2FixedHeader>() <= Cmap2::MIN_SIZE);
578
579#[derive(Clone)]
581pub struct Cmap2<'a> {
582 data: TableDataRef<'a, Cmap2FixedHeader>,
583}
584
585#[allow(clippy::needless_lifetimes)]
586impl<'a> Cmap2<'a> {
587 pub const MIN_SIZE: usize =
588 (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN * 256_usize);
589 basic_table_impls!(impl_the_methods);
590
591 pub fn format(&self) -> u16 {
593 self.data.header().format.get()
594 }
595
596 pub fn length(&self) -> u16 {
598 self.data.header().length.get()
599 }
600
601 pub fn language(&self) -> u16 {
604 self.data.header().language.get()
605 }
606
607 pub fn sub_header_keys(&self) -> &'a [BigEndian<u16>] {
610 let range = self.sub_header_keys_byte_range();
611 self.offset_data()
612 .read_array(range)
613 .ok()
614 .unwrap_or_default()
615 }
616
617 pub fn format_byte_range(&self) -> Range<usize> {
618 let start = 0;
619 let end = start + u16::RAW_BYTE_LEN;
620 start..end
621 }
622
623 pub fn length_byte_range(&self) -> Range<usize> {
624 let start = self.format_byte_range().end;
625 let end = start + u16::RAW_BYTE_LEN;
626 start..end
627 }
628
629 pub fn language_byte_range(&self) -> Range<usize> {
630 let start = self.length_byte_range().end;
631 let end = start + u16::RAW_BYTE_LEN;
632 start..end
633 }
634
635 pub fn sub_header_keys_byte_range(&self) -> Range<usize> {
636 let start = self.language_byte_range().end;
637 let end = start + (256_usize).saturating_mul(u16::RAW_BYTE_LEN);
638 start..end
639 }
640}
641
642#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
644#[repr(C)]
645#[repr(packed)]
646pub struct SubHeader {
647 pub first_code: BigEndian<u16>,
649 pub entry_count: BigEndian<u16>,
651 pub id_delta: BigEndian<i16>,
653 pub id_range_offset: BigEndian<u16>,
655}
656
657impl SubHeader {
658 pub fn first_code(&self) -> u16 {
660 self.first_code.get()
661 }
662
663 pub fn entry_count(&self) -> u16 {
665 self.entry_count.get()
666 }
667
668 pub fn id_delta(&self) -> i16 {
670 self.id_delta.get()
671 }
672
673 pub fn id_range_offset(&self) -> u16 {
675 self.id_range_offset.get()
676 }
677}
678
679impl FixedSize for SubHeader {
680 const RAW_BYTE_LEN: usize =
681 u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + i16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
682}
683
684impl Format<u16> for Cmap4<'_> {
685 const FORMAT: u16 = 4;
686}
687
688impl<'a> MinByteRange<'a> for Cmap4<'a> {
689 fn min_byte_range(&self) -> Range<usize> {
690 0..self.glyph_id_array_byte_range().end
691 }
692 fn min_table_bytes(&self) -> &'a [u8] {
693 let range = self.min_byte_range();
694 self.offset_data().as_bytes().get(range).unwrap_or_default()
695 }
696}
697
698impl ReadArgs for Cmap4<'_> {
699 type Args = ();
700}
701
702impl<'a> FontRead<'a> for Cmap4<'a> {
703 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
704 #[allow(clippy::absurd_extreme_comparisons)]
705 if data.len() < Self::MIN_SIZE {
706 return Err(ReadError::OutOfBounds);
707 }
708 let Some(data) = TableDataRef::new(data.as_bytes()) else {
709 return Err(ReadError::OutOfBounds);
710 };
711 Ok(Self { data })
712 }
713}
714
715#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
717#[repr(C, packed)]
718#[doc(hidden)]
719pub struct Cmap4FixedHeader {
720 pub format: BigEndian<u16>,
721 pub length: BigEndian<u16>,
722 pub language: BigEndian<u16>,
723 pub seg_count_x2: BigEndian<u16>,
724 pub search_range: BigEndian<u16>,
725 pub entry_selector: BigEndian<u16>,
726 pub range_shift: BigEndian<u16>,
727}
728
729#[allow(clippy::absurd_extreme_comparisons)]
730const _: () = assert!(std::mem::size_of::<Cmap4FixedHeader>() <= Cmap4::MIN_SIZE);
731
732#[derive(Clone)]
734pub struct Cmap4<'a> {
735 data: TableDataRef<'a, Cmap4FixedHeader>,
736}
737
738#[allow(clippy::needless_lifetimes)]
739impl<'a> Cmap4<'a> {
740 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN
741 + u16::RAW_BYTE_LEN
742 + u16::RAW_BYTE_LEN
743 + u16::RAW_BYTE_LEN
744 + u16::RAW_BYTE_LEN
745 + u16::RAW_BYTE_LEN
746 + u16::RAW_BYTE_LEN
747 + u16::RAW_BYTE_LEN);
748 basic_table_impls!(impl_the_methods);
749
750 pub fn format(&self) -> u16 {
752 self.data.header().format.get()
753 }
754
755 pub fn length(&self) -> u16 {
757 self.data.header().length.get()
758 }
759
760 pub fn language(&self) -> u16 {
763 self.data.header().language.get()
764 }
765
766 pub fn seg_count_x2(&self) -> u16 {
768 self.data.header().seg_count_x2.get()
769 }
770
771 pub fn search_range(&self) -> u16 {
775 self.data.header().search_range.get()
776 }
777
778 pub fn entry_selector(&self) -> u16 {
781 self.data.header().entry_selector.get()
782 }
783
784 pub fn range_shift(&self) -> u16 {
787 self.data.header().range_shift.get()
788 }
789
790 pub fn end_code(&self) -> &'a [BigEndian<u16>] {
792 let range = self.end_code_byte_range();
793 self.offset_data()
794 .read_array(range)
795 .ok()
796 .unwrap_or_default()
797 }
798
799 pub fn start_code(&self) -> &'a [BigEndian<u16>] {
801 let range = self.start_code_byte_range();
802 self.offset_data()
803 .read_array(range)
804 .ok()
805 .unwrap_or_default()
806 }
807
808 pub fn id_delta(&self) -> &'a [BigEndian<i16>] {
810 let range = self.id_delta_byte_range();
811 self.offset_data()
812 .read_array(range)
813 .ok()
814 .unwrap_or_default()
815 }
816
817 pub fn id_range_offsets(&self) -> &'a [BigEndian<u16>] {
819 let range = self.id_range_offsets_byte_range();
820 self.offset_data()
821 .read_array(range)
822 .ok()
823 .unwrap_or_default()
824 }
825
826 pub fn glyph_id_array(&self) -> &'a [BigEndian<u16>] {
828 let range = self.glyph_id_array_byte_range();
829 self.offset_data()
830 .read_array(range)
831 .ok()
832 .unwrap_or_default()
833 }
834
835 pub fn format_byte_range(&self) -> Range<usize> {
836 let start = 0;
837 let end = start + u16::RAW_BYTE_LEN;
838 start..end
839 }
840
841 pub fn length_byte_range(&self) -> Range<usize> {
842 let start = self.format_byte_range().end;
843 let end = start + u16::RAW_BYTE_LEN;
844 start..end
845 }
846
847 pub fn language_byte_range(&self) -> Range<usize> {
848 let start = self.length_byte_range().end;
849 let end = start + u16::RAW_BYTE_LEN;
850 start..end
851 }
852
853 pub fn seg_count_x2_byte_range(&self) -> Range<usize> {
854 let start = self.language_byte_range().end;
855 let end = start + u16::RAW_BYTE_LEN;
856 start..end
857 }
858
859 pub fn search_range_byte_range(&self) -> Range<usize> {
860 let start = self.seg_count_x2_byte_range().end;
861 let end = start + u16::RAW_BYTE_LEN;
862 start..end
863 }
864
865 pub fn entry_selector_byte_range(&self) -> Range<usize> {
866 let start = self.search_range_byte_range().end;
867 let end = start + u16::RAW_BYTE_LEN;
868 start..end
869 }
870
871 pub fn range_shift_byte_range(&self) -> Range<usize> {
872 let start = self.entry_selector_byte_range().end;
873 let end = start + u16::RAW_BYTE_LEN;
874 start..end
875 }
876
877 pub fn end_code_byte_range(&self) -> Range<usize> {
878 let seg_count_x2 = self.seg_count_x2();
879 let start = self.range_shift_byte_range().end;
880 let end = start + (transforms::half(seg_count_x2)).saturating_mul(u16::RAW_BYTE_LEN);
881 start..end
882 }
883
884 pub fn reserved_pad_byte_range(&self) -> Range<usize> {
885 let start = self.end_code_byte_range().end;
886 let end = start + u16::RAW_BYTE_LEN;
887 start..end
888 }
889
890 pub fn start_code_byte_range(&self) -> Range<usize> {
891 let seg_count_x2 = self.seg_count_x2();
892 let start = self.reserved_pad_byte_range().end;
893 let end = start + (transforms::half(seg_count_x2)).saturating_mul(u16::RAW_BYTE_LEN);
894 start..end
895 }
896
897 pub fn id_delta_byte_range(&self) -> Range<usize> {
898 let seg_count_x2 = self.seg_count_x2();
899 let start = self.start_code_byte_range().end;
900 let end = start + (transforms::half(seg_count_x2)).saturating_mul(i16::RAW_BYTE_LEN);
901 start..end
902 }
903
904 pub fn id_range_offsets_byte_range(&self) -> Range<usize> {
905 let seg_count_x2 = self.seg_count_x2();
906 let start = self.id_delta_byte_range().end;
907 let end = start + (transforms::half(seg_count_x2)).saturating_mul(u16::RAW_BYTE_LEN);
908 start..end
909 }
910
911 pub fn glyph_id_array_byte_range(&self) -> Range<usize> {
912 let start = self.id_range_offsets_byte_range().end;
913 let end = start
914 + self.offset_data().len().saturating_sub(start) / u16::RAW_BYTE_LEN
915 * u16::RAW_BYTE_LEN;
916 start..end
917 }
918}
919
920impl Format<u16> for Cmap6<'_> {
921 const FORMAT: u16 = 6;
922}
923
924impl<'a> MinByteRange<'a> for Cmap6<'a> {
925 fn min_byte_range(&self) -> Range<usize> {
926 0..self.glyph_id_array_byte_range().end
927 }
928 fn min_table_bytes(&self) -> &'a [u8] {
929 let range = self.min_byte_range();
930 self.offset_data().as_bytes().get(range).unwrap_or_default()
931 }
932}
933
934impl ReadArgs for Cmap6<'_> {
935 type Args = ();
936}
937
938impl<'a> FontRead<'a> for Cmap6<'a> {
939 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
940 #[allow(clippy::absurd_extreme_comparisons)]
941 if data.len() < Self::MIN_SIZE {
942 return Err(ReadError::OutOfBounds);
943 }
944 let Some(data) = TableDataRef::new(data.as_bytes()) else {
945 return Err(ReadError::OutOfBounds);
946 };
947 Ok(Self { data })
948 }
949}
950
951#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
953#[repr(C, packed)]
954#[doc(hidden)]
955pub struct Cmap6FixedHeader {
956 pub format: BigEndian<u16>,
957 pub length: BigEndian<u16>,
958 pub language: BigEndian<u16>,
959 pub first_code: BigEndian<u16>,
960 pub entry_count: BigEndian<u16>,
961}
962
963#[allow(clippy::absurd_extreme_comparisons)]
964const _: () = assert!(std::mem::size_of::<Cmap6FixedHeader>() <= Cmap6::MIN_SIZE);
965
966#[derive(Clone)]
968pub struct Cmap6<'a> {
969 data: TableDataRef<'a, Cmap6FixedHeader>,
970}
971
972#[allow(clippy::needless_lifetimes)]
973impl<'a> Cmap6<'a> {
974 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN
975 + u16::RAW_BYTE_LEN
976 + u16::RAW_BYTE_LEN
977 + u16::RAW_BYTE_LEN
978 + u16::RAW_BYTE_LEN);
979 basic_table_impls!(impl_the_methods);
980
981 pub fn format(&self) -> u16 {
983 self.data.header().format.get()
984 }
985
986 pub fn length(&self) -> u16 {
988 self.data.header().length.get()
989 }
990
991 pub fn language(&self) -> u16 {
994 self.data.header().language.get()
995 }
996
997 pub fn first_code(&self) -> u16 {
999 self.data.header().first_code.get()
1000 }
1001
1002 pub fn entry_count(&self) -> u16 {
1004 self.data.header().entry_count.get()
1005 }
1006
1007 pub fn glyph_id_array(&self) -> &'a [BigEndian<u16>] {
1009 let range = self.glyph_id_array_byte_range();
1010 self.offset_data()
1011 .read_array(range)
1012 .ok()
1013 .unwrap_or_default()
1014 }
1015
1016 pub fn format_byte_range(&self) -> Range<usize> {
1017 let start = 0;
1018 let end = start + u16::RAW_BYTE_LEN;
1019 start..end
1020 }
1021
1022 pub fn length_byte_range(&self) -> Range<usize> {
1023 let start = self.format_byte_range().end;
1024 let end = start + u16::RAW_BYTE_LEN;
1025 start..end
1026 }
1027
1028 pub fn language_byte_range(&self) -> Range<usize> {
1029 let start = self.length_byte_range().end;
1030 let end = start + u16::RAW_BYTE_LEN;
1031 start..end
1032 }
1033
1034 pub fn first_code_byte_range(&self) -> Range<usize> {
1035 let start = self.language_byte_range().end;
1036 let end = start + u16::RAW_BYTE_LEN;
1037 start..end
1038 }
1039
1040 pub fn entry_count_byte_range(&self) -> Range<usize> {
1041 let start = self.first_code_byte_range().end;
1042 let end = start + u16::RAW_BYTE_LEN;
1043 start..end
1044 }
1045
1046 pub fn glyph_id_array_byte_range(&self) -> Range<usize> {
1047 let entry_count = self.entry_count();
1048 let start = self.entry_count_byte_range().end;
1049 let end = start + (transforms::to_usize(entry_count)).saturating_mul(u16::RAW_BYTE_LEN);
1050 start..end
1051 }
1052}
1053
1054impl Format<u16> for Cmap8<'_> {
1055 const FORMAT: u16 = 8;
1056}
1057
1058impl<'a> MinByteRange<'a> for Cmap8<'a> {
1059 fn min_byte_range(&self) -> Range<usize> {
1060 0..self.groups_byte_range().end
1061 }
1062 fn min_table_bytes(&self) -> &'a [u8] {
1063 let range = self.min_byte_range();
1064 self.offset_data().as_bytes().get(range).unwrap_or_default()
1065 }
1066}
1067
1068impl ReadArgs for Cmap8<'_> {
1069 type Args = ();
1070}
1071
1072impl<'a> FontRead<'a> for Cmap8<'a> {
1073 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1074 #[allow(clippy::absurd_extreme_comparisons)]
1075 if data.len() < Self::MIN_SIZE {
1076 return Err(ReadError::OutOfBounds);
1077 }
1078 let Some(data) = TableDataRef::new(data.as_bytes()) else {
1079 return Err(ReadError::OutOfBounds);
1080 };
1081 Ok(Self { data })
1082 }
1083}
1084
1085#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
1087#[repr(C, packed)]
1088#[doc(hidden)]
1089pub struct Cmap8FixedHeader {
1090 pub format: BigEndian<u16>,
1091 pub reserved: BigEndian<u16>,
1092 pub length: BigEndian<u32>,
1093 pub language: BigEndian<u32>,
1094}
1095
1096#[allow(clippy::absurd_extreme_comparisons)]
1097const _: () = assert!(std::mem::size_of::<Cmap8FixedHeader>() <= Cmap8::MIN_SIZE);
1098
1099#[derive(Clone)]
1101pub struct Cmap8<'a> {
1102 data: TableDataRef<'a, Cmap8FixedHeader>,
1103}
1104
1105#[allow(clippy::needless_lifetimes)]
1106impl<'a> Cmap8<'a> {
1107 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN
1108 + u16::RAW_BYTE_LEN
1109 + u32::RAW_BYTE_LEN
1110 + u32::RAW_BYTE_LEN
1111 + u8::RAW_BYTE_LEN * 8192_usize
1112 + u32::RAW_BYTE_LEN);
1113 basic_table_impls!(impl_the_methods);
1114
1115 pub fn format(&self) -> u16 {
1117 self.data.header().format.get()
1118 }
1119
1120 pub fn length(&self) -> u32 {
1122 self.data.header().length.get()
1123 }
1124
1125 pub fn language(&self) -> u32 {
1128 self.data.header().language.get()
1129 }
1130
1131 pub fn is32(&self) -> &'a [u8] {
1135 let range = self.is32_byte_range();
1136 self.offset_data()
1137 .read_array(range)
1138 .ok()
1139 .unwrap_or_default()
1140 }
1141
1142 pub fn num_groups(&self) -> u32 {
1144 let range = self.num_groups_byte_range();
1145 self.offset_data()
1146 .read_at(range.start)
1147 .ok()
1148 .unwrap_or_default()
1149 }
1150
1151 pub fn groups(&self) -> &'a [SequentialMapGroup] {
1153 let range = self.groups_byte_range();
1154 self.offset_data()
1155 .read_array(range)
1156 .ok()
1157 .unwrap_or_default()
1158 }
1159
1160 pub fn format_byte_range(&self) -> Range<usize> {
1161 let start = 0;
1162 let end = start + u16::RAW_BYTE_LEN;
1163 start..end
1164 }
1165
1166 pub fn reserved_byte_range(&self) -> Range<usize> {
1167 let start = self.format_byte_range().end;
1168 let end = start + u16::RAW_BYTE_LEN;
1169 start..end
1170 }
1171
1172 pub fn length_byte_range(&self) -> Range<usize> {
1173 let start = self.reserved_byte_range().end;
1174 let end = start + u32::RAW_BYTE_LEN;
1175 start..end
1176 }
1177
1178 pub fn language_byte_range(&self) -> Range<usize> {
1179 let start = self.length_byte_range().end;
1180 let end = start + u32::RAW_BYTE_LEN;
1181 start..end
1182 }
1183
1184 pub fn is32_byte_range(&self) -> Range<usize> {
1185 let start = self.language_byte_range().end;
1186 let end = start + (8192_usize).saturating_mul(u8::RAW_BYTE_LEN);
1187 start..end
1188 }
1189
1190 pub fn num_groups_byte_range(&self) -> Range<usize> {
1191 let start = self.is32_byte_range().end;
1192 let end = start + u32::RAW_BYTE_LEN;
1193 start..end
1194 }
1195
1196 pub fn groups_byte_range(&self) -> Range<usize> {
1197 let num_groups = self.num_groups();
1198 let start = self.num_groups_byte_range().end;
1199 let end = start
1200 + (transforms::to_usize(num_groups)).saturating_mul(SequentialMapGroup::RAW_BYTE_LEN);
1201 start..end
1202 }
1203}
1204
1205#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
1207#[repr(C)]
1208#[repr(packed)]
1209pub struct SequentialMapGroup {
1210 pub start_char_code: BigEndian<u32>,
1215 pub end_char_code: BigEndian<u32>,
1218 pub start_glyph_id: BigEndian<u32>,
1220}
1221
1222impl SequentialMapGroup {
1223 pub fn start_char_code(&self) -> u32 {
1228 self.start_char_code.get()
1229 }
1230
1231 pub fn end_char_code(&self) -> u32 {
1234 self.end_char_code.get()
1235 }
1236
1237 pub fn start_glyph_id(&self) -> u32 {
1239 self.start_glyph_id.get()
1240 }
1241}
1242
1243impl FixedSize for SequentialMapGroup {
1244 const RAW_BYTE_LEN: usize = u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN;
1245}
1246
1247impl Format<u16> for Cmap10<'_> {
1248 const FORMAT: u16 = 10;
1249}
1250
1251impl<'a> MinByteRange<'a> for Cmap10<'a> {
1252 fn min_byte_range(&self) -> Range<usize> {
1253 0..self.glyph_id_array_byte_range().end
1254 }
1255 fn min_table_bytes(&self) -> &'a [u8] {
1256 let range = self.min_byte_range();
1257 self.offset_data().as_bytes().get(range).unwrap_or_default()
1258 }
1259}
1260
1261impl ReadArgs for Cmap10<'_> {
1262 type Args = ();
1263}
1264
1265impl<'a> FontRead<'a> for Cmap10<'a> {
1266 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1267 #[allow(clippy::absurd_extreme_comparisons)]
1268 if data.len() < Self::MIN_SIZE {
1269 return Err(ReadError::OutOfBounds);
1270 }
1271 let Some(data) = TableDataRef::new(data.as_bytes()) else {
1272 return Err(ReadError::OutOfBounds);
1273 };
1274 Ok(Self { data })
1275 }
1276}
1277
1278#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
1280#[repr(C, packed)]
1281#[doc(hidden)]
1282pub struct Cmap10FixedHeader {
1283 pub format: BigEndian<u16>,
1284 pub reserved: BigEndian<u16>,
1285 pub length: BigEndian<u32>,
1286 pub language: BigEndian<u32>,
1287 pub start_char_code: BigEndian<u32>,
1288 pub num_chars: BigEndian<u32>,
1289}
1290
1291#[allow(clippy::absurd_extreme_comparisons)]
1292const _: () = assert!(std::mem::size_of::<Cmap10FixedHeader>() <= Cmap10::MIN_SIZE);
1293
1294#[derive(Clone)]
1296pub struct Cmap10<'a> {
1297 data: TableDataRef<'a, Cmap10FixedHeader>,
1298}
1299
1300#[allow(clippy::needless_lifetimes)]
1301impl<'a> Cmap10<'a> {
1302 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN
1303 + u16::RAW_BYTE_LEN
1304 + u32::RAW_BYTE_LEN
1305 + u32::RAW_BYTE_LEN
1306 + u32::RAW_BYTE_LEN
1307 + u32::RAW_BYTE_LEN);
1308 basic_table_impls!(impl_the_methods);
1309
1310 pub fn format(&self) -> u16 {
1312 self.data.header().format.get()
1313 }
1314
1315 pub fn length(&self) -> u32 {
1317 self.data.header().length.get()
1318 }
1319
1320 pub fn language(&self) -> u32 {
1323 self.data.header().language.get()
1324 }
1325
1326 pub fn start_char_code(&self) -> u32 {
1328 self.data.header().start_char_code.get()
1329 }
1330
1331 pub fn num_chars(&self) -> u32 {
1333 self.data.header().num_chars.get()
1334 }
1335
1336 pub fn glyph_id_array(&self) -> &'a [BigEndian<u16>] {
1338 let range = self.glyph_id_array_byte_range();
1339 self.offset_data()
1340 .read_array(range)
1341 .ok()
1342 .unwrap_or_default()
1343 }
1344
1345 pub fn format_byte_range(&self) -> Range<usize> {
1346 let start = 0;
1347 let end = start + u16::RAW_BYTE_LEN;
1348 start..end
1349 }
1350
1351 pub fn reserved_byte_range(&self) -> Range<usize> {
1352 let start = self.format_byte_range().end;
1353 let end = start + u16::RAW_BYTE_LEN;
1354 start..end
1355 }
1356
1357 pub fn length_byte_range(&self) -> Range<usize> {
1358 let start = self.reserved_byte_range().end;
1359 let end = start + u32::RAW_BYTE_LEN;
1360 start..end
1361 }
1362
1363 pub fn language_byte_range(&self) -> Range<usize> {
1364 let start = self.length_byte_range().end;
1365 let end = start + u32::RAW_BYTE_LEN;
1366 start..end
1367 }
1368
1369 pub fn start_char_code_byte_range(&self) -> Range<usize> {
1370 let start = self.language_byte_range().end;
1371 let end = start + u32::RAW_BYTE_LEN;
1372 start..end
1373 }
1374
1375 pub fn num_chars_byte_range(&self) -> Range<usize> {
1376 let start = self.start_char_code_byte_range().end;
1377 let end = start + u32::RAW_BYTE_LEN;
1378 start..end
1379 }
1380
1381 pub fn glyph_id_array_byte_range(&self) -> Range<usize> {
1382 let num_chars = self.num_chars();
1383 let start = self.num_chars_byte_range().end;
1384 let end = start + (transforms::to_usize(num_chars)).saturating_mul(u16::RAW_BYTE_LEN);
1385 start..end
1386 }
1387}
1388
1389impl Format<u16> for Cmap12<'_> {
1390 const FORMAT: u16 = 12;
1391}
1392
1393impl<'a> MinByteRange<'a> for Cmap12<'a> {
1394 fn min_byte_range(&self) -> Range<usize> {
1395 0..self.groups_byte_range().end
1396 }
1397 fn min_table_bytes(&self) -> &'a [u8] {
1398 let range = self.min_byte_range();
1399 self.offset_data().as_bytes().get(range).unwrap_or_default()
1400 }
1401}
1402
1403impl ReadArgs for Cmap12<'_> {
1404 type Args = ();
1405}
1406
1407impl<'a> FontRead<'a> for Cmap12<'a> {
1408 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1409 #[allow(clippy::absurd_extreme_comparisons)]
1410 if data.len() < Self::MIN_SIZE {
1411 return Err(ReadError::OutOfBounds);
1412 }
1413 let Some(data) = TableDataRef::new(data.as_bytes()) else {
1414 return Err(ReadError::OutOfBounds);
1415 };
1416 Ok(Self { data })
1417 }
1418}
1419
1420#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
1422#[repr(C, packed)]
1423#[doc(hidden)]
1424pub struct Cmap12FixedHeader {
1425 pub format: BigEndian<u16>,
1426 pub reserved: BigEndian<u16>,
1427 pub length: BigEndian<u32>,
1428 pub language: BigEndian<u32>,
1429 pub num_groups: BigEndian<u32>,
1430}
1431
1432#[allow(clippy::absurd_extreme_comparisons)]
1433const _: () = assert!(std::mem::size_of::<Cmap12FixedHeader>() <= Cmap12::MIN_SIZE);
1434
1435#[derive(Clone)]
1437pub struct Cmap12<'a> {
1438 data: TableDataRef<'a, Cmap12FixedHeader>,
1439}
1440
1441#[allow(clippy::needless_lifetimes)]
1442impl<'a> Cmap12<'a> {
1443 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN
1444 + u16::RAW_BYTE_LEN
1445 + u32::RAW_BYTE_LEN
1446 + u32::RAW_BYTE_LEN
1447 + u32::RAW_BYTE_LEN);
1448 basic_table_impls!(impl_the_methods);
1449
1450 pub fn format(&self) -> u16 {
1452 self.data.header().format.get()
1453 }
1454
1455 pub fn length(&self) -> u32 {
1457 self.data.header().length.get()
1458 }
1459
1460 pub fn language(&self) -> u32 {
1463 self.data.header().language.get()
1464 }
1465
1466 pub fn num_groups(&self) -> u32 {
1468 self.data.header().num_groups.get()
1469 }
1470
1471 pub fn groups(&self) -> &'a [SequentialMapGroup] {
1473 let range = self.groups_byte_range();
1474 self.offset_data()
1475 .read_array(range)
1476 .ok()
1477 .unwrap_or_default()
1478 }
1479
1480 pub fn format_byte_range(&self) -> Range<usize> {
1481 let start = 0;
1482 let end = start + u16::RAW_BYTE_LEN;
1483 start..end
1484 }
1485
1486 pub fn reserved_byte_range(&self) -> Range<usize> {
1487 let start = self.format_byte_range().end;
1488 let end = start + u16::RAW_BYTE_LEN;
1489 start..end
1490 }
1491
1492 pub fn length_byte_range(&self) -> Range<usize> {
1493 let start = self.reserved_byte_range().end;
1494 let end = start + u32::RAW_BYTE_LEN;
1495 start..end
1496 }
1497
1498 pub fn language_byte_range(&self) -> Range<usize> {
1499 let start = self.length_byte_range().end;
1500 let end = start + u32::RAW_BYTE_LEN;
1501 start..end
1502 }
1503
1504 pub fn num_groups_byte_range(&self) -> Range<usize> {
1505 let start = self.language_byte_range().end;
1506 let end = start + u32::RAW_BYTE_LEN;
1507 start..end
1508 }
1509
1510 pub fn groups_byte_range(&self) -> Range<usize> {
1511 let num_groups = self.num_groups();
1512 let start = self.num_groups_byte_range().end;
1513 let end = start
1514 + (transforms::to_usize(num_groups)).saturating_mul(SequentialMapGroup::RAW_BYTE_LEN);
1515 start..end
1516 }
1517}
1518
1519impl Format<u16> for Cmap13<'_> {
1520 const FORMAT: u16 = 13;
1521}
1522
1523impl<'a> MinByteRange<'a> for Cmap13<'a> {
1524 fn min_byte_range(&self) -> Range<usize> {
1525 0..self.groups_byte_range().end
1526 }
1527 fn min_table_bytes(&self) -> &'a [u8] {
1528 let range = self.min_byte_range();
1529 self.offset_data().as_bytes().get(range).unwrap_or_default()
1530 }
1531}
1532
1533impl ReadArgs for Cmap13<'_> {
1534 type Args = ();
1535}
1536
1537impl<'a> FontRead<'a> for Cmap13<'a> {
1538 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1539 #[allow(clippy::absurd_extreme_comparisons)]
1540 if data.len() < Self::MIN_SIZE {
1541 return Err(ReadError::OutOfBounds);
1542 }
1543 let Some(data) = TableDataRef::new(data.as_bytes()) else {
1544 return Err(ReadError::OutOfBounds);
1545 };
1546 Ok(Self { data })
1547 }
1548}
1549
1550#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
1552#[repr(C, packed)]
1553#[doc(hidden)]
1554pub struct Cmap13FixedHeader {
1555 pub format: BigEndian<u16>,
1556 pub reserved: BigEndian<u16>,
1557 pub length: BigEndian<u32>,
1558 pub language: BigEndian<u32>,
1559 pub num_groups: BigEndian<u32>,
1560}
1561
1562#[allow(clippy::absurd_extreme_comparisons)]
1563const _: () = assert!(std::mem::size_of::<Cmap13FixedHeader>() <= Cmap13::MIN_SIZE);
1564
1565#[derive(Clone)]
1567pub struct Cmap13<'a> {
1568 data: TableDataRef<'a, Cmap13FixedHeader>,
1569}
1570
1571#[allow(clippy::needless_lifetimes)]
1572impl<'a> Cmap13<'a> {
1573 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN
1574 + u16::RAW_BYTE_LEN
1575 + u32::RAW_BYTE_LEN
1576 + u32::RAW_BYTE_LEN
1577 + u32::RAW_BYTE_LEN);
1578 basic_table_impls!(impl_the_methods);
1579
1580 pub fn format(&self) -> u16 {
1582 self.data.header().format.get()
1583 }
1584
1585 pub fn length(&self) -> u32 {
1587 self.data.header().length.get()
1588 }
1589
1590 pub fn language(&self) -> u32 {
1593 self.data.header().language.get()
1594 }
1595
1596 pub fn num_groups(&self) -> u32 {
1598 self.data.header().num_groups.get()
1599 }
1600
1601 pub fn groups(&self) -> &'a [ConstantMapGroup] {
1603 let range = self.groups_byte_range();
1604 self.offset_data()
1605 .read_array(range)
1606 .ok()
1607 .unwrap_or_default()
1608 }
1609
1610 pub fn format_byte_range(&self) -> Range<usize> {
1611 let start = 0;
1612 let end = start + u16::RAW_BYTE_LEN;
1613 start..end
1614 }
1615
1616 pub fn reserved_byte_range(&self) -> Range<usize> {
1617 let start = self.format_byte_range().end;
1618 let end = start + u16::RAW_BYTE_LEN;
1619 start..end
1620 }
1621
1622 pub fn length_byte_range(&self) -> Range<usize> {
1623 let start = self.reserved_byte_range().end;
1624 let end = start + u32::RAW_BYTE_LEN;
1625 start..end
1626 }
1627
1628 pub fn language_byte_range(&self) -> Range<usize> {
1629 let start = self.length_byte_range().end;
1630 let end = start + u32::RAW_BYTE_LEN;
1631 start..end
1632 }
1633
1634 pub fn num_groups_byte_range(&self) -> Range<usize> {
1635 let start = self.language_byte_range().end;
1636 let end = start + u32::RAW_BYTE_LEN;
1637 start..end
1638 }
1639
1640 pub fn groups_byte_range(&self) -> Range<usize> {
1641 let num_groups = self.num_groups();
1642 let start = self.num_groups_byte_range().end;
1643 let end = start
1644 + (transforms::to_usize(num_groups)).saturating_mul(ConstantMapGroup::RAW_BYTE_LEN);
1645 start..end
1646 }
1647}
1648
1649#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
1651#[repr(C)]
1652#[repr(packed)]
1653pub struct ConstantMapGroup {
1654 pub start_char_code: BigEndian<u32>,
1656 pub end_char_code: BigEndian<u32>,
1658 pub glyph_id: BigEndian<u32>,
1661}
1662
1663impl ConstantMapGroup {
1664 pub fn start_char_code(&self) -> u32 {
1666 self.start_char_code.get()
1667 }
1668
1669 pub fn end_char_code(&self) -> u32 {
1671 self.end_char_code.get()
1672 }
1673
1674 pub fn glyph_id(&self) -> u32 {
1677 self.glyph_id.get()
1678 }
1679}
1680
1681impl FixedSize for ConstantMapGroup {
1682 const RAW_BYTE_LEN: usize = u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN;
1683}
1684
1685impl Format<u16> for Cmap14<'_> {
1686 const FORMAT: u16 = 14;
1687}
1688
1689impl<'a> MinByteRange<'a> for Cmap14<'a> {
1690 fn min_byte_range(&self) -> Range<usize> {
1691 0..self.var_selector_byte_range().end
1692 }
1693 fn min_table_bytes(&self) -> &'a [u8] {
1694 let range = self.min_byte_range();
1695 self.offset_data().as_bytes().get(range).unwrap_or_default()
1696 }
1697}
1698
1699impl ReadArgs for Cmap14<'_> {
1700 type Args = ();
1701}
1702
1703impl<'a> FontRead<'a> for Cmap14<'a> {
1704 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1705 #[allow(clippy::absurd_extreme_comparisons)]
1706 if data.len() < Self::MIN_SIZE {
1707 return Err(ReadError::OutOfBounds);
1708 }
1709 let Some(data) = TableDataRef::new(data.as_bytes()) else {
1710 return Err(ReadError::OutOfBounds);
1711 };
1712 Ok(Self { data })
1713 }
1714}
1715
1716#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
1718#[repr(C, packed)]
1719#[doc(hidden)]
1720pub struct Cmap14FixedHeader {
1721 pub format: BigEndian<u16>,
1722 pub length: BigEndian<u32>,
1723 pub num_var_selector_records: BigEndian<u32>,
1724}
1725
1726#[allow(clippy::absurd_extreme_comparisons)]
1727const _: () = assert!(std::mem::size_of::<Cmap14FixedHeader>() <= Cmap14::MIN_SIZE);
1728
1729#[derive(Clone)]
1731pub struct Cmap14<'a> {
1732 data: TableDataRef<'a, Cmap14FixedHeader>,
1733}
1734
1735#[allow(clippy::needless_lifetimes)]
1736impl<'a> Cmap14<'a> {
1737 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
1738 basic_table_impls!(impl_the_methods);
1739
1740 pub fn format(&self) -> u16 {
1742 self.data.header().format.get()
1743 }
1744
1745 pub fn length(&self) -> u32 {
1747 self.data.header().length.get()
1748 }
1749
1750 pub fn num_var_selector_records(&self) -> u32 {
1752 self.data.header().num_var_selector_records.get()
1753 }
1754
1755 pub fn var_selector(&self) -> &'a [VariationSelector] {
1757 let range = self.var_selector_byte_range();
1758 self.offset_data()
1759 .read_array(range)
1760 .ok()
1761 .unwrap_or_default()
1762 }
1763
1764 pub fn format_byte_range(&self) -> Range<usize> {
1765 let start = 0;
1766 let end = start + u16::RAW_BYTE_LEN;
1767 start..end
1768 }
1769
1770 pub fn length_byte_range(&self) -> Range<usize> {
1771 let start = self.format_byte_range().end;
1772 let end = start + u32::RAW_BYTE_LEN;
1773 start..end
1774 }
1775
1776 pub fn num_var_selector_records_byte_range(&self) -> Range<usize> {
1777 let start = self.length_byte_range().end;
1778 let end = start + u32::RAW_BYTE_LEN;
1779 start..end
1780 }
1781
1782 pub fn var_selector_byte_range(&self) -> Range<usize> {
1783 let num_var_selector_records = self.num_var_selector_records();
1784 let start = self.num_var_selector_records_byte_range().end;
1785 let end = start
1786 + (transforms::to_usize(num_var_selector_records))
1787 .saturating_mul(VariationSelector::RAW_BYTE_LEN);
1788 start..end
1789 }
1790}
1791
1792impl Format<u16> for Cmap15<'_> {
1793 const FORMAT: u16 = 15;
1794}
1795
1796impl<'a> MinByteRange<'a> for Cmap15<'a> {
1797 fn min_byte_range(&self) -> Range<usize> {
1798 0..self.var_selector_byte_range().end
1799 }
1800 fn min_table_bytes(&self) -> &'a [u8] {
1801 let range = self.min_byte_range();
1802 self.offset_data().as_bytes().get(range).unwrap_or_default()
1803 }
1804}
1805
1806impl ReadArgs for Cmap15<'_> {
1807 type Args = ();
1808}
1809
1810impl<'a> FontRead<'a> for Cmap15<'a> {
1811 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1812 #[allow(clippy::absurd_extreme_comparisons)]
1813 if data.len() < Self::MIN_SIZE {
1814 return Err(ReadError::OutOfBounds);
1815 }
1816 let Some(data) = TableDataRef::new(data.as_bytes()) else {
1817 return Err(ReadError::OutOfBounds);
1818 };
1819 Ok(Self { data })
1820 }
1821}
1822
1823#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
1825#[repr(C, packed)]
1826#[doc(hidden)]
1827pub struct Cmap15FixedHeader {
1828 pub format: BigEndian<u16>,
1829 pub length: BigEndian<u32>,
1830 pub num_var_selector_records: BigEndian<u32>,
1831}
1832
1833#[allow(clippy::absurd_extreme_comparisons)]
1834const _: () = assert!(std::mem::size_of::<Cmap15FixedHeader>() <= Cmap15::MIN_SIZE);
1835
1836#[derive(Clone)]
1838pub struct Cmap15<'a> {
1839 data: TableDataRef<'a, Cmap15FixedHeader>,
1840}
1841
1842#[allow(clippy::needless_lifetimes)]
1843impl<'a> Cmap15<'a> {
1844 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
1845 basic_table_impls!(impl_the_methods);
1846
1847 pub fn format(&self) -> u16 {
1849 self.data.header().format.get()
1850 }
1851
1852 pub fn length(&self) -> u32 {
1854 self.data.header().length.get()
1855 }
1856
1857 pub fn num_var_selector_records(&self) -> u32 {
1859 self.data.header().num_var_selector_records.get()
1860 }
1861
1862 pub fn var_selector(&self) -> &'a [VariationSelector15] {
1863 let range = self.var_selector_byte_range();
1864 self.offset_data()
1865 .read_array(range)
1866 .ok()
1867 .unwrap_or_default()
1868 }
1869
1870 pub fn format_byte_range(&self) -> Range<usize> {
1871 let start = 0;
1872 let end = start + u16::RAW_BYTE_LEN;
1873 start..end
1874 }
1875
1876 pub fn length_byte_range(&self) -> Range<usize> {
1877 let start = self.format_byte_range().end;
1878 let end = start + u32::RAW_BYTE_LEN;
1879 start..end
1880 }
1881
1882 pub fn num_var_selector_records_byte_range(&self) -> Range<usize> {
1883 let start = self.length_byte_range().end;
1884 let end = start + u32::RAW_BYTE_LEN;
1885 start..end
1886 }
1887
1888 pub fn var_selector_byte_range(&self) -> Range<usize> {
1889 let num_var_selector_records = self.num_var_selector_records();
1890 let start = self.num_var_selector_records_byte_range().end;
1891 let end = start
1892 + (transforms::to_usize(num_var_selector_records))
1893 .saturating_mul(VariationSelector15::RAW_BYTE_LEN);
1894 start..end
1895 }
1896}
1897
1898#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
1900#[repr(C)]
1901#[repr(packed)]
1902pub struct VariationSelector15 {
1903 pub var_selector: BigEndian<Uint24>,
1904 pub default_uvs_offset: BigEndian<Nullable<Offset32>>,
1905 pub non_default_uvs_offset: BigEndian<Nullable<Offset32>>,
1906}
1907
1908impl VariationSelector15 {
1909 pub fn var_selector(&self) -> Uint24 {
1910 self.var_selector.get()
1911 }
1912
1913 pub fn default_uvs_offset(&self) -> Nullable<Offset32> {
1914 self.default_uvs_offset.get()
1915 }
1916
1917 pub fn default_uvs<'a>(&self, data: FontData<'a>) -> Option<Result<DefaultUvs<'a>, ReadError>> {
1921 self.default_uvs_offset().resolve(data)
1922 }
1923
1924 pub fn non_default_uvs_offset(&self) -> Nullable<Offset32> {
1925 self.non_default_uvs_offset.get()
1926 }
1927
1928 pub fn non_default_uvs<'a>(
1932 &self,
1933 data: FontData<'a>,
1934 ) -> Option<Result<NonDefaultUvs24<'a>, ReadError>> {
1935 self.non_default_uvs_offset().resolve(data)
1936 }
1937}
1938
1939impl FixedSize for VariationSelector15 {
1940 const RAW_BYTE_LEN: usize =
1941 Uint24::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN;
1942}
1943
1944#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
1946#[repr(C)]
1947#[repr(packed)]
1948pub struct VariationSelector {
1949 pub var_selector: BigEndian<Uint24>,
1951 pub default_uvs_offset: BigEndian<Nullable<Offset32>>,
1954 pub non_default_uvs_offset: BigEndian<Nullable<Offset32>>,
1957}
1958
1959impl VariationSelector {
1960 pub fn var_selector(&self) -> Uint24 {
1962 self.var_selector.get()
1963 }
1964
1965 pub fn default_uvs_offset(&self) -> Nullable<Offset32> {
1968 self.default_uvs_offset.get()
1969 }
1970
1971 pub fn default_uvs<'a>(&self, data: FontData<'a>) -> Option<Result<DefaultUvs<'a>, ReadError>> {
1977 self.default_uvs_offset().resolve(data)
1978 }
1979
1980 pub fn non_default_uvs_offset(&self) -> Nullable<Offset32> {
1983 self.non_default_uvs_offset.get()
1984 }
1985
1986 pub fn non_default_uvs<'a>(
1992 &self,
1993 data: FontData<'a>,
1994 ) -> Option<Result<NonDefaultUvs<'a>, ReadError>> {
1995 self.non_default_uvs_offset().resolve(data)
1996 }
1997}
1998
1999impl FixedSize for VariationSelector {
2000 const RAW_BYTE_LEN: usize =
2001 Uint24::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN;
2002}
2003
2004impl<'a> MinByteRange<'a> for DefaultUvs<'a> {
2005 fn min_byte_range(&self) -> Range<usize> {
2006 0..self.ranges_byte_range().end
2007 }
2008 fn min_table_bytes(&self) -> &'a [u8] {
2009 let range = self.min_byte_range();
2010 self.offset_data().as_bytes().get(range).unwrap_or_default()
2011 }
2012}
2013
2014impl ReadArgs for DefaultUvs<'_> {
2015 type Args = ();
2016}
2017
2018impl<'a> FontRead<'a> for DefaultUvs<'a> {
2019 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2020 #[allow(clippy::absurd_extreme_comparisons)]
2021 if data.len() < Self::MIN_SIZE {
2022 return Err(ReadError::OutOfBounds);
2023 }
2024 let Some(data) = TableDataRef::new(data.as_bytes()) else {
2025 return Err(ReadError::OutOfBounds);
2026 };
2027 Ok(Self { data })
2028 }
2029}
2030
2031#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
2033#[repr(C, packed)]
2034#[doc(hidden)]
2035pub struct DefaultUvsFixedHeader {
2036 pub num_unicode_value_ranges: BigEndian<u32>,
2037}
2038
2039#[allow(clippy::absurd_extreme_comparisons)]
2040const _: () = assert!(std::mem::size_of::<DefaultUvsFixedHeader>() <= DefaultUvs::MIN_SIZE);
2041
2042#[derive(Clone)]
2044pub struct DefaultUvs<'a> {
2045 data: TableDataRef<'a, DefaultUvsFixedHeader>,
2046}
2047
2048#[allow(clippy::needless_lifetimes)]
2049impl<'a> DefaultUvs<'a> {
2050 pub const MIN_SIZE: usize = u32::RAW_BYTE_LEN;
2051 basic_table_impls!(impl_the_methods);
2052
2053 pub fn num_unicode_value_ranges(&self) -> u32 {
2055 self.data.header().num_unicode_value_ranges.get()
2056 }
2057
2058 pub fn ranges(&self) -> &'a [UnicodeRange] {
2060 let range = self.ranges_byte_range();
2061 self.offset_data()
2062 .read_array(range)
2063 .ok()
2064 .unwrap_or_default()
2065 }
2066
2067 pub fn num_unicode_value_ranges_byte_range(&self) -> Range<usize> {
2068 let start = 0;
2069 let end = start + u32::RAW_BYTE_LEN;
2070 start..end
2071 }
2072
2073 pub fn ranges_byte_range(&self) -> Range<usize> {
2074 let num_unicode_value_ranges = self.num_unicode_value_ranges();
2075 let start = self.num_unicode_value_ranges_byte_range().end;
2076 let end = start
2077 + (transforms::to_usize(num_unicode_value_ranges))
2078 .saturating_mul(UnicodeRange::RAW_BYTE_LEN);
2079 start..end
2080 }
2081}
2082
2083const _: () = assert!(FontData::default_data_long_enough(DefaultUvs::MIN_SIZE));
2084
2085impl Default for DefaultUvs<'_> {
2086 fn default() -> Self {
2087 Self {
2088 data: TableDataRef::new(FontData::default_table_data().as_bytes())
2089 .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
2090 }
2091 }
2092}
2093
2094impl<'a> MinByteRange<'a> for NonDefaultUvs<'a> {
2095 fn min_byte_range(&self) -> Range<usize> {
2096 0..self.uvs_mapping_byte_range().end
2097 }
2098 fn min_table_bytes(&self) -> &'a [u8] {
2099 let range = self.min_byte_range();
2100 self.offset_data().as_bytes().get(range).unwrap_or_default()
2101 }
2102}
2103
2104impl ReadArgs for NonDefaultUvs<'_> {
2105 type Args = ();
2106}
2107
2108impl<'a> FontRead<'a> for NonDefaultUvs<'a> {
2109 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2110 #[allow(clippy::absurd_extreme_comparisons)]
2111 if data.len() < Self::MIN_SIZE {
2112 return Err(ReadError::OutOfBounds);
2113 }
2114 let Some(data) = TableDataRef::new(data.as_bytes()) else {
2115 return Err(ReadError::OutOfBounds);
2116 };
2117 Ok(Self { data })
2118 }
2119}
2120
2121#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
2123#[repr(C, packed)]
2124#[doc(hidden)]
2125pub struct NonDefaultUvsFixedHeader {
2126 pub num_uvs_mappings: BigEndian<u32>,
2127}
2128
2129#[allow(clippy::absurd_extreme_comparisons)]
2130const _: () = assert!(std::mem::size_of::<NonDefaultUvsFixedHeader>() <= NonDefaultUvs::MIN_SIZE);
2131
2132#[derive(Clone)]
2134pub struct NonDefaultUvs<'a> {
2135 data: TableDataRef<'a, NonDefaultUvsFixedHeader>,
2136}
2137
2138#[allow(clippy::needless_lifetimes)]
2139impl<'a> NonDefaultUvs<'a> {
2140 pub const MIN_SIZE: usize = u32::RAW_BYTE_LEN;
2141 basic_table_impls!(impl_the_methods);
2142
2143 pub fn num_uvs_mappings(&self) -> u32 {
2144 self.data.header().num_uvs_mappings.get()
2145 }
2146
2147 pub fn uvs_mapping(&self) -> &'a [UvsMapping] {
2148 let range = self.uvs_mapping_byte_range();
2149 self.offset_data()
2150 .read_array(range)
2151 .ok()
2152 .unwrap_or_default()
2153 }
2154
2155 pub fn num_uvs_mappings_byte_range(&self) -> Range<usize> {
2156 let start = 0;
2157 let end = start + u32::RAW_BYTE_LEN;
2158 start..end
2159 }
2160
2161 pub fn uvs_mapping_byte_range(&self) -> Range<usize> {
2162 let num_uvs_mappings = self.num_uvs_mappings();
2163 let start = self.num_uvs_mappings_byte_range().end;
2164 let end = start
2165 + (transforms::to_usize(num_uvs_mappings)).saturating_mul(UvsMapping::RAW_BYTE_LEN);
2166 start..end
2167 }
2168}
2169
2170const _: () = assert!(FontData::default_data_long_enough(NonDefaultUvs::MIN_SIZE));
2171
2172impl Default for NonDefaultUvs<'_> {
2173 fn default() -> Self {
2174 Self {
2175 data: TableDataRef::new(FontData::default_table_data().as_bytes())
2176 .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
2177 }
2178 }
2179}
2180
2181impl<'a> MinByteRange<'a> for NonDefaultUvs24<'a> {
2182 fn min_byte_range(&self) -> Range<usize> {
2183 0..self.uvs_mapping_byte_range().end
2184 }
2185 fn min_table_bytes(&self) -> &'a [u8] {
2186 let range = self.min_byte_range();
2187 self.offset_data().as_bytes().get(range).unwrap_or_default()
2188 }
2189}
2190
2191impl ReadArgs for NonDefaultUvs24<'_> {
2192 type Args = ();
2193}
2194
2195impl<'a> FontRead<'a> for NonDefaultUvs24<'a> {
2196 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2197 #[allow(clippy::absurd_extreme_comparisons)]
2198 if data.len() < Self::MIN_SIZE {
2199 return Err(ReadError::OutOfBounds);
2200 }
2201 let Some(data) = TableDataRef::new(data.as_bytes()) else {
2202 return Err(ReadError::OutOfBounds);
2203 };
2204 Ok(Self { data })
2205 }
2206}
2207
2208#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
2210#[repr(C, packed)]
2211#[doc(hidden)]
2212pub struct NonDefaultUvs24FixedHeader {
2213 pub num_uvs_mappings: BigEndian<u32>,
2214}
2215
2216#[allow(clippy::absurd_extreme_comparisons)]
2217const _: () =
2218 assert!(std::mem::size_of::<NonDefaultUvs24FixedHeader>() <= NonDefaultUvs24::MIN_SIZE);
2219
2220#[derive(Clone)]
2222pub struct NonDefaultUvs24<'a> {
2223 data: TableDataRef<'a, NonDefaultUvs24FixedHeader>,
2224}
2225
2226#[allow(clippy::needless_lifetimes)]
2227impl<'a> NonDefaultUvs24<'a> {
2228 pub const MIN_SIZE: usize = u32::RAW_BYTE_LEN;
2229 basic_table_impls!(impl_the_methods);
2230
2231 pub fn num_uvs_mappings(&self) -> u32 {
2232 self.data.header().num_uvs_mappings.get()
2233 }
2234
2235 pub fn uvs_mapping(&self) -> &'a [UvsMapping24] {
2236 let range = self.uvs_mapping_byte_range();
2237 self.offset_data()
2238 .read_array(range)
2239 .ok()
2240 .unwrap_or_default()
2241 }
2242
2243 pub fn num_uvs_mappings_byte_range(&self) -> Range<usize> {
2244 let start = 0;
2245 let end = start + u32::RAW_BYTE_LEN;
2246 start..end
2247 }
2248
2249 pub fn uvs_mapping_byte_range(&self) -> Range<usize> {
2250 let num_uvs_mappings = self.num_uvs_mappings();
2251 let start = self.num_uvs_mappings_byte_range().end;
2252 let end = start
2253 + (transforms::to_usize(num_uvs_mappings)).saturating_mul(UvsMapping24::RAW_BYTE_LEN);
2254 start..end
2255 }
2256}
2257
2258const _: () = assert!(FontData::default_data_long_enough(
2259 NonDefaultUvs24::MIN_SIZE
2260));
2261
2262impl Default for NonDefaultUvs24<'_> {
2263 fn default() -> Self {
2264 Self {
2265 data: TableDataRef::new(FontData::default_table_data().as_bytes())
2266 .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
2267 }
2268 }
2269}
2270
2271#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
2273#[repr(C)]
2274#[repr(packed)]
2275pub struct UvsMapping24 {
2276 pub unicode_value: BigEndian<Uint24>,
2277 pub glyph_id: BigEndian<Uint24>,
2278}
2279
2280impl UvsMapping24 {
2281 pub fn unicode_value(&self) -> Uint24 {
2282 self.unicode_value.get()
2283 }
2284
2285 pub fn glyph_id(&self) -> Uint24 {
2286 self.glyph_id.get()
2287 }
2288}
2289
2290impl FixedSize for UvsMapping24 {
2291 const RAW_BYTE_LEN: usize = Uint24::RAW_BYTE_LEN + Uint24::RAW_BYTE_LEN;
2292}
2293
2294#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
2296#[repr(C)]
2297#[repr(packed)]
2298pub struct UvsMapping {
2299 pub unicode_value: BigEndian<Uint24>,
2301 pub glyph_id: BigEndian<u16>,
2303}
2304
2305impl UvsMapping {
2306 pub fn unicode_value(&self) -> Uint24 {
2308 self.unicode_value.get()
2309 }
2310
2311 pub fn glyph_id(&self) -> u16 {
2313 self.glyph_id.get()
2314 }
2315}
2316
2317impl FixedSize for UvsMapping {
2318 const RAW_BYTE_LEN: usize = Uint24::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
2319}
2320
2321#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
2323#[repr(C)]
2324#[repr(packed)]
2325pub struct UnicodeRange {
2326 pub start_unicode_value: BigEndian<Uint24>,
2328 pub additional_count: u8,
2330}
2331
2332impl UnicodeRange {
2333 pub fn start_unicode_value(&self) -> Uint24 {
2335 self.start_unicode_value.get()
2336 }
2337
2338 pub fn additional_count(&self) -> u8 {
2340 self.additional_count
2341 }
2342}
2343
2344impl FixedSize for UnicodeRange {
2345 const RAW_BYTE_LEN: usize = Uint24::RAW_BYTE_LEN + u8::RAW_BYTE_LEN;
2346}