1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8impl<'a> MinByteRange<'a> for TupleVariationHeader<'a> {
9 fn min_byte_range(&self) -> Range<usize> {
10 0..self.intermediate_end_tuple_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 TupleVariationHeader<'_> {
19 type Args = u16;
20}
21
22impl<'a> FontRead<'a> for TupleVariationHeader<'a> {
23 fn read_with_args(data: FontData<'a>, args: u16) -> Result<Self, ReadError> {
24 let axis_count = args;
25
26 #[allow(clippy::absurd_extreme_comparisons)]
27 if data.len() < Self::MIN_SIZE {
28 return Err(ReadError::OutOfBounds);
29 }
30 Ok(Self { data, axis_count })
31 }
32}
33
34impl<'a> TupleVariationHeader<'a> {
35 pub fn read(data: FontData<'a>, axis_count: u16) -> Result<Self, ReadError> {
40 let args = axis_count;
41 Self::read_with_args(data, args)
42 }
43}
44
45#[derive(Clone)]
47pub struct TupleVariationHeader<'a> {
48 data: FontData<'a>,
49 axis_count: u16,
50}
51
52#[allow(clippy::needless_lifetimes)]
53impl<'a> TupleVariationHeader<'a> {
54 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + TupleIndex::RAW_BYTE_LEN);
55 basic_table_impls!(impl_the_methods);
56
57 pub fn variation_data_size(&self) -> u16 {
60 let range = self.variation_data_size_byte_range();
61 self.data.read_at(range.start).ok().unwrap()
62 }
63
64 pub fn tuple_index(&self) -> TupleIndex {
67 let range = self.tuple_index_byte_range();
68 self.data.read_at(range.start).ok().unwrap()
69 }
70
71 pub(crate) fn axis_count(&self) -> u16 {
72 self.axis_count
73 }
74
75 pub fn variation_data_size_byte_range(&self) -> Range<usize> {
76 let start = 0;
77 let end = start + u16::RAW_BYTE_LEN;
78 start..end
79 }
80
81 pub fn tuple_index_byte_range(&self) -> Range<usize> {
82 let start = self.variation_data_size_byte_range().end;
83 let end = start + TupleIndex::RAW_BYTE_LEN;
84 start..end
85 }
86
87 pub fn peak_tuple_byte_range(&self) -> Range<usize> {
88 let tuple_index = self.tuple_index();
89 let axis_count = self.axis_count();
90 let start = self.tuple_index_byte_range().end;
91 let end = start
92 + (TupleIndex::tuple_len(tuple_index, axis_count, 0_usize))
93 .saturating_mul(F2Dot14::RAW_BYTE_LEN);
94 start..end
95 }
96
97 pub fn intermediate_start_tuple_byte_range(&self) -> Range<usize> {
98 let tuple_index = self.tuple_index();
99 let axis_count = self.axis_count();
100 let start = self.peak_tuple_byte_range().end;
101 let end = start
102 + (TupleIndex::tuple_len(tuple_index, axis_count, 1_usize))
103 .saturating_mul(F2Dot14::RAW_BYTE_LEN);
104 start..end
105 }
106
107 pub fn intermediate_end_tuple_byte_range(&self) -> Range<usize> {
108 let tuple_index = self.tuple_index();
109 let axis_count = self.axis_count();
110 let start = self.intermediate_start_tuple_byte_range().end;
111 let end = start
112 + (TupleIndex::tuple_len(tuple_index, axis_count, 1_usize))
113 .saturating_mul(F2Dot14::RAW_BYTE_LEN);
114 start..end
115 }
116}
117
118const _: () = assert!(FontData::default_data_long_enough(
119 TupleVariationHeader::MIN_SIZE
120));
121
122impl Default for TupleVariationHeader<'_> {
123 fn default() -> Self {
124 Self {
125 data: FontData::default_table_data(),
126 axis_count: Default::default(),
127 }
128 }
129}
130
131#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
137pub struct Tuple<'a> {
138 pub values: &'a [BigEndian<F2Dot14>],
143}
144
145impl<'a> Tuple<'a> {
146 pub fn values(&self) -> &'a [BigEndian<F2Dot14>] {
151 self.values
152 }
153}
154
155impl ReadArgs for Tuple<'_> {
156 type Args = u16;
157}
158
159impl ComputeSize for Tuple<'_> {
160 #[allow(clippy::needless_question_mark)]
161 fn compute_size(args: u16) -> Result<usize, ReadError> {
162 let axis_count = args;
163 Ok((transforms::to_usize(axis_count)).saturating_mul(F2Dot14::RAW_BYTE_LEN))
164 }
165}
166
167impl<'a> FontRead<'a> for Tuple<'a> {
168 fn read_with_args(data: FontData<'a>, args: u16) -> Result<Self, ReadError> {
169 let mut cursor = data.cursor();
170 let axis_count = args;
171 Ok(Self {
172 values: cursor.read_array(transforms::to_usize(axis_count))?,
173 })
174 }
175}
176
177crate::impl_font_read_at!(Tuple<'a>);
178
179#[allow(clippy::needless_lifetimes)]
180impl<'a> Tuple<'a> {
181 pub fn read(data: FontData<'a>, axis_count: u16) -> Result<Self, ReadError> {
186 let args = axis_count;
187 Self::read_with_args(data, args)
188 }
189}
190
191impl Format<u8> for DeltaSetIndexMapFormat0<'_> {
192 const FORMAT: u8 = 0;
193}
194
195impl<'a> MinByteRange<'a> for DeltaSetIndexMapFormat0<'a> {
196 fn min_byte_range(&self) -> Range<usize> {
197 0..self.map_data_byte_range().end
198 }
199 fn min_table_bytes(&self) -> &'a [u8] {
200 let range = self.min_byte_range();
201 self.data.as_bytes().get(range).unwrap_or_default()
202 }
203}
204
205impl ReadArgs for DeltaSetIndexMapFormat0<'_> {
206 type Args = ();
207}
208
209impl<'a> FontRead<'a> for DeltaSetIndexMapFormat0<'a> {
210 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
211 #[allow(clippy::absurd_extreme_comparisons)]
212 if data.len() < Self::MIN_SIZE {
213 return Err(ReadError::OutOfBounds);
214 }
215 Ok(Self { data })
216 }
217}
218
219#[derive(Clone)]
221pub struct DeltaSetIndexMapFormat0<'a> {
222 data: FontData<'a>,
223}
224
225#[allow(clippy::needless_lifetimes)]
226impl<'a> DeltaSetIndexMapFormat0<'a> {
227 pub const MIN_SIZE: usize = (u8::RAW_BYTE_LEN + EntryFormat::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
228 basic_table_impls!(impl_the_methods);
229
230 pub fn format(&self) -> u8 {
232 let range = self.format_byte_range();
233 self.data.read_at(range.start).ok().unwrap()
234 }
235
236 pub fn entry_format(&self) -> EntryFormat {
239 let range = self.entry_format_byte_range();
240 self.data.read_at(range.start).ok().unwrap()
241 }
242
243 pub fn map_count(&self) -> u16 {
245 let range = self.map_count_byte_range();
246 self.data.read_at(range.start).ok().unwrap()
247 }
248
249 pub fn map_data(&self) -> &'a [u8] {
251 let range = self.map_data_byte_range();
252 self.data.read_array(range).ok().unwrap_or_default()
253 }
254
255 pub fn format_byte_range(&self) -> Range<usize> {
256 let start = 0;
257 let end = start + u8::RAW_BYTE_LEN;
258 start..end
259 }
260
261 pub fn entry_format_byte_range(&self) -> Range<usize> {
262 let start = self.format_byte_range().end;
263 let end = start + EntryFormat::RAW_BYTE_LEN;
264 start..end
265 }
266
267 pub fn map_count_byte_range(&self) -> Range<usize> {
268 let start = self.entry_format_byte_range().end;
269 let end = start + u16::RAW_BYTE_LEN;
270 start..end
271 }
272
273 pub fn map_data_byte_range(&self) -> Range<usize> {
274 let entry_format = self.entry_format();
275 let map_count = self.map_count();
276 let start = self.map_count_byte_range().end;
277 let end = start
278 + (EntryFormat::map_size(entry_format, map_count)).saturating_mul(u8::RAW_BYTE_LEN);
279 start..end
280 }
281}
282
283const _: () = assert!(FontData::default_data_long_enough(
284 DeltaSetIndexMapFormat0::MIN_SIZE
285));
286
287impl Default for DeltaSetIndexMapFormat0<'_> {
288 fn default() -> Self {
289 Self {
290 data: FontData::default_table_data(),
291 }
292 }
293}
294
295impl Format<u8> for DeltaSetIndexMapFormat1<'_> {
296 const FORMAT: u8 = 1;
297}
298
299impl<'a> MinByteRange<'a> for DeltaSetIndexMapFormat1<'a> {
300 fn min_byte_range(&self) -> Range<usize> {
301 0..self.map_data_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 DeltaSetIndexMapFormat1<'_> {
310 type Args = ();
311}
312
313impl<'a> FontRead<'a> for DeltaSetIndexMapFormat1<'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#[derive(Clone)]
325pub struct DeltaSetIndexMapFormat1<'a> {
326 data: FontData<'a>,
327}
328
329#[allow(clippy::needless_lifetimes)]
330impl<'a> DeltaSetIndexMapFormat1<'a> {
331 pub const MIN_SIZE: usize = (u8::RAW_BYTE_LEN + EntryFormat::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
332 basic_table_impls!(impl_the_methods);
333
334 pub fn format(&self) -> u8 {
336 let range = self.format_byte_range();
337 self.data.read_at(range.start).ok().unwrap()
338 }
339
340 pub fn entry_format(&self) -> EntryFormat {
343 let range = self.entry_format_byte_range();
344 self.data.read_at(range.start).ok().unwrap()
345 }
346
347 pub fn map_count(&self) -> u32 {
349 let range = self.map_count_byte_range();
350 self.data.read_at(range.start).ok().unwrap()
351 }
352
353 pub fn map_data(&self) -> &'a [u8] {
355 let range = self.map_data_byte_range();
356 self.data.read_array(range).ok().unwrap_or_default()
357 }
358
359 pub fn format_byte_range(&self) -> Range<usize> {
360 let start = 0;
361 let end = start + u8::RAW_BYTE_LEN;
362 start..end
363 }
364
365 pub fn entry_format_byte_range(&self) -> Range<usize> {
366 let start = self.format_byte_range().end;
367 let end = start + EntryFormat::RAW_BYTE_LEN;
368 start..end
369 }
370
371 pub fn map_count_byte_range(&self) -> Range<usize> {
372 let start = self.entry_format_byte_range().end;
373 let end = start + u32::RAW_BYTE_LEN;
374 start..end
375 }
376
377 pub fn map_data_byte_range(&self) -> Range<usize> {
378 let entry_format = self.entry_format();
379 let map_count = self.map_count();
380 let start = self.map_count_byte_range().end;
381 let end = start
382 + (EntryFormat::map_size(entry_format, map_count)).saturating_mul(u8::RAW_BYTE_LEN);
383 start..end
384 }
385}
386
387const _: () = assert!(FontData::default_data_long_enough(
388 DeltaSetIndexMapFormat1::MIN_SIZE
389));
390
391impl Default for DeltaSetIndexMapFormat1<'_> {
392 fn default() -> Self {
393 Self {
394 data: FontData::default_format_1_u8_table_data(),
395 }
396 }
397}
398
399#[derive(Clone)]
401pub enum DeltaSetIndexMap<'a> {
402 Format0(DeltaSetIndexMapFormat0<'a>),
403 Format1(DeltaSetIndexMapFormat1<'a>),
404}
405
406impl Default for DeltaSetIndexMap<'_> {
407 fn default() -> Self {
408 Self::Format0(Default::default())
409 }
410}
411
412impl<'a> DeltaSetIndexMap<'a> {
413 pub fn offset_data(&self) -> FontData<'a> {
415 match self {
416 Self::Format0(item) => item.offset_data(),
417 Self::Format1(item) => item.offset_data(),
418 }
419 }
420
421 pub fn format(&self) -> u8 {
423 match self {
424 Self::Format0(item) => item.format(),
425 Self::Format1(item) => item.format(),
426 }
427 }
428
429 pub fn entry_format(&self) -> EntryFormat {
432 match self {
433 Self::Format0(item) => item.entry_format(),
434 Self::Format1(item) => item.entry_format(),
435 }
436 }
437
438 pub fn map_data(&self) -> &'a [u8] {
440 match self {
441 Self::Format0(item) => item.map_data(),
442 Self::Format1(item) => item.map_data(),
443 }
444 }
445}
446
447impl ReadArgs for DeltaSetIndexMap<'_> {
448 type Args = ();
449}
450
451impl<'a> FontRead<'a> for DeltaSetIndexMap<'a> {
452 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
453 let format: u8 = data.read_at(0usize)?;
454 match format {
455 DeltaSetIndexMapFormat0::FORMAT => Ok(Self::Format0(FontRead::read(data)?)),
456 DeltaSetIndexMapFormat1::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
457 other => Err(ReadError::InvalidFormat(other.into())),
458 }
459 }
460}
461
462impl<'a> MinByteRange<'a> for DeltaSetIndexMap<'a> {
463 fn min_byte_range(&self) -> Range<usize> {
464 match self {
465 Self::Format0(item) => item.min_byte_range(),
466 Self::Format1(item) => item.min_byte_range(),
467 }
468 }
469 fn min_table_bytes(&self) -> &'a [u8] {
470 match self {
471 Self::Format0(item) => item.min_table_bytes(),
472 Self::Format1(item) => item.min_table_bytes(),
473 }
474 }
475}
476
477#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
479#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
480#[repr(transparent)]
481pub struct EntryFormat {
482 bits: u8,
483}
484
485impl EntryFormat {
486 pub const INNER_INDEX_BIT_COUNT_MASK: Self = Self { bits: 0x0F };
488
489 pub const MAP_ENTRY_SIZE_MASK: Self = Self { bits: 0x30 };
491}
492
493impl EntryFormat {
494 #[inline]
496 pub const fn empty() -> Self {
497 Self { bits: 0 }
498 }
499
500 #[inline]
502 pub const fn all() -> Self {
503 Self {
504 bits: Self::INNER_INDEX_BIT_COUNT_MASK.bits | Self::MAP_ENTRY_SIZE_MASK.bits,
505 }
506 }
507
508 #[inline]
510 pub const fn bits(&self) -> u8 {
511 self.bits
512 }
513
514 #[inline]
517 pub const fn from_bits(bits: u8) -> Option<Self> {
518 if (bits & !Self::all().bits()) == 0 {
519 Some(Self { bits })
520 } else {
521 None
522 }
523 }
524
525 #[inline]
528 pub const fn from_bits_truncate(bits: u8) -> Self {
529 Self {
530 bits: bits & Self::all().bits,
531 }
532 }
533
534 #[inline]
536 pub const fn is_empty(&self) -> bool {
537 self.bits() == Self::empty().bits()
538 }
539
540 #[inline]
542 pub const fn intersects(&self, other: Self) -> bool {
543 !(Self {
544 bits: self.bits & other.bits,
545 })
546 .is_empty()
547 }
548
549 #[inline]
551 pub const fn contains(&self, other: Self) -> bool {
552 (self.bits & other.bits) == other.bits
553 }
554
555 #[inline]
557 pub fn insert(&mut self, other: Self) {
558 self.bits |= other.bits;
559 }
560
561 #[inline]
563 pub fn remove(&mut self, other: Self) {
564 self.bits &= !other.bits;
565 }
566
567 #[inline]
569 pub fn toggle(&mut self, other: Self) {
570 self.bits ^= other.bits;
571 }
572
573 #[inline]
584 #[must_use]
585 pub const fn intersection(self, other: Self) -> Self {
586 Self {
587 bits: self.bits & other.bits,
588 }
589 }
590
591 #[inline]
602 #[must_use]
603 pub const fn union(self, other: Self) -> Self {
604 Self {
605 bits: self.bits | other.bits,
606 }
607 }
608
609 #[inline]
622 #[must_use]
623 pub const fn difference(self, other: Self) -> Self {
624 Self {
625 bits: self.bits & !other.bits,
626 }
627 }
628}
629
630impl std::ops::BitOr for EntryFormat {
631 type Output = Self;
632
633 #[inline]
635 fn bitor(self, other: EntryFormat) -> Self {
636 Self {
637 bits: self.bits | other.bits,
638 }
639 }
640}
641
642impl std::ops::BitOrAssign for EntryFormat {
643 #[inline]
645 fn bitor_assign(&mut self, other: Self) {
646 self.bits |= other.bits;
647 }
648}
649
650impl std::ops::BitXor for EntryFormat {
651 type Output = Self;
652
653 #[inline]
655 fn bitxor(self, other: Self) -> Self {
656 Self {
657 bits: self.bits ^ other.bits,
658 }
659 }
660}
661
662impl std::ops::BitXorAssign for EntryFormat {
663 #[inline]
665 fn bitxor_assign(&mut self, other: Self) {
666 self.bits ^= other.bits;
667 }
668}
669
670impl std::ops::BitAnd for EntryFormat {
671 type Output = Self;
672
673 #[inline]
675 fn bitand(self, other: Self) -> Self {
676 Self {
677 bits: self.bits & other.bits,
678 }
679 }
680}
681
682impl std::ops::BitAndAssign for EntryFormat {
683 #[inline]
685 fn bitand_assign(&mut self, other: Self) {
686 self.bits &= other.bits;
687 }
688}
689
690impl std::ops::Sub for EntryFormat {
691 type Output = Self;
692
693 #[inline]
695 fn sub(self, other: Self) -> Self {
696 Self {
697 bits: self.bits & !other.bits,
698 }
699 }
700}
701
702impl std::ops::SubAssign for EntryFormat {
703 #[inline]
705 fn sub_assign(&mut self, other: Self) {
706 self.bits &= !other.bits;
707 }
708}
709
710impl std::ops::Not for EntryFormat {
711 type Output = Self;
712
713 #[inline]
715 fn not(self) -> Self {
716 Self { bits: !self.bits } & Self::all()
717 }
718}
719
720impl std::fmt::Debug for EntryFormat {
721 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
722 let members: &[(&str, Self)] = &[
723 (
724 "INNER_INDEX_BIT_COUNT_MASK",
725 Self::INNER_INDEX_BIT_COUNT_MASK,
726 ),
727 ("MAP_ENTRY_SIZE_MASK", Self::MAP_ENTRY_SIZE_MASK),
728 ];
729 let mut first = true;
730 for (name, value) in members {
731 if self.contains(*value) {
732 if !first {
733 f.write_str(" | ")?;
734 }
735 first = false;
736 f.write_str(name)?;
737 }
738 }
739 if first {
740 f.write_str("(empty)")?;
741 }
742 Ok(())
743 }
744}
745
746impl std::fmt::Binary for EntryFormat {
747 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
748 std::fmt::Binary::fmt(&self.bits, f)
749 }
750}
751
752impl std::fmt::Octal for EntryFormat {
753 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
754 std::fmt::Octal::fmt(&self.bits, f)
755 }
756}
757
758impl std::fmt::LowerHex for EntryFormat {
759 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
760 std::fmt::LowerHex::fmt(&self.bits, f)
761 }
762}
763
764impl std::fmt::UpperHex for EntryFormat {
765 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
766 std::fmt::UpperHex::fmt(&self.bits, f)
767 }
768}
769
770impl font_types::Scalar for EntryFormat {
771 type Raw = <u8 as font_types::Scalar>::Raw;
772 fn to_raw(self) -> Self::Raw {
773 self.bits().to_raw()
774 }
775 fn from_raw(raw: Self::Raw) -> Self {
776 let t = <u8>::from_raw(raw);
777 Self::from_bits_truncate(t)
778 }
779}
780
781impl<'a> MinByteRange<'a> for VariationRegionList<'a> {
782 fn min_byte_range(&self) -> Range<usize> {
783 0..self.variation_regions_byte_range().end
784 }
785 fn min_table_bytes(&self) -> &'a [u8] {
786 let range = self.min_byte_range();
787 self.data.as_bytes().get(range).unwrap_or_default()
788 }
789}
790
791impl ReadArgs for VariationRegionList<'_> {
792 type Args = ();
793}
794
795impl<'a> FontRead<'a> for VariationRegionList<'a> {
796 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
797 #[allow(clippy::absurd_extreme_comparisons)]
798 if data.len() < Self::MIN_SIZE {
799 return Err(ReadError::OutOfBounds);
800 }
801 Ok(Self { data })
802 }
803}
804
805#[derive(Clone)]
807pub struct VariationRegionList<'a> {
808 data: FontData<'a>,
809}
810
811#[allow(clippy::needless_lifetimes)]
812impl<'a> VariationRegionList<'a> {
813 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
814 basic_table_impls!(impl_the_methods);
815
816 pub fn axis_count(&self) -> u16 {
819 let range = self.axis_count_byte_range();
820 self.data.read_at(range.start).ok().unwrap()
821 }
822
823 pub fn region_count(&self) -> u16 {
826 let range = self.region_count_byte_range();
827 self.data.read_at(range.start).ok().unwrap()
828 }
829
830 pub fn variation_regions(&self) -> ComputedArray<'a, VariationRegion<'a>> {
832 let range = self.variation_regions_byte_range();
833 ComputedArray::new(self.data, range, self.axis_count()).unwrap_or_default()
834 }
835
836 pub fn axis_count_byte_range(&self) -> Range<usize> {
837 let start = 0;
838 let end = start + u16::RAW_BYTE_LEN;
839 start..end
840 }
841
842 pub fn region_count_byte_range(&self) -> Range<usize> {
843 let start = self.axis_count_byte_range().end;
844 let end = start + u16::RAW_BYTE_LEN;
845 start..end
846 }
847
848 pub fn variation_regions_byte_range(&self) -> Range<usize> {
849 let region_count = self.region_count();
850 let start = self.region_count_byte_range().end;
851 let end = start
852 + (transforms::to_usize(region_count)).saturating_mul(
853 <VariationRegion as ComputeSize>::compute_size(self.axis_count()).unwrap_or(0),
854 );
855 start..end
856 }
857}
858
859const _: () = assert!(FontData::default_data_long_enough(
860 VariationRegionList::MIN_SIZE
861));
862
863impl Default for VariationRegionList<'_> {
864 fn default() -> Self {
865 Self {
866 data: FontData::default_table_data(),
867 }
868 }
869}
870
871#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
873pub struct VariationRegion<'a> {
874 pub region_axes: &'a [RegionAxisCoordinates],
877}
878
879impl<'a> VariationRegion<'a> {
880 pub fn region_axes(&self) -> &'a [RegionAxisCoordinates] {
883 self.region_axes
884 }
885}
886
887impl ReadArgs for VariationRegion<'_> {
888 type Args = u16;
889}
890
891impl ComputeSize for VariationRegion<'_> {
892 #[allow(clippy::needless_question_mark)]
893 fn compute_size(args: u16) -> Result<usize, ReadError> {
894 let axis_count = args;
895 Ok((transforms::to_usize(axis_count)).saturating_mul(RegionAxisCoordinates::RAW_BYTE_LEN))
896 }
897}
898
899impl<'a> FontRead<'a> for VariationRegion<'a> {
900 fn read_with_args(data: FontData<'a>, args: u16) -> Result<Self, ReadError> {
901 let mut cursor = data.cursor();
902 let axis_count = args;
903 Ok(Self {
904 region_axes: cursor.read_array(transforms::to_usize(axis_count))?,
905 })
906 }
907}
908
909crate::impl_font_read_at!(VariationRegion<'a>);
910
911#[allow(clippy::needless_lifetimes)]
912impl<'a> VariationRegion<'a> {
913 pub fn read(data: FontData<'a>, axis_count: u16) -> Result<Self, ReadError> {
918 let args = axis_count;
919 Self::read_with_args(data, args)
920 }
921}
922
923#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
925#[repr(C)]
926#[repr(packed)]
927pub struct RegionAxisCoordinates {
928 pub start_coord: BigEndian<F2Dot14>,
930 pub peak_coord: BigEndian<F2Dot14>,
932 pub end_coord: BigEndian<F2Dot14>,
934}
935
936impl RegionAxisCoordinates {
937 pub fn start_coord(&self) -> F2Dot14 {
939 self.start_coord.get()
940 }
941
942 pub fn peak_coord(&self) -> F2Dot14 {
944 self.peak_coord.get()
945 }
946
947 pub fn end_coord(&self) -> F2Dot14 {
949 self.end_coord.get()
950 }
951}
952
953impl FixedSize for RegionAxisCoordinates {
954 const RAW_BYTE_LEN: usize =
955 F2Dot14::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN;
956}
957
958impl<'a> MinByteRange<'a> for ItemVariationStore<'a> {
959 fn min_byte_range(&self) -> Range<usize> {
960 0..self.item_variation_data_offsets_byte_range().end
961 }
962 fn min_table_bytes(&self) -> &'a [u8] {
963 let range = self.min_byte_range();
964 self.data.as_bytes().get(range).unwrap_or_default()
965 }
966}
967
968impl ReadArgs for ItemVariationStore<'_> {
969 type Args = ();
970}
971
972impl<'a> FontRead<'a> for ItemVariationStore<'a> {
973 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
974 #[allow(clippy::absurd_extreme_comparisons)]
975 if data.len() < Self::MIN_SIZE {
976 return Err(ReadError::OutOfBounds);
977 }
978 Ok(Self { data })
979 }
980}
981
982#[derive(Clone)]
984pub struct ItemVariationStore<'a> {
985 data: FontData<'a>,
986}
987
988#[allow(clippy::needless_lifetimes)]
989impl<'a> ItemVariationStore<'a> {
990 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
991 basic_table_impls!(impl_the_methods);
992
993 pub fn format(&self) -> u16 {
995 let range = self.format_byte_range();
996 self.data.read_at(range.start).ok().unwrap()
997 }
998
999 pub fn variation_region_list_offset(&self) -> Offset32 {
1002 let range = self.variation_region_list_offset_byte_range();
1003 self.data.read_at(range.start).ok().unwrap()
1004 }
1005
1006 pub fn variation_region_list(&self) -> Result<VariationRegionList<'a>, ReadError> {
1008 let data = self.data;
1009 self.variation_region_list_offset().resolve(data)
1010 }
1011
1012 pub fn item_variation_data_count(&self) -> u16 {
1014 let range = self.item_variation_data_count_byte_range();
1015 self.data.read_at(range.start).ok().unwrap()
1016 }
1017
1018 pub fn item_variation_data_offsets(&self) -> &'a [BigEndian<Nullable<Offset32>>] {
1021 let range = self.item_variation_data_offsets_byte_range();
1022 self.data.read_array(range).ok().unwrap_or_default()
1023 }
1024
1025 pub fn item_variation_data(
1027 &self,
1028 ) -> ArrayOfNullableOffsets<'a, ItemVariationData<'a>, Offset32> {
1029 let data = self.data;
1030 let offsets = self.item_variation_data_offsets();
1031 ArrayOfNullableOffsets::new(offsets, data, ())
1032 }
1033
1034 pub fn format_byte_range(&self) -> Range<usize> {
1035 let start = 0;
1036 let end = start + u16::RAW_BYTE_LEN;
1037 start..end
1038 }
1039
1040 pub fn variation_region_list_offset_byte_range(&self) -> Range<usize> {
1041 let start = self.format_byte_range().end;
1042 let end = start + Offset32::RAW_BYTE_LEN;
1043 start..end
1044 }
1045
1046 pub fn item_variation_data_count_byte_range(&self) -> Range<usize> {
1047 let start = self.variation_region_list_offset_byte_range().end;
1048 let end = start + u16::RAW_BYTE_LEN;
1049 start..end
1050 }
1051
1052 pub fn item_variation_data_offsets_byte_range(&self) -> Range<usize> {
1053 let item_variation_data_count = self.item_variation_data_count();
1054 let start = self.item_variation_data_count_byte_range().end;
1055 let end = start
1056 + (transforms::to_usize(item_variation_data_count))
1057 .saturating_mul(Offset32::RAW_BYTE_LEN);
1058 start..end
1059 }
1060}
1061
1062const _: () = assert!(FontData::default_data_long_enough(
1063 ItemVariationStore::MIN_SIZE
1064));
1065
1066impl Default for ItemVariationStore<'_> {
1067 fn default() -> Self {
1068 Self {
1069 data: FontData::default_table_data(),
1070 }
1071 }
1072}
1073
1074impl<'a> MinByteRange<'a> for ItemVariationData<'a> {
1075 fn min_byte_range(&self) -> Range<usize> {
1076 0..self.delta_sets_byte_range().end
1077 }
1078 fn min_table_bytes(&self) -> &'a [u8] {
1079 let range = self.min_byte_range();
1080 self.data.as_bytes().get(range).unwrap_or_default()
1081 }
1082}
1083
1084impl ReadArgs for ItemVariationData<'_> {
1085 type Args = ();
1086}
1087
1088impl<'a> FontRead<'a> for ItemVariationData<'a> {
1089 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1090 #[allow(clippy::absurd_extreme_comparisons)]
1091 if data.len() < Self::MIN_SIZE {
1092 return Err(ReadError::OutOfBounds);
1093 }
1094 Ok(Self { data })
1095 }
1096}
1097
1098#[derive(Clone)]
1100pub struct ItemVariationData<'a> {
1101 data: FontData<'a>,
1102}
1103
1104#[allow(clippy::needless_lifetimes)]
1105impl<'a> ItemVariationData<'a> {
1106 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
1107 basic_table_impls!(impl_the_methods);
1108
1109 pub fn item_count(&self) -> u16 {
1111 let range = self.item_count_byte_range();
1112 self.data.read_at(range.start).ok().unwrap()
1113 }
1114
1115 pub fn word_delta_count(&self) -> u16 {
1117 let range = self.word_delta_count_byte_range();
1118 self.data.read_at(range.start).ok().unwrap()
1119 }
1120
1121 pub fn region_index_count(&self) -> u16 {
1123 let range = self.region_index_count_byte_range();
1124 self.data.read_at(range.start).ok().unwrap()
1125 }
1126
1127 pub fn region_indexes(&self) -> &'a [BigEndian<u16>] {
1130 let range = self.region_indexes_byte_range();
1131 self.data.read_array(range).ok().unwrap_or_default()
1132 }
1133
1134 pub fn delta_sets(&self) -> &'a [u8] {
1136 let range = self.delta_sets_byte_range();
1137 self.data.read_array(range).ok().unwrap_or_default()
1138 }
1139
1140 pub fn item_count_byte_range(&self) -> Range<usize> {
1141 let start = 0;
1142 let end = start + u16::RAW_BYTE_LEN;
1143 start..end
1144 }
1145
1146 pub fn word_delta_count_byte_range(&self) -> Range<usize> {
1147 let start = self.item_count_byte_range().end;
1148 let end = start + u16::RAW_BYTE_LEN;
1149 start..end
1150 }
1151
1152 pub fn region_index_count_byte_range(&self) -> Range<usize> {
1153 let start = self.word_delta_count_byte_range().end;
1154 let end = start + u16::RAW_BYTE_LEN;
1155 start..end
1156 }
1157
1158 pub fn region_indexes_byte_range(&self) -> Range<usize> {
1159 let region_index_count = self.region_index_count();
1160 let start = self.region_index_count_byte_range().end;
1161 let end =
1162 start + (transforms::to_usize(region_index_count)).saturating_mul(u16::RAW_BYTE_LEN);
1163 start..end
1164 }
1165
1166 pub fn delta_sets_byte_range(&self) -> Range<usize> {
1167 let item_count = self.item_count();
1168 let word_delta_count = self.word_delta_count();
1169 let region_index_count = self.region_index_count();
1170 let start = self.region_indexes_byte_range().end;
1171 let end = start
1172 + (ItemVariationData::delta_sets_len(item_count, word_delta_count, region_index_count))
1173 .saturating_mul(u8::RAW_BYTE_LEN);
1174 start..end
1175 }
1176}
1177
1178const _: () = assert!(FontData::default_data_long_enough(
1179 ItemVariationData::MIN_SIZE
1180));
1181
1182impl Default for ItemVariationData<'_> {
1183 fn default() -> Self {
1184 Self {
1185 data: FontData::default_table_data(),
1186 }
1187 }
1188}