Skip to main content

read_fonts/generated/
generated_glyf.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 TopLevelTable for Glyf<'_> {
9    /// `glyf`
10    const TAG: Tag = Tag::new(b"glyf");
11}
12
13impl ReadArgs for Glyf<'_> {
14    type Args = ();
15}
16
17impl<'a> FontRead<'a> for Glyf<'a> {
18    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
19        #[allow(clippy::absurd_extreme_comparisons)]
20        if data.len() < Self::MIN_SIZE {
21            return Err(ReadError::OutOfBounds);
22        }
23        Ok(Self { data })
24    }
25}
26
27/// The [glyf (Glyph Data)](https://docs.microsoft.com/en-us/typography/opentype/spec/glyf) table
28#[derive(Clone)]
29pub struct Glyf<'a> {
30    data: FontData<'a>,
31}
32
33#[allow(clippy::needless_lifetimes)]
34impl<'a> Glyf<'a> {
35    pub const MIN_SIZE: usize = 0;
36    basic_table_impls!(impl_the_methods);
37}
38
39#[allow(clippy::absurd_extreme_comparisons)]
40const _: () = assert!(FontData::default_data_long_enough(Glyf::MIN_SIZE));
41
42impl Default for Glyf<'_> {
43    fn default() -> Self {
44        Self {
45            data: FontData::default_table_data(),
46        }
47    }
48}
49
50#[cfg(feature = "experimental_traverse")]
51impl<'a> SomeTable<'a> for Glyf<'a> {
52    fn type_name(&self) -> &str {
53        "Glyf"
54    }
55
56    #[allow(unused_variables)]
57    #[allow(clippy::match_single_binding)]
58    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
59        match idx {
60            _ => None,
61        }
62    }
63}
64
65#[cfg(feature = "experimental_traverse")]
66#[allow(clippy::needless_lifetimes)]
67impl<'a> std::fmt::Debug for Glyf<'a> {
68    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69        (self as &dyn SomeTable<'a>).fmt(f)
70    }
71}
72
73impl<'a> MinByteRange<'a> for SimpleGlyph<'a> {
74    fn min_byte_range(&self) -> Range<usize> {
75        0..self.glyph_data_byte_range().end
76    }
77    fn min_table_bytes(&self) -> &'a [u8] {
78        let range = self.min_byte_range();
79        self.data.as_bytes().get(range).unwrap_or_default()
80    }
81}
82
83impl ReadArgs for SimpleGlyph<'_> {
84    type Args = ();
85}
86
87impl<'a> FontRead<'a> for SimpleGlyph<'a> {
88    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
89        #[allow(clippy::absurd_extreme_comparisons)]
90        if data.len() < Self::MIN_SIZE {
91            return Err(ReadError::OutOfBounds);
92        }
93        Ok(Self { data })
94    }
95}
96
97/// The [Glyph Header](https://docs.microsoft.com/en-us/typography/opentype/spec/glyf#glyph-headers)
98#[derive(Clone)]
99pub struct SimpleGlyph<'a> {
100    data: FontData<'a>,
101}
102
103#[allow(clippy::needless_lifetimes)]
104impl<'a> SimpleGlyph<'a> {
105    pub const MIN_SIZE: usize = (i16::RAW_BYTE_LEN
106        + i16::RAW_BYTE_LEN
107        + i16::RAW_BYTE_LEN
108        + i16::RAW_BYTE_LEN
109        + i16::RAW_BYTE_LEN
110        + u16::RAW_BYTE_LEN);
111    basic_table_impls!(impl_the_methods);
112
113    /// If the number of contours is greater than or equal to zero,
114    /// this is a simple glyph. If negative, this is a composite glyph
115    /// — the value -1 should be used for composite glyphs.
116    pub fn number_of_contours(&self) -> i16 {
117        let range = self.number_of_contours_byte_range();
118        self.data.read_at(range.start).ok().unwrap()
119    }
120
121    /// Minimum x for coordinate data.
122    pub fn x_min(&self) -> i16 {
123        let range = self.x_min_byte_range();
124        self.data.read_at(range.start).ok().unwrap()
125    }
126
127    /// Minimum y for coordinate data.
128    pub fn y_min(&self) -> i16 {
129        let range = self.y_min_byte_range();
130        self.data.read_at(range.start).ok().unwrap()
131    }
132
133    /// Maximum x for coordinate data.
134    pub fn x_max(&self) -> i16 {
135        let range = self.x_max_byte_range();
136        self.data.read_at(range.start).ok().unwrap()
137    }
138
139    /// Maximum y for coordinate data.
140    pub fn y_max(&self) -> i16 {
141        let range = self.y_max_byte_range();
142        self.data.read_at(range.start).ok().unwrap()
143    }
144
145    /// Array of point indices for the last point of each contour,
146    /// in increasing numeric order
147    pub fn end_pts_of_contours(&self) -> &'a [BigEndian<u16>] {
148        let range = self.end_pts_of_contours_byte_range();
149        self.data.read_array(range).ok().unwrap_or_default()
150    }
151
152    /// Total number of bytes for instructions. If instructionLength is
153    /// zero, no instructions are present for this glyph, and this
154    /// field is followed directly by the flags field.
155    pub fn instruction_length(&self) -> u16 {
156        let range = self.instruction_length_byte_range();
157        self.data.read_at(range.start).ok().unwrap_or_default()
158    }
159
160    /// Array of instruction byte code for the glyph.
161    pub fn instructions(&self) -> &'a [u8] {
162        let range = self.instructions_byte_range();
163        self.data.read_array(range).ok().unwrap_or_default()
164    }
165
166    /// the raw data for flags & x/y coordinates
167    pub fn glyph_data(&self) -> &'a [u8] {
168        let range = self.glyph_data_byte_range();
169        self.data.read_array(range).ok().unwrap_or_default()
170    }
171
172    pub fn number_of_contours_byte_range(&self) -> Range<usize> {
173        let start = 0;
174        let end = start + i16::RAW_BYTE_LEN;
175        start..end
176    }
177
178    pub fn x_min_byte_range(&self) -> Range<usize> {
179        let start = self.number_of_contours_byte_range().end;
180        let end = start + i16::RAW_BYTE_LEN;
181        start..end
182    }
183
184    pub fn y_min_byte_range(&self) -> Range<usize> {
185        let start = self.x_min_byte_range().end;
186        let end = start + i16::RAW_BYTE_LEN;
187        start..end
188    }
189
190    pub fn x_max_byte_range(&self) -> Range<usize> {
191        let start = self.y_min_byte_range().end;
192        let end = start + i16::RAW_BYTE_LEN;
193        start..end
194    }
195
196    pub fn y_max_byte_range(&self) -> Range<usize> {
197        let start = self.x_max_byte_range().end;
198        let end = start + i16::RAW_BYTE_LEN;
199        start..end
200    }
201
202    pub fn end_pts_of_contours_byte_range(&self) -> Range<usize> {
203        let number_of_contours = self.number_of_contours();
204        let start = self.y_max_byte_range().end;
205        let end =
206            start + (transforms::to_usize(number_of_contours)).saturating_mul(u16::RAW_BYTE_LEN);
207        start..end
208    }
209
210    pub fn instruction_length_byte_range(&self) -> Range<usize> {
211        let start = self.end_pts_of_contours_byte_range().end;
212        let end = start + u16::RAW_BYTE_LEN;
213        start..end
214    }
215
216    pub fn instructions_byte_range(&self) -> Range<usize> {
217        let instruction_length = self.instruction_length();
218        let start = self.instruction_length_byte_range().end;
219        let end =
220            start + (transforms::to_usize(instruction_length)).saturating_mul(u8::RAW_BYTE_LEN);
221        start..end
222    }
223
224    pub fn glyph_data_byte_range(&self) -> Range<usize> {
225        let start = self.instructions_byte_range().end;
226        let end =
227            start + self.data.len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
228        start..end
229    }
230}
231
232const _: () = assert!(FontData::default_data_long_enough(SimpleGlyph::MIN_SIZE));
233
234impl Default for SimpleGlyph<'_> {
235    fn default() -> Self {
236        Self {
237            data: FontData::default_table_data(),
238        }
239    }
240}
241
242#[cfg(feature = "experimental_traverse")]
243impl<'a> SomeTable<'a> for SimpleGlyph<'a> {
244    fn type_name(&self) -> &str {
245        "SimpleGlyph"
246    }
247    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
248        match idx {
249            0usize => Some(Field::new("number_of_contours", self.number_of_contours())),
250            1usize => Some(Field::new("x_min", self.x_min())),
251            2usize => Some(Field::new("y_min", self.y_min())),
252            3usize => Some(Field::new("x_max", self.x_max())),
253            4usize => Some(Field::new("y_max", self.y_max())),
254            5usize => Some(Field::new(
255                "end_pts_of_contours",
256                self.end_pts_of_contours(),
257            )),
258            6usize => Some(Field::new("instruction_length", self.instruction_length())),
259            7usize => Some(Field::new("instructions", self.instructions())),
260            8usize => Some(Field::new("glyph_data", self.glyph_data())),
261            _ => None,
262        }
263    }
264}
265
266#[cfg(feature = "experimental_traverse")]
267#[allow(clippy::needless_lifetimes)]
268impl<'a> std::fmt::Debug for SimpleGlyph<'a> {
269    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
270        (self as &dyn SomeTable<'a>).fmt(f)
271    }
272}
273
274/// Flags used in [SimpleGlyph]
275#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
276#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
277#[repr(transparent)]
278pub struct SimpleGlyphFlags {
279    bits: u8,
280}
281
282impl SimpleGlyphFlags {
283    /// Bit 0: If set, the point is on the curve; otherwise, it is off
284    /// the curve.
285    pub const ON_CURVE_POINT: Self = Self { bits: 0x01 };
286
287    /// Bit 1: If set, the corresponding x-coordinate is 1 byte long,
288    /// and the sign is determined by the
289    /// X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR flag. If not set, its
290    /// interpretation depends on the
291    /// X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR flag: If that other flag
292    /// is set, the x-coordinate is the same as the previous
293    /// x-coordinate, and no element is added to the xCoordinates
294    /// array. If both flags are not set, the corresponding element in
295    /// the xCoordinates array is two bytes and interpreted as a signed
296    /// integer. See the description of the
297    /// X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR flag for additional
298    /// information.
299    pub const X_SHORT_VECTOR: Self = Self { bits: 0x02 };
300
301    /// Bit 2: If set, the corresponding y-coordinate is 1 byte long,
302    /// and the sign is determined by the
303    /// Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR flag. If not set, its
304    /// interpretation depends on the
305    /// Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR flag: If that other flag
306    /// is set, the y-coordinate is the same as the previous
307    /// y-coordinate, and no element is added to the yCoordinates
308    /// array. If both flags are not set, the corresponding element in
309    /// the yCoordinates array is two bytes and interpreted as a signed
310    /// integer. See the description of the
311    /// Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR flag for additional
312    /// information.
313    pub const Y_SHORT_VECTOR: Self = Self { bits: 0x04 };
314
315    /// Bit 3: If set, the next byte (read as unsigned) specifies the
316    /// number of additional times this flag byte is to be repeated in
317    /// the logical flags array — that is, the number of additional
318    /// logical flag entries inserted after this entry. (In the
319    /// expanded logical array, this bit is ignored.) In this way, the
320    /// number of flags listed can be smaller than the number of points
321    /// in the glyph description.
322    pub const REPEAT_FLAG: Self = Self { bits: 0x08 };
323
324    /// Bit 4: This flag has two meanings, depending on how the
325    /// X_SHORT_VECTOR flag is set. If X_SHORT_VECTOR is set, this bit
326    /// describes the sign of the value, with 1 equalling positive and
327    /// 0 negative. If X_SHORT_VECTOR is not set and this bit is set,
328    /// then the current x-coordinate is the same as the previous
329    /// x-coordinate. If X_SHORT_VECTOR is not set and this bit is also
330    /// not set, the current x-coordinate is a signed 16-bit delta
331    /// vector.
332    pub const X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR: Self = Self { bits: 0x10 };
333
334    /// Bit 5: This flag has two meanings, depending on how the
335    /// Y_SHORT_VECTOR flag is set. If Y_SHORT_VECTOR is set, this bit
336    /// describes the sign of the value, with 1 equalling positive and
337    /// 0 negative. If Y_SHORT_VECTOR is not set and this bit is set,
338    /// then the current y-coordinate is the same as the previous
339    /// y-coordinate. If Y_SHORT_VECTOR is not set and this bit is also
340    /// not set, the current y-coordinate is a signed 16-bit delta
341    /// vector.
342    pub const Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR: Self = Self { bits: 0x20 };
343
344    /// Bit 6: If set, contours in the glyph description may overlap.
345    /// Use of this flag is not required in OpenType — that is, it is
346    /// valid to have contours overlap without having this flag set. It
347    /// may affect behaviors in some platforms, however. (See the
348    /// discussion of “Overlapping contours” in Apple’s
349    /// specification for details regarding behavior in Apple
350    /// platforms.) When used, it must be set on the first flag byte
351    /// for the glyph. See additional details below.
352    pub const OVERLAP_SIMPLE: Self = Self { bits: 0x40 };
353
354    /// Bit 7: Off-curve point belongs to a cubic-Bezier segment
355    ///
356    /// * [Spec](https://github.com/harfbuzz/boring-expansion-spec/blob/main/glyf1-cubicOutlines.md)
357    /// * [harfbuzz](https://github.com/harfbuzz/harfbuzz/blob/c1ca46e4ebb6457dfe00a5441d52a4a66134ac58/src/OT/glyf/SimpleGlyph.hh#L23)
358    pub const CUBIC: Self = Self { bits: 0x80 };
359}
360
361impl SimpleGlyphFlags {
362    ///  Returns an empty set of flags.
363    #[inline]
364    pub const fn empty() -> Self {
365        Self { bits: 0 }
366    }
367
368    /// Returns the set containing all flags.
369    #[inline]
370    pub const fn all() -> Self {
371        Self {
372            bits: Self::ON_CURVE_POINT.bits
373                | Self::X_SHORT_VECTOR.bits
374                | Self::Y_SHORT_VECTOR.bits
375                | Self::REPEAT_FLAG.bits
376                | Self::X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR.bits
377                | Self::Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR.bits
378                | Self::OVERLAP_SIMPLE.bits
379                | Self::CUBIC.bits,
380        }
381    }
382
383    /// Returns the raw value of the flags currently stored.
384    #[inline]
385    pub const fn bits(&self) -> u8 {
386        self.bits
387    }
388
389    /// Convert from underlying bit representation, unless that
390    /// representation contains bits that do not correspond to a flag.
391    #[inline]
392    pub const fn from_bits(bits: u8) -> Option<Self> {
393        if (bits & !Self::all().bits()) == 0 {
394            Some(Self { bits })
395        } else {
396            None
397        }
398    }
399
400    /// Convert from underlying bit representation, dropping any bits
401    /// that do not correspond to flags.
402    #[inline]
403    pub const fn from_bits_truncate(bits: u8) -> Self {
404        Self {
405            bits: bits & Self::all().bits,
406        }
407    }
408
409    /// Returns `true` if no flags are currently stored.
410    #[inline]
411    pub const fn is_empty(&self) -> bool {
412        self.bits() == Self::empty().bits()
413    }
414
415    /// Returns `true` if there are flags common to both `self` and `other`.
416    #[inline]
417    pub const fn intersects(&self, other: Self) -> bool {
418        !(Self {
419            bits: self.bits & other.bits,
420        })
421        .is_empty()
422    }
423
424    /// Returns `true` if all of the flags in `other` are contained within `self`.
425    #[inline]
426    pub const fn contains(&self, other: Self) -> bool {
427        (self.bits & other.bits) == other.bits
428    }
429
430    /// Inserts the specified flags in-place.
431    #[inline]
432    pub fn insert(&mut self, other: Self) {
433        self.bits |= other.bits;
434    }
435
436    /// Removes the specified flags in-place.
437    #[inline]
438    pub fn remove(&mut self, other: Self) {
439        self.bits &= !other.bits;
440    }
441
442    /// Toggles the specified flags in-place.
443    #[inline]
444    pub fn toggle(&mut self, other: Self) {
445        self.bits ^= other.bits;
446    }
447
448    /// Returns the intersection between the flags in `self` and
449    /// `other`.
450    ///
451    /// Specifically, the returned set contains only the flags which are
452    /// present in *both* `self` *and* `other`.
453    ///
454    /// This is equivalent to using the `&` operator (e.g.
455    /// [`ops::BitAnd`]), as in `flags & other`.
456    ///
457    /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
458    #[inline]
459    #[must_use]
460    pub const fn intersection(self, other: Self) -> Self {
461        Self {
462            bits: self.bits & other.bits,
463        }
464    }
465
466    /// Returns the union of between the flags in `self` and `other`.
467    ///
468    /// Specifically, the returned set contains all flags which are
469    /// present in *either* `self` *or* `other`, including any which are
470    /// present in both.
471    ///
472    /// This is equivalent to using the `|` operator (e.g.
473    /// [`ops::BitOr`]), as in `flags | other`.
474    ///
475    /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
476    #[inline]
477    #[must_use]
478    pub const fn union(self, other: Self) -> Self {
479        Self {
480            bits: self.bits | other.bits,
481        }
482    }
483
484    /// Returns the difference between the flags in `self` and `other`.
485    ///
486    /// Specifically, the returned set contains all flags present in
487    /// `self`, except for the ones present in `other`.
488    ///
489    /// It is also conceptually equivalent to the "bit-clear" operation:
490    /// `flags & !other` (and this syntax is also supported).
491    ///
492    /// This is equivalent to using the `-` operator (e.g.
493    /// [`ops::Sub`]), as in `flags - other`.
494    ///
495    /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
496    #[inline]
497    #[must_use]
498    pub const fn difference(self, other: Self) -> Self {
499        Self {
500            bits: self.bits & !other.bits,
501        }
502    }
503}
504
505impl std::ops::BitOr for SimpleGlyphFlags {
506    type Output = Self;
507
508    /// Returns the union of the two sets of flags.
509    #[inline]
510    fn bitor(self, other: SimpleGlyphFlags) -> Self {
511        Self {
512            bits: self.bits | other.bits,
513        }
514    }
515}
516
517impl std::ops::BitOrAssign for SimpleGlyphFlags {
518    /// Adds the set of flags.
519    #[inline]
520    fn bitor_assign(&mut self, other: Self) {
521        self.bits |= other.bits;
522    }
523}
524
525impl std::ops::BitXor for SimpleGlyphFlags {
526    type Output = Self;
527
528    /// Returns the left flags, but with all the right flags toggled.
529    #[inline]
530    fn bitxor(self, other: Self) -> Self {
531        Self {
532            bits: self.bits ^ other.bits,
533        }
534    }
535}
536
537impl std::ops::BitXorAssign for SimpleGlyphFlags {
538    /// Toggles the set of flags.
539    #[inline]
540    fn bitxor_assign(&mut self, other: Self) {
541        self.bits ^= other.bits;
542    }
543}
544
545impl std::ops::BitAnd for SimpleGlyphFlags {
546    type Output = Self;
547
548    /// Returns the intersection between the two sets of flags.
549    #[inline]
550    fn bitand(self, other: Self) -> Self {
551        Self {
552            bits: self.bits & other.bits,
553        }
554    }
555}
556
557impl std::ops::BitAndAssign for SimpleGlyphFlags {
558    /// Disables all flags disabled in the set.
559    #[inline]
560    fn bitand_assign(&mut self, other: Self) {
561        self.bits &= other.bits;
562    }
563}
564
565impl std::ops::Sub for SimpleGlyphFlags {
566    type Output = Self;
567
568    /// Returns the set difference of the two sets of flags.
569    #[inline]
570    fn sub(self, other: Self) -> Self {
571        Self {
572            bits: self.bits & !other.bits,
573        }
574    }
575}
576
577impl std::ops::SubAssign for SimpleGlyphFlags {
578    /// Disables all flags enabled in the set.
579    #[inline]
580    fn sub_assign(&mut self, other: Self) {
581        self.bits &= !other.bits;
582    }
583}
584
585impl std::ops::Not for SimpleGlyphFlags {
586    type Output = Self;
587
588    /// Returns the complement of this set of flags.
589    #[inline]
590    fn not(self) -> Self {
591        Self { bits: !self.bits } & Self::all()
592    }
593}
594
595impl std::fmt::Debug for SimpleGlyphFlags {
596    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
597        let members: &[(&str, Self)] = &[
598            ("ON_CURVE_POINT", Self::ON_CURVE_POINT),
599            ("X_SHORT_VECTOR", Self::X_SHORT_VECTOR),
600            ("Y_SHORT_VECTOR", Self::Y_SHORT_VECTOR),
601            ("REPEAT_FLAG", Self::REPEAT_FLAG),
602            (
603                "X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR",
604                Self::X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR,
605            ),
606            (
607                "Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR",
608                Self::Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR,
609            ),
610            ("OVERLAP_SIMPLE", Self::OVERLAP_SIMPLE),
611            ("CUBIC", Self::CUBIC),
612        ];
613        let mut first = true;
614        for (name, value) in members {
615            if self.contains(*value) {
616                if !first {
617                    f.write_str(" | ")?;
618                }
619                first = false;
620                f.write_str(name)?;
621            }
622        }
623        if first {
624            f.write_str("(empty)")?;
625        }
626        Ok(())
627    }
628}
629
630impl std::fmt::Binary for SimpleGlyphFlags {
631    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
632        std::fmt::Binary::fmt(&self.bits, f)
633    }
634}
635
636impl std::fmt::Octal for SimpleGlyphFlags {
637    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
638        std::fmt::Octal::fmt(&self.bits, f)
639    }
640}
641
642impl std::fmt::LowerHex for SimpleGlyphFlags {
643    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
644        std::fmt::LowerHex::fmt(&self.bits, f)
645    }
646}
647
648impl std::fmt::UpperHex for SimpleGlyphFlags {
649    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
650        std::fmt::UpperHex::fmt(&self.bits, f)
651    }
652}
653
654impl font_types::Scalar for SimpleGlyphFlags {
655    type Raw = <u8 as font_types::Scalar>::Raw;
656    fn to_raw(self) -> Self::Raw {
657        self.bits().to_raw()
658    }
659    fn from_raw(raw: Self::Raw) -> Self {
660        let t = <u8>::from_raw(raw);
661        Self::from_bits_truncate(t)
662    }
663}
664
665#[cfg(feature = "experimental_traverse")]
666impl<'a> From<SimpleGlyphFlags> for FieldType<'a> {
667    fn from(src: SimpleGlyphFlags) -> FieldType<'a> {
668        src.bits().into()
669    }
670}
671
672impl<'a> MinByteRange<'a> for CompositeGlyph<'a> {
673    fn min_byte_range(&self) -> Range<usize> {
674        0..self.component_data_byte_range().end
675    }
676    fn min_table_bytes(&self) -> &'a [u8] {
677        let range = self.min_byte_range();
678        self.data.as_bytes().get(range).unwrap_or_default()
679    }
680}
681
682impl ReadArgs for CompositeGlyph<'_> {
683    type Args = ();
684}
685
686impl<'a> FontRead<'a> for CompositeGlyph<'a> {
687    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
688        #[allow(clippy::absurd_extreme_comparisons)]
689        if data.len() < Self::MIN_SIZE {
690            return Err(ReadError::OutOfBounds);
691        }
692        Ok(Self { data })
693    }
694}
695
696/// [CompositeGlyph](https://docs.microsoft.com/en-us/typography/opentype/spec/glyf#glyph-headers)
697#[derive(Clone)]
698pub struct CompositeGlyph<'a> {
699    data: FontData<'a>,
700}
701
702#[allow(clippy::needless_lifetimes)]
703impl<'a> CompositeGlyph<'a> {
704    pub const MIN_SIZE: usize = (i16::RAW_BYTE_LEN
705        + i16::RAW_BYTE_LEN
706        + i16::RAW_BYTE_LEN
707        + i16::RAW_BYTE_LEN
708        + i16::RAW_BYTE_LEN);
709    basic_table_impls!(impl_the_methods);
710
711    /// If the number of contours is greater than or equal to zero,
712    /// this is a simple glyph. If negative, this is a composite glyph
713    /// — the value -1 should be used for composite glyphs.
714    pub fn number_of_contours(&self) -> i16 {
715        let range = self.number_of_contours_byte_range();
716        self.data.read_at(range.start).ok().unwrap()
717    }
718
719    /// Minimum x for coordinate data.
720    pub fn x_min(&self) -> i16 {
721        let range = self.x_min_byte_range();
722        self.data.read_at(range.start).ok().unwrap()
723    }
724
725    /// Minimum y for coordinate data.
726    pub fn y_min(&self) -> i16 {
727        let range = self.y_min_byte_range();
728        self.data.read_at(range.start).ok().unwrap()
729    }
730
731    /// Maximum x for coordinate data.
732    pub fn x_max(&self) -> i16 {
733        let range = self.x_max_byte_range();
734        self.data.read_at(range.start).ok().unwrap()
735    }
736
737    /// Maximum y for coordinate data.
738    pub fn y_max(&self) -> i16 {
739        let range = self.y_max_byte_range();
740        self.data.read_at(range.start).ok().unwrap()
741    }
742
743    /// component flag
744    /// glyph index of component
745    pub fn component_data(&self) -> &'a [u8] {
746        let range = self.component_data_byte_range();
747        self.data.read_array(range).ok().unwrap_or_default()
748    }
749
750    pub fn number_of_contours_byte_range(&self) -> Range<usize> {
751        let start = 0;
752        let end = start + i16::RAW_BYTE_LEN;
753        start..end
754    }
755
756    pub fn x_min_byte_range(&self) -> Range<usize> {
757        let start = self.number_of_contours_byte_range().end;
758        let end = start + i16::RAW_BYTE_LEN;
759        start..end
760    }
761
762    pub fn y_min_byte_range(&self) -> Range<usize> {
763        let start = self.x_min_byte_range().end;
764        let end = start + i16::RAW_BYTE_LEN;
765        start..end
766    }
767
768    pub fn x_max_byte_range(&self) -> Range<usize> {
769        let start = self.y_min_byte_range().end;
770        let end = start + i16::RAW_BYTE_LEN;
771        start..end
772    }
773
774    pub fn y_max_byte_range(&self) -> Range<usize> {
775        let start = self.x_max_byte_range().end;
776        let end = start + i16::RAW_BYTE_LEN;
777        start..end
778    }
779
780    pub fn component_data_byte_range(&self) -> Range<usize> {
781        let start = self.y_max_byte_range().end;
782        let end =
783            start + self.data.len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
784        start..end
785    }
786}
787
788const _: () = assert!(FontData::default_data_long_enough(CompositeGlyph::MIN_SIZE));
789
790impl Default for CompositeGlyph<'_> {
791    fn default() -> Self {
792        Self {
793            data: FontData::default_table_data(),
794        }
795    }
796}
797
798#[cfg(feature = "experimental_traverse")]
799impl<'a> SomeTable<'a> for CompositeGlyph<'a> {
800    fn type_name(&self) -> &str {
801        "CompositeGlyph"
802    }
803    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
804        match idx {
805            0usize => Some(Field::new("number_of_contours", self.number_of_contours())),
806            1usize => Some(Field::new("x_min", self.x_min())),
807            2usize => Some(Field::new("y_min", self.y_min())),
808            3usize => Some(Field::new("x_max", self.x_max())),
809            4usize => Some(Field::new("y_max", self.y_max())),
810            5usize => Some(Field::new("component_data", self.component_data())),
811            _ => None,
812        }
813    }
814}
815
816#[cfg(feature = "experimental_traverse")]
817#[allow(clippy::needless_lifetimes)]
818impl<'a> std::fmt::Debug for CompositeGlyph<'a> {
819    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
820        (self as &dyn SomeTable<'a>).fmt(f)
821    }
822}
823
824/// Flags used in [CompositeGlyph]
825#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
826#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
827#[repr(transparent)]
828pub struct CompositeGlyphFlags {
829    bits: u16,
830}
831
832impl CompositeGlyphFlags {
833    /// Bit 0: If this is set, the arguments are 16-bit (uint16 or
834    /// int16); otherwise, they are bytes (uint8 or int8).
835    pub const ARG_1_AND_2_ARE_WORDS: Self = Self { bits: 0x0001 };
836
837    /// Bit 1: If this is set, the arguments are signed xy values,
838    /// otherwise, they are unsigned point numbers.
839    pub const ARGS_ARE_XY_VALUES: Self = Self { bits: 0x0002 };
840
841    /// Bit 2: If set and ARGS_ARE_XY_VALUES is also set, the xy values
842    /// are rounded to the nearest grid line. Ignored if
843    /// ARGS_ARE_XY_VALUES is not set.
844    pub const ROUND_XY_TO_GRID: Self = Self { bits: 0x0004 };
845
846    /// Bit 3: This indicates that there is a simple scale for the
847    /// component. Otherwise, scale = 1.0.
848    pub const WE_HAVE_A_SCALE: Self = Self { bits: 0x0008 };
849
850    /// Bit 5: Indicates at least one more glyph after this one.
851    pub const MORE_COMPONENTS: Self = Self { bits: 0x0020 };
852
853    /// Bit 6: The x direction will use a different scale from the y
854    /// direction.
855    pub const WE_HAVE_AN_X_AND_Y_SCALE: Self = Self { bits: 0x0040 };
856
857    /// Bit 7: There is a 2 by 2 transformation that will be used to
858    /// scale the component.
859    pub const WE_HAVE_A_TWO_BY_TWO: Self = Self { bits: 0x0080 };
860
861    /// Bit 8: Following the last component are instructions for the
862    /// composite character.
863    pub const WE_HAVE_INSTRUCTIONS: Self = Self { bits: 0x0100 };
864
865    /// Bit 9: If set, this forces the aw and lsb (and rsb) for the
866    /// composite to be equal to those from this component glyph. This
867    /// works for hinted and unhinted glyphs.
868    pub const USE_MY_METRICS: Self = Self { bits: 0x0200 };
869
870    /// Bit 10: If set, the components of the compound glyph overlap.
871    /// Use of this flag is not required in OpenType — that is, it is
872    /// valid to have components overlap without having this flag set.
873    /// It may affect behaviors in some platforms, however. (See
874    /// Apple’s specification for details regarding behavior in Apple
875    /// platforms.) When used, it must be set on the flag word for the
876    /// first component. See additional remarks, above, for the similar
877    /// OVERLAP_SIMPLE flag used in simple-glyph descriptions.
878    pub const OVERLAP_COMPOUND: Self = Self { bits: 0x0400 };
879
880    /// Bit 11: The composite is designed to have the component offset
881    /// scaled. Ignored if ARGS_ARE_XY_VALUES is not set.
882    pub const SCALED_COMPONENT_OFFSET: Self = Self { bits: 0x0800 };
883
884    /// Bit 12: The composite is designed not to have the component
885    /// offset scaled. Ignored if ARGS_ARE_XY_VALUES is not set.
886    pub const UNSCALED_COMPONENT_OFFSET: Self = Self { bits: 0x1000 };
887}
888
889impl CompositeGlyphFlags {
890    ///  Returns an empty set of flags.
891    #[inline]
892    pub const fn empty() -> Self {
893        Self { bits: 0 }
894    }
895
896    /// Returns the set containing all flags.
897    #[inline]
898    pub const fn all() -> Self {
899        Self {
900            bits: Self::ARG_1_AND_2_ARE_WORDS.bits
901                | Self::ARGS_ARE_XY_VALUES.bits
902                | Self::ROUND_XY_TO_GRID.bits
903                | Self::WE_HAVE_A_SCALE.bits
904                | Self::MORE_COMPONENTS.bits
905                | Self::WE_HAVE_AN_X_AND_Y_SCALE.bits
906                | Self::WE_HAVE_A_TWO_BY_TWO.bits
907                | Self::WE_HAVE_INSTRUCTIONS.bits
908                | Self::USE_MY_METRICS.bits
909                | Self::OVERLAP_COMPOUND.bits
910                | Self::SCALED_COMPONENT_OFFSET.bits
911                | Self::UNSCALED_COMPONENT_OFFSET.bits,
912        }
913    }
914
915    /// Returns the raw value of the flags currently stored.
916    #[inline]
917    pub const fn bits(&self) -> u16 {
918        self.bits
919    }
920
921    /// Convert from underlying bit representation, unless that
922    /// representation contains bits that do not correspond to a flag.
923    #[inline]
924    pub const fn from_bits(bits: u16) -> Option<Self> {
925        if (bits & !Self::all().bits()) == 0 {
926            Some(Self { bits })
927        } else {
928            None
929        }
930    }
931
932    /// Convert from underlying bit representation, dropping any bits
933    /// that do not correspond to flags.
934    #[inline]
935    pub const fn from_bits_truncate(bits: u16) -> Self {
936        Self {
937            bits: bits & Self::all().bits,
938        }
939    }
940
941    /// Returns `true` if no flags are currently stored.
942    #[inline]
943    pub const fn is_empty(&self) -> bool {
944        self.bits() == Self::empty().bits()
945    }
946
947    /// Returns `true` if there are flags common to both `self` and `other`.
948    #[inline]
949    pub const fn intersects(&self, other: Self) -> bool {
950        !(Self {
951            bits: self.bits & other.bits,
952        })
953        .is_empty()
954    }
955
956    /// Returns `true` if all of the flags in `other` are contained within `self`.
957    #[inline]
958    pub const fn contains(&self, other: Self) -> bool {
959        (self.bits & other.bits) == other.bits
960    }
961
962    /// Inserts the specified flags in-place.
963    #[inline]
964    pub fn insert(&mut self, other: Self) {
965        self.bits |= other.bits;
966    }
967
968    /// Removes the specified flags in-place.
969    #[inline]
970    pub fn remove(&mut self, other: Self) {
971        self.bits &= !other.bits;
972    }
973
974    /// Toggles the specified flags in-place.
975    #[inline]
976    pub fn toggle(&mut self, other: Self) {
977        self.bits ^= other.bits;
978    }
979
980    /// Returns the intersection between the flags in `self` and
981    /// `other`.
982    ///
983    /// Specifically, the returned set contains only the flags which are
984    /// present in *both* `self` *and* `other`.
985    ///
986    /// This is equivalent to using the `&` operator (e.g.
987    /// [`ops::BitAnd`]), as in `flags & other`.
988    ///
989    /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
990    #[inline]
991    #[must_use]
992    pub const fn intersection(self, other: Self) -> Self {
993        Self {
994            bits: self.bits & other.bits,
995        }
996    }
997
998    /// Returns the union of between the flags in `self` and `other`.
999    ///
1000    /// Specifically, the returned set contains all flags which are
1001    /// present in *either* `self` *or* `other`, including any which are
1002    /// present in both.
1003    ///
1004    /// This is equivalent to using the `|` operator (e.g.
1005    /// [`ops::BitOr`]), as in `flags | other`.
1006    ///
1007    /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
1008    #[inline]
1009    #[must_use]
1010    pub const fn union(self, other: Self) -> Self {
1011        Self {
1012            bits: self.bits | other.bits,
1013        }
1014    }
1015
1016    /// Returns the difference between the flags in `self` and `other`.
1017    ///
1018    /// Specifically, the returned set contains all flags present in
1019    /// `self`, except for the ones present in `other`.
1020    ///
1021    /// It is also conceptually equivalent to the "bit-clear" operation:
1022    /// `flags & !other` (and this syntax is also supported).
1023    ///
1024    /// This is equivalent to using the `-` operator (e.g.
1025    /// [`ops::Sub`]), as in `flags - other`.
1026    ///
1027    /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
1028    #[inline]
1029    #[must_use]
1030    pub const fn difference(self, other: Self) -> Self {
1031        Self {
1032            bits: self.bits & !other.bits,
1033        }
1034    }
1035}
1036
1037impl std::ops::BitOr for CompositeGlyphFlags {
1038    type Output = Self;
1039
1040    /// Returns the union of the two sets of flags.
1041    #[inline]
1042    fn bitor(self, other: CompositeGlyphFlags) -> Self {
1043        Self {
1044            bits: self.bits | other.bits,
1045        }
1046    }
1047}
1048
1049impl std::ops::BitOrAssign for CompositeGlyphFlags {
1050    /// Adds the set of flags.
1051    #[inline]
1052    fn bitor_assign(&mut self, other: Self) {
1053        self.bits |= other.bits;
1054    }
1055}
1056
1057impl std::ops::BitXor for CompositeGlyphFlags {
1058    type Output = Self;
1059
1060    /// Returns the left flags, but with all the right flags toggled.
1061    #[inline]
1062    fn bitxor(self, other: Self) -> Self {
1063        Self {
1064            bits: self.bits ^ other.bits,
1065        }
1066    }
1067}
1068
1069impl std::ops::BitXorAssign for CompositeGlyphFlags {
1070    /// Toggles the set of flags.
1071    #[inline]
1072    fn bitxor_assign(&mut self, other: Self) {
1073        self.bits ^= other.bits;
1074    }
1075}
1076
1077impl std::ops::BitAnd for CompositeGlyphFlags {
1078    type Output = Self;
1079
1080    /// Returns the intersection between the two sets of flags.
1081    #[inline]
1082    fn bitand(self, other: Self) -> Self {
1083        Self {
1084            bits: self.bits & other.bits,
1085        }
1086    }
1087}
1088
1089impl std::ops::BitAndAssign for CompositeGlyphFlags {
1090    /// Disables all flags disabled in the set.
1091    #[inline]
1092    fn bitand_assign(&mut self, other: Self) {
1093        self.bits &= other.bits;
1094    }
1095}
1096
1097impl std::ops::Sub for CompositeGlyphFlags {
1098    type Output = Self;
1099
1100    /// Returns the set difference of the two sets of flags.
1101    #[inline]
1102    fn sub(self, other: Self) -> Self {
1103        Self {
1104            bits: self.bits & !other.bits,
1105        }
1106    }
1107}
1108
1109impl std::ops::SubAssign for CompositeGlyphFlags {
1110    /// Disables all flags enabled in the set.
1111    #[inline]
1112    fn sub_assign(&mut self, other: Self) {
1113        self.bits &= !other.bits;
1114    }
1115}
1116
1117impl std::ops::Not for CompositeGlyphFlags {
1118    type Output = Self;
1119
1120    /// Returns the complement of this set of flags.
1121    #[inline]
1122    fn not(self) -> Self {
1123        Self { bits: !self.bits } & Self::all()
1124    }
1125}
1126
1127impl std::fmt::Debug for CompositeGlyphFlags {
1128    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1129        let members: &[(&str, Self)] = &[
1130            ("ARG_1_AND_2_ARE_WORDS", Self::ARG_1_AND_2_ARE_WORDS),
1131            ("ARGS_ARE_XY_VALUES", Self::ARGS_ARE_XY_VALUES),
1132            ("ROUND_XY_TO_GRID", Self::ROUND_XY_TO_GRID),
1133            ("WE_HAVE_A_SCALE", Self::WE_HAVE_A_SCALE),
1134            ("MORE_COMPONENTS", Self::MORE_COMPONENTS),
1135            ("WE_HAVE_AN_X_AND_Y_SCALE", Self::WE_HAVE_AN_X_AND_Y_SCALE),
1136            ("WE_HAVE_A_TWO_BY_TWO", Self::WE_HAVE_A_TWO_BY_TWO),
1137            ("WE_HAVE_INSTRUCTIONS", Self::WE_HAVE_INSTRUCTIONS),
1138            ("USE_MY_METRICS", Self::USE_MY_METRICS),
1139            ("OVERLAP_COMPOUND", Self::OVERLAP_COMPOUND),
1140            ("SCALED_COMPONENT_OFFSET", Self::SCALED_COMPONENT_OFFSET),
1141            ("UNSCALED_COMPONENT_OFFSET", Self::UNSCALED_COMPONENT_OFFSET),
1142        ];
1143        let mut first = true;
1144        for (name, value) in members {
1145            if self.contains(*value) {
1146                if !first {
1147                    f.write_str(" | ")?;
1148                }
1149                first = false;
1150                f.write_str(name)?;
1151            }
1152        }
1153        if first {
1154            f.write_str("(empty)")?;
1155        }
1156        Ok(())
1157    }
1158}
1159
1160impl std::fmt::Binary for CompositeGlyphFlags {
1161    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1162        std::fmt::Binary::fmt(&self.bits, f)
1163    }
1164}
1165
1166impl std::fmt::Octal for CompositeGlyphFlags {
1167    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1168        std::fmt::Octal::fmt(&self.bits, f)
1169    }
1170}
1171
1172impl std::fmt::LowerHex for CompositeGlyphFlags {
1173    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1174        std::fmt::LowerHex::fmt(&self.bits, f)
1175    }
1176}
1177
1178impl std::fmt::UpperHex for CompositeGlyphFlags {
1179    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1180        std::fmt::UpperHex::fmt(&self.bits, f)
1181    }
1182}
1183
1184impl font_types::Scalar for CompositeGlyphFlags {
1185    type Raw = <u16 as font_types::Scalar>::Raw;
1186    fn to_raw(self) -> Self::Raw {
1187        self.bits().to_raw()
1188    }
1189    fn from_raw(raw: Self::Raw) -> Self {
1190        let t = <u16>::from_raw(raw);
1191        Self::from_bits_truncate(t)
1192    }
1193}
1194
1195#[cfg(feature = "experimental_traverse")]
1196impl<'a> From<CompositeGlyphFlags> for FieldType<'a> {
1197    fn from(src: CompositeGlyphFlags) -> FieldType<'a> {
1198        src.bits().into()
1199    }
1200}
1201
1202/// Simple or composite glyph.
1203#[derive(Clone)]
1204pub enum Glyph<'a> {
1205    Simple(SimpleGlyph<'a>),
1206    Composite(CompositeGlyph<'a>),
1207}
1208
1209impl Default for Glyph<'_> {
1210    fn default() -> Self {
1211        Self::Simple(Default::default())
1212    }
1213}
1214
1215impl<'a> Glyph<'a> {
1216    ///Return the `FontData` used to resolve offsets for this table.
1217    pub fn offset_data(&self) -> FontData<'a> {
1218        match self {
1219            Self::Simple(item) => item.offset_data(),
1220            Self::Composite(item) => item.offset_data(),
1221        }
1222    }
1223
1224    /// If the number of contours is greater than or equal to zero,
1225    /// this is a simple glyph. If negative, this is a composite glyph
1226    /// — the value -1 should be used for composite glyphs.
1227    pub fn number_of_contours(&self) -> i16 {
1228        match self {
1229            Self::Simple(item) => item.number_of_contours(),
1230            Self::Composite(item) => item.number_of_contours(),
1231        }
1232    }
1233
1234    /// Minimum x for coordinate data.
1235    pub fn x_min(&self) -> i16 {
1236        match self {
1237            Self::Simple(item) => item.x_min(),
1238            Self::Composite(item) => item.x_min(),
1239        }
1240    }
1241
1242    /// Minimum y for coordinate data.
1243    pub fn y_min(&self) -> i16 {
1244        match self {
1245            Self::Simple(item) => item.y_min(),
1246            Self::Composite(item) => item.y_min(),
1247        }
1248    }
1249
1250    /// Maximum x for coordinate data.
1251    pub fn x_max(&self) -> i16 {
1252        match self {
1253            Self::Simple(item) => item.x_max(),
1254            Self::Composite(item) => item.x_max(),
1255        }
1256    }
1257
1258    /// Maximum y for coordinate data.
1259    pub fn y_max(&self) -> i16 {
1260        match self {
1261            Self::Simple(item) => item.y_max(),
1262            Self::Composite(item) => item.y_max(),
1263        }
1264    }
1265}
1266
1267impl ReadArgs for Glyph<'_> {
1268    type Args = ();
1269}
1270
1271impl<'a> FontRead<'a> for Glyph<'a> {
1272    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1273        let format: i16 = data.read_at(0usize)?;
1274
1275        #[allow(clippy::redundant_guards)]
1276        match format {
1277            format if format >= 0 => Ok(Self::Simple(FontRead::read(data)?)),
1278            format if format < 0 => Ok(Self::Composite(FontRead::read(data)?)),
1279            other => Err(ReadError::InvalidFormat(other.into())),
1280        }
1281    }
1282}
1283
1284impl<'a> MinByteRange<'a> for Glyph<'a> {
1285    fn min_byte_range(&self) -> Range<usize> {
1286        match self {
1287            Self::Simple(item) => item.min_byte_range(),
1288            Self::Composite(item) => item.min_byte_range(),
1289        }
1290    }
1291    fn min_table_bytes(&self) -> &'a [u8] {
1292        match self {
1293            Self::Simple(item) => item.min_table_bytes(),
1294            Self::Composite(item) => item.min_table_bytes(),
1295        }
1296    }
1297}
1298
1299#[cfg(feature = "experimental_traverse")]
1300impl<'a> Glyph<'a> {
1301    fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
1302        match self {
1303            Self::Simple(table) => table,
1304            Self::Composite(table) => table,
1305        }
1306    }
1307}
1308
1309#[cfg(feature = "experimental_traverse")]
1310impl std::fmt::Debug for Glyph<'_> {
1311    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1312        self.dyn_inner().fmt(f)
1313    }
1314}
1315
1316#[cfg(feature = "experimental_traverse")]
1317impl<'a> SomeTable<'a> for Glyph<'a> {
1318    fn type_name(&self) -> &str {
1319        self.dyn_inner().type_name()
1320    }
1321    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1322        self.dyn_inner().get_field(idx)
1323    }
1324}