Skip to main content

read_fonts/generated/
generated_variations.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 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    /// A constructor that requires additional arguments.
36    ///
37    /// This type requires some external state in order to be
38    /// parsed.
39    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/// [TupleVariationHeader](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader)
46#[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    /// The size in bytes of the serialized data for this tuple
58    /// variation table.
59    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    /// A packed field. The high 4 bits are flags (see below). The low
65    /// 12 bits are an index into a shared tuple records array.
66    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/// A [Tuple Record](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuple-records)
132///
133/// The tuple variation store formats reference regions within the font’s
134/// variation space using tuple records. A tuple record identifies a position
135/// in terms of normalized coordinates, which use F2DOT14 values.
136#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
137pub struct Tuple<'a> {
138    /// Coordinate array specifying a position within the font’s variation space.
139    ///
140    /// The number of elements must match the axisCount specified in the
141    /// 'fvar' table.
142    pub values: &'a [BigEndian<F2Dot14>],
143}
144
145impl<'a> Tuple<'a> {
146    /// Coordinate array specifying a position within the font’s variation space.
147    ///
148    /// The number of elements must match the axisCount specified in the
149    /// 'fvar' table.
150    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    /// A constructor that requires additional arguments.
182    ///
183    /// This type requires some external state in order to be
184    /// parsed.
185    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/// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table format 0
220#[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    /// DeltaSetIndexMap format: set to 0.
231    pub fn format(&self) -> u8 {
232        let range = self.format_byte_range();
233        self.data.read_at(range.start).ok().unwrap()
234    }
235
236    /// A packed field that describes the compressed representation of
237    /// delta-set indices. See details below.
238    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    /// The number of mapping entries.
244    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    /// The delta-set index mapping data. See details below.
250    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/// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table format 1
324#[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    /// DeltaSetIndexMap format: set to 1.
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    /// A packed field that describes the compressed representation of
341    /// delta-set indices. See details below.
342    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    /// The number of mapping entries.
348    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    /// The delta-set index mapping data. See details below.
354    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/// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table
400#[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    ///Return the `FontData` used to resolve offsets for this table.
414    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    /// DeltaSetIndexMap format: set to 0.
422    pub fn format(&self) -> u8 {
423        match self {
424            Self::Format0(item) => item.format(),
425            Self::Format1(item) => item.format(),
426        }
427    }
428
429    /// A packed field that describes the compressed representation of
430    /// delta-set indices. See details below.
431    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    /// The delta-set index mapping data. See details below.
439    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/// Entry format for a [DeltaSetIndexMap].
478#[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    /// Mask for the low 4 bits, which give the count of bits minus one that are used in each entry for the inner-level index.
487    pub const INNER_INDEX_BIT_COUNT_MASK: Self = Self { bits: 0x0F };
488
489    /// Mask for bits that indicate the size in bytes minus one of each entry.
490    pub const MAP_ENTRY_SIZE_MASK: Self = Self { bits: 0x30 };
491}
492
493impl EntryFormat {
494    ///  Returns an empty set of flags.
495    #[inline]
496    pub const fn empty() -> Self {
497        Self { bits: 0 }
498    }
499
500    /// Returns the set containing all flags.
501    #[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    /// Returns the raw value of the flags currently stored.
509    #[inline]
510    pub const fn bits(&self) -> u8 {
511        self.bits
512    }
513
514    /// Convert from underlying bit representation, unless that
515    /// representation contains bits that do not correspond to a flag.
516    #[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    /// Convert from underlying bit representation, dropping any bits
526    /// that do not correspond to flags.
527    #[inline]
528    pub const fn from_bits_truncate(bits: u8) -> Self {
529        Self {
530            bits: bits & Self::all().bits,
531        }
532    }
533
534    /// Returns `true` if no flags are currently stored.
535    #[inline]
536    pub const fn is_empty(&self) -> bool {
537        self.bits() == Self::empty().bits()
538    }
539
540    /// Returns `true` if there are flags common to both `self` and `other`.
541    #[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    /// Returns `true` if all of the flags in `other` are contained within `self`.
550    #[inline]
551    pub const fn contains(&self, other: Self) -> bool {
552        (self.bits & other.bits) == other.bits
553    }
554
555    /// Inserts the specified flags in-place.
556    #[inline]
557    pub fn insert(&mut self, other: Self) {
558        self.bits |= other.bits;
559    }
560
561    /// Removes the specified flags in-place.
562    #[inline]
563    pub fn remove(&mut self, other: Self) {
564        self.bits &= !other.bits;
565    }
566
567    /// Toggles the specified flags in-place.
568    #[inline]
569    pub fn toggle(&mut self, other: Self) {
570        self.bits ^= other.bits;
571    }
572
573    /// Returns the intersection between the flags in `self` and
574    /// `other`.
575    ///
576    /// Specifically, the returned set contains only the flags which are
577    /// present in *both* `self` *and* `other`.
578    ///
579    /// This is equivalent to using the `&` operator (e.g.
580    /// [`ops::BitAnd`]), as in `flags & other`.
581    ///
582    /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
583    #[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    /// Returns the union of between the flags in `self` and `other`.
592    ///
593    /// Specifically, the returned set contains all flags which are
594    /// present in *either* `self` *or* `other`, including any which are
595    /// present in both.
596    ///
597    /// This is equivalent to using the `|` operator (e.g.
598    /// [`ops::BitOr`]), as in `flags | other`.
599    ///
600    /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
601    #[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    /// Returns the difference between the flags in `self` and `other`.
610    ///
611    /// Specifically, the returned set contains all flags present in
612    /// `self`, except for the ones present in `other`.
613    ///
614    /// It is also conceptually equivalent to the "bit-clear" operation:
615    /// `flags & !other` (and this syntax is also supported).
616    ///
617    /// This is equivalent to using the `-` operator (e.g.
618    /// [`ops::Sub`]), as in `flags - other`.
619    ///
620    /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
621    #[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    /// Returns the union of the two sets of flags.
634    #[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    /// Adds the set of flags.
644    #[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    /// Returns the left flags, but with all the right flags toggled.
654    #[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    /// Toggles the set of flags.
664    #[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    /// Returns the intersection between the two sets of flags.
674    #[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    /// Disables all flags disabled in the set.
684    #[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    /// Returns the set difference of the two sets of flags.
694    #[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    /// Disables all flags enabled in the set.
704    #[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    /// Returns the complement of this set of flags.
714    #[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/// The [VariationRegionList](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#variation-regions) table
806#[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    /// The number of variation axes for this font. This must be the
817    /// same number as axisCount in the 'fvar' table.
818    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    /// The number of variation region tables in the variation region
824    /// list. Must be less than 32,768.
825    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    /// Array of variation regions.
831    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/// The [VariationRegion](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#variation-regions) record
872#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
873pub struct VariationRegion<'a> {
874    /// Array of region axis coordinates records, in the order of axes
875    /// given in the 'fvar' table.
876    pub region_axes: &'a [RegionAxisCoordinates],
877}
878
879impl<'a> VariationRegion<'a> {
880    /// Array of region axis coordinates records, in the order of axes
881    /// given in the 'fvar' table.
882    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    /// A constructor that requires additional arguments.
914    ///
915    /// This type requires some external state in order to be
916    /// parsed.
917    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/// The [RegionAxisCoordinates](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#variation-regions) record
924#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
925#[repr(C)]
926#[repr(packed)]
927pub struct RegionAxisCoordinates {
928    /// The region start coordinate value for the current axis.
929    pub start_coord: BigEndian<F2Dot14>,
930    /// The region peak coordinate value for the current axis.
931    pub peak_coord: BigEndian<F2Dot14>,
932    /// The region end coordinate value for the current axis.
933    pub end_coord: BigEndian<F2Dot14>,
934}
935
936impl RegionAxisCoordinates {
937    /// The region start coordinate value for the current axis.
938    pub fn start_coord(&self) -> F2Dot14 {
939        self.start_coord.get()
940    }
941
942    /// The region peak coordinate value for the current axis.
943    pub fn peak_coord(&self) -> F2Dot14 {
944        self.peak_coord.get()
945    }
946
947    /// The region end coordinate value for the current axis.
948    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/// The [ItemVariationStore](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables) table
983#[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    /// Format— set to 1
994    pub fn format(&self) -> u16 {
995        let range = self.format_byte_range();
996        self.data.read_at(range.start).ok().unwrap()
997    }
998
999    /// Offset in bytes from the start of the item variation store to
1000    /// the variation region list.
1001    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    /// Attempt to resolve [`variation_region_list_offset`][Self::variation_region_list_offset].
1007    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    /// The number of item variation data subtables.
1013    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    /// Offsets in bytes from the start of the item variation store to
1019    /// each item variation data subtable.
1020    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    /// A dynamically resolving wrapper for [`item_variation_data_offsets`][Self::item_variation_data_offsets].
1026    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/// The [ItemVariationData](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables) subtable
1099#[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    /// The number of delta sets for distinct items.
1110    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    /// A packed field: the high bit is a flag—see details below.
1116    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    /// The number of variation regions referenced.
1122    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    /// Array of indices into the variation region list for the regions
1128    /// referenced by this item variation data table.
1129    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    /// Delta-set rows.
1135    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}