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
8/// [TupleVariationHeader](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader)
9#[derive(Debug, Clone, Copy)]
10#[doc(hidden)]
11pub struct TupleVariationHeaderMarker {
12    peak_tuple_byte_len: usize,
13    intermediate_start_tuple_byte_len: usize,
14    intermediate_end_tuple_byte_len: usize,
15}
16
17impl TupleVariationHeaderMarker {
18    pub fn variation_data_size_byte_range(&self) -> Range<usize> {
19        let start = 0;
20        start..start + u16::RAW_BYTE_LEN
21    }
22
23    pub fn tuple_index_byte_range(&self) -> Range<usize> {
24        let start = self.variation_data_size_byte_range().end;
25        start..start + TupleIndex::RAW_BYTE_LEN
26    }
27
28    pub fn peak_tuple_byte_range(&self) -> Range<usize> {
29        let start = self.tuple_index_byte_range().end;
30        start..start + self.peak_tuple_byte_len
31    }
32
33    pub fn intermediate_start_tuple_byte_range(&self) -> Range<usize> {
34        let start = self.peak_tuple_byte_range().end;
35        start..start + self.intermediate_start_tuple_byte_len
36    }
37
38    pub fn intermediate_end_tuple_byte_range(&self) -> Range<usize> {
39        let start = self.intermediate_start_tuple_byte_range().end;
40        start..start + self.intermediate_end_tuple_byte_len
41    }
42}
43
44impl MinByteRange for TupleVariationHeaderMarker {
45    fn min_byte_range(&self) -> Range<usize> {
46        0..self.intermediate_end_tuple_byte_range().end
47    }
48}
49
50impl ReadArgs for TupleVariationHeader<'_> {
51    type Args = u16;
52}
53
54impl<'a> FontReadWithArgs<'a> for TupleVariationHeader<'a> {
55    fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> {
56        let axis_count = *args;
57        let mut cursor = data.cursor();
58        cursor.advance::<u16>();
59        let tuple_index: TupleIndex = cursor.read()?;
60        let peak_tuple_byte_len = (TupleIndex::tuple_len(tuple_index, axis_count, 0_usize))
61            .checked_mul(F2Dot14::RAW_BYTE_LEN)
62            .ok_or(ReadError::OutOfBounds)?;
63        cursor.advance_by(peak_tuple_byte_len);
64        let intermediate_start_tuple_byte_len =
65            (TupleIndex::tuple_len(tuple_index, axis_count, 1_usize))
66                .checked_mul(F2Dot14::RAW_BYTE_LEN)
67                .ok_or(ReadError::OutOfBounds)?;
68        cursor.advance_by(intermediate_start_tuple_byte_len);
69        let intermediate_end_tuple_byte_len =
70            (TupleIndex::tuple_len(tuple_index, axis_count, 1_usize))
71                .checked_mul(F2Dot14::RAW_BYTE_LEN)
72                .ok_or(ReadError::OutOfBounds)?;
73        cursor.advance_by(intermediate_end_tuple_byte_len);
74        cursor.finish(TupleVariationHeaderMarker {
75            peak_tuple_byte_len,
76            intermediate_start_tuple_byte_len,
77            intermediate_end_tuple_byte_len,
78        })
79    }
80}
81
82impl<'a> TupleVariationHeader<'a> {
83    /// A constructor that requires additional arguments.
84    ///
85    /// This type requires some external state in order to be
86    /// parsed.
87    pub fn read(data: FontData<'a>, axis_count: u16) -> Result<Self, ReadError> {
88        let args = axis_count;
89        Self::read_with_args(data, &args)
90    }
91}
92
93/// [TupleVariationHeader](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader)
94pub type TupleVariationHeader<'a> = TableRef<'a, TupleVariationHeaderMarker>;
95
96#[allow(clippy::needless_lifetimes)]
97impl<'a> TupleVariationHeader<'a> {
98    /// The size in bytes of the serialized data for this tuple
99    /// variation table.
100    pub fn variation_data_size(&self) -> u16 {
101        let range = self.shape.variation_data_size_byte_range();
102        self.data.read_at(range.start).unwrap()
103    }
104
105    /// A packed field. The high 4 bits are flags (see below). The low
106    /// 12 bits are an index into a shared tuple records array.
107    pub fn tuple_index(&self) -> TupleIndex {
108        let range = self.shape.tuple_index_byte_range();
109        self.data.read_at(range.start).unwrap()
110    }
111}
112
113#[cfg(feature = "experimental_traverse")]
114impl<'a> SomeTable<'a> for TupleVariationHeader<'a> {
115    fn type_name(&self) -> &str {
116        "TupleVariationHeader"
117    }
118    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
119        match idx {
120            0usize => Some(Field::new(
121                "variation_data_size",
122                self.variation_data_size(),
123            )),
124            1usize => Some(Field::new("tuple_index", self.traverse_tuple_index())),
125            _ => None,
126        }
127    }
128}
129
130#[cfg(feature = "experimental_traverse")]
131#[allow(clippy::needless_lifetimes)]
132impl<'a> std::fmt::Debug for TupleVariationHeader<'a> {
133    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134        (self as &dyn SomeTable<'a>).fmt(f)
135    }
136}
137
138/// A [Tuple Record](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuple-records)
139///
140/// The tuple variation store formats reference regions within the font’s
141/// variation space using tuple records. A tuple record identifies a position
142/// in terms of normalized coordinates, which use F2DOT14 values.
143#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
144pub struct Tuple<'a> {
145    /// Coordinate array specifying a position within the font’s variation space.
146    ///
147    /// The number of elements must match the axisCount specified in the
148    /// 'fvar' table.
149    pub values: &'a [BigEndian<F2Dot14>],
150}
151
152impl<'a> Tuple<'a> {
153    /// Coordinate array specifying a position within the font’s variation space.
154    ///
155    /// The number of elements must match the axisCount specified in the
156    /// 'fvar' table.
157    pub fn values(&self) -> &'a [BigEndian<F2Dot14>] {
158        self.values
159    }
160}
161
162impl ReadArgs for Tuple<'_> {
163    type Args = u16;
164}
165
166impl ComputeSize for Tuple<'_> {
167    #[allow(clippy::needless_question_mark)]
168    fn compute_size(args: &u16) -> Result<usize, ReadError> {
169        let axis_count = *args;
170        Ok((axis_count as usize)
171            .checked_mul(F2Dot14::RAW_BYTE_LEN)
172            .ok_or(ReadError::OutOfBounds)?)
173    }
174}
175
176impl<'a> FontReadWithArgs<'a> for Tuple<'a> {
177    fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> {
178        let mut cursor = data.cursor();
179        let axis_count = *args;
180        Ok(Self {
181            values: cursor.read_array(axis_count as usize)?,
182        })
183    }
184}
185
186#[allow(clippy::needless_lifetimes)]
187impl<'a> Tuple<'a> {
188    /// A constructor that requires additional arguments.
189    ///
190    /// This type requires some external state in order to be
191    /// parsed.
192    pub fn read(data: FontData<'a>, axis_count: u16) -> Result<Self, ReadError> {
193        let args = axis_count;
194        Self::read_with_args(data, &args)
195    }
196}
197
198#[cfg(feature = "experimental_traverse")]
199impl<'a> SomeRecord<'a> for Tuple<'a> {
200    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
201        RecordResolver {
202            name: "Tuple",
203            get_field: Box::new(move |idx, _data| match idx {
204                0usize => Some(Field::new("values", self.values())),
205                _ => None,
206            }),
207            data,
208        }
209    }
210}
211
212impl Format<u8> for DeltaSetIndexMapFormat0Marker {
213    const FORMAT: u8 = 0;
214}
215
216/// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table format 0
217#[derive(Debug, Clone, Copy)]
218#[doc(hidden)]
219pub struct DeltaSetIndexMapFormat0Marker {
220    map_data_byte_len: usize,
221}
222
223impl DeltaSetIndexMapFormat0Marker {
224    pub fn format_byte_range(&self) -> Range<usize> {
225        let start = 0;
226        start..start + u8::RAW_BYTE_LEN
227    }
228
229    pub fn entry_format_byte_range(&self) -> Range<usize> {
230        let start = self.format_byte_range().end;
231        start..start + EntryFormat::RAW_BYTE_LEN
232    }
233
234    pub fn map_count_byte_range(&self) -> Range<usize> {
235        let start = self.entry_format_byte_range().end;
236        start..start + u16::RAW_BYTE_LEN
237    }
238
239    pub fn map_data_byte_range(&self) -> Range<usize> {
240        let start = self.map_count_byte_range().end;
241        start..start + self.map_data_byte_len
242    }
243}
244
245impl MinByteRange for DeltaSetIndexMapFormat0Marker {
246    fn min_byte_range(&self) -> Range<usize> {
247        0..self.map_data_byte_range().end
248    }
249}
250
251impl<'a> FontRead<'a> for DeltaSetIndexMapFormat0<'a> {
252    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
253        let mut cursor = data.cursor();
254        cursor.advance::<u8>();
255        let entry_format: EntryFormat = cursor.read()?;
256        let map_count: u16 = cursor.read()?;
257        let map_data_byte_len = (EntryFormat::map_size(entry_format, map_count))
258            .checked_mul(u8::RAW_BYTE_LEN)
259            .ok_or(ReadError::OutOfBounds)?;
260        cursor.advance_by(map_data_byte_len);
261        cursor.finish(DeltaSetIndexMapFormat0Marker { map_data_byte_len })
262    }
263}
264
265/// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table format 0
266pub type DeltaSetIndexMapFormat0<'a> = TableRef<'a, DeltaSetIndexMapFormat0Marker>;
267
268#[allow(clippy::needless_lifetimes)]
269impl<'a> DeltaSetIndexMapFormat0<'a> {
270    /// DeltaSetIndexMap format: set to 0.
271    pub fn format(&self) -> u8 {
272        let range = self.shape.format_byte_range();
273        self.data.read_at(range.start).unwrap()
274    }
275
276    /// A packed field that describes the compressed representation of
277    /// delta-set indices. See details below.
278    pub fn entry_format(&self) -> EntryFormat {
279        let range = self.shape.entry_format_byte_range();
280        self.data.read_at(range.start).unwrap()
281    }
282
283    /// The number of mapping entries.
284    pub fn map_count(&self) -> u16 {
285        let range = self.shape.map_count_byte_range();
286        self.data.read_at(range.start).unwrap()
287    }
288
289    /// The delta-set index mapping data. See details below.
290    pub fn map_data(&self) -> &'a [u8] {
291        let range = self.shape.map_data_byte_range();
292        self.data.read_array(range).unwrap()
293    }
294}
295
296#[cfg(feature = "experimental_traverse")]
297impl<'a> SomeTable<'a> for DeltaSetIndexMapFormat0<'a> {
298    fn type_name(&self) -> &str {
299        "DeltaSetIndexMapFormat0"
300    }
301    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
302        match idx {
303            0usize => Some(Field::new("format", self.format())),
304            1usize => Some(Field::new("entry_format", self.entry_format())),
305            2usize => Some(Field::new("map_count", self.map_count())),
306            3usize => Some(Field::new("map_data", self.map_data())),
307            _ => None,
308        }
309    }
310}
311
312#[cfg(feature = "experimental_traverse")]
313#[allow(clippy::needless_lifetimes)]
314impl<'a> std::fmt::Debug for DeltaSetIndexMapFormat0<'a> {
315    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
316        (self as &dyn SomeTable<'a>).fmt(f)
317    }
318}
319
320impl Format<u8> for DeltaSetIndexMapFormat1Marker {
321    const FORMAT: u8 = 1;
322}
323
324/// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table format 1
325#[derive(Debug, Clone, Copy)]
326#[doc(hidden)]
327pub struct DeltaSetIndexMapFormat1Marker {
328    map_data_byte_len: usize,
329}
330
331impl DeltaSetIndexMapFormat1Marker {
332    pub fn format_byte_range(&self) -> Range<usize> {
333        let start = 0;
334        start..start + u8::RAW_BYTE_LEN
335    }
336
337    pub fn entry_format_byte_range(&self) -> Range<usize> {
338        let start = self.format_byte_range().end;
339        start..start + EntryFormat::RAW_BYTE_LEN
340    }
341
342    pub fn map_count_byte_range(&self) -> Range<usize> {
343        let start = self.entry_format_byte_range().end;
344        start..start + u32::RAW_BYTE_LEN
345    }
346
347    pub fn map_data_byte_range(&self) -> Range<usize> {
348        let start = self.map_count_byte_range().end;
349        start..start + self.map_data_byte_len
350    }
351}
352
353impl MinByteRange for DeltaSetIndexMapFormat1Marker {
354    fn min_byte_range(&self) -> Range<usize> {
355        0..self.map_data_byte_range().end
356    }
357}
358
359impl<'a> FontRead<'a> for DeltaSetIndexMapFormat1<'a> {
360    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
361        let mut cursor = data.cursor();
362        cursor.advance::<u8>();
363        let entry_format: EntryFormat = cursor.read()?;
364        let map_count: u32 = cursor.read()?;
365        let map_data_byte_len = (EntryFormat::map_size(entry_format, map_count))
366            .checked_mul(u8::RAW_BYTE_LEN)
367            .ok_or(ReadError::OutOfBounds)?;
368        cursor.advance_by(map_data_byte_len);
369        cursor.finish(DeltaSetIndexMapFormat1Marker { map_data_byte_len })
370    }
371}
372
373/// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table format 1
374pub type DeltaSetIndexMapFormat1<'a> = TableRef<'a, DeltaSetIndexMapFormat1Marker>;
375
376#[allow(clippy::needless_lifetimes)]
377impl<'a> DeltaSetIndexMapFormat1<'a> {
378    /// DeltaSetIndexMap format: set to 1.
379    pub fn format(&self) -> u8 {
380        let range = self.shape.format_byte_range();
381        self.data.read_at(range.start).unwrap()
382    }
383
384    /// A packed field that describes the compressed representation of
385    /// delta-set indices. See details below.
386    pub fn entry_format(&self) -> EntryFormat {
387        let range = self.shape.entry_format_byte_range();
388        self.data.read_at(range.start).unwrap()
389    }
390
391    /// The number of mapping entries.
392    pub fn map_count(&self) -> u32 {
393        let range = self.shape.map_count_byte_range();
394        self.data.read_at(range.start).unwrap()
395    }
396
397    /// The delta-set index mapping data. See details below.
398    pub fn map_data(&self) -> &'a [u8] {
399        let range = self.shape.map_data_byte_range();
400        self.data.read_array(range).unwrap()
401    }
402}
403
404#[cfg(feature = "experimental_traverse")]
405impl<'a> SomeTable<'a> for DeltaSetIndexMapFormat1<'a> {
406    fn type_name(&self) -> &str {
407        "DeltaSetIndexMapFormat1"
408    }
409    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
410        match idx {
411            0usize => Some(Field::new("format", self.format())),
412            1usize => Some(Field::new("entry_format", self.entry_format())),
413            2usize => Some(Field::new("map_count", self.map_count())),
414            3usize => Some(Field::new("map_data", self.map_data())),
415            _ => None,
416        }
417    }
418}
419
420#[cfg(feature = "experimental_traverse")]
421#[allow(clippy::needless_lifetimes)]
422impl<'a> std::fmt::Debug for DeltaSetIndexMapFormat1<'a> {
423    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
424        (self as &dyn SomeTable<'a>).fmt(f)
425    }
426}
427
428/// The [DeltaSetIndexMap](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#associating-target-items-to-variation-data) table
429#[derive(Clone)]
430pub enum DeltaSetIndexMap<'a> {
431    Format0(DeltaSetIndexMapFormat0<'a>),
432    Format1(DeltaSetIndexMapFormat1<'a>),
433}
434
435impl<'a> DeltaSetIndexMap<'a> {
436    ///Return the `FontData` used to resolve offsets for this table.
437    pub fn offset_data(&self) -> FontData<'a> {
438        match self {
439            Self::Format0(item) => item.offset_data(),
440            Self::Format1(item) => item.offset_data(),
441        }
442    }
443
444    /// DeltaSetIndexMap format: set to 0.
445    pub fn format(&self) -> u8 {
446        match self {
447            Self::Format0(item) => item.format(),
448            Self::Format1(item) => item.format(),
449        }
450    }
451
452    /// A packed field that describes the compressed representation of
453    /// delta-set indices. See details below.
454    pub fn entry_format(&self) -> EntryFormat {
455        match self {
456            Self::Format0(item) => item.entry_format(),
457            Self::Format1(item) => item.entry_format(),
458        }
459    }
460
461    /// The delta-set index mapping data. See details below.
462    pub fn map_data(&self) -> &'a [u8] {
463        match self {
464            Self::Format0(item) => item.map_data(),
465            Self::Format1(item) => item.map_data(),
466        }
467    }
468}
469
470impl<'a> FontRead<'a> for DeltaSetIndexMap<'a> {
471    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
472        let format: u8 = data.read_at(0usize)?;
473        match format {
474            DeltaSetIndexMapFormat0Marker::FORMAT => Ok(Self::Format0(FontRead::read(data)?)),
475            DeltaSetIndexMapFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
476            other => Err(ReadError::InvalidFormat(other.into())),
477        }
478    }
479}
480
481impl MinByteRange for DeltaSetIndexMap<'_> {
482    fn min_byte_range(&self) -> Range<usize> {
483        match self {
484            Self::Format0(item) => item.min_byte_range(),
485            Self::Format1(item) => item.min_byte_range(),
486        }
487    }
488}
489
490#[cfg(feature = "experimental_traverse")]
491impl<'a> DeltaSetIndexMap<'a> {
492    fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
493        match self {
494            Self::Format0(table) => table,
495            Self::Format1(table) => table,
496        }
497    }
498}
499
500#[cfg(feature = "experimental_traverse")]
501impl std::fmt::Debug for DeltaSetIndexMap<'_> {
502    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
503        self.dyn_inner().fmt(f)
504    }
505}
506
507#[cfg(feature = "experimental_traverse")]
508impl<'a> SomeTable<'a> for DeltaSetIndexMap<'a> {
509    fn type_name(&self) -> &str {
510        self.dyn_inner().type_name()
511    }
512    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
513        self.dyn_inner().get_field(idx)
514    }
515}
516
517/// Entry format for a [DeltaSetIndexMap].
518#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
519#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
520#[repr(transparent)]
521pub struct EntryFormat {
522    bits: u8,
523}
524
525impl EntryFormat {
526    /// 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.
527    pub const INNER_INDEX_BIT_COUNT_MASK: Self = Self { bits: 0x0F };
528
529    /// Mask for bits that indicate the size in bytes minus one of each entry.
530    pub const MAP_ENTRY_SIZE_MASK: Self = Self { bits: 0x30 };
531}
532
533impl EntryFormat {
534    ///  Returns an empty set of flags.
535    #[inline]
536    pub const fn empty() -> Self {
537        Self { bits: 0 }
538    }
539
540    /// Returns the set containing all flags.
541    #[inline]
542    pub const fn all() -> Self {
543        Self {
544            bits: Self::INNER_INDEX_BIT_COUNT_MASK.bits | Self::MAP_ENTRY_SIZE_MASK.bits,
545        }
546    }
547
548    /// Returns the raw value of the flags currently stored.
549    #[inline]
550    pub const fn bits(&self) -> u8 {
551        self.bits
552    }
553
554    /// Convert from underlying bit representation, unless that
555    /// representation contains bits that do not correspond to a flag.
556    #[inline]
557    pub const fn from_bits(bits: u8) -> Option<Self> {
558        if (bits & !Self::all().bits()) == 0 {
559            Some(Self { bits })
560        } else {
561            None
562        }
563    }
564
565    /// Convert from underlying bit representation, dropping any bits
566    /// that do not correspond to flags.
567    #[inline]
568    pub const fn from_bits_truncate(bits: u8) -> Self {
569        Self {
570            bits: bits & Self::all().bits,
571        }
572    }
573
574    /// Returns `true` if no flags are currently stored.
575    #[inline]
576    pub const fn is_empty(&self) -> bool {
577        self.bits() == Self::empty().bits()
578    }
579
580    /// Returns `true` if there are flags common to both `self` and `other`.
581    #[inline]
582    pub const fn intersects(&self, other: Self) -> bool {
583        !(Self {
584            bits: self.bits & other.bits,
585        })
586        .is_empty()
587    }
588
589    /// Returns `true` if all of the flags in `other` are contained within `self`.
590    #[inline]
591    pub const fn contains(&self, other: Self) -> bool {
592        (self.bits & other.bits) == other.bits
593    }
594
595    /// Inserts the specified flags in-place.
596    #[inline]
597    pub fn insert(&mut self, other: Self) {
598        self.bits |= other.bits;
599    }
600
601    /// Removes the specified flags in-place.
602    #[inline]
603    pub fn remove(&mut self, other: Self) {
604        self.bits &= !other.bits;
605    }
606
607    /// Toggles the specified flags in-place.
608    #[inline]
609    pub fn toggle(&mut self, other: Self) {
610        self.bits ^= other.bits;
611    }
612
613    /// Returns the intersection between the flags in `self` and
614    /// `other`.
615    ///
616    /// Specifically, the returned set contains only the flags which are
617    /// present in *both* `self` *and* `other`.
618    ///
619    /// This is equivalent to using the `&` operator (e.g.
620    /// [`ops::BitAnd`]), as in `flags & other`.
621    ///
622    /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
623    #[inline]
624    #[must_use]
625    pub const fn intersection(self, other: Self) -> Self {
626        Self {
627            bits: self.bits & other.bits,
628        }
629    }
630
631    /// Returns the union of between the flags in `self` and `other`.
632    ///
633    /// Specifically, the returned set contains all flags which are
634    /// present in *either* `self` *or* `other`, including any which are
635    /// present in both.
636    ///
637    /// This is equivalent to using the `|` operator (e.g.
638    /// [`ops::BitOr`]), as in `flags | other`.
639    ///
640    /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
641    #[inline]
642    #[must_use]
643    pub const fn union(self, other: Self) -> Self {
644        Self {
645            bits: self.bits | other.bits,
646        }
647    }
648
649    /// Returns the difference between the flags in `self` and `other`.
650    ///
651    /// Specifically, the returned set contains all flags present in
652    /// `self`, except for the ones present in `other`.
653    ///
654    /// It is also conceptually equivalent to the "bit-clear" operation:
655    /// `flags & !other` (and this syntax is also supported).
656    ///
657    /// This is equivalent to using the `-` operator (e.g.
658    /// [`ops::Sub`]), as in `flags - other`.
659    ///
660    /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
661    #[inline]
662    #[must_use]
663    pub const fn difference(self, other: Self) -> Self {
664        Self {
665            bits: self.bits & !other.bits,
666        }
667    }
668}
669
670impl std::ops::BitOr for EntryFormat {
671    type Output = Self;
672
673    /// Returns the union of the two sets of flags.
674    #[inline]
675    fn bitor(self, other: EntryFormat) -> Self {
676        Self {
677            bits: self.bits | other.bits,
678        }
679    }
680}
681
682impl std::ops::BitOrAssign for EntryFormat {
683    /// Adds the set of flags.
684    #[inline]
685    fn bitor_assign(&mut self, other: Self) {
686        self.bits |= other.bits;
687    }
688}
689
690impl std::ops::BitXor for EntryFormat {
691    type Output = Self;
692
693    /// Returns the left flags, but with all the right flags toggled.
694    #[inline]
695    fn bitxor(self, other: Self) -> Self {
696        Self {
697            bits: self.bits ^ other.bits,
698        }
699    }
700}
701
702impl std::ops::BitXorAssign for EntryFormat {
703    /// Toggles the set of flags.
704    #[inline]
705    fn bitxor_assign(&mut self, other: Self) {
706        self.bits ^= other.bits;
707    }
708}
709
710impl std::ops::BitAnd for EntryFormat {
711    type Output = Self;
712
713    /// Returns the intersection between the two sets of flags.
714    #[inline]
715    fn bitand(self, other: Self) -> Self {
716        Self {
717            bits: self.bits & other.bits,
718        }
719    }
720}
721
722impl std::ops::BitAndAssign for EntryFormat {
723    /// Disables all flags disabled in the set.
724    #[inline]
725    fn bitand_assign(&mut self, other: Self) {
726        self.bits &= other.bits;
727    }
728}
729
730impl std::ops::Sub for EntryFormat {
731    type Output = Self;
732
733    /// Returns the set difference of the two sets of flags.
734    #[inline]
735    fn sub(self, other: Self) -> Self {
736        Self {
737            bits: self.bits & !other.bits,
738        }
739    }
740}
741
742impl std::ops::SubAssign for EntryFormat {
743    /// Disables all flags enabled in the set.
744    #[inline]
745    fn sub_assign(&mut self, other: Self) {
746        self.bits &= !other.bits;
747    }
748}
749
750impl std::ops::Not for EntryFormat {
751    type Output = Self;
752
753    /// Returns the complement of this set of flags.
754    #[inline]
755    fn not(self) -> Self {
756        Self { bits: !self.bits } & Self::all()
757    }
758}
759
760impl std::fmt::Debug for EntryFormat {
761    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
762        let members: &[(&str, Self)] = &[
763            (
764                "INNER_INDEX_BIT_COUNT_MASK",
765                Self::INNER_INDEX_BIT_COUNT_MASK,
766            ),
767            ("MAP_ENTRY_SIZE_MASK", Self::MAP_ENTRY_SIZE_MASK),
768        ];
769        let mut first = true;
770        for (name, value) in members {
771            if self.contains(*value) {
772                if !first {
773                    f.write_str(" | ")?;
774                }
775                first = false;
776                f.write_str(name)?;
777            }
778        }
779        if first {
780            f.write_str("(empty)")?;
781        }
782        Ok(())
783    }
784}
785
786impl std::fmt::Binary for EntryFormat {
787    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
788        std::fmt::Binary::fmt(&self.bits, f)
789    }
790}
791
792impl std::fmt::Octal for EntryFormat {
793    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
794        std::fmt::Octal::fmt(&self.bits, f)
795    }
796}
797
798impl std::fmt::LowerHex for EntryFormat {
799    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
800        std::fmt::LowerHex::fmt(&self.bits, f)
801    }
802}
803
804impl std::fmt::UpperHex for EntryFormat {
805    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
806        std::fmt::UpperHex::fmt(&self.bits, f)
807    }
808}
809
810impl font_types::Scalar for EntryFormat {
811    type Raw = <u8 as font_types::Scalar>::Raw;
812    fn to_raw(self) -> Self::Raw {
813        self.bits().to_raw()
814    }
815    fn from_raw(raw: Self::Raw) -> Self {
816        let t = <u8>::from_raw(raw);
817        Self::from_bits_truncate(t)
818    }
819}
820
821#[cfg(feature = "experimental_traverse")]
822impl<'a> From<EntryFormat> for FieldType<'a> {
823    fn from(src: EntryFormat) -> FieldType<'a> {
824        src.bits().into()
825    }
826}
827
828/// The [VariationRegionList](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#variation-regions) table
829#[derive(Debug, Clone, Copy)]
830#[doc(hidden)]
831pub struct VariationRegionListMarker {
832    variation_regions_byte_len: usize,
833}
834
835impl VariationRegionListMarker {
836    pub fn axis_count_byte_range(&self) -> Range<usize> {
837        let start = 0;
838        start..start + u16::RAW_BYTE_LEN
839    }
840
841    pub fn region_count_byte_range(&self) -> Range<usize> {
842        let start = self.axis_count_byte_range().end;
843        start..start + u16::RAW_BYTE_LEN
844    }
845
846    pub fn variation_regions_byte_range(&self) -> Range<usize> {
847        let start = self.region_count_byte_range().end;
848        start..start + self.variation_regions_byte_len
849    }
850}
851
852impl MinByteRange for VariationRegionListMarker {
853    fn min_byte_range(&self) -> Range<usize> {
854        0..self.variation_regions_byte_range().end
855    }
856}
857
858impl<'a> FontRead<'a> for VariationRegionList<'a> {
859    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
860        let mut cursor = data.cursor();
861        let axis_count: u16 = cursor.read()?;
862        let region_count: u16 = cursor.read()?;
863        let variation_regions_byte_len = (region_count as usize)
864            .checked_mul(<VariationRegion as ComputeSize>::compute_size(&axis_count)?)
865            .ok_or(ReadError::OutOfBounds)?;
866        cursor.advance_by(variation_regions_byte_len);
867        cursor.finish(VariationRegionListMarker {
868            variation_regions_byte_len,
869        })
870    }
871}
872
873/// The [VariationRegionList](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#variation-regions) table
874pub type VariationRegionList<'a> = TableRef<'a, VariationRegionListMarker>;
875
876#[allow(clippy::needless_lifetimes)]
877impl<'a> VariationRegionList<'a> {
878    /// The number of variation axes for this font. This must be the
879    /// same number as axisCount in the 'fvar' table.
880    pub fn axis_count(&self) -> u16 {
881        let range = self.shape.axis_count_byte_range();
882        self.data.read_at(range.start).unwrap()
883    }
884
885    /// The number of variation region tables in the variation region
886    /// list. Must be less than 32,768.
887    pub fn region_count(&self) -> u16 {
888        let range = self.shape.region_count_byte_range();
889        self.data.read_at(range.start).unwrap()
890    }
891
892    /// Array of variation regions.
893    pub fn variation_regions(&self) -> ComputedArray<'a, VariationRegion<'a>> {
894        let range = self.shape.variation_regions_byte_range();
895        self.data.read_with_args(range, &self.axis_count()).unwrap()
896    }
897}
898
899#[cfg(feature = "experimental_traverse")]
900impl<'a> SomeTable<'a> for VariationRegionList<'a> {
901    fn type_name(&self) -> &str {
902        "VariationRegionList"
903    }
904    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
905        match idx {
906            0usize => Some(Field::new("axis_count", self.axis_count())),
907            1usize => Some(Field::new("region_count", self.region_count())),
908            2usize => Some(Field::new(
909                "variation_regions",
910                traversal::FieldType::computed_array(
911                    "VariationRegion",
912                    self.variation_regions(),
913                    self.offset_data(),
914                ),
915            )),
916            _ => None,
917        }
918    }
919}
920
921#[cfg(feature = "experimental_traverse")]
922#[allow(clippy::needless_lifetimes)]
923impl<'a> std::fmt::Debug for VariationRegionList<'a> {
924    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
925        (self as &dyn SomeTable<'a>).fmt(f)
926    }
927}
928
929/// The [VariationRegion](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#variation-regions) record
930#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
931pub struct VariationRegion<'a> {
932    /// Array of region axis coordinates records, in the order of axes
933    /// given in the 'fvar' table.
934    pub region_axes: &'a [RegionAxisCoordinates],
935}
936
937impl<'a> VariationRegion<'a> {
938    /// Array of region axis coordinates records, in the order of axes
939    /// given in the 'fvar' table.
940    pub fn region_axes(&self) -> &'a [RegionAxisCoordinates] {
941        self.region_axes
942    }
943}
944
945impl ReadArgs for VariationRegion<'_> {
946    type Args = u16;
947}
948
949impl ComputeSize for VariationRegion<'_> {
950    #[allow(clippy::needless_question_mark)]
951    fn compute_size(args: &u16) -> Result<usize, ReadError> {
952        let axis_count = *args;
953        Ok((axis_count as usize)
954            .checked_mul(RegionAxisCoordinates::RAW_BYTE_LEN)
955            .ok_or(ReadError::OutOfBounds)?)
956    }
957}
958
959impl<'a> FontReadWithArgs<'a> for VariationRegion<'a> {
960    fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> {
961        let mut cursor = data.cursor();
962        let axis_count = *args;
963        Ok(Self {
964            region_axes: cursor.read_array(axis_count as usize)?,
965        })
966    }
967}
968
969#[allow(clippy::needless_lifetimes)]
970impl<'a> VariationRegion<'a> {
971    /// A constructor that requires additional arguments.
972    ///
973    /// This type requires some external state in order to be
974    /// parsed.
975    pub fn read(data: FontData<'a>, axis_count: u16) -> Result<Self, ReadError> {
976        let args = axis_count;
977        Self::read_with_args(data, &args)
978    }
979}
980
981#[cfg(feature = "experimental_traverse")]
982impl<'a> SomeRecord<'a> for VariationRegion<'a> {
983    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
984        RecordResolver {
985            name: "VariationRegion",
986            get_field: Box::new(move |idx, _data| match idx {
987                0usize => Some(Field::new(
988                    "region_axes",
989                    traversal::FieldType::array_of_records(
990                        stringify!(RegionAxisCoordinates),
991                        self.region_axes(),
992                        _data,
993                    ),
994                )),
995                _ => None,
996            }),
997            data,
998        }
999    }
1000}
1001
1002/// The [RegionAxisCoordinates](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#variation-regions) record
1003#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
1004#[repr(C)]
1005#[repr(packed)]
1006pub struct RegionAxisCoordinates {
1007    /// The region start coordinate value for the current axis.
1008    pub start_coord: BigEndian<F2Dot14>,
1009    /// The region peak coordinate value for the current axis.
1010    pub peak_coord: BigEndian<F2Dot14>,
1011    /// The region end coordinate value for the current axis.
1012    pub end_coord: BigEndian<F2Dot14>,
1013}
1014
1015impl RegionAxisCoordinates {
1016    /// The region start coordinate value for the current axis.
1017    pub fn start_coord(&self) -> F2Dot14 {
1018        self.start_coord.get()
1019    }
1020
1021    /// The region peak coordinate value for the current axis.
1022    pub fn peak_coord(&self) -> F2Dot14 {
1023        self.peak_coord.get()
1024    }
1025
1026    /// The region end coordinate value for the current axis.
1027    pub fn end_coord(&self) -> F2Dot14 {
1028        self.end_coord.get()
1029    }
1030}
1031
1032impl FixedSize for RegionAxisCoordinates {
1033    const RAW_BYTE_LEN: usize =
1034        F2Dot14::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN;
1035}
1036
1037#[cfg(feature = "experimental_traverse")]
1038impl<'a> SomeRecord<'a> for RegionAxisCoordinates {
1039    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
1040        RecordResolver {
1041            name: "RegionAxisCoordinates",
1042            get_field: Box::new(move |idx, _data| match idx {
1043                0usize => Some(Field::new("start_coord", self.start_coord())),
1044                1usize => Some(Field::new("peak_coord", self.peak_coord())),
1045                2usize => Some(Field::new("end_coord", self.end_coord())),
1046                _ => None,
1047            }),
1048            data,
1049        }
1050    }
1051}
1052
1053/// The [ItemVariationStore](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables) table
1054#[derive(Debug, Clone, Copy)]
1055#[doc(hidden)]
1056pub struct ItemVariationStoreMarker {
1057    item_variation_data_offsets_byte_len: usize,
1058}
1059
1060impl ItemVariationStoreMarker {
1061    pub fn format_byte_range(&self) -> Range<usize> {
1062        let start = 0;
1063        start..start + u16::RAW_BYTE_LEN
1064    }
1065
1066    pub fn variation_region_list_offset_byte_range(&self) -> Range<usize> {
1067        let start = self.format_byte_range().end;
1068        start..start + Offset32::RAW_BYTE_LEN
1069    }
1070
1071    pub fn item_variation_data_count_byte_range(&self) -> Range<usize> {
1072        let start = self.variation_region_list_offset_byte_range().end;
1073        start..start + u16::RAW_BYTE_LEN
1074    }
1075
1076    pub fn item_variation_data_offsets_byte_range(&self) -> Range<usize> {
1077        let start = self.item_variation_data_count_byte_range().end;
1078        start..start + self.item_variation_data_offsets_byte_len
1079    }
1080}
1081
1082impl MinByteRange for ItemVariationStoreMarker {
1083    fn min_byte_range(&self) -> Range<usize> {
1084        0..self.item_variation_data_offsets_byte_range().end
1085    }
1086}
1087
1088impl<'a> FontRead<'a> for ItemVariationStore<'a> {
1089    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1090        let mut cursor = data.cursor();
1091        cursor.advance::<u16>();
1092        cursor.advance::<Offset32>();
1093        let item_variation_data_count: u16 = cursor.read()?;
1094        let item_variation_data_offsets_byte_len = (item_variation_data_count as usize)
1095            .checked_mul(Offset32::RAW_BYTE_LEN)
1096            .ok_or(ReadError::OutOfBounds)?;
1097        cursor.advance_by(item_variation_data_offsets_byte_len);
1098        cursor.finish(ItemVariationStoreMarker {
1099            item_variation_data_offsets_byte_len,
1100        })
1101    }
1102}
1103
1104/// The [ItemVariationStore](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables) table
1105pub type ItemVariationStore<'a> = TableRef<'a, ItemVariationStoreMarker>;
1106
1107#[allow(clippy::needless_lifetimes)]
1108impl<'a> ItemVariationStore<'a> {
1109    /// Format— set to 1
1110    pub fn format(&self) -> u16 {
1111        let range = self.shape.format_byte_range();
1112        self.data.read_at(range.start).unwrap()
1113    }
1114
1115    /// Offset in bytes from the start of the item variation store to
1116    /// the variation region list.
1117    pub fn variation_region_list_offset(&self) -> Offset32 {
1118        let range = self.shape.variation_region_list_offset_byte_range();
1119        self.data.read_at(range.start).unwrap()
1120    }
1121
1122    /// Attempt to resolve [`variation_region_list_offset`][Self::variation_region_list_offset].
1123    pub fn variation_region_list(&self) -> Result<VariationRegionList<'a>, ReadError> {
1124        let data = self.data;
1125        self.variation_region_list_offset().resolve(data)
1126    }
1127
1128    /// The number of item variation data subtables.
1129    pub fn item_variation_data_count(&self) -> u16 {
1130        let range = self.shape.item_variation_data_count_byte_range();
1131        self.data.read_at(range.start).unwrap()
1132    }
1133
1134    /// Offsets in bytes from the start of the item variation store to
1135    /// each item variation data subtable.
1136    pub fn item_variation_data_offsets(&self) -> &'a [BigEndian<Nullable<Offset32>>] {
1137        let range = self.shape.item_variation_data_offsets_byte_range();
1138        self.data.read_array(range).unwrap()
1139    }
1140
1141    /// A dynamically resolving wrapper for [`item_variation_data_offsets`][Self::item_variation_data_offsets].
1142    pub fn item_variation_data(
1143        &self,
1144    ) -> ArrayOfNullableOffsets<'a, ItemVariationData<'a>, Offset32> {
1145        let data = self.data;
1146        let offsets = self.item_variation_data_offsets();
1147        ArrayOfNullableOffsets::new(offsets, data, ())
1148    }
1149}
1150
1151#[cfg(feature = "experimental_traverse")]
1152impl<'a> SomeTable<'a> for ItemVariationStore<'a> {
1153    fn type_name(&self) -> &str {
1154        "ItemVariationStore"
1155    }
1156    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1157        match idx {
1158            0usize => Some(Field::new("format", self.format())),
1159            1usize => Some(Field::new(
1160                "variation_region_list_offset",
1161                FieldType::offset(
1162                    self.variation_region_list_offset(),
1163                    self.variation_region_list(),
1164                ),
1165            )),
1166            2usize => Some(Field::new(
1167                "item_variation_data_count",
1168                self.item_variation_data_count(),
1169            )),
1170            3usize => Some({
1171                let data = self.data;
1172                Field::new(
1173                    "item_variation_data_offsets",
1174                    FieldType::array_of_offsets(
1175                        better_type_name::<ItemVariationData>(),
1176                        self.item_variation_data_offsets(),
1177                        move |off| {
1178                            let target = off.get().resolve::<ItemVariationData>(data);
1179                            FieldType::offset(off.get(), target)
1180                        },
1181                    ),
1182                )
1183            }),
1184            _ => None,
1185        }
1186    }
1187}
1188
1189#[cfg(feature = "experimental_traverse")]
1190#[allow(clippy::needless_lifetimes)]
1191impl<'a> std::fmt::Debug for ItemVariationStore<'a> {
1192    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1193        (self as &dyn SomeTable<'a>).fmt(f)
1194    }
1195}
1196
1197/// The [ItemVariationData](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables) subtable
1198#[derive(Debug, Clone, Copy)]
1199#[doc(hidden)]
1200pub struct ItemVariationDataMarker {
1201    region_indexes_byte_len: usize,
1202    delta_sets_byte_len: usize,
1203}
1204
1205impl ItemVariationDataMarker {
1206    pub fn item_count_byte_range(&self) -> Range<usize> {
1207        let start = 0;
1208        start..start + u16::RAW_BYTE_LEN
1209    }
1210
1211    pub fn word_delta_count_byte_range(&self) -> Range<usize> {
1212        let start = self.item_count_byte_range().end;
1213        start..start + u16::RAW_BYTE_LEN
1214    }
1215
1216    pub fn region_index_count_byte_range(&self) -> Range<usize> {
1217        let start = self.word_delta_count_byte_range().end;
1218        start..start + u16::RAW_BYTE_LEN
1219    }
1220
1221    pub fn region_indexes_byte_range(&self) -> Range<usize> {
1222        let start = self.region_index_count_byte_range().end;
1223        start..start + self.region_indexes_byte_len
1224    }
1225
1226    pub fn delta_sets_byte_range(&self) -> Range<usize> {
1227        let start = self.region_indexes_byte_range().end;
1228        start..start + self.delta_sets_byte_len
1229    }
1230}
1231
1232impl MinByteRange for ItemVariationDataMarker {
1233    fn min_byte_range(&self) -> Range<usize> {
1234        0..self.delta_sets_byte_range().end
1235    }
1236}
1237
1238impl<'a> FontRead<'a> for ItemVariationData<'a> {
1239    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1240        let mut cursor = data.cursor();
1241        let item_count: u16 = cursor.read()?;
1242        let word_delta_count: u16 = cursor.read()?;
1243        let region_index_count: u16 = cursor.read()?;
1244        let region_indexes_byte_len = (region_index_count as usize)
1245            .checked_mul(u16::RAW_BYTE_LEN)
1246            .ok_or(ReadError::OutOfBounds)?;
1247        cursor.advance_by(region_indexes_byte_len);
1248        let delta_sets_byte_len =
1249            (ItemVariationData::delta_sets_len(item_count, word_delta_count, region_index_count))
1250                .checked_mul(u8::RAW_BYTE_LEN)
1251                .ok_or(ReadError::OutOfBounds)?;
1252        cursor.advance_by(delta_sets_byte_len);
1253        cursor.finish(ItemVariationDataMarker {
1254            region_indexes_byte_len,
1255            delta_sets_byte_len,
1256        })
1257    }
1258}
1259
1260/// The [ItemVariationData](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables) subtable
1261pub type ItemVariationData<'a> = TableRef<'a, ItemVariationDataMarker>;
1262
1263#[allow(clippy::needless_lifetimes)]
1264impl<'a> ItemVariationData<'a> {
1265    /// The number of delta sets for distinct items.
1266    pub fn item_count(&self) -> u16 {
1267        let range = self.shape.item_count_byte_range();
1268        self.data.read_at(range.start).unwrap()
1269    }
1270
1271    /// A packed field: the high bit is a flag—see details below.
1272    pub fn word_delta_count(&self) -> u16 {
1273        let range = self.shape.word_delta_count_byte_range();
1274        self.data.read_at(range.start).unwrap()
1275    }
1276
1277    /// The number of variation regions referenced.
1278    pub fn region_index_count(&self) -> u16 {
1279        let range = self.shape.region_index_count_byte_range();
1280        self.data.read_at(range.start).unwrap()
1281    }
1282
1283    /// Array of indices into the variation region list for the regions
1284    /// referenced by this item variation data table.
1285    pub fn region_indexes(&self) -> &'a [BigEndian<u16>] {
1286        let range = self.shape.region_indexes_byte_range();
1287        self.data.read_array(range).unwrap()
1288    }
1289
1290    /// Delta-set rows.
1291    pub fn delta_sets(&self) -> &'a [u8] {
1292        let range = self.shape.delta_sets_byte_range();
1293        self.data.read_array(range).unwrap()
1294    }
1295}
1296
1297#[cfg(feature = "experimental_traverse")]
1298impl<'a> SomeTable<'a> for ItemVariationData<'a> {
1299    fn type_name(&self) -> &str {
1300        "ItemVariationData"
1301    }
1302    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1303        match idx {
1304            0usize => Some(Field::new("item_count", self.item_count())),
1305            1usize => Some(Field::new("word_delta_count", self.word_delta_count())),
1306            2usize => Some(Field::new("region_index_count", self.region_index_count())),
1307            3usize => Some(Field::new("region_indexes", self.region_indexes())),
1308            4usize => Some(Field::new("delta_sets", self.delta_sets())),
1309            _ => None,
1310        }
1311    }
1312}
1313
1314#[cfg(feature = "experimental_traverse")]
1315#[allow(clippy::needless_lifetimes)]
1316impl<'a> std::fmt::Debug for ItemVariationData<'a> {
1317    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1318        (self as &dyn SomeTable<'a>).fmt(f)
1319    }
1320}