read_fonts/generated/
generated_colr.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/// [COLR (Color)](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#colr-header) table
9#[derive(Debug, Clone, Copy)]
10#[doc(hidden)]
11pub struct ColrMarker {
12    base_glyph_list_offset_byte_start: Option<usize>,
13    layer_list_offset_byte_start: Option<usize>,
14    clip_list_offset_byte_start: Option<usize>,
15    var_index_map_offset_byte_start: Option<usize>,
16    item_variation_store_offset_byte_start: Option<usize>,
17}
18
19impl ColrMarker {
20    pub fn version_byte_range(&self) -> Range<usize> {
21        let start = 0;
22        start..start + u16::RAW_BYTE_LEN
23    }
24
25    pub fn num_base_glyph_records_byte_range(&self) -> Range<usize> {
26        let start = self.version_byte_range().end;
27        start..start + u16::RAW_BYTE_LEN
28    }
29
30    pub fn base_glyph_records_offset_byte_range(&self) -> Range<usize> {
31        let start = self.num_base_glyph_records_byte_range().end;
32        start..start + Offset32::RAW_BYTE_LEN
33    }
34
35    pub fn layer_records_offset_byte_range(&self) -> Range<usize> {
36        let start = self.base_glyph_records_offset_byte_range().end;
37        start..start + Offset32::RAW_BYTE_LEN
38    }
39
40    pub fn num_layer_records_byte_range(&self) -> Range<usize> {
41        let start = self.layer_records_offset_byte_range().end;
42        start..start + u16::RAW_BYTE_LEN
43    }
44
45    pub fn base_glyph_list_offset_byte_range(&self) -> Option<Range<usize>> {
46        let start = self.base_glyph_list_offset_byte_start?;
47        Some(start..start + Offset32::RAW_BYTE_LEN)
48    }
49
50    pub fn layer_list_offset_byte_range(&self) -> Option<Range<usize>> {
51        let start = self.layer_list_offset_byte_start?;
52        Some(start..start + Offset32::RAW_BYTE_LEN)
53    }
54
55    pub fn clip_list_offset_byte_range(&self) -> Option<Range<usize>> {
56        let start = self.clip_list_offset_byte_start?;
57        Some(start..start + Offset32::RAW_BYTE_LEN)
58    }
59
60    pub fn var_index_map_offset_byte_range(&self) -> Option<Range<usize>> {
61        let start = self.var_index_map_offset_byte_start?;
62        Some(start..start + Offset32::RAW_BYTE_LEN)
63    }
64
65    pub fn item_variation_store_offset_byte_range(&self) -> Option<Range<usize>> {
66        let start = self.item_variation_store_offset_byte_start?;
67        Some(start..start + Offset32::RAW_BYTE_LEN)
68    }
69}
70
71impl MinByteRange for ColrMarker {
72    fn min_byte_range(&self) -> Range<usize> {
73        0..self.num_layer_records_byte_range().end
74    }
75}
76
77impl TopLevelTable for Colr<'_> {
78    /// `COLR`
79    const TAG: Tag = Tag::new(b"COLR");
80}
81
82impl<'a> FontRead<'a> for Colr<'a> {
83    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
84        let mut cursor = data.cursor();
85        let version: u16 = cursor.read()?;
86        cursor.advance::<u16>();
87        cursor.advance::<Offset32>();
88        cursor.advance::<Offset32>();
89        cursor.advance::<u16>();
90        let base_glyph_list_offset_byte_start = version
91            .compatible(1u16)
92            .then(|| cursor.position())
93            .transpose()?;
94        version
95            .compatible(1u16)
96            .then(|| cursor.advance::<Offset32>());
97        let layer_list_offset_byte_start = version
98            .compatible(1u16)
99            .then(|| cursor.position())
100            .transpose()?;
101        version
102            .compatible(1u16)
103            .then(|| cursor.advance::<Offset32>());
104        let clip_list_offset_byte_start = version
105            .compatible(1u16)
106            .then(|| cursor.position())
107            .transpose()?;
108        version
109            .compatible(1u16)
110            .then(|| cursor.advance::<Offset32>());
111        let var_index_map_offset_byte_start = version
112            .compatible(1u16)
113            .then(|| cursor.position())
114            .transpose()?;
115        version
116            .compatible(1u16)
117            .then(|| cursor.advance::<Offset32>());
118        let item_variation_store_offset_byte_start = version
119            .compatible(1u16)
120            .then(|| cursor.position())
121            .transpose()?;
122        version
123            .compatible(1u16)
124            .then(|| cursor.advance::<Offset32>());
125        cursor.finish(ColrMarker {
126            base_glyph_list_offset_byte_start,
127            layer_list_offset_byte_start,
128            clip_list_offset_byte_start,
129            var_index_map_offset_byte_start,
130            item_variation_store_offset_byte_start,
131        })
132    }
133}
134
135/// [COLR (Color)](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#colr-header) table
136pub type Colr<'a> = TableRef<'a, ColrMarker>;
137
138#[allow(clippy::needless_lifetimes)]
139impl<'a> Colr<'a> {
140    /// Table version number - set to 0 or 1.
141    pub fn version(&self) -> u16 {
142        let range = self.shape.version_byte_range();
143        self.data.read_at(range.start).unwrap()
144    }
145
146    /// Number of BaseGlyph records; may be 0 in a version 1 table.
147    pub fn num_base_glyph_records(&self) -> u16 {
148        let range = self.shape.num_base_glyph_records_byte_range();
149        self.data.read_at(range.start).unwrap()
150    }
151
152    /// Offset to baseGlyphRecords array (may be NULL).
153    pub fn base_glyph_records_offset(&self) -> Nullable<Offset32> {
154        let range = self.shape.base_glyph_records_offset_byte_range();
155        self.data.read_at(range.start).unwrap()
156    }
157
158    /// Attempt to resolve [`base_glyph_records_offset`][Self::base_glyph_records_offset].
159    pub fn base_glyph_records(&self) -> Option<Result<&'a [BaseGlyph], ReadError>> {
160        let data = self.data;
161        let args = self.num_base_glyph_records();
162        self.base_glyph_records_offset()
163            .resolve_with_args(data, &args)
164    }
165
166    /// Offset to layerRecords array (may be NULL).
167    pub fn layer_records_offset(&self) -> Nullable<Offset32> {
168        let range = self.shape.layer_records_offset_byte_range();
169        self.data.read_at(range.start).unwrap()
170    }
171
172    /// Attempt to resolve [`layer_records_offset`][Self::layer_records_offset].
173    pub fn layer_records(&self) -> Option<Result<&'a [Layer], ReadError>> {
174        let data = self.data;
175        let args = self.num_layer_records();
176        self.layer_records_offset().resolve_with_args(data, &args)
177    }
178
179    /// Number of Layer records; may be 0 in a version 1 table.
180    pub fn num_layer_records(&self) -> u16 {
181        let range = self.shape.num_layer_records_byte_range();
182        self.data.read_at(range.start).unwrap()
183    }
184
185    /// Offset to BaseGlyphList table.
186    pub fn base_glyph_list_offset(&self) -> Option<Nullable<Offset32>> {
187        let range = self.shape.base_glyph_list_offset_byte_range()?;
188        Some(self.data.read_at(range.start).unwrap())
189    }
190
191    /// Attempt to resolve [`base_glyph_list_offset`][Self::base_glyph_list_offset].
192    pub fn base_glyph_list(&self) -> Option<Result<BaseGlyphList<'a>, ReadError>> {
193        let data = self.data;
194        self.base_glyph_list_offset().map(|x| x.resolve(data))?
195    }
196
197    /// Offset to LayerList table (may be NULL).
198    pub fn layer_list_offset(&self) -> Option<Nullable<Offset32>> {
199        let range = self.shape.layer_list_offset_byte_range()?;
200        Some(self.data.read_at(range.start).unwrap())
201    }
202
203    /// Attempt to resolve [`layer_list_offset`][Self::layer_list_offset].
204    pub fn layer_list(&self) -> Option<Result<LayerList<'a>, ReadError>> {
205        let data = self.data;
206        self.layer_list_offset().map(|x| x.resolve(data))?
207    }
208
209    /// Offset to ClipList table (may be NULL).
210    pub fn clip_list_offset(&self) -> Option<Nullable<Offset32>> {
211        let range = self.shape.clip_list_offset_byte_range()?;
212        Some(self.data.read_at(range.start).unwrap())
213    }
214
215    /// Attempt to resolve [`clip_list_offset`][Self::clip_list_offset].
216    pub fn clip_list(&self) -> Option<Result<ClipList<'a>, ReadError>> {
217        let data = self.data;
218        self.clip_list_offset().map(|x| x.resolve(data))?
219    }
220
221    /// Offset to DeltaSetIndexMap table (may be NULL).
222    pub fn var_index_map_offset(&self) -> Option<Nullable<Offset32>> {
223        let range = self.shape.var_index_map_offset_byte_range()?;
224        Some(self.data.read_at(range.start).unwrap())
225    }
226
227    /// Attempt to resolve [`var_index_map_offset`][Self::var_index_map_offset].
228    pub fn var_index_map(&self) -> Option<Result<DeltaSetIndexMap<'a>, ReadError>> {
229        let data = self.data;
230        self.var_index_map_offset().map(|x| x.resolve(data))?
231    }
232
233    /// Offset to ItemVariationStore (may be NULL).
234    pub fn item_variation_store_offset(&self) -> Option<Nullable<Offset32>> {
235        let range = self.shape.item_variation_store_offset_byte_range()?;
236        Some(self.data.read_at(range.start).unwrap())
237    }
238
239    /// Attempt to resolve [`item_variation_store_offset`][Self::item_variation_store_offset].
240    pub fn item_variation_store(&self) -> Option<Result<ItemVariationStore<'a>, ReadError>> {
241        let data = self.data;
242        self.item_variation_store_offset()
243            .map(|x| x.resolve(data))?
244    }
245}
246
247#[cfg(feature = "experimental_traverse")]
248impl<'a> SomeTable<'a> for Colr<'a> {
249    fn type_name(&self) -> &str {
250        "Colr"
251    }
252    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
253        let version = self.version();
254        match idx {
255            0usize => Some(Field::new("version", self.version())),
256            1usize => Some(Field::new(
257                "num_base_glyph_records",
258                self.num_base_glyph_records(),
259            )),
260            2usize => Some(Field::new(
261                "base_glyph_records_offset",
262                traversal::FieldType::offset_to_array_of_records(
263                    self.base_glyph_records_offset(),
264                    self.base_glyph_records(),
265                    stringify!(BaseGlyph),
266                    self.offset_data(),
267                ),
268            )),
269            3usize => Some(Field::new(
270                "layer_records_offset",
271                traversal::FieldType::offset_to_array_of_records(
272                    self.layer_records_offset(),
273                    self.layer_records(),
274                    stringify!(Layer),
275                    self.offset_data(),
276                ),
277            )),
278            4usize => Some(Field::new("num_layer_records", self.num_layer_records())),
279            5usize if version.compatible(1u16) => Some(Field::new(
280                "base_glyph_list_offset",
281                FieldType::offset(
282                    self.base_glyph_list_offset().unwrap(),
283                    self.base_glyph_list(),
284                ),
285            )),
286            6usize if version.compatible(1u16) => Some(Field::new(
287                "layer_list_offset",
288                FieldType::offset(self.layer_list_offset().unwrap(), self.layer_list()),
289            )),
290            7usize if version.compatible(1u16) => Some(Field::new(
291                "clip_list_offset",
292                FieldType::offset(self.clip_list_offset().unwrap(), self.clip_list()),
293            )),
294            8usize if version.compatible(1u16) => Some(Field::new(
295                "var_index_map_offset",
296                FieldType::offset(self.var_index_map_offset().unwrap(), self.var_index_map()),
297            )),
298            9usize if version.compatible(1u16) => Some(Field::new(
299                "item_variation_store_offset",
300                FieldType::offset(
301                    self.item_variation_store_offset().unwrap(),
302                    self.item_variation_store(),
303                ),
304            )),
305            _ => None,
306        }
307    }
308}
309
310#[cfg(feature = "experimental_traverse")]
311#[allow(clippy::needless_lifetimes)]
312impl<'a> std::fmt::Debug for Colr<'a> {
313    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
314        (self as &dyn SomeTable<'a>).fmt(f)
315    }
316}
317
318/// [BaseGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyph-and-layer-records) record
319#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
320#[repr(C)]
321#[repr(packed)]
322pub struct BaseGlyph {
323    /// Glyph ID of the base glyph.
324    pub glyph_id: BigEndian<GlyphId16>,
325    /// Index (base 0) into the layerRecords array.
326    pub first_layer_index: BigEndian<u16>,
327    /// Number of color layers associated with this glyph.
328    pub num_layers: BigEndian<u16>,
329}
330
331impl BaseGlyph {
332    /// Glyph ID of the base glyph.
333    pub fn glyph_id(&self) -> GlyphId16 {
334        self.glyph_id.get()
335    }
336
337    /// Index (base 0) into the layerRecords array.
338    pub fn first_layer_index(&self) -> u16 {
339        self.first_layer_index.get()
340    }
341
342    /// Number of color layers associated with this glyph.
343    pub fn num_layers(&self) -> u16 {
344        self.num_layers.get()
345    }
346}
347
348impl FixedSize for BaseGlyph {
349    const RAW_BYTE_LEN: usize = GlyphId16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
350}
351
352#[cfg(feature = "experimental_traverse")]
353impl<'a> SomeRecord<'a> for BaseGlyph {
354    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
355        RecordResolver {
356            name: "BaseGlyph",
357            get_field: Box::new(move |idx, _data| match idx {
358                0usize => Some(Field::new("glyph_id", self.glyph_id())),
359                1usize => Some(Field::new("first_layer_index", self.first_layer_index())),
360                2usize => Some(Field::new("num_layers", self.num_layers())),
361                _ => None,
362            }),
363            data,
364        }
365    }
366}
367
368/// [Layer](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyph-and-layer-records) record
369#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
370#[repr(C)]
371#[repr(packed)]
372pub struct Layer {
373    /// Glyph ID of the glyph used for a given layer.
374    pub glyph_id: BigEndian<GlyphId16>,
375    /// Index (base 0) for a palette entry in the CPAL table.
376    pub palette_index: BigEndian<u16>,
377}
378
379impl Layer {
380    /// Glyph ID of the glyph used for a given layer.
381    pub fn glyph_id(&self) -> GlyphId16 {
382        self.glyph_id.get()
383    }
384
385    /// Index (base 0) for a palette entry in the CPAL table.
386    pub fn palette_index(&self) -> u16 {
387        self.palette_index.get()
388    }
389}
390
391impl FixedSize for Layer {
392    const RAW_BYTE_LEN: usize = GlyphId16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
393}
394
395#[cfg(feature = "experimental_traverse")]
396impl<'a> SomeRecord<'a> for Layer {
397    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
398        RecordResolver {
399            name: "Layer",
400            get_field: Box::new(move |idx, _data| match idx {
401                0usize => Some(Field::new("glyph_id", self.glyph_id())),
402                1usize => Some(Field::new("palette_index", self.palette_index())),
403                _ => None,
404            }),
405            data,
406        }
407    }
408}
409
410/// [BaseGlyphList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table
411#[derive(Debug, Clone, Copy)]
412#[doc(hidden)]
413pub struct BaseGlyphListMarker {
414    base_glyph_paint_records_byte_len: usize,
415}
416
417impl BaseGlyphListMarker {
418    pub fn num_base_glyph_paint_records_byte_range(&self) -> Range<usize> {
419        let start = 0;
420        start..start + u32::RAW_BYTE_LEN
421    }
422
423    pub fn base_glyph_paint_records_byte_range(&self) -> Range<usize> {
424        let start = self.num_base_glyph_paint_records_byte_range().end;
425        start..start + self.base_glyph_paint_records_byte_len
426    }
427}
428
429impl MinByteRange for BaseGlyphListMarker {
430    fn min_byte_range(&self) -> Range<usize> {
431        0..self.base_glyph_paint_records_byte_range().end
432    }
433}
434
435impl<'a> FontRead<'a> for BaseGlyphList<'a> {
436    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
437        let mut cursor = data.cursor();
438        let num_base_glyph_paint_records: u32 = cursor.read()?;
439        let base_glyph_paint_records_byte_len = (num_base_glyph_paint_records as usize)
440            .checked_mul(BaseGlyphPaint::RAW_BYTE_LEN)
441            .ok_or(ReadError::OutOfBounds)?;
442        cursor.advance_by(base_glyph_paint_records_byte_len);
443        cursor.finish(BaseGlyphListMarker {
444            base_glyph_paint_records_byte_len,
445        })
446    }
447}
448
449/// [BaseGlyphList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table
450pub type BaseGlyphList<'a> = TableRef<'a, BaseGlyphListMarker>;
451
452#[allow(clippy::needless_lifetimes)]
453impl<'a> BaseGlyphList<'a> {
454    pub fn num_base_glyph_paint_records(&self) -> u32 {
455        let range = self.shape.num_base_glyph_paint_records_byte_range();
456        self.data.read_at(range.start).unwrap()
457    }
458
459    pub fn base_glyph_paint_records(&self) -> &'a [BaseGlyphPaint] {
460        let range = self.shape.base_glyph_paint_records_byte_range();
461        self.data.read_array(range).unwrap()
462    }
463}
464
465#[cfg(feature = "experimental_traverse")]
466impl<'a> SomeTable<'a> for BaseGlyphList<'a> {
467    fn type_name(&self) -> &str {
468        "BaseGlyphList"
469    }
470    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
471        match idx {
472            0usize => Some(Field::new(
473                "num_base_glyph_paint_records",
474                self.num_base_glyph_paint_records(),
475            )),
476            1usize => Some(Field::new(
477                "base_glyph_paint_records",
478                traversal::FieldType::array_of_records(
479                    stringify!(BaseGlyphPaint),
480                    self.base_glyph_paint_records(),
481                    self.offset_data(),
482                ),
483            )),
484            _ => None,
485        }
486    }
487}
488
489#[cfg(feature = "experimental_traverse")]
490#[allow(clippy::needless_lifetimes)]
491impl<'a> std::fmt::Debug for BaseGlyphList<'a> {
492    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
493        (self as &dyn SomeTable<'a>).fmt(f)
494    }
495}
496
497/// [BaseGlyphPaint](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record
498#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
499#[repr(C)]
500#[repr(packed)]
501pub struct BaseGlyphPaint {
502    /// Glyph ID of the base glyph.
503    pub glyph_id: BigEndian<GlyphId16>,
504    /// Offset to a Paint table, from the beginning of the [`BaseGlyphList`] table.
505    pub paint_offset: BigEndian<Offset32>,
506}
507
508impl BaseGlyphPaint {
509    /// Glyph ID of the base glyph.
510    pub fn glyph_id(&self) -> GlyphId16 {
511        self.glyph_id.get()
512    }
513
514    /// Offset to a Paint table, from the beginning of the [`BaseGlyphList`] table.
515    pub fn paint_offset(&self) -> Offset32 {
516        self.paint_offset.get()
517    }
518
519    /// Offset to a Paint table, from the beginning of the [`BaseGlyphList`] table.
520    ///
521    /// The `data` argument should be retrieved from the parent table
522    /// By calling its `offset_data` method.
523    pub fn paint<'a>(&self, data: FontData<'a>) -> Result<Paint<'a>, ReadError> {
524        self.paint_offset().resolve(data)
525    }
526}
527
528impl FixedSize for BaseGlyphPaint {
529    const RAW_BYTE_LEN: usize = GlyphId16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN;
530}
531
532#[cfg(feature = "experimental_traverse")]
533impl<'a> SomeRecord<'a> for BaseGlyphPaint {
534    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
535        RecordResolver {
536            name: "BaseGlyphPaint",
537            get_field: Box::new(move |idx, _data| match idx {
538                0usize => Some(Field::new("glyph_id", self.glyph_id())),
539                1usize => Some(Field::new(
540                    "paint_offset",
541                    FieldType::offset(self.paint_offset(), self.paint(_data)),
542                )),
543                _ => None,
544            }),
545            data,
546        }
547    }
548}
549
550/// [LayerList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table
551#[derive(Debug, Clone, Copy)]
552#[doc(hidden)]
553pub struct LayerListMarker {
554    paint_offsets_byte_len: usize,
555}
556
557impl LayerListMarker {
558    pub fn num_layers_byte_range(&self) -> Range<usize> {
559        let start = 0;
560        start..start + u32::RAW_BYTE_LEN
561    }
562
563    pub fn paint_offsets_byte_range(&self) -> Range<usize> {
564        let start = self.num_layers_byte_range().end;
565        start..start + self.paint_offsets_byte_len
566    }
567}
568
569impl MinByteRange for LayerListMarker {
570    fn min_byte_range(&self) -> Range<usize> {
571        0..self.paint_offsets_byte_range().end
572    }
573}
574
575impl<'a> FontRead<'a> for LayerList<'a> {
576    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
577        let mut cursor = data.cursor();
578        let num_layers: u32 = cursor.read()?;
579        let paint_offsets_byte_len = (num_layers as usize)
580            .checked_mul(Offset32::RAW_BYTE_LEN)
581            .ok_or(ReadError::OutOfBounds)?;
582        cursor.advance_by(paint_offsets_byte_len);
583        cursor.finish(LayerListMarker {
584            paint_offsets_byte_len,
585        })
586    }
587}
588
589/// [LayerList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table
590pub type LayerList<'a> = TableRef<'a, LayerListMarker>;
591
592#[allow(clippy::needless_lifetimes)]
593impl<'a> LayerList<'a> {
594    pub fn num_layers(&self) -> u32 {
595        let range = self.shape.num_layers_byte_range();
596        self.data.read_at(range.start).unwrap()
597    }
598
599    /// Offsets to Paint tables.
600    pub fn paint_offsets(&self) -> &'a [BigEndian<Offset32>] {
601        let range = self.shape.paint_offsets_byte_range();
602        self.data.read_array(range).unwrap()
603    }
604
605    /// A dynamically resolving wrapper for [`paint_offsets`][Self::paint_offsets].
606    pub fn paints(&self) -> ArrayOfOffsets<'a, Paint<'a>, Offset32> {
607        let data = self.data;
608        let offsets = self.paint_offsets();
609        ArrayOfOffsets::new(offsets, data, ())
610    }
611}
612
613#[cfg(feature = "experimental_traverse")]
614impl<'a> SomeTable<'a> for LayerList<'a> {
615    fn type_name(&self) -> &str {
616        "LayerList"
617    }
618    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
619        match idx {
620            0usize => Some(Field::new("num_layers", self.num_layers())),
621            1usize => Some({
622                let data = self.data;
623                Field::new(
624                    "paint_offsets",
625                    FieldType::array_of_offsets(
626                        better_type_name::<Paint>(),
627                        self.paint_offsets(),
628                        move |off| {
629                            let target = off.get().resolve::<Paint>(data);
630                            FieldType::offset(off.get(), target)
631                        },
632                    ),
633                )
634            }),
635            _ => None,
636        }
637    }
638}
639
640#[cfg(feature = "experimental_traverse")]
641#[allow(clippy::needless_lifetimes)]
642impl<'a> std::fmt::Debug for LayerList<'a> {
643    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
644        (self as &dyn SomeTable<'a>).fmt(f)
645    }
646}
647
648/// [ClipList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table
649#[derive(Debug, Clone, Copy)]
650#[doc(hidden)]
651pub struct ClipListMarker {
652    clips_byte_len: usize,
653}
654
655impl ClipListMarker {
656    pub fn format_byte_range(&self) -> Range<usize> {
657        let start = 0;
658        start..start + u8::RAW_BYTE_LEN
659    }
660
661    pub fn num_clips_byte_range(&self) -> Range<usize> {
662        let start = self.format_byte_range().end;
663        start..start + u32::RAW_BYTE_LEN
664    }
665
666    pub fn clips_byte_range(&self) -> Range<usize> {
667        let start = self.num_clips_byte_range().end;
668        start..start + self.clips_byte_len
669    }
670}
671
672impl MinByteRange for ClipListMarker {
673    fn min_byte_range(&self) -> Range<usize> {
674        0..self.clips_byte_range().end
675    }
676}
677
678impl<'a> FontRead<'a> for ClipList<'a> {
679    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
680        let mut cursor = data.cursor();
681        cursor.advance::<u8>();
682        let num_clips: u32 = cursor.read()?;
683        let clips_byte_len = (num_clips as usize)
684            .checked_mul(Clip::RAW_BYTE_LEN)
685            .ok_or(ReadError::OutOfBounds)?;
686        cursor.advance_by(clips_byte_len);
687        cursor.finish(ClipListMarker { clips_byte_len })
688    }
689}
690
691/// [ClipList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table
692pub type ClipList<'a> = TableRef<'a, ClipListMarker>;
693
694#[allow(clippy::needless_lifetimes)]
695impl<'a> ClipList<'a> {
696    /// Set to 1.
697    pub fn format(&self) -> u8 {
698        let range = self.shape.format_byte_range();
699        self.data.read_at(range.start).unwrap()
700    }
701
702    /// Number of Clip records.
703    pub fn num_clips(&self) -> u32 {
704        let range = self.shape.num_clips_byte_range();
705        self.data.read_at(range.start).unwrap()
706    }
707
708    /// Clip records. Sorted by startGlyphID.
709    pub fn clips(&self) -> &'a [Clip] {
710        let range = self.shape.clips_byte_range();
711        self.data.read_array(range).unwrap()
712    }
713}
714
715#[cfg(feature = "experimental_traverse")]
716impl<'a> SomeTable<'a> for ClipList<'a> {
717    fn type_name(&self) -> &str {
718        "ClipList"
719    }
720    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
721        match idx {
722            0usize => Some(Field::new("format", self.format())),
723            1usize => Some(Field::new("num_clips", self.num_clips())),
724            2usize => Some(Field::new(
725                "clips",
726                traversal::FieldType::array_of_records(
727                    stringify!(Clip),
728                    self.clips(),
729                    self.offset_data(),
730                ),
731            )),
732            _ => None,
733        }
734    }
735}
736
737#[cfg(feature = "experimental_traverse")]
738#[allow(clippy::needless_lifetimes)]
739impl<'a> std::fmt::Debug for ClipList<'a> {
740    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
741        (self as &dyn SomeTable<'a>).fmt(f)
742    }
743}
744
745/// [Clip](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record
746#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
747#[repr(C)]
748#[repr(packed)]
749pub struct Clip {
750    /// First glyph ID in the range.
751    pub start_glyph_id: BigEndian<GlyphId16>,
752    /// Last glyph ID in the range.
753    pub end_glyph_id: BigEndian<GlyphId16>,
754    /// Offset to a ClipBox table, from the beginning of the [`ClipList`] table.
755    pub clip_box_offset: BigEndian<Offset24>,
756}
757
758impl Clip {
759    /// First glyph ID in the range.
760    pub fn start_glyph_id(&self) -> GlyphId16 {
761        self.start_glyph_id.get()
762    }
763
764    /// Last glyph ID in the range.
765    pub fn end_glyph_id(&self) -> GlyphId16 {
766        self.end_glyph_id.get()
767    }
768
769    /// Offset to a ClipBox table, from the beginning of the [`ClipList`] table.
770    pub fn clip_box_offset(&self) -> Offset24 {
771        self.clip_box_offset.get()
772    }
773
774    /// Offset to a ClipBox table, from the beginning of the [`ClipList`] table.
775    ///
776    /// The `data` argument should be retrieved from the parent table
777    /// By calling its `offset_data` method.
778    pub fn clip_box<'a>(&self, data: FontData<'a>) -> Result<ClipBox<'a>, ReadError> {
779        self.clip_box_offset().resolve(data)
780    }
781}
782
783impl FixedSize for Clip {
784    const RAW_BYTE_LEN: usize =
785        GlyphId16::RAW_BYTE_LEN + GlyphId16::RAW_BYTE_LEN + Offset24::RAW_BYTE_LEN;
786}
787
788#[cfg(feature = "experimental_traverse")]
789impl<'a> SomeRecord<'a> for Clip {
790    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
791        RecordResolver {
792            name: "Clip",
793            get_field: Box::new(move |idx, _data| match idx {
794                0usize => Some(Field::new("start_glyph_id", self.start_glyph_id())),
795                1usize => Some(Field::new("end_glyph_id", self.end_glyph_id())),
796                2usize => Some(Field::new(
797                    "clip_box_offset",
798                    FieldType::offset(self.clip_box_offset(), self.clip_box(_data)),
799                )),
800                _ => None,
801            }),
802            data,
803        }
804    }
805}
806
807/// [ClipBox](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table
808#[derive(Clone)]
809pub enum ClipBox<'a> {
810    Format1(ClipBoxFormat1<'a>),
811    Format2(ClipBoxFormat2<'a>),
812}
813
814impl<'a> ClipBox<'a> {
815    ///Return the `FontData` used to resolve offsets for this table.
816    pub fn offset_data(&self) -> FontData<'a> {
817        match self {
818            Self::Format1(item) => item.offset_data(),
819            Self::Format2(item) => item.offset_data(),
820        }
821    }
822
823    /// Set to 1.
824    pub fn format(&self) -> u8 {
825        match self {
826            Self::Format1(item) => item.format(),
827            Self::Format2(item) => item.format(),
828        }
829    }
830
831    /// Minimum x of clip box.
832    pub fn x_min(&self) -> FWord {
833        match self {
834            Self::Format1(item) => item.x_min(),
835            Self::Format2(item) => item.x_min(),
836        }
837    }
838
839    /// Minimum y of clip box.
840    pub fn y_min(&self) -> FWord {
841        match self {
842            Self::Format1(item) => item.y_min(),
843            Self::Format2(item) => item.y_min(),
844        }
845    }
846
847    /// Maximum x of clip box.
848    pub fn x_max(&self) -> FWord {
849        match self {
850            Self::Format1(item) => item.x_max(),
851            Self::Format2(item) => item.x_max(),
852        }
853    }
854
855    /// Maximum y of clip box.
856    pub fn y_max(&self) -> FWord {
857        match self {
858            Self::Format1(item) => item.y_max(),
859            Self::Format2(item) => item.y_max(),
860        }
861    }
862}
863
864impl<'a> FontRead<'a> for ClipBox<'a> {
865    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
866        let format: u8 = data.read_at(0usize)?;
867        match format {
868            ClipBoxFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
869            ClipBoxFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
870            other => Err(ReadError::InvalidFormat(other.into())),
871        }
872    }
873}
874
875impl MinByteRange for ClipBox<'_> {
876    fn min_byte_range(&self) -> Range<usize> {
877        match self {
878            Self::Format1(item) => item.min_byte_range(),
879            Self::Format2(item) => item.min_byte_range(),
880        }
881    }
882}
883
884#[cfg(feature = "experimental_traverse")]
885impl<'a> ClipBox<'a> {
886    fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
887        match self {
888            Self::Format1(table) => table,
889            Self::Format2(table) => table,
890        }
891    }
892}
893
894#[cfg(feature = "experimental_traverse")]
895impl std::fmt::Debug for ClipBox<'_> {
896    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
897        self.dyn_inner().fmt(f)
898    }
899}
900
901#[cfg(feature = "experimental_traverse")]
902impl<'a> SomeTable<'a> for ClipBox<'a> {
903    fn type_name(&self) -> &str {
904        self.dyn_inner().type_name()
905    }
906    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
907        self.dyn_inner().get_field(idx)
908    }
909}
910
911impl Format<u8> for ClipBoxFormat1Marker {
912    const FORMAT: u8 = 1;
913}
914
915/// [ClipBoxFormat1](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record
916#[derive(Debug, Clone, Copy)]
917#[doc(hidden)]
918pub struct ClipBoxFormat1Marker {}
919
920impl ClipBoxFormat1Marker {
921    pub fn format_byte_range(&self) -> Range<usize> {
922        let start = 0;
923        start..start + u8::RAW_BYTE_LEN
924    }
925
926    pub fn x_min_byte_range(&self) -> Range<usize> {
927        let start = self.format_byte_range().end;
928        start..start + FWord::RAW_BYTE_LEN
929    }
930
931    pub fn y_min_byte_range(&self) -> Range<usize> {
932        let start = self.x_min_byte_range().end;
933        start..start + FWord::RAW_BYTE_LEN
934    }
935
936    pub fn x_max_byte_range(&self) -> Range<usize> {
937        let start = self.y_min_byte_range().end;
938        start..start + FWord::RAW_BYTE_LEN
939    }
940
941    pub fn y_max_byte_range(&self) -> Range<usize> {
942        let start = self.x_max_byte_range().end;
943        start..start + FWord::RAW_BYTE_LEN
944    }
945}
946
947impl MinByteRange for ClipBoxFormat1Marker {
948    fn min_byte_range(&self) -> Range<usize> {
949        0..self.y_max_byte_range().end
950    }
951}
952
953impl<'a> FontRead<'a> for ClipBoxFormat1<'a> {
954    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
955        let mut cursor = data.cursor();
956        cursor.advance::<u8>();
957        cursor.advance::<FWord>();
958        cursor.advance::<FWord>();
959        cursor.advance::<FWord>();
960        cursor.advance::<FWord>();
961        cursor.finish(ClipBoxFormat1Marker {})
962    }
963}
964
965/// [ClipBoxFormat1](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record
966pub type ClipBoxFormat1<'a> = TableRef<'a, ClipBoxFormat1Marker>;
967
968#[allow(clippy::needless_lifetimes)]
969impl<'a> ClipBoxFormat1<'a> {
970    /// Set to 1.
971    pub fn format(&self) -> u8 {
972        let range = self.shape.format_byte_range();
973        self.data.read_at(range.start).unwrap()
974    }
975
976    /// Minimum x of clip box.
977    pub fn x_min(&self) -> FWord {
978        let range = self.shape.x_min_byte_range();
979        self.data.read_at(range.start).unwrap()
980    }
981
982    /// Minimum y of clip box.
983    pub fn y_min(&self) -> FWord {
984        let range = self.shape.y_min_byte_range();
985        self.data.read_at(range.start).unwrap()
986    }
987
988    /// Maximum x of clip box.
989    pub fn x_max(&self) -> FWord {
990        let range = self.shape.x_max_byte_range();
991        self.data.read_at(range.start).unwrap()
992    }
993
994    /// Maximum y of clip box.
995    pub fn y_max(&self) -> FWord {
996        let range = self.shape.y_max_byte_range();
997        self.data.read_at(range.start).unwrap()
998    }
999}
1000
1001#[cfg(feature = "experimental_traverse")]
1002impl<'a> SomeTable<'a> for ClipBoxFormat1<'a> {
1003    fn type_name(&self) -> &str {
1004        "ClipBoxFormat1"
1005    }
1006    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1007        match idx {
1008            0usize => Some(Field::new("format", self.format())),
1009            1usize => Some(Field::new("x_min", self.x_min())),
1010            2usize => Some(Field::new("y_min", self.y_min())),
1011            3usize => Some(Field::new("x_max", self.x_max())),
1012            4usize => Some(Field::new("y_max", self.y_max())),
1013            _ => None,
1014        }
1015    }
1016}
1017
1018#[cfg(feature = "experimental_traverse")]
1019#[allow(clippy::needless_lifetimes)]
1020impl<'a> std::fmt::Debug for ClipBoxFormat1<'a> {
1021    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1022        (self as &dyn SomeTable<'a>).fmt(f)
1023    }
1024}
1025
1026impl Format<u8> for ClipBoxFormat2Marker {
1027    const FORMAT: u8 = 2;
1028}
1029
1030/// [ClipBoxFormat2](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record
1031#[derive(Debug, Clone, Copy)]
1032#[doc(hidden)]
1033pub struct ClipBoxFormat2Marker {}
1034
1035impl ClipBoxFormat2Marker {
1036    pub fn format_byte_range(&self) -> Range<usize> {
1037        let start = 0;
1038        start..start + u8::RAW_BYTE_LEN
1039    }
1040
1041    pub fn x_min_byte_range(&self) -> Range<usize> {
1042        let start = self.format_byte_range().end;
1043        start..start + FWord::RAW_BYTE_LEN
1044    }
1045
1046    pub fn y_min_byte_range(&self) -> Range<usize> {
1047        let start = self.x_min_byte_range().end;
1048        start..start + FWord::RAW_BYTE_LEN
1049    }
1050
1051    pub fn x_max_byte_range(&self) -> Range<usize> {
1052        let start = self.y_min_byte_range().end;
1053        start..start + FWord::RAW_BYTE_LEN
1054    }
1055
1056    pub fn y_max_byte_range(&self) -> Range<usize> {
1057        let start = self.x_max_byte_range().end;
1058        start..start + FWord::RAW_BYTE_LEN
1059    }
1060
1061    pub fn var_index_base_byte_range(&self) -> Range<usize> {
1062        let start = self.y_max_byte_range().end;
1063        start..start + u32::RAW_BYTE_LEN
1064    }
1065}
1066
1067impl MinByteRange for ClipBoxFormat2Marker {
1068    fn min_byte_range(&self) -> Range<usize> {
1069        0..self.var_index_base_byte_range().end
1070    }
1071}
1072
1073impl<'a> FontRead<'a> for ClipBoxFormat2<'a> {
1074    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1075        let mut cursor = data.cursor();
1076        cursor.advance::<u8>();
1077        cursor.advance::<FWord>();
1078        cursor.advance::<FWord>();
1079        cursor.advance::<FWord>();
1080        cursor.advance::<FWord>();
1081        cursor.advance::<u32>();
1082        cursor.finish(ClipBoxFormat2Marker {})
1083    }
1084}
1085
1086/// [ClipBoxFormat2](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record
1087pub type ClipBoxFormat2<'a> = TableRef<'a, ClipBoxFormat2Marker>;
1088
1089#[allow(clippy::needless_lifetimes)]
1090impl<'a> ClipBoxFormat2<'a> {
1091    /// Set to 2.
1092    pub fn format(&self) -> u8 {
1093        let range = self.shape.format_byte_range();
1094        self.data.read_at(range.start).unwrap()
1095    }
1096
1097    /// Minimum x of clip box. For variation, use varIndexBase + 0.
1098    pub fn x_min(&self) -> FWord {
1099        let range = self.shape.x_min_byte_range();
1100        self.data.read_at(range.start).unwrap()
1101    }
1102
1103    /// Minimum y of clip box. For variation, use varIndexBase + 1.
1104    pub fn y_min(&self) -> FWord {
1105        let range = self.shape.y_min_byte_range();
1106        self.data.read_at(range.start).unwrap()
1107    }
1108
1109    /// Maximum x of clip box. For variation, use varIndexBase + 2.
1110    pub fn x_max(&self) -> FWord {
1111        let range = self.shape.x_max_byte_range();
1112        self.data.read_at(range.start).unwrap()
1113    }
1114
1115    /// Maximum y of clip box. For variation, use varIndexBase + 3.
1116    pub fn y_max(&self) -> FWord {
1117        let range = self.shape.y_max_byte_range();
1118        self.data.read_at(range.start).unwrap()
1119    }
1120
1121    /// Base index into DeltaSetIndexMap.
1122    pub fn var_index_base(&self) -> u32 {
1123        let range = self.shape.var_index_base_byte_range();
1124        self.data.read_at(range.start).unwrap()
1125    }
1126}
1127
1128#[cfg(feature = "experimental_traverse")]
1129impl<'a> SomeTable<'a> for ClipBoxFormat2<'a> {
1130    fn type_name(&self) -> &str {
1131        "ClipBoxFormat2"
1132    }
1133    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1134        match idx {
1135            0usize => Some(Field::new("format", self.format())),
1136            1usize => Some(Field::new("x_min", self.x_min())),
1137            2usize => Some(Field::new("y_min", self.y_min())),
1138            3usize => Some(Field::new("x_max", self.x_max())),
1139            4usize => Some(Field::new("y_max", self.y_max())),
1140            5usize => Some(Field::new("var_index_base", self.var_index_base())),
1141            _ => None,
1142        }
1143    }
1144}
1145
1146#[cfg(feature = "experimental_traverse")]
1147#[allow(clippy::needless_lifetimes)]
1148impl<'a> std::fmt::Debug for ClipBoxFormat2<'a> {
1149    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1150        (self as &dyn SomeTable<'a>).fmt(f)
1151    }
1152}
1153
1154/// [ColorIndex](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) record
1155#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
1156#[repr(C)]
1157#[repr(packed)]
1158pub struct ColorIndex {
1159    /// Index for a CPAL palette entry.
1160    pub palette_index: BigEndian<u16>,
1161    /// Alpha value.
1162    pub alpha: BigEndian<F2Dot14>,
1163}
1164
1165impl ColorIndex {
1166    /// Index for a CPAL palette entry.
1167    pub fn palette_index(&self) -> u16 {
1168        self.palette_index.get()
1169    }
1170
1171    /// Alpha value.
1172    pub fn alpha(&self) -> F2Dot14 {
1173        self.alpha.get()
1174    }
1175}
1176
1177impl FixedSize for ColorIndex {
1178    const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN;
1179}
1180
1181#[cfg(feature = "experimental_traverse")]
1182impl<'a> SomeRecord<'a> for ColorIndex {
1183    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
1184        RecordResolver {
1185            name: "ColorIndex",
1186            get_field: Box::new(move |idx, _data| match idx {
1187                0usize => Some(Field::new("palette_index", self.palette_index())),
1188                1usize => Some(Field::new("alpha", self.alpha())),
1189                _ => None,
1190            }),
1191            data,
1192        }
1193    }
1194}
1195
1196/// [VarColorIndex](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) record
1197#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
1198#[repr(C)]
1199#[repr(packed)]
1200pub struct VarColorIndex {
1201    /// Index for a CPAL palette entry.
1202    pub palette_index: BigEndian<u16>,
1203    /// Alpha value. For variation, use varIndexBase + 0.
1204    pub alpha: BigEndian<F2Dot14>,
1205    /// Base index into DeltaSetIndexMap.
1206    pub var_index_base: BigEndian<u32>,
1207}
1208
1209impl VarColorIndex {
1210    /// Index for a CPAL palette entry.
1211    pub fn palette_index(&self) -> u16 {
1212        self.palette_index.get()
1213    }
1214
1215    /// Alpha value. For variation, use varIndexBase + 0.
1216    pub fn alpha(&self) -> F2Dot14 {
1217        self.alpha.get()
1218    }
1219
1220    /// Base index into DeltaSetIndexMap.
1221    pub fn var_index_base(&self) -> u32 {
1222        self.var_index_base.get()
1223    }
1224}
1225
1226impl FixedSize for VarColorIndex {
1227    const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + u32::RAW_BYTE_LEN;
1228}
1229
1230#[cfg(feature = "experimental_traverse")]
1231impl<'a> SomeRecord<'a> for VarColorIndex {
1232    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
1233        RecordResolver {
1234            name: "VarColorIndex",
1235            get_field: Box::new(move |idx, _data| match idx {
1236                0usize => Some(Field::new("palette_index", self.palette_index())),
1237                1usize => Some(Field::new("alpha", self.alpha())),
1238                2usize => Some(Field::new("var_index_base", self.var_index_base())),
1239                _ => None,
1240            }),
1241            data,
1242        }
1243    }
1244}
1245
1246/// [ColorStop](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) record
1247#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
1248#[repr(C)]
1249#[repr(packed)]
1250pub struct ColorStop {
1251    /// Position on a color line.
1252    pub stop_offset: BigEndian<F2Dot14>,
1253    /// Index for a CPAL palette entry.
1254    pub palette_index: BigEndian<u16>,
1255    /// Alpha value.
1256    pub alpha: BigEndian<F2Dot14>,
1257}
1258
1259impl ColorStop {
1260    /// Position on a color line.
1261    pub fn stop_offset(&self) -> F2Dot14 {
1262        self.stop_offset.get()
1263    }
1264
1265    /// Index for a CPAL palette entry.
1266    pub fn palette_index(&self) -> u16 {
1267        self.palette_index.get()
1268    }
1269
1270    /// Alpha value.
1271    pub fn alpha(&self) -> F2Dot14 {
1272        self.alpha.get()
1273    }
1274}
1275
1276impl FixedSize for ColorStop {
1277    const RAW_BYTE_LEN: usize = F2Dot14::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN;
1278}
1279
1280#[cfg(feature = "experimental_traverse")]
1281impl<'a> SomeRecord<'a> for ColorStop {
1282    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
1283        RecordResolver {
1284            name: "ColorStop",
1285            get_field: Box::new(move |idx, _data| match idx {
1286                0usize => Some(Field::new("stop_offset", self.stop_offset())),
1287                1usize => Some(Field::new("palette_index", self.palette_index())),
1288                2usize => Some(Field::new("alpha", self.alpha())),
1289                _ => None,
1290            }),
1291            data,
1292        }
1293    }
1294}
1295
1296/// [VarColorStop](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) record
1297#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
1298#[repr(C)]
1299#[repr(packed)]
1300pub struct VarColorStop {
1301    /// Position on a color line. For variation, use varIndexBase + 0.
1302    pub stop_offset: BigEndian<F2Dot14>,
1303    /// Index for a CPAL palette entry.
1304    pub palette_index: BigEndian<u16>,
1305    /// Alpha value. For variation, use varIndexBase + 1.
1306    pub alpha: BigEndian<F2Dot14>,
1307    /// Base index into DeltaSetIndexMap.
1308    pub var_index_base: BigEndian<u32>,
1309}
1310
1311impl VarColorStop {
1312    /// Position on a color line. For variation, use varIndexBase + 0.
1313    pub fn stop_offset(&self) -> F2Dot14 {
1314        self.stop_offset.get()
1315    }
1316
1317    /// Index for a CPAL palette entry.
1318    pub fn palette_index(&self) -> u16 {
1319        self.palette_index.get()
1320    }
1321
1322    /// Alpha value. For variation, use varIndexBase + 1.
1323    pub fn alpha(&self) -> F2Dot14 {
1324        self.alpha.get()
1325    }
1326
1327    /// Base index into DeltaSetIndexMap.
1328    pub fn var_index_base(&self) -> u32 {
1329        self.var_index_base.get()
1330    }
1331}
1332
1333impl FixedSize for VarColorStop {
1334    const RAW_BYTE_LEN: usize =
1335        F2Dot14::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + u32::RAW_BYTE_LEN;
1336}
1337
1338#[cfg(feature = "experimental_traverse")]
1339impl<'a> SomeRecord<'a> for VarColorStop {
1340    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
1341        RecordResolver {
1342            name: "VarColorStop",
1343            get_field: Box::new(move |idx, _data| match idx {
1344                0usize => Some(Field::new("stop_offset", self.stop_offset())),
1345                1usize => Some(Field::new("palette_index", self.palette_index())),
1346                2usize => Some(Field::new("alpha", self.alpha())),
1347                3usize => Some(Field::new("var_index_base", self.var_index_base())),
1348                _ => None,
1349            }),
1350            data,
1351        }
1352    }
1353}
1354
1355/// [ColorLine](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) table
1356#[derive(Debug, Clone, Copy)]
1357#[doc(hidden)]
1358pub struct ColorLineMarker {
1359    color_stops_byte_len: usize,
1360}
1361
1362impl ColorLineMarker {
1363    pub fn extend_byte_range(&self) -> Range<usize> {
1364        let start = 0;
1365        start..start + Extend::RAW_BYTE_LEN
1366    }
1367
1368    pub fn num_stops_byte_range(&self) -> Range<usize> {
1369        let start = self.extend_byte_range().end;
1370        start..start + u16::RAW_BYTE_LEN
1371    }
1372
1373    pub fn color_stops_byte_range(&self) -> Range<usize> {
1374        let start = self.num_stops_byte_range().end;
1375        start..start + self.color_stops_byte_len
1376    }
1377}
1378
1379impl MinByteRange for ColorLineMarker {
1380    fn min_byte_range(&self) -> Range<usize> {
1381        0..self.color_stops_byte_range().end
1382    }
1383}
1384
1385impl<'a> FontRead<'a> for ColorLine<'a> {
1386    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1387        let mut cursor = data.cursor();
1388        cursor.advance::<Extend>();
1389        let num_stops: u16 = cursor.read()?;
1390        let color_stops_byte_len = (num_stops as usize)
1391            .checked_mul(ColorStop::RAW_BYTE_LEN)
1392            .ok_or(ReadError::OutOfBounds)?;
1393        cursor.advance_by(color_stops_byte_len);
1394        cursor.finish(ColorLineMarker {
1395            color_stops_byte_len,
1396        })
1397    }
1398}
1399
1400/// [ColorLine](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) table
1401pub type ColorLine<'a> = TableRef<'a, ColorLineMarker>;
1402
1403#[allow(clippy::needless_lifetimes)]
1404impl<'a> ColorLine<'a> {
1405    /// An Extend enum value.
1406    pub fn extend(&self) -> Extend {
1407        let range = self.shape.extend_byte_range();
1408        self.data.read_at(range.start).unwrap()
1409    }
1410
1411    /// Number of ColorStop records.
1412    pub fn num_stops(&self) -> u16 {
1413        let range = self.shape.num_stops_byte_range();
1414        self.data.read_at(range.start).unwrap()
1415    }
1416
1417    pub fn color_stops(&self) -> &'a [ColorStop] {
1418        let range = self.shape.color_stops_byte_range();
1419        self.data.read_array(range).unwrap()
1420    }
1421}
1422
1423#[cfg(feature = "experimental_traverse")]
1424impl<'a> SomeTable<'a> for ColorLine<'a> {
1425    fn type_name(&self) -> &str {
1426        "ColorLine"
1427    }
1428    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1429        match idx {
1430            0usize => Some(Field::new("extend", self.extend())),
1431            1usize => Some(Field::new("num_stops", self.num_stops())),
1432            2usize => Some(Field::new(
1433                "color_stops",
1434                traversal::FieldType::array_of_records(
1435                    stringify!(ColorStop),
1436                    self.color_stops(),
1437                    self.offset_data(),
1438                ),
1439            )),
1440            _ => None,
1441        }
1442    }
1443}
1444
1445#[cfg(feature = "experimental_traverse")]
1446#[allow(clippy::needless_lifetimes)]
1447impl<'a> std::fmt::Debug for ColorLine<'a> {
1448    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1449        (self as &dyn SomeTable<'a>).fmt(f)
1450    }
1451}
1452
1453/// [VarColorLine](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) table
1454#[derive(Debug, Clone, Copy)]
1455#[doc(hidden)]
1456pub struct VarColorLineMarker {
1457    color_stops_byte_len: usize,
1458}
1459
1460impl VarColorLineMarker {
1461    pub fn extend_byte_range(&self) -> Range<usize> {
1462        let start = 0;
1463        start..start + Extend::RAW_BYTE_LEN
1464    }
1465
1466    pub fn num_stops_byte_range(&self) -> Range<usize> {
1467        let start = self.extend_byte_range().end;
1468        start..start + u16::RAW_BYTE_LEN
1469    }
1470
1471    pub fn color_stops_byte_range(&self) -> Range<usize> {
1472        let start = self.num_stops_byte_range().end;
1473        start..start + self.color_stops_byte_len
1474    }
1475}
1476
1477impl MinByteRange for VarColorLineMarker {
1478    fn min_byte_range(&self) -> Range<usize> {
1479        0..self.color_stops_byte_range().end
1480    }
1481}
1482
1483impl<'a> FontRead<'a> for VarColorLine<'a> {
1484    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1485        let mut cursor = data.cursor();
1486        cursor.advance::<Extend>();
1487        let num_stops: u16 = cursor.read()?;
1488        let color_stops_byte_len = (num_stops as usize)
1489            .checked_mul(VarColorStop::RAW_BYTE_LEN)
1490            .ok_or(ReadError::OutOfBounds)?;
1491        cursor.advance_by(color_stops_byte_len);
1492        cursor.finish(VarColorLineMarker {
1493            color_stops_byte_len,
1494        })
1495    }
1496}
1497
1498/// [VarColorLine](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) table
1499pub type VarColorLine<'a> = TableRef<'a, VarColorLineMarker>;
1500
1501#[allow(clippy::needless_lifetimes)]
1502impl<'a> VarColorLine<'a> {
1503    /// An Extend enum value.
1504    pub fn extend(&self) -> Extend {
1505        let range = self.shape.extend_byte_range();
1506        self.data.read_at(range.start).unwrap()
1507    }
1508
1509    /// Number of ColorStop records.
1510    pub fn num_stops(&self) -> u16 {
1511        let range = self.shape.num_stops_byte_range();
1512        self.data.read_at(range.start).unwrap()
1513    }
1514
1515    /// Allows for variations.
1516    pub fn color_stops(&self) -> &'a [VarColorStop] {
1517        let range = self.shape.color_stops_byte_range();
1518        self.data.read_array(range).unwrap()
1519    }
1520}
1521
1522#[cfg(feature = "experimental_traverse")]
1523impl<'a> SomeTable<'a> for VarColorLine<'a> {
1524    fn type_name(&self) -> &str {
1525        "VarColorLine"
1526    }
1527    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1528        match idx {
1529            0usize => Some(Field::new("extend", self.extend())),
1530            1usize => Some(Field::new("num_stops", self.num_stops())),
1531            2usize => Some(Field::new(
1532                "color_stops",
1533                traversal::FieldType::array_of_records(
1534                    stringify!(VarColorStop),
1535                    self.color_stops(),
1536                    self.offset_data(),
1537                ),
1538            )),
1539            _ => None,
1540        }
1541    }
1542}
1543
1544#[cfg(feature = "experimental_traverse")]
1545#[allow(clippy::needless_lifetimes)]
1546impl<'a> std::fmt::Debug for VarColorLine<'a> {
1547    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1548        (self as &dyn SomeTable<'a>).fmt(f)
1549    }
1550}
1551
1552/// [Extend](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) enumeration
1553#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
1554#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1555#[repr(u8)]
1556#[allow(clippy::manual_non_exhaustive)]
1557pub enum Extend {
1558    #[default]
1559    Pad = 0,
1560    Repeat = 1,
1561    Reflect = 2,
1562    #[doc(hidden)]
1563    /// If font data is malformed we will map unknown values to this variant
1564    Unknown,
1565}
1566
1567impl Extend {
1568    /// Create from a raw scalar.
1569    ///
1570    /// This will never fail; unknown values will be mapped to the `Unknown` variant
1571    pub fn new(raw: u8) -> Self {
1572        match raw {
1573            0 => Self::Pad,
1574            1 => Self::Repeat,
1575            2 => Self::Reflect,
1576            _ => Self::Unknown,
1577        }
1578    }
1579}
1580
1581impl font_types::Scalar for Extend {
1582    type Raw = <u8 as font_types::Scalar>::Raw;
1583    fn to_raw(self) -> Self::Raw {
1584        (self as u8).to_raw()
1585    }
1586    fn from_raw(raw: Self::Raw) -> Self {
1587        let t = <u8>::from_raw(raw);
1588        Self::new(t)
1589    }
1590}
1591
1592#[cfg(feature = "experimental_traverse")]
1593impl<'a> From<Extend> for FieldType<'a> {
1594    fn from(src: Extend) -> FieldType<'a> {
1595        (src as u8).into()
1596    }
1597}
1598
1599/// [Paint](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#paint-tables) tables
1600#[derive(Clone)]
1601pub enum Paint<'a> {
1602    ColrLayers(PaintColrLayers<'a>),
1603    Solid(PaintSolid<'a>),
1604    VarSolid(PaintVarSolid<'a>),
1605    LinearGradient(PaintLinearGradient<'a>),
1606    VarLinearGradient(PaintVarLinearGradient<'a>),
1607    RadialGradient(PaintRadialGradient<'a>),
1608    VarRadialGradient(PaintVarRadialGradient<'a>),
1609    SweepGradient(PaintSweepGradient<'a>),
1610    VarSweepGradient(PaintVarSweepGradient<'a>),
1611    Glyph(PaintGlyph<'a>),
1612    ColrGlyph(PaintColrGlyph<'a>),
1613    Transform(PaintTransform<'a>),
1614    VarTransform(PaintVarTransform<'a>),
1615    Translate(PaintTranslate<'a>),
1616    VarTranslate(PaintVarTranslate<'a>),
1617    Scale(PaintScale<'a>),
1618    VarScale(PaintVarScale<'a>),
1619    ScaleAroundCenter(PaintScaleAroundCenter<'a>),
1620    VarScaleAroundCenter(PaintVarScaleAroundCenter<'a>),
1621    ScaleUniform(PaintScaleUniform<'a>),
1622    VarScaleUniform(PaintVarScaleUniform<'a>),
1623    ScaleUniformAroundCenter(PaintScaleUniformAroundCenter<'a>),
1624    VarScaleUniformAroundCenter(PaintVarScaleUniformAroundCenter<'a>),
1625    Rotate(PaintRotate<'a>),
1626    VarRotate(PaintVarRotate<'a>),
1627    RotateAroundCenter(PaintRotateAroundCenter<'a>),
1628    VarRotateAroundCenter(PaintVarRotateAroundCenter<'a>),
1629    Skew(PaintSkew<'a>),
1630    VarSkew(PaintVarSkew<'a>),
1631    SkewAroundCenter(PaintSkewAroundCenter<'a>),
1632    VarSkewAroundCenter(PaintVarSkewAroundCenter<'a>),
1633    Composite(PaintComposite<'a>),
1634}
1635
1636impl<'a> Paint<'a> {
1637    ///Return the `FontData` used to resolve offsets for this table.
1638    pub fn offset_data(&self) -> FontData<'a> {
1639        match self {
1640            Self::ColrLayers(item) => item.offset_data(),
1641            Self::Solid(item) => item.offset_data(),
1642            Self::VarSolid(item) => item.offset_data(),
1643            Self::LinearGradient(item) => item.offset_data(),
1644            Self::VarLinearGradient(item) => item.offset_data(),
1645            Self::RadialGradient(item) => item.offset_data(),
1646            Self::VarRadialGradient(item) => item.offset_data(),
1647            Self::SweepGradient(item) => item.offset_data(),
1648            Self::VarSweepGradient(item) => item.offset_data(),
1649            Self::Glyph(item) => item.offset_data(),
1650            Self::ColrGlyph(item) => item.offset_data(),
1651            Self::Transform(item) => item.offset_data(),
1652            Self::VarTransform(item) => item.offset_data(),
1653            Self::Translate(item) => item.offset_data(),
1654            Self::VarTranslate(item) => item.offset_data(),
1655            Self::Scale(item) => item.offset_data(),
1656            Self::VarScale(item) => item.offset_data(),
1657            Self::ScaleAroundCenter(item) => item.offset_data(),
1658            Self::VarScaleAroundCenter(item) => item.offset_data(),
1659            Self::ScaleUniform(item) => item.offset_data(),
1660            Self::VarScaleUniform(item) => item.offset_data(),
1661            Self::ScaleUniformAroundCenter(item) => item.offset_data(),
1662            Self::VarScaleUniformAroundCenter(item) => item.offset_data(),
1663            Self::Rotate(item) => item.offset_data(),
1664            Self::VarRotate(item) => item.offset_data(),
1665            Self::RotateAroundCenter(item) => item.offset_data(),
1666            Self::VarRotateAroundCenter(item) => item.offset_data(),
1667            Self::Skew(item) => item.offset_data(),
1668            Self::VarSkew(item) => item.offset_data(),
1669            Self::SkewAroundCenter(item) => item.offset_data(),
1670            Self::VarSkewAroundCenter(item) => item.offset_data(),
1671            Self::Composite(item) => item.offset_data(),
1672        }
1673    }
1674
1675    /// Set to 1.
1676    pub fn format(&self) -> u8 {
1677        match self {
1678            Self::ColrLayers(item) => item.format(),
1679            Self::Solid(item) => item.format(),
1680            Self::VarSolid(item) => item.format(),
1681            Self::LinearGradient(item) => item.format(),
1682            Self::VarLinearGradient(item) => item.format(),
1683            Self::RadialGradient(item) => item.format(),
1684            Self::VarRadialGradient(item) => item.format(),
1685            Self::SweepGradient(item) => item.format(),
1686            Self::VarSweepGradient(item) => item.format(),
1687            Self::Glyph(item) => item.format(),
1688            Self::ColrGlyph(item) => item.format(),
1689            Self::Transform(item) => item.format(),
1690            Self::VarTransform(item) => item.format(),
1691            Self::Translate(item) => item.format(),
1692            Self::VarTranslate(item) => item.format(),
1693            Self::Scale(item) => item.format(),
1694            Self::VarScale(item) => item.format(),
1695            Self::ScaleAroundCenter(item) => item.format(),
1696            Self::VarScaleAroundCenter(item) => item.format(),
1697            Self::ScaleUniform(item) => item.format(),
1698            Self::VarScaleUniform(item) => item.format(),
1699            Self::ScaleUniformAroundCenter(item) => item.format(),
1700            Self::VarScaleUniformAroundCenter(item) => item.format(),
1701            Self::Rotate(item) => item.format(),
1702            Self::VarRotate(item) => item.format(),
1703            Self::RotateAroundCenter(item) => item.format(),
1704            Self::VarRotateAroundCenter(item) => item.format(),
1705            Self::Skew(item) => item.format(),
1706            Self::VarSkew(item) => item.format(),
1707            Self::SkewAroundCenter(item) => item.format(),
1708            Self::VarSkewAroundCenter(item) => item.format(),
1709            Self::Composite(item) => item.format(),
1710        }
1711    }
1712}
1713
1714impl<'a> FontRead<'a> for Paint<'a> {
1715    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1716        let format: u8 = data.read_at(0usize)?;
1717        match format {
1718            PaintColrLayersMarker::FORMAT => Ok(Self::ColrLayers(FontRead::read(data)?)),
1719            PaintSolidMarker::FORMAT => Ok(Self::Solid(FontRead::read(data)?)),
1720            PaintVarSolidMarker::FORMAT => Ok(Self::VarSolid(FontRead::read(data)?)),
1721            PaintLinearGradientMarker::FORMAT => Ok(Self::LinearGradient(FontRead::read(data)?)),
1722            PaintVarLinearGradientMarker::FORMAT => {
1723                Ok(Self::VarLinearGradient(FontRead::read(data)?))
1724            }
1725            PaintRadialGradientMarker::FORMAT => Ok(Self::RadialGradient(FontRead::read(data)?)),
1726            PaintVarRadialGradientMarker::FORMAT => {
1727                Ok(Self::VarRadialGradient(FontRead::read(data)?))
1728            }
1729            PaintSweepGradientMarker::FORMAT => Ok(Self::SweepGradient(FontRead::read(data)?)),
1730            PaintVarSweepGradientMarker::FORMAT => {
1731                Ok(Self::VarSweepGradient(FontRead::read(data)?))
1732            }
1733            PaintGlyphMarker::FORMAT => Ok(Self::Glyph(FontRead::read(data)?)),
1734            PaintColrGlyphMarker::FORMAT => Ok(Self::ColrGlyph(FontRead::read(data)?)),
1735            PaintTransformMarker::FORMAT => Ok(Self::Transform(FontRead::read(data)?)),
1736            PaintVarTransformMarker::FORMAT => Ok(Self::VarTransform(FontRead::read(data)?)),
1737            PaintTranslateMarker::FORMAT => Ok(Self::Translate(FontRead::read(data)?)),
1738            PaintVarTranslateMarker::FORMAT => Ok(Self::VarTranslate(FontRead::read(data)?)),
1739            PaintScaleMarker::FORMAT => Ok(Self::Scale(FontRead::read(data)?)),
1740            PaintVarScaleMarker::FORMAT => Ok(Self::VarScale(FontRead::read(data)?)),
1741            PaintScaleAroundCenterMarker::FORMAT => {
1742                Ok(Self::ScaleAroundCenter(FontRead::read(data)?))
1743            }
1744            PaintVarScaleAroundCenterMarker::FORMAT => {
1745                Ok(Self::VarScaleAroundCenter(FontRead::read(data)?))
1746            }
1747            PaintScaleUniformMarker::FORMAT => Ok(Self::ScaleUniform(FontRead::read(data)?)),
1748            PaintVarScaleUniformMarker::FORMAT => Ok(Self::VarScaleUniform(FontRead::read(data)?)),
1749            PaintScaleUniformAroundCenterMarker::FORMAT => {
1750                Ok(Self::ScaleUniformAroundCenter(FontRead::read(data)?))
1751            }
1752            PaintVarScaleUniformAroundCenterMarker::FORMAT => {
1753                Ok(Self::VarScaleUniformAroundCenter(FontRead::read(data)?))
1754            }
1755            PaintRotateMarker::FORMAT => Ok(Self::Rotate(FontRead::read(data)?)),
1756            PaintVarRotateMarker::FORMAT => Ok(Self::VarRotate(FontRead::read(data)?)),
1757            PaintRotateAroundCenterMarker::FORMAT => {
1758                Ok(Self::RotateAroundCenter(FontRead::read(data)?))
1759            }
1760            PaintVarRotateAroundCenterMarker::FORMAT => {
1761                Ok(Self::VarRotateAroundCenter(FontRead::read(data)?))
1762            }
1763            PaintSkewMarker::FORMAT => Ok(Self::Skew(FontRead::read(data)?)),
1764            PaintVarSkewMarker::FORMAT => Ok(Self::VarSkew(FontRead::read(data)?)),
1765            PaintSkewAroundCenterMarker::FORMAT => {
1766                Ok(Self::SkewAroundCenter(FontRead::read(data)?))
1767            }
1768            PaintVarSkewAroundCenterMarker::FORMAT => {
1769                Ok(Self::VarSkewAroundCenter(FontRead::read(data)?))
1770            }
1771            PaintCompositeMarker::FORMAT => Ok(Self::Composite(FontRead::read(data)?)),
1772            other => Err(ReadError::InvalidFormat(other.into())),
1773        }
1774    }
1775}
1776
1777impl MinByteRange for Paint<'_> {
1778    fn min_byte_range(&self) -> Range<usize> {
1779        match self {
1780            Self::ColrLayers(item) => item.min_byte_range(),
1781            Self::Solid(item) => item.min_byte_range(),
1782            Self::VarSolid(item) => item.min_byte_range(),
1783            Self::LinearGradient(item) => item.min_byte_range(),
1784            Self::VarLinearGradient(item) => item.min_byte_range(),
1785            Self::RadialGradient(item) => item.min_byte_range(),
1786            Self::VarRadialGradient(item) => item.min_byte_range(),
1787            Self::SweepGradient(item) => item.min_byte_range(),
1788            Self::VarSweepGradient(item) => item.min_byte_range(),
1789            Self::Glyph(item) => item.min_byte_range(),
1790            Self::ColrGlyph(item) => item.min_byte_range(),
1791            Self::Transform(item) => item.min_byte_range(),
1792            Self::VarTransform(item) => item.min_byte_range(),
1793            Self::Translate(item) => item.min_byte_range(),
1794            Self::VarTranslate(item) => item.min_byte_range(),
1795            Self::Scale(item) => item.min_byte_range(),
1796            Self::VarScale(item) => item.min_byte_range(),
1797            Self::ScaleAroundCenter(item) => item.min_byte_range(),
1798            Self::VarScaleAroundCenter(item) => item.min_byte_range(),
1799            Self::ScaleUniform(item) => item.min_byte_range(),
1800            Self::VarScaleUniform(item) => item.min_byte_range(),
1801            Self::ScaleUniformAroundCenter(item) => item.min_byte_range(),
1802            Self::VarScaleUniformAroundCenter(item) => item.min_byte_range(),
1803            Self::Rotate(item) => item.min_byte_range(),
1804            Self::VarRotate(item) => item.min_byte_range(),
1805            Self::RotateAroundCenter(item) => item.min_byte_range(),
1806            Self::VarRotateAroundCenter(item) => item.min_byte_range(),
1807            Self::Skew(item) => item.min_byte_range(),
1808            Self::VarSkew(item) => item.min_byte_range(),
1809            Self::SkewAroundCenter(item) => item.min_byte_range(),
1810            Self::VarSkewAroundCenter(item) => item.min_byte_range(),
1811            Self::Composite(item) => item.min_byte_range(),
1812        }
1813    }
1814}
1815
1816#[cfg(feature = "experimental_traverse")]
1817impl<'a> Paint<'a> {
1818    fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
1819        match self {
1820            Self::ColrLayers(table) => table,
1821            Self::Solid(table) => table,
1822            Self::VarSolid(table) => table,
1823            Self::LinearGradient(table) => table,
1824            Self::VarLinearGradient(table) => table,
1825            Self::RadialGradient(table) => table,
1826            Self::VarRadialGradient(table) => table,
1827            Self::SweepGradient(table) => table,
1828            Self::VarSweepGradient(table) => table,
1829            Self::Glyph(table) => table,
1830            Self::ColrGlyph(table) => table,
1831            Self::Transform(table) => table,
1832            Self::VarTransform(table) => table,
1833            Self::Translate(table) => table,
1834            Self::VarTranslate(table) => table,
1835            Self::Scale(table) => table,
1836            Self::VarScale(table) => table,
1837            Self::ScaleAroundCenter(table) => table,
1838            Self::VarScaleAroundCenter(table) => table,
1839            Self::ScaleUniform(table) => table,
1840            Self::VarScaleUniform(table) => table,
1841            Self::ScaleUniformAroundCenter(table) => table,
1842            Self::VarScaleUniformAroundCenter(table) => table,
1843            Self::Rotate(table) => table,
1844            Self::VarRotate(table) => table,
1845            Self::RotateAroundCenter(table) => table,
1846            Self::VarRotateAroundCenter(table) => table,
1847            Self::Skew(table) => table,
1848            Self::VarSkew(table) => table,
1849            Self::SkewAroundCenter(table) => table,
1850            Self::VarSkewAroundCenter(table) => table,
1851            Self::Composite(table) => table,
1852        }
1853    }
1854}
1855
1856#[cfg(feature = "experimental_traverse")]
1857impl std::fmt::Debug for Paint<'_> {
1858    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1859        self.dyn_inner().fmt(f)
1860    }
1861}
1862
1863#[cfg(feature = "experimental_traverse")]
1864impl<'a> SomeTable<'a> for Paint<'a> {
1865    fn type_name(&self) -> &str {
1866        self.dyn_inner().type_name()
1867    }
1868    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1869        self.dyn_inner().get_field(idx)
1870    }
1871}
1872
1873impl Format<u8> for PaintColrLayersMarker {
1874    const FORMAT: u8 = 1;
1875}
1876
1877/// [PaintColrLayers](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-1-paintcolrlayers) table
1878#[derive(Debug, Clone, Copy)]
1879#[doc(hidden)]
1880pub struct PaintColrLayersMarker {}
1881
1882impl PaintColrLayersMarker {
1883    pub fn format_byte_range(&self) -> Range<usize> {
1884        let start = 0;
1885        start..start + u8::RAW_BYTE_LEN
1886    }
1887
1888    pub fn num_layers_byte_range(&self) -> Range<usize> {
1889        let start = self.format_byte_range().end;
1890        start..start + u8::RAW_BYTE_LEN
1891    }
1892
1893    pub fn first_layer_index_byte_range(&self) -> Range<usize> {
1894        let start = self.num_layers_byte_range().end;
1895        start..start + u32::RAW_BYTE_LEN
1896    }
1897}
1898
1899impl MinByteRange for PaintColrLayersMarker {
1900    fn min_byte_range(&self) -> Range<usize> {
1901        0..self.first_layer_index_byte_range().end
1902    }
1903}
1904
1905impl<'a> FontRead<'a> for PaintColrLayers<'a> {
1906    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1907        let mut cursor = data.cursor();
1908        cursor.advance::<u8>();
1909        cursor.advance::<u8>();
1910        cursor.advance::<u32>();
1911        cursor.finish(PaintColrLayersMarker {})
1912    }
1913}
1914
1915/// [PaintColrLayers](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-1-paintcolrlayers) table
1916pub type PaintColrLayers<'a> = TableRef<'a, PaintColrLayersMarker>;
1917
1918#[allow(clippy::needless_lifetimes)]
1919impl<'a> PaintColrLayers<'a> {
1920    /// Set to 1.
1921    pub fn format(&self) -> u8 {
1922        let range = self.shape.format_byte_range();
1923        self.data.read_at(range.start).unwrap()
1924    }
1925
1926    /// Number of offsets to paint tables to read from LayerList.
1927    pub fn num_layers(&self) -> u8 {
1928        let range = self.shape.num_layers_byte_range();
1929        self.data.read_at(range.start).unwrap()
1930    }
1931
1932    /// Index (base 0) into the LayerList.
1933    pub fn first_layer_index(&self) -> u32 {
1934        let range = self.shape.first_layer_index_byte_range();
1935        self.data.read_at(range.start).unwrap()
1936    }
1937}
1938
1939#[cfg(feature = "experimental_traverse")]
1940impl<'a> SomeTable<'a> for PaintColrLayers<'a> {
1941    fn type_name(&self) -> &str {
1942        "PaintColrLayers"
1943    }
1944    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1945        match idx {
1946            0usize => Some(Field::new("format", self.format())),
1947            1usize => Some(Field::new("num_layers", self.num_layers())),
1948            2usize => Some(Field::new("first_layer_index", self.first_layer_index())),
1949            _ => None,
1950        }
1951    }
1952}
1953
1954#[cfg(feature = "experimental_traverse")]
1955#[allow(clippy::needless_lifetimes)]
1956impl<'a> std::fmt::Debug for PaintColrLayers<'a> {
1957    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1958        (self as &dyn SomeTable<'a>).fmt(f)
1959    }
1960}
1961
1962impl Format<u8> for PaintSolidMarker {
1963    const FORMAT: u8 = 2;
1964}
1965
1966/// [PaintSolid](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-2-and-3-paintsolid-paintvarsolid) table
1967#[derive(Debug, Clone, Copy)]
1968#[doc(hidden)]
1969pub struct PaintSolidMarker {}
1970
1971impl PaintSolidMarker {
1972    pub fn format_byte_range(&self) -> Range<usize> {
1973        let start = 0;
1974        start..start + u8::RAW_BYTE_LEN
1975    }
1976
1977    pub fn palette_index_byte_range(&self) -> Range<usize> {
1978        let start = self.format_byte_range().end;
1979        start..start + u16::RAW_BYTE_LEN
1980    }
1981
1982    pub fn alpha_byte_range(&self) -> Range<usize> {
1983        let start = self.palette_index_byte_range().end;
1984        start..start + F2Dot14::RAW_BYTE_LEN
1985    }
1986}
1987
1988impl MinByteRange for PaintSolidMarker {
1989    fn min_byte_range(&self) -> Range<usize> {
1990        0..self.alpha_byte_range().end
1991    }
1992}
1993
1994impl<'a> FontRead<'a> for PaintSolid<'a> {
1995    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1996        let mut cursor = data.cursor();
1997        cursor.advance::<u8>();
1998        cursor.advance::<u16>();
1999        cursor.advance::<F2Dot14>();
2000        cursor.finish(PaintSolidMarker {})
2001    }
2002}
2003
2004/// [PaintSolid](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-2-and-3-paintsolid-paintvarsolid) table
2005pub type PaintSolid<'a> = TableRef<'a, PaintSolidMarker>;
2006
2007#[allow(clippy::needless_lifetimes)]
2008impl<'a> PaintSolid<'a> {
2009    /// Set to 2.
2010    pub fn format(&self) -> u8 {
2011        let range = self.shape.format_byte_range();
2012        self.data.read_at(range.start).unwrap()
2013    }
2014
2015    /// Index for a CPAL palette entry.
2016    pub fn palette_index(&self) -> u16 {
2017        let range = self.shape.palette_index_byte_range();
2018        self.data.read_at(range.start).unwrap()
2019    }
2020
2021    /// Alpha value.
2022    pub fn alpha(&self) -> F2Dot14 {
2023        let range = self.shape.alpha_byte_range();
2024        self.data.read_at(range.start).unwrap()
2025    }
2026}
2027
2028#[cfg(feature = "experimental_traverse")]
2029impl<'a> SomeTable<'a> for PaintSolid<'a> {
2030    fn type_name(&self) -> &str {
2031        "PaintSolid"
2032    }
2033    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2034        match idx {
2035            0usize => Some(Field::new("format", self.format())),
2036            1usize => Some(Field::new("palette_index", self.palette_index())),
2037            2usize => Some(Field::new("alpha", self.alpha())),
2038            _ => None,
2039        }
2040    }
2041}
2042
2043#[cfg(feature = "experimental_traverse")]
2044#[allow(clippy::needless_lifetimes)]
2045impl<'a> std::fmt::Debug for PaintSolid<'a> {
2046    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2047        (self as &dyn SomeTable<'a>).fmt(f)
2048    }
2049}
2050
2051impl Format<u8> for PaintVarSolidMarker {
2052    const FORMAT: u8 = 3;
2053}
2054
2055/// [PaintVarSolid](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-2-and-3-paintsolid-paintvarsolid) table
2056#[derive(Debug, Clone, Copy)]
2057#[doc(hidden)]
2058pub struct PaintVarSolidMarker {}
2059
2060impl PaintVarSolidMarker {
2061    pub fn format_byte_range(&self) -> Range<usize> {
2062        let start = 0;
2063        start..start + u8::RAW_BYTE_LEN
2064    }
2065
2066    pub fn palette_index_byte_range(&self) -> Range<usize> {
2067        let start = self.format_byte_range().end;
2068        start..start + u16::RAW_BYTE_LEN
2069    }
2070
2071    pub fn alpha_byte_range(&self) -> Range<usize> {
2072        let start = self.palette_index_byte_range().end;
2073        start..start + F2Dot14::RAW_BYTE_LEN
2074    }
2075
2076    pub fn var_index_base_byte_range(&self) -> Range<usize> {
2077        let start = self.alpha_byte_range().end;
2078        start..start + u32::RAW_BYTE_LEN
2079    }
2080}
2081
2082impl MinByteRange for PaintVarSolidMarker {
2083    fn min_byte_range(&self) -> Range<usize> {
2084        0..self.var_index_base_byte_range().end
2085    }
2086}
2087
2088impl<'a> FontRead<'a> for PaintVarSolid<'a> {
2089    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2090        let mut cursor = data.cursor();
2091        cursor.advance::<u8>();
2092        cursor.advance::<u16>();
2093        cursor.advance::<F2Dot14>();
2094        cursor.advance::<u32>();
2095        cursor.finish(PaintVarSolidMarker {})
2096    }
2097}
2098
2099/// [PaintVarSolid](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-2-and-3-paintsolid-paintvarsolid) table
2100pub type PaintVarSolid<'a> = TableRef<'a, PaintVarSolidMarker>;
2101
2102#[allow(clippy::needless_lifetimes)]
2103impl<'a> PaintVarSolid<'a> {
2104    /// Set to 3.
2105    pub fn format(&self) -> u8 {
2106        let range = self.shape.format_byte_range();
2107        self.data.read_at(range.start).unwrap()
2108    }
2109
2110    /// Index for a CPAL palette entry.
2111    pub fn palette_index(&self) -> u16 {
2112        let range = self.shape.palette_index_byte_range();
2113        self.data.read_at(range.start).unwrap()
2114    }
2115
2116    /// Alpha value. For variation, use varIndexBase + 0.
2117    pub fn alpha(&self) -> F2Dot14 {
2118        let range = self.shape.alpha_byte_range();
2119        self.data.read_at(range.start).unwrap()
2120    }
2121
2122    /// Base index into DeltaSetIndexMap.
2123    pub fn var_index_base(&self) -> u32 {
2124        let range = self.shape.var_index_base_byte_range();
2125        self.data.read_at(range.start).unwrap()
2126    }
2127}
2128
2129#[cfg(feature = "experimental_traverse")]
2130impl<'a> SomeTable<'a> for PaintVarSolid<'a> {
2131    fn type_name(&self) -> &str {
2132        "PaintVarSolid"
2133    }
2134    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2135        match idx {
2136            0usize => Some(Field::new("format", self.format())),
2137            1usize => Some(Field::new("palette_index", self.palette_index())),
2138            2usize => Some(Field::new("alpha", self.alpha())),
2139            3usize => Some(Field::new("var_index_base", self.var_index_base())),
2140            _ => None,
2141        }
2142    }
2143}
2144
2145#[cfg(feature = "experimental_traverse")]
2146#[allow(clippy::needless_lifetimes)]
2147impl<'a> std::fmt::Debug for PaintVarSolid<'a> {
2148    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2149        (self as &dyn SomeTable<'a>).fmt(f)
2150    }
2151}
2152
2153impl Format<u8> for PaintLinearGradientMarker {
2154    const FORMAT: u8 = 4;
2155}
2156
2157/// [PaintLinearGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-4-and-5-paintlineargradient-paintvarlineargradient) table
2158#[derive(Debug, Clone, Copy)]
2159#[doc(hidden)]
2160pub struct PaintLinearGradientMarker {}
2161
2162impl PaintLinearGradientMarker {
2163    pub fn format_byte_range(&self) -> Range<usize> {
2164        let start = 0;
2165        start..start + u8::RAW_BYTE_LEN
2166    }
2167
2168    pub fn color_line_offset_byte_range(&self) -> Range<usize> {
2169        let start = self.format_byte_range().end;
2170        start..start + Offset24::RAW_BYTE_LEN
2171    }
2172
2173    pub fn x0_byte_range(&self) -> Range<usize> {
2174        let start = self.color_line_offset_byte_range().end;
2175        start..start + FWord::RAW_BYTE_LEN
2176    }
2177
2178    pub fn y0_byte_range(&self) -> Range<usize> {
2179        let start = self.x0_byte_range().end;
2180        start..start + FWord::RAW_BYTE_LEN
2181    }
2182
2183    pub fn x1_byte_range(&self) -> Range<usize> {
2184        let start = self.y0_byte_range().end;
2185        start..start + FWord::RAW_BYTE_LEN
2186    }
2187
2188    pub fn y1_byte_range(&self) -> Range<usize> {
2189        let start = self.x1_byte_range().end;
2190        start..start + FWord::RAW_BYTE_LEN
2191    }
2192
2193    pub fn x2_byte_range(&self) -> Range<usize> {
2194        let start = self.y1_byte_range().end;
2195        start..start + FWord::RAW_BYTE_LEN
2196    }
2197
2198    pub fn y2_byte_range(&self) -> Range<usize> {
2199        let start = self.x2_byte_range().end;
2200        start..start + FWord::RAW_BYTE_LEN
2201    }
2202}
2203
2204impl MinByteRange for PaintLinearGradientMarker {
2205    fn min_byte_range(&self) -> Range<usize> {
2206        0..self.y2_byte_range().end
2207    }
2208}
2209
2210impl<'a> FontRead<'a> for PaintLinearGradient<'a> {
2211    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2212        let mut cursor = data.cursor();
2213        cursor.advance::<u8>();
2214        cursor.advance::<Offset24>();
2215        cursor.advance::<FWord>();
2216        cursor.advance::<FWord>();
2217        cursor.advance::<FWord>();
2218        cursor.advance::<FWord>();
2219        cursor.advance::<FWord>();
2220        cursor.advance::<FWord>();
2221        cursor.finish(PaintLinearGradientMarker {})
2222    }
2223}
2224
2225/// [PaintLinearGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-4-and-5-paintlineargradient-paintvarlineargradient) table
2226pub type PaintLinearGradient<'a> = TableRef<'a, PaintLinearGradientMarker>;
2227
2228#[allow(clippy::needless_lifetimes)]
2229impl<'a> PaintLinearGradient<'a> {
2230    /// Set to 4.
2231    pub fn format(&self) -> u8 {
2232        let range = self.shape.format_byte_range();
2233        self.data.read_at(range.start).unwrap()
2234    }
2235
2236    /// Offset to ColorLine table.
2237    pub fn color_line_offset(&self) -> Offset24 {
2238        let range = self.shape.color_line_offset_byte_range();
2239        self.data.read_at(range.start).unwrap()
2240    }
2241
2242    /// Attempt to resolve [`color_line_offset`][Self::color_line_offset].
2243    pub fn color_line(&self) -> Result<ColorLine<'a>, ReadError> {
2244        let data = self.data;
2245        self.color_line_offset().resolve(data)
2246    }
2247
2248    /// Start point (p₀) x coordinate.
2249    pub fn x0(&self) -> FWord {
2250        let range = self.shape.x0_byte_range();
2251        self.data.read_at(range.start).unwrap()
2252    }
2253
2254    /// Start point (p₀) y coordinate.
2255    pub fn y0(&self) -> FWord {
2256        let range = self.shape.y0_byte_range();
2257        self.data.read_at(range.start).unwrap()
2258    }
2259
2260    /// End point (p₁) x coordinate.
2261    pub fn x1(&self) -> FWord {
2262        let range = self.shape.x1_byte_range();
2263        self.data.read_at(range.start).unwrap()
2264    }
2265
2266    /// End point (p₁) y coordinate.
2267    pub fn y1(&self) -> FWord {
2268        let range = self.shape.y1_byte_range();
2269        self.data.read_at(range.start).unwrap()
2270    }
2271
2272    /// Rotation point (p₂) x coordinate.
2273    pub fn x2(&self) -> FWord {
2274        let range = self.shape.x2_byte_range();
2275        self.data.read_at(range.start).unwrap()
2276    }
2277
2278    /// Rotation point (p₂) y coordinate.
2279    pub fn y2(&self) -> FWord {
2280        let range = self.shape.y2_byte_range();
2281        self.data.read_at(range.start).unwrap()
2282    }
2283}
2284
2285#[cfg(feature = "experimental_traverse")]
2286impl<'a> SomeTable<'a> for PaintLinearGradient<'a> {
2287    fn type_name(&self) -> &str {
2288        "PaintLinearGradient"
2289    }
2290    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2291        match idx {
2292            0usize => Some(Field::new("format", self.format())),
2293            1usize => Some(Field::new(
2294                "color_line_offset",
2295                FieldType::offset(self.color_line_offset(), self.color_line()),
2296            )),
2297            2usize => Some(Field::new("x0", self.x0())),
2298            3usize => Some(Field::new("y0", self.y0())),
2299            4usize => Some(Field::new("x1", self.x1())),
2300            5usize => Some(Field::new("y1", self.y1())),
2301            6usize => Some(Field::new("x2", self.x2())),
2302            7usize => Some(Field::new("y2", self.y2())),
2303            _ => None,
2304        }
2305    }
2306}
2307
2308#[cfg(feature = "experimental_traverse")]
2309#[allow(clippy::needless_lifetimes)]
2310impl<'a> std::fmt::Debug for PaintLinearGradient<'a> {
2311    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2312        (self as &dyn SomeTable<'a>).fmt(f)
2313    }
2314}
2315
2316impl Format<u8> for PaintVarLinearGradientMarker {
2317    const FORMAT: u8 = 5;
2318}
2319
2320/// [PaintVarLinearGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-4-and-5-paintlineargradient-paintvarlineargradient) table
2321#[derive(Debug, Clone, Copy)]
2322#[doc(hidden)]
2323pub struct PaintVarLinearGradientMarker {}
2324
2325impl PaintVarLinearGradientMarker {
2326    pub fn format_byte_range(&self) -> Range<usize> {
2327        let start = 0;
2328        start..start + u8::RAW_BYTE_LEN
2329    }
2330
2331    pub fn color_line_offset_byte_range(&self) -> Range<usize> {
2332        let start = self.format_byte_range().end;
2333        start..start + Offset24::RAW_BYTE_LEN
2334    }
2335
2336    pub fn x0_byte_range(&self) -> Range<usize> {
2337        let start = self.color_line_offset_byte_range().end;
2338        start..start + FWord::RAW_BYTE_LEN
2339    }
2340
2341    pub fn y0_byte_range(&self) -> Range<usize> {
2342        let start = self.x0_byte_range().end;
2343        start..start + FWord::RAW_BYTE_LEN
2344    }
2345
2346    pub fn x1_byte_range(&self) -> Range<usize> {
2347        let start = self.y0_byte_range().end;
2348        start..start + FWord::RAW_BYTE_LEN
2349    }
2350
2351    pub fn y1_byte_range(&self) -> Range<usize> {
2352        let start = self.x1_byte_range().end;
2353        start..start + FWord::RAW_BYTE_LEN
2354    }
2355
2356    pub fn x2_byte_range(&self) -> Range<usize> {
2357        let start = self.y1_byte_range().end;
2358        start..start + FWord::RAW_BYTE_LEN
2359    }
2360
2361    pub fn y2_byte_range(&self) -> Range<usize> {
2362        let start = self.x2_byte_range().end;
2363        start..start + FWord::RAW_BYTE_LEN
2364    }
2365
2366    pub fn var_index_base_byte_range(&self) -> Range<usize> {
2367        let start = self.y2_byte_range().end;
2368        start..start + u32::RAW_BYTE_LEN
2369    }
2370}
2371
2372impl MinByteRange for PaintVarLinearGradientMarker {
2373    fn min_byte_range(&self) -> Range<usize> {
2374        0..self.var_index_base_byte_range().end
2375    }
2376}
2377
2378impl<'a> FontRead<'a> for PaintVarLinearGradient<'a> {
2379    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2380        let mut cursor = data.cursor();
2381        cursor.advance::<u8>();
2382        cursor.advance::<Offset24>();
2383        cursor.advance::<FWord>();
2384        cursor.advance::<FWord>();
2385        cursor.advance::<FWord>();
2386        cursor.advance::<FWord>();
2387        cursor.advance::<FWord>();
2388        cursor.advance::<FWord>();
2389        cursor.advance::<u32>();
2390        cursor.finish(PaintVarLinearGradientMarker {})
2391    }
2392}
2393
2394/// [PaintVarLinearGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-4-and-5-paintlineargradient-paintvarlineargradient) table
2395pub type PaintVarLinearGradient<'a> = TableRef<'a, PaintVarLinearGradientMarker>;
2396
2397#[allow(clippy::needless_lifetimes)]
2398impl<'a> PaintVarLinearGradient<'a> {
2399    /// Set to 5.
2400    pub fn format(&self) -> u8 {
2401        let range = self.shape.format_byte_range();
2402        self.data.read_at(range.start).unwrap()
2403    }
2404
2405    /// Offset to VarColorLine table.
2406    pub fn color_line_offset(&self) -> Offset24 {
2407        let range = self.shape.color_line_offset_byte_range();
2408        self.data.read_at(range.start).unwrap()
2409    }
2410
2411    /// Attempt to resolve [`color_line_offset`][Self::color_line_offset].
2412    pub fn color_line(&self) -> Result<VarColorLine<'a>, ReadError> {
2413        let data = self.data;
2414        self.color_line_offset().resolve(data)
2415    }
2416
2417    /// Start point (p₀) x coordinate. For variation, use
2418    /// varIndexBase + 0.
2419    pub fn x0(&self) -> FWord {
2420        let range = self.shape.x0_byte_range();
2421        self.data.read_at(range.start).unwrap()
2422    }
2423
2424    /// Start point (p₀) y coordinate. For variation, use
2425    /// varIndexBase + 1.
2426    pub fn y0(&self) -> FWord {
2427        let range = self.shape.y0_byte_range();
2428        self.data.read_at(range.start).unwrap()
2429    }
2430
2431    /// End point (p₁) x coordinate. For variation, use varIndexBase
2432    /// + 2.
2433    pub fn x1(&self) -> FWord {
2434        let range = self.shape.x1_byte_range();
2435        self.data.read_at(range.start).unwrap()
2436    }
2437
2438    /// End point (p₁) y coordinate. For variation, use varIndexBase
2439    /// + 3.
2440    pub fn y1(&self) -> FWord {
2441        let range = self.shape.y1_byte_range();
2442        self.data.read_at(range.start).unwrap()
2443    }
2444
2445    /// Rotation point (p₂) x coordinate. For variation, use
2446    /// varIndexBase + 4.
2447    pub fn x2(&self) -> FWord {
2448        let range = self.shape.x2_byte_range();
2449        self.data.read_at(range.start).unwrap()
2450    }
2451
2452    /// Rotation point (p₂) y coordinate. For variation, use
2453    /// varIndexBase + 5.
2454    pub fn y2(&self) -> FWord {
2455        let range = self.shape.y2_byte_range();
2456        self.data.read_at(range.start).unwrap()
2457    }
2458
2459    /// Base index into DeltaSetIndexMap.
2460    pub fn var_index_base(&self) -> u32 {
2461        let range = self.shape.var_index_base_byte_range();
2462        self.data.read_at(range.start).unwrap()
2463    }
2464}
2465
2466#[cfg(feature = "experimental_traverse")]
2467impl<'a> SomeTable<'a> for PaintVarLinearGradient<'a> {
2468    fn type_name(&self) -> &str {
2469        "PaintVarLinearGradient"
2470    }
2471    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2472        match idx {
2473            0usize => Some(Field::new("format", self.format())),
2474            1usize => Some(Field::new(
2475                "color_line_offset",
2476                FieldType::offset(self.color_line_offset(), self.color_line()),
2477            )),
2478            2usize => Some(Field::new("x0", self.x0())),
2479            3usize => Some(Field::new("y0", self.y0())),
2480            4usize => Some(Field::new("x1", self.x1())),
2481            5usize => Some(Field::new("y1", self.y1())),
2482            6usize => Some(Field::new("x2", self.x2())),
2483            7usize => Some(Field::new("y2", self.y2())),
2484            8usize => Some(Field::new("var_index_base", self.var_index_base())),
2485            _ => None,
2486        }
2487    }
2488}
2489
2490#[cfg(feature = "experimental_traverse")]
2491#[allow(clippy::needless_lifetimes)]
2492impl<'a> std::fmt::Debug for PaintVarLinearGradient<'a> {
2493    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2494        (self as &dyn SomeTable<'a>).fmt(f)
2495    }
2496}
2497
2498impl Format<u8> for PaintRadialGradientMarker {
2499    const FORMAT: u8 = 6;
2500}
2501
2502/// [PaintRadialGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-6-and-7-paintradialgradient-paintvarradialgradient) table
2503#[derive(Debug, Clone, Copy)]
2504#[doc(hidden)]
2505pub struct PaintRadialGradientMarker {}
2506
2507impl PaintRadialGradientMarker {
2508    pub fn format_byte_range(&self) -> Range<usize> {
2509        let start = 0;
2510        start..start + u8::RAW_BYTE_LEN
2511    }
2512
2513    pub fn color_line_offset_byte_range(&self) -> Range<usize> {
2514        let start = self.format_byte_range().end;
2515        start..start + Offset24::RAW_BYTE_LEN
2516    }
2517
2518    pub fn x0_byte_range(&self) -> Range<usize> {
2519        let start = self.color_line_offset_byte_range().end;
2520        start..start + FWord::RAW_BYTE_LEN
2521    }
2522
2523    pub fn y0_byte_range(&self) -> Range<usize> {
2524        let start = self.x0_byte_range().end;
2525        start..start + FWord::RAW_BYTE_LEN
2526    }
2527
2528    pub fn radius0_byte_range(&self) -> Range<usize> {
2529        let start = self.y0_byte_range().end;
2530        start..start + UfWord::RAW_BYTE_LEN
2531    }
2532
2533    pub fn x1_byte_range(&self) -> Range<usize> {
2534        let start = self.radius0_byte_range().end;
2535        start..start + FWord::RAW_BYTE_LEN
2536    }
2537
2538    pub fn y1_byte_range(&self) -> Range<usize> {
2539        let start = self.x1_byte_range().end;
2540        start..start + FWord::RAW_BYTE_LEN
2541    }
2542
2543    pub fn radius1_byte_range(&self) -> Range<usize> {
2544        let start = self.y1_byte_range().end;
2545        start..start + UfWord::RAW_BYTE_LEN
2546    }
2547}
2548
2549impl MinByteRange for PaintRadialGradientMarker {
2550    fn min_byte_range(&self) -> Range<usize> {
2551        0..self.radius1_byte_range().end
2552    }
2553}
2554
2555impl<'a> FontRead<'a> for PaintRadialGradient<'a> {
2556    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2557        let mut cursor = data.cursor();
2558        cursor.advance::<u8>();
2559        cursor.advance::<Offset24>();
2560        cursor.advance::<FWord>();
2561        cursor.advance::<FWord>();
2562        cursor.advance::<UfWord>();
2563        cursor.advance::<FWord>();
2564        cursor.advance::<FWord>();
2565        cursor.advance::<UfWord>();
2566        cursor.finish(PaintRadialGradientMarker {})
2567    }
2568}
2569
2570/// [PaintRadialGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-6-and-7-paintradialgradient-paintvarradialgradient) table
2571pub type PaintRadialGradient<'a> = TableRef<'a, PaintRadialGradientMarker>;
2572
2573#[allow(clippy::needless_lifetimes)]
2574impl<'a> PaintRadialGradient<'a> {
2575    /// Set to 6.
2576    pub fn format(&self) -> u8 {
2577        let range = self.shape.format_byte_range();
2578        self.data.read_at(range.start).unwrap()
2579    }
2580
2581    /// Offset to ColorLine table.
2582    pub fn color_line_offset(&self) -> Offset24 {
2583        let range = self.shape.color_line_offset_byte_range();
2584        self.data.read_at(range.start).unwrap()
2585    }
2586
2587    /// Attempt to resolve [`color_line_offset`][Self::color_line_offset].
2588    pub fn color_line(&self) -> Result<ColorLine<'a>, ReadError> {
2589        let data = self.data;
2590        self.color_line_offset().resolve(data)
2591    }
2592
2593    /// Start circle center x coordinate.
2594    pub fn x0(&self) -> FWord {
2595        let range = self.shape.x0_byte_range();
2596        self.data.read_at(range.start).unwrap()
2597    }
2598
2599    /// Start circle center y coordinate.
2600    pub fn y0(&self) -> FWord {
2601        let range = self.shape.y0_byte_range();
2602        self.data.read_at(range.start).unwrap()
2603    }
2604
2605    /// Start circle radius.
2606    pub fn radius0(&self) -> UfWord {
2607        let range = self.shape.radius0_byte_range();
2608        self.data.read_at(range.start).unwrap()
2609    }
2610
2611    /// End circle center x coordinate.
2612    pub fn x1(&self) -> FWord {
2613        let range = self.shape.x1_byte_range();
2614        self.data.read_at(range.start).unwrap()
2615    }
2616
2617    /// End circle center y coordinate.
2618    pub fn y1(&self) -> FWord {
2619        let range = self.shape.y1_byte_range();
2620        self.data.read_at(range.start).unwrap()
2621    }
2622
2623    /// End circle radius.
2624    pub fn radius1(&self) -> UfWord {
2625        let range = self.shape.radius1_byte_range();
2626        self.data.read_at(range.start).unwrap()
2627    }
2628}
2629
2630#[cfg(feature = "experimental_traverse")]
2631impl<'a> SomeTable<'a> for PaintRadialGradient<'a> {
2632    fn type_name(&self) -> &str {
2633        "PaintRadialGradient"
2634    }
2635    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2636        match idx {
2637            0usize => Some(Field::new("format", self.format())),
2638            1usize => Some(Field::new(
2639                "color_line_offset",
2640                FieldType::offset(self.color_line_offset(), self.color_line()),
2641            )),
2642            2usize => Some(Field::new("x0", self.x0())),
2643            3usize => Some(Field::new("y0", self.y0())),
2644            4usize => Some(Field::new("radius0", self.radius0())),
2645            5usize => Some(Field::new("x1", self.x1())),
2646            6usize => Some(Field::new("y1", self.y1())),
2647            7usize => Some(Field::new("radius1", self.radius1())),
2648            _ => None,
2649        }
2650    }
2651}
2652
2653#[cfg(feature = "experimental_traverse")]
2654#[allow(clippy::needless_lifetimes)]
2655impl<'a> std::fmt::Debug for PaintRadialGradient<'a> {
2656    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2657        (self as &dyn SomeTable<'a>).fmt(f)
2658    }
2659}
2660
2661impl Format<u8> for PaintVarRadialGradientMarker {
2662    const FORMAT: u8 = 7;
2663}
2664
2665/// [PaintVarRadialGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-6-and-7-paintradialgradient-paintvarradialgradient) table
2666#[derive(Debug, Clone, Copy)]
2667#[doc(hidden)]
2668pub struct PaintVarRadialGradientMarker {}
2669
2670impl PaintVarRadialGradientMarker {
2671    pub fn format_byte_range(&self) -> Range<usize> {
2672        let start = 0;
2673        start..start + u8::RAW_BYTE_LEN
2674    }
2675
2676    pub fn color_line_offset_byte_range(&self) -> Range<usize> {
2677        let start = self.format_byte_range().end;
2678        start..start + Offset24::RAW_BYTE_LEN
2679    }
2680
2681    pub fn x0_byte_range(&self) -> Range<usize> {
2682        let start = self.color_line_offset_byte_range().end;
2683        start..start + FWord::RAW_BYTE_LEN
2684    }
2685
2686    pub fn y0_byte_range(&self) -> Range<usize> {
2687        let start = self.x0_byte_range().end;
2688        start..start + FWord::RAW_BYTE_LEN
2689    }
2690
2691    pub fn radius0_byte_range(&self) -> Range<usize> {
2692        let start = self.y0_byte_range().end;
2693        start..start + UfWord::RAW_BYTE_LEN
2694    }
2695
2696    pub fn x1_byte_range(&self) -> Range<usize> {
2697        let start = self.radius0_byte_range().end;
2698        start..start + FWord::RAW_BYTE_LEN
2699    }
2700
2701    pub fn y1_byte_range(&self) -> Range<usize> {
2702        let start = self.x1_byte_range().end;
2703        start..start + FWord::RAW_BYTE_LEN
2704    }
2705
2706    pub fn radius1_byte_range(&self) -> Range<usize> {
2707        let start = self.y1_byte_range().end;
2708        start..start + UfWord::RAW_BYTE_LEN
2709    }
2710
2711    pub fn var_index_base_byte_range(&self) -> Range<usize> {
2712        let start = self.radius1_byte_range().end;
2713        start..start + u32::RAW_BYTE_LEN
2714    }
2715}
2716
2717impl MinByteRange for PaintVarRadialGradientMarker {
2718    fn min_byte_range(&self) -> Range<usize> {
2719        0..self.var_index_base_byte_range().end
2720    }
2721}
2722
2723impl<'a> FontRead<'a> for PaintVarRadialGradient<'a> {
2724    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2725        let mut cursor = data.cursor();
2726        cursor.advance::<u8>();
2727        cursor.advance::<Offset24>();
2728        cursor.advance::<FWord>();
2729        cursor.advance::<FWord>();
2730        cursor.advance::<UfWord>();
2731        cursor.advance::<FWord>();
2732        cursor.advance::<FWord>();
2733        cursor.advance::<UfWord>();
2734        cursor.advance::<u32>();
2735        cursor.finish(PaintVarRadialGradientMarker {})
2736    }
2737}
2738
2739/// [PaintVarRadialGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-6-and-7-paintradialgradient-paintvarradialgradient) table
2740pub type PaintVarRadialGradient<'a> = TableRef<'a, PaintVarRadialGradientMarker>;
2741
2742#[allow(clippy::needless_lifetimes)]
2743impl<'a> PaintVarRadialGradient<'a> {
2744    /// Set to 7.
2745    pub fn format(&self) -> u8 {
2746        let range = self.shape.format_byte_range();
2747        self.data.read_at(range.start).unwrap()
2748    }
2749
2750    /// Offset to VarColorLine table.
2751    pub fn color_line_offset(&self) -> Offset24 {
2752        let range = self.shape.color_line_offset_byte_range();
2753        self.data.read_at(range.start).unwrap()
2754    }
2755
2756    /// Attempt to resolve [`color_line_offset`][Self::color_line_offset].
2757    pub fn color_line(&self) -> Result<VarColorLine<'a>, ReadError> {
2758        let data = self.data;
2759        self.color_line_offset().resolve(data)
2760    }
2761
2762    /// Start circle center x coordinate. For variation, use
2763    /// varIndexBase + 0.
2764    pub fn x0(&self) -> FWord {
2765        let range = self.shape.x0_byte_range();
2766        self.data.read_at(range.start).unwrap()
2767    }
2768
2769    /// Start circle center y coordinate. For variation, use
2770    /// varIndexBase + 1.
2771    pub fn y0(&self) -> FWord {
2772        let range = self.shape.y0_byte_range();
2773        self.data.read_at(range.start).unwrap()
2774    }
2775
2776    /// Start circle radius. For variation, use varIndexBase + 2.
2777    pub fn radius0(&self) -> UfWord {
2778        let range = self.shape.radius0_byte_range();
2779        self.data.read_at(range.start).unwrap()
2780    }
2781
2782    /// End circle center x coordinate. For variation, use varIndexBase
2783    /// + 3.
2784    pub fn x1(&self) -> FWord {
2785        let range = self.shape.x1_byte_range();
2786        self.data.read_at(range.start).unwrap()
2787    }
2788
2789    /// End circle center y coordinate. For variation, use varIndexBase
2790    /// + 4.
2791    pub fn y1(&self) -> FWord {
2792        let range = self.shape.y1_byte_range();
2793        self.data.read_at(range.start).unwrap()
2794    }
2795
2796    /// End circle radius. For variation, use varIndexBase + 5.
2797    pub fn radius1(&self) -> UfWord {
2798        let range = self.shape.radius1_byte_range();
2799        self.data.read_at(range.start).unwrap()
2800    }
2801
2802    /// Base index into DeltaSetIndexMap.
2803    pub fn var_index_base(&self) -> u32 {
2804        let range = self.shape.var_index_base_byte_range();
2805        self.data.read_at(range.start).unwrap()
2806    }
2807}
2808
2809#[cfg(feature = "experimental_traverse")]
2810impl<'a> SomeTable<'a> for PaintVarRadialGradient<'a> {
2811    fn type_name(&self) -> &str {
2812        "PaintVarRadialGradient"
2813    }
2814    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2815        match idx {
2816            0usize => Some(Field::new("format", self.format())),
2817            1usize => Some(Field::new(
2818                "color_line_offset",
2819                FieldType::offset(self.color_line_offset(), self.color_line()),
2820            )),
2821            2usize => Some(Field::new("x0", self.x0())),
2822            3usize => Some(Field::new("y0", self.y0())),
2823            4usize => Some(Field::new("radius0", self.radius0())),
2824            5usize => Some(Field::new("x1", self.x1())),
2825            6usize => Some(Field::new("y1", self.y1())),
2826            7usize => Some(Field::new("radius1", self.radius1())),
2827            8usize => Some(Field::new("var_index_base", self.var_index_base())),
2828            _ => None,
2829        }
2830    }
2831}
2832
2833#[cfg(feature = "experimental_traverse")]
2834#[allow(clippy::needless_lifetimes)]
2835impl<'a> std::fmt::Debug for PaintVarRadialGradient<'a> {
2836    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2837        (self as &dyn SomeTable<'a>).fmt(f)
2838    }
2839}
2840
2841impl Format<u8> for PaintSweepGradientMarker {
2842    const FORMAT: u8 = 8;
2843}
2844
2845/// [PaintSweepGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-8-and-9-paintsweepgradient-paintvarsweepgradient) table
2846#[derive(Debug, Clone, Copy)]
2847#[doc(hidden)]
2848pub struct PaintSweepGradientMarker {}
2849
2850impl PaintSweepGradientMarker {
2851    pub fn format_byte_range(&self) -> Range<usize> {
2852        let start = 0;
2853        start..start + u8::RAW_BYTE_LEN
2854    }
2855
2856    pub fn color_line_offset_byte_range(&self) -> Range<usize> {
2857        let start = self.format_byte_range().end;
2858        start..start + Offset24::RAW_BYTE_LEN
2859    }
2860
2861    pub fn center_x_byte_range(&self) -> Range<usize> {
2862        let start = self.color_line_offset_byte_range().end;
2863        start..start + FWord::RAW_BYTE_LEN
2864    }
2865
2866    pub fn center_y_byte_range(&self) -> Range<usize> {
2867        let start = self.center_x_byte_range().end;
2868        start..start + FWord::RAW_BYTE_LEN
2869    }
2870
2871    pub fn start_angle_byte_range(&self) -> Range<usize> {
2872        let start = self.center_y_byte_range().end;
2873        start..start + F2Dot14::RAW_BYTE_LEN
2874    }
2875
2876    pub fn end_angle_byte_range(&self) -> Range<usize> {
2877        let start = self.start_angle_byte_range().end;
2878        start..start + F2Dot14::RAW_BYTE_LEN
2879    }
2880}
2881
2882impl MinByteRange for PaintSweepGradientMarker {
2883    fn min_byte_range(&self) -> Range<usize> {
2884        0..self.end_angle_byte_range().end
2885    }
2886}
2887
2888impl<'a> FontRead<'a> for PaintSweepGradient<'a> {
2889    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2890        let mut cursor = data.cursor();
2891        cursor.advance::<u8>();
2892        cursor.advance::<Offset24>();
2893        cursor.advance::<FWord>();
2894        cursor.advance::<FWord>();
2895        cursor.advance::<F2Dot14>();
2896        cursor.advance::<F2Dot14>();
2897        cursor.finish(PaintSweepGradientMarker {})
2898    }
2899}
2900
2901/// [PaintSweepGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-8-and-9-paintsweepgradient-paintvarsweepgradient) table
2902pub type PaintSweepGradient<'a> = TableRef<'a, PaintSweepGradientMarker>;
2903
2904#[allow(clippy::needless_lifetimes)]
2905impl<'a> PaintSweepGradient<'a> {
2906    /// Set to 8.
2907    pub fn format(&self) -> u8 {
2908        let range = self.shape.format_byte_range();
2909        self.data.read_at(range.start).unwrap()
2910    }
2911
2912    /// Offset to ColorLine table.
2913    pub fn color_line_offset(&self) -> Offset24 {
2914        let range = self.shape.color_line_offset_byte_range();
2915        self.data.read_at(range.start).unwrap()
2916    }
2917
2918    /// Attempt to resolve [`color_line_offset`][Self::color_line_offset].
2919    pub fn color_line(&self) -> Result<ColorLine<'a>, ReadError> {
2920        let data = self.data;
2921        self.color_line_offset().resolve(data)
2922    }
2923
2924    /// Center x coordinate.
2925    pub fn center_x(&self) -> FWord {
2926        let range = self.shape.center_x_byte_range();
2927        self.data.read_at(range.start).unwrap()
2928    }
2929
2930    /// Center y coordinate.
2931    pub fn center_y(&self) -> FWord {
2932        let range = self.shape.center_y_byte_range();
2933        self.data.read_at(range.start).unwrap()
2934    }
2935
2936    /// Start of the angular range of the gradient, 180° in
2937    /// counter-clockwise degrees per 1.0 of value.
2938    pub fn start_angle(&self) -> F2Dot14 {
2939        let range = self.shape.start_angle_byte_range();
2940        self.data.read_at(range.start).unwrap()
2941    }
2942
2943    /// End of the angular range of the gradient, 180° in
2944    /// counter-clockwise degrees per 1.0 of value.
2945    pub fn end_angle(&self) -> F2Dot14 {
2946        let range = self.shape.end_angle_byte_range();
2947        self.data.read_at(range.start).unwrap()
2948    }
2949}
2950
2951#[cfg(feature = "experimental_traverse")]
2952impl<'a> SomeTable<'a> for PaintSweepGradient<'a> {
2953    fn type_name(&self) -> &str {
2954        "PaintSweepGradient"
2955    }
2956    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2957        match idx {
2958            0usize => Some(Field::new("format", self.format())),
2959            1usize => Some(Field::new(
2960                "color_line_offset",
2961                FieldType::offset(self.color_line_offset(), self.color_line()),
2962            )),
2963            2usize => Some(Field::new("center_x", self.center_x())),
2964            3usize => Some(Field::new("center_y", self.center_y())),
2965            4usize => Some(Field::new("start_angle", self.start_angle())),
2966            5usize => Some(Field::new("end_angle", self.end_angle())),
2967            _ => None,
2968        }
2969    }
2970}
2971
2972#[cfg(feature = "experimental_traverse")]
2973#[allow(clippy::needless_lifetimes)]
2974impl<'a> std::fmt::Debug for PaintSweepGradient<'a> {
2975    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2976        (self as &dyn SomeTable<'a>).fmt(f)
2977    }
2978}
2979
2980impl Format<u8> for PaintVarSweepGradientMarker {
2981    const FORMAT: u8 = 9;
2982}
2983
2984/// [PaintVarSweepGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-8-and-9-paintsweepgradient-paintvarsweepgradient) table
2985#[derive(Debug, Clone, Copy)]
2986#[doc(hidden)]
2987pub struct PaintVarSweepGradientMarker {}
2988
2989impl PaintVarSweepGradientMarker {
2990    pub fn format_byte_range(&self) -> Range<usize> {
2991        let start = 0;
2992        start..start + u8::RAW_BYTE_LEN
2993    }
2994
2995    pub fn color_line_offset_byte_range(&self) -> Range<usize> {
2996        let start = self.format_byte_range().end;
2997        start..start + Offset24::RAW_BYTE_LEN
2998    }
2999
3000    pub fn center_x_byte_range(&self) -> Range<usize> {
3001        let start = self.color_line_offset_byte_range().end;
3002        start..start + FWord::RAW_BYTE_LEN
3003    }
3004
3005    pub fn center_y_byte_range(&self) -> Range<usize> {
3006        let start = self.center_x_byte_range().end;
3007        start..start + FWord::RAW_BYTE_LEN
3008    }
3009
3010    pub fn start_angle_byte_range(&self) -> Range<usize> {
3011        let start = self.center_y_byte_range().end;
3012        start..start + F2Dot14::RAW_BYTE_LEN
3013    }
3014
3015    pub fn end_angle_byte_range(&self) -> Range<usize> {
3016        let start = self.start_angle_byte_range().end;
3017        start..start + F2Dot14::RAW_BYTE_LEN
3018    }
3019
3020    pub fn var_index_base_byte_range(&self) -> Range<usize> {
3021        let start = self.end_angle_byte_range().end;
3022        start..start + u32::RAW_BYTE_LEN
3023    }
3024}
3025
3026impl MinByteRange for PaintVarSweepGradientMarker {
3027    fn min_byte_range(&self) -> Range<usize> {
3028        0..self.var_index_base_byte_range().end
3029    }
3030}
3031
3032impl<'a> FontRead<'a> for PaintVarSweepGradient<'a> {
3033    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3034        let mut cursor = data.cursor();
3035        cursor.advance::<u8>();
3036        cursor.advance::<Offset24>();
3037        cursor.advance::<FWord>();
3038        cursor.advance::<FWord>();
3039        cursor.advance::<F2Dot14>();
3040        cursor.advance::<F2Dot14>();
3041        cursor.advance::<u32>();
3042        cursor.finish(PaintVarSweepGradientMarker {})
3043    }
3044}
3045
3046/// [PaintVarSweepGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-8-and-9-paintsweepgradient-paintvarsweepgradient) table
3047pub type PaintVarSweepGradient<'a> = TableRef<'a, PaintVarSweepGradientMarker>;
3048
3049#[allow(clippy::needless_lifetimes)]
3050impl<'a> PaintVarSweepGradient<'a> {
3051    /// Set to 9.
3052    pub fn format(&self) -> u8 {
3053        let range = self.shape.format_byte_range();
3054        self.data.read_at(range.start).unwrap()
3055    }
3056
3057    /// Offset to VarColorLine table.
3058    pub fn color_line_offset(&self) -> Offset24 {
3059        let range = self.shape.color_line_offset_byte_range();
3060        self.data.read_at(range.start).unwrap()
3061    }
3062
3063    /// Attempt to resolve [`color_line_offset`][Self::color_line_offset].
3064    pub fn color_line(&self) -> Result<VarColorLine<'a>, ReadError> {
3065        let data = self.data;
3066        self.color_line_offset().resolve(data)
3067    }
3068
3069    /// Center x coordinate. For variation, use varIndexBase + 0.
3070    pub fn center_x(&self) -> FWord {
3071        let range = self.shape.center_x_byte_range();
3072        self.data.read_at(range.start).unwrap()
3073    }
3074
3075    /// Center y coordinate. For variation, use varIndexBase + 1.
3076    pub fn center_y(&self) -> FWord {
3077        let range = self.shape.center_y_byte_range();
3078        self.data.read_at(range.start).unwrap()
3079    }
3080
3081    /// Start of the angular range of the gradient, 180° in
3082    /// counter-clockwise degrees per 1.0 of value. For variation, use
3083    /// varIndexBase + 2.
3084    pub fn start_angle(&self) -> F2Dot14 {
3085        let range = self.shape.start_angle_byte_range();
3086        self.data.read_at(range.start).unwrap()
3087    }
3088
3089    /// End of the angular range of the gradient, 180° in
3090    /// counter-clockwise degrees per 1.0 of value. For variation, use
3091    /// varIndexBase + 3.
3092    pub fn end_angle(&self) -> F2Dot14 {
3093        let range = self.shape.end_angle_byte_range();
3094        self.data.read_at(range.start).unwrap()
3095    }
3096
3097    /// Base index into DeltaSetIndexMap.
3098    pub fn var_index_base(&self) -> u32 {
3099        let range = self.shape.var_index_base_byte_range();
3100        self.data.read_at(range.start).unwrap()
3101    }
3102}
3103
3104#[cfg(feature = "experimental_traverse")]
3105impl<'a> SomeTable<'a> for PaintVarSweepGradient<'a> {
3106    fn type_name(&self) -> &str {
3107        "PaintVarSweepGradient"
3108    }
3109    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3110        match idx {
3111            0usize => Some(Field::new("format", self.format())),
3112            1usize => Some(Field::new(
3113                "color_line_offset",
3114                FieldType::offset(self.color_line_offset(), self.color_line()),
3115            )),
3116            2usize => Some(Field::new("center_x", self.center_x())),
3117            3usize => Some(Field::new("center_y", self.center_y())),
3118            4usize => Some(Field::new("start_angle", self.start_angle())),
3119            5usize => Some(Field::new("end_angle", self.end_angle())),
3120            6usize => Some(Field::new("var_index_base", self.var_index_base())),
3121            _ => None,
3122        }
3123    }
3124}
3125
3126#[cfg(feature = "experimental_traverse")]
3127#[allow(clippy::needless_lifetimes)]
3128impl<'a> std::fmt::Debug for PaintVarSweepGradient<'a> {
3129    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3130        (self as &dyn SomeTable<'a>).fmt(f)
3131    }
3132}
3133
3134impl Format<u8> for PaintGlyphMarker {
3135    const FORMAT: u8 = 10;
3136}
3137
3138/// [PaintGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-10-paintglyph) table
3139#[derive(Debug, Clone, Copy)]
3140#[doc(hidden)]
3141pub struct PaintGlyphMarker {}
3142
3143impl PaintGlyphMarker {
3144    pub fn format_byte_range(&self) -> Range<usize> {
3145        let start = 0;
3146        start..start + u8::RAW_BYTE_LEN
3147    }
3148
3149    pub fn paint_offset_byte_range(&self) -> Range<usize> {
3150        let start = self.format_byte_range().end;
3151        start..start + Offset24::RAW_BYTE_LEN
3152    }
3153
3154    pub fn glyph_id_byte_range(&self) -> Range<usize> {
3155        let start = self.paint_offset_byte_range().end;
3156        start..start + GlyphId16::RAW_BYTE_LEN
3157    }
3158}
3159
3160impl MinByteRange for PaintGlyphMarker {
3161    fn min_byte_range(&self) -> Range<usize> {
3162        0..self.glyph_id_byte_range().end
3163    }
3164}
3165
3166impl<'a> FontRead<'a> for PaintGlyph<'a> {
3167    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3168        let mut cursor = data.cursor();
3169        cursor.advance::<u8>();
3170        cursor.advance::<Offset24>();
3171        cursor.advance::<GlyphId16>();
3172        cursor.finish(PaintGlyphMarker {})
3173    }
3174}
3175
3176/// [PaintGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-10-paintglyph) table
3177pub type PaintGlyph<'a> = TableRef<'a, PaintGlyphMarker>;
3178
3179#[allow(clippy::needless_lifetimes)]
3180impl<'a> PaintGlyph<'a> {
3181    /// Set to 10.
3182    pub fn format(&self) -> u8 {
3183        let range = self.shape.format_byte_range();
3184        self.data.read_at(range.start).unwrap()
3185    }
3186
3187    /// Offset to a Paint table.
3188    pub fn paint_offset(&self) -> Offset24 {
3189        let range = self.shape.paint_offset_byte_range();
3190        self.data.read_at(range.start).unwrap()
3191    }
3192
3193    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
3194    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
3195        let data = self.data;
3196        self.paint_offset().resolve(data)
3197    }
3198
3199    /// Glyph ID for the source outline.
3200    pub fn glyph_id(&self) -> GlyphId16 {
3201        let range = self.shape.glyph_id_byte_range();
3202        self.data.read_at(range.start).unwrap()
3203    }
3204}
3205
3206#[cfg(feature = "experimental_traverse")]
3207impl<'a> SomeTable<'a> for PaintGlyph<'a> {
3208    fn type_name(&self) -> &str {
3209        "PaintGlyph"
3210    }
3211    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3212        match idx {
3213            0usize => Some(Field::new("format", self.format())),
3214            1usize => Some(Field::new(
3215                "paint_offset",
3216                FieldType::offset(self.paint_offset(), self.paint()),
3217            )),
3218            2usize => Some(Field::new("glyph_id", self.glyph_id())),
3219            _ => None,
3220        }
3221    }
3222}
3223
3224#[cfg(feature = "experimental_traverse")]
3225#[allow(clippy::needless_lifetimes)]
3226impl<'a> std::fmt::Debug for PaintGlyph<'a> {
3227    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3228        (self as &dyn SomeTable<'a>).fmt(f)
3229    }
3230}
3231
3232impl Format<u8> for PaintColrGlyphMarker {
3233    const FORMAT: u8 = 11;
3234}
3235
3236/// [PaintColrGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-11-paintcolrglyph) table
3237#[derive(Debug, Clone, Copy)]
3238#[doc(hidden)]
3239pub struct PaintColrGlyphMarker {}
3240
3241impl PaintColrGlyphMarker {
3242    pub fn format_byte_range(&self) -> Range<usize> {
3243        let start = 0;
3244        start..start + u8::RAW_BYTE_LEN
3245    }
3246
3247    pub fn glyph_id_byte_range(&self) -> Range<usize> {
3248        let start = self.format_byte_range().end;
3249        start..start + GlyphId16::RAW_BYTE_LEN
3250    }
3251}
3252
3253impl MinByteRange for PaintColrGlyphMarker {
3254    fn min_byte_range(&self) -> Range<usize> {
3255        0..self.glyph_id_byte_range().end
3256    }
3257}
3258
3259impl<'a> FontRead<'a> for PaintColrGlyph<'a> {
3260    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3261        let mut cursor = data.cursor();
3262        cursor.advance::<u8>();
3263        cursor.advance::<GlyphId16>();
3264        cursor.finish(PaintColrGlyphMarker {})
3265    }
3266}
3267
3268/// [PaintColrGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-11-paintcolrglyph) table
3269pub type PaintColrGlyph<'a> = TableRef<'a, PaintColrGlyphMarker>;
3270
3271#[allow(clippy::needless_lifetimes)]
3272impl<'a> PaintColrGlyph<'a> {
3273    /// Set to 11.
3274    pub fn format(&self) -> u8 {
3275        let range = self.shape.format_byte_range();
3276        self.data.read_at(range.start).unwrap()
3277    }
3278
3279    /// Glyph ID for a BaseGlyphList base glyph.
3280    pub fn glyph_id(&self) -> GlyphId16 {
3281        let range = self.shape.glyph_id_byte_range();
3282        self.data.read_at(range.start).unwrap()
3283    }
3284}
3285
3286#[cfg(feature = "experimental_traverse")]
3287impl<'a> SomeTable<'a> for PaintColrGlyph<'a> {
3288    fn type_name(&self) -> &str {
3289        "PaintColrGlyph"
3290    }
3291    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3292        match idx {
3293            0usize => Some(Field::new("format", self.format())),
3294            1usize => Some(Field::new("glyph_id", self.glyph_id())),
3295            _ => None,
3296        }
3297    }
3298}
3299
3300#[cfg(feature = "experimental_traverse")]
3301#[allow(clippy::needless_lifetimes)]
3302impl<'a> std::fmt::Debug for PaintColrGlyph<'a> {
3303    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3304        (self as &dyn SomeTable<'a>).fmt(f)
3305    }
3306}
3307
3308impl Format<u8> for PaintTransformMarker {
3309    const FORMAT: u8 = 12;
3310}
3311
3312/// [PaintTransform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) table
3313#[derive(Debug, Clone, Copy)]
3314#[doc(hidden)]
3315pub struct PaintTransformMarker {}
3316
3317impl PaintTransformMarker {
3318    pub fn format_byte_range(&self) -> Range<usize> {
3319        let start = 0;
3320        start..start + u8::RAW_BYTE_LEN
3321    }
3322
3323    pub fn paint_offset_byte_range(&self) -> Range<usize> {
3324        let start = self.format_byte_range().end;
3325        start..start + Offset24::RAW_BYTE_LEN
3326    }
3327
3328    pub fn transform_offset_byte_range(&self) -> Range<usize> {
3329        let start = self.paint_offset_byte_range().end;
3330        start..start + Offset24::RAW_BYTE_LEN
3331    }
3332}
3333
3334impl MinByteRange for PaintTransformMarker {
3335    fn min_byte_range(&self) -> Range<usize> {
3336        0..self.transform_offset_byte_range().end
3337    }
3338}
3339
3340impl<'a> FontRead<'a> for PaintTransform<'a> {
3341    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3342        let mut cursor = data.cursor();
3343        cursor.advance::<u8>();
3344        cursor.advance::<Offset24>();
3345        cursor.advance::<Offset24>();
3346        cursor.finish(PaintTransformMarker {})
3347    }
3348}
3349
3350/// [PaintTransform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) table
3351pub type PaintTransform<'a> = TableRef<'a, PaintTransformMarker>;
3352
3353#[allow(clippy::needless_lifetimes)]
3354impl<'a> PaintTransform<'a> {
3355    /// Set to 12.
3356    pub fn format(&self) -> u8 {
3357        let range = self.shape.format_byte_range();
3358        self.data.read_at(range.start).unwrap()
3359    }
3360
3361    /// Offset to a Paint subtable.
3362    pub fn paint_offset(&self) -> Offset24 {
3363        let range = self.shape.paint_offset_byte_range();
3364        self.data.read_at(range.start).unwrap()
3365    }
3366
3367    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
3368    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
3369        let data = self.data;
3370        self.paint_offset().resolve(data)
3371    }
3372
3373    /// Offset to an Affine2x3 table.
3374    pub fn transform_offset(&self) -> Offset24 {
3375        let range = self.shape.transform_offset_byte_range();
3376        self.data.read_at(range.start).unwrap()
3377    }
3378
3379    /// Attempt to resolve [`transform_offset`][Self::transform_offset].
3380    pub fn transform(&self) -> Result<Affine2x3<'a>, ReadError> {
3381        let data = self.data;
3382        self.transform_offset().resolve(data)
3383    }
3384}
3385
3386#[cfg(feature = "experimental_traverse")]
3387impl<'a> SomeTable<'a> for PaintTransform<'a> {
3388    fn type_name(&self) -> &str {
3389        "PaintTransform"
3390    }
3391    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3392        match idx {
3393            0usize => Some(Field::new("format", self.format())),
3394            1usize => Some(Field::new(
3395                "paint_offset",
3396                FieldType::offset(self.paint_offset(), self.paint()),
3397            )),
3398            2usize => Some(Field::new(
3399                "transform_offset",
3400                FieldType::offset(self.transform_offset(), self.transform()),
3401            )),
3402            _ => None,
3403        }
3404    }
3405}
3406
3407#[cfg(feature = "experimental_traverse")]
3408#[allow(clippy::needless_lifetimes)]
3409impl<'a> std::fmt::Debug for PaintTransform<'a> {
3410    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3411        (self as &dyn SomeTable<'a>).fmt(f)
3412    }
3413}
3414
3415impl Format<u8> for PaintVarTransformMarker {
3416    const FORMAT: u8 = 13;
3417}
3418
3419/// [PaintVarTransform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) table
3420#[derive(Debug, Clone, Copy)]
3421#[doc(hidden)]
3422pub struct PaintVarTransformMarker {}
3423
3424impl PaintVarTransformMarker {
3425    pub fn format_byte_range(&self) -> Range<usize> {
3426        let start = 0;
3427        start..start + u8::RAW_BYTE_LEN
3428    }
3429
3430    pub fn paint_offset_byte_range(&self) -> Range<usize> {
3431        let start = self.format_byte_range().end;
3432        start..start + Offset24::RAW_BYTE_LEN
3433    }
3434
3435    pub fn transform_offset_byte_range(&self) -> Range<usize> {
3436        let start = self.paint_offset_byte_range().end;
3437        start..start + Offset24::RAW_BYTE_LEN
3438    }
3439}
3440
3441impl MinByteRange for PaintVarTransformMarker {
3442    fn min_byte_range(&self) -> Range<usize> {
3443        0..self.transform_offset_byte_range().end
3444    }
3445}
3446
3447impl<'a> FontRead<'a> for PaintVarTransform<'a> {
3448    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3449        let mut cursor = data.cursor();
3450        cursor.advance::<u8>();
3451        cursor.advance::<Offset24>();
3452        cursor.advance::<Offset24>();
3453        cursor.finish(PaintVarTransformMarker {})
3454    }
3455}
3456
3457/// [PaintVarTransform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) table
3458pub type PaintVarTransform<'a> = TableRef<'a, PaintVarTransformMarker>;
3459
3460#[allow(clippy::needless_lifetimes)]
3461impl<'a> PaintVarTransform<'a> {
3462    /// Set to 13.
3463    pub fn format(&self) -> u8 {
3464        let range = self.shape.format_byte_range();
3465        self.data.read_at(range.start).unwrap()
3466    }
3467
3468    /// Offset to a Paint subtable.
3469    pub fn paint_offset(&self) -> Offset24 {
3470        let range = self.shape.paint_offset_byte_range();
3471        self.data.read_at(range.start).unwrap()
3472    }
3473
3474    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
3475    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
3476        let data = self.data;
3477        self.paint_offset().resolve(data)
3478    }
3479
3480    /// Offset to a VarAffine2x3 table.
3481    pub fn transform_offset(&self) -> Offset24 {
3482        let range = self.shape.transform_offset_byte_range();
3483        self.data.read_at(range.start).unwrap()
3484    }
3485
3486    /// Attempt to resolve [`transform_offset`][Self::transform_offset].
3487    pub fn transform(&self) -> Result<VarAffine2x3<'a>, ReadError> {
3488        let data = self.data;
3489        self.transform_offset().resolve(data)
3490    }
3491}
3492
3493#[cfg(feature = "experimental_traverse")]
3494impl<'a> SomeTable<'a> for PaintVarTransform<'a> {
3495    fn type_name(&self) -> &str {
3496        "PaintVarTransform"
3497    }
3498    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3499        match idx {
3500            0usize => Some(Field::new("format", self.format())),
3501            1usize => Some(Field::new(
3502                "paint_offset",
3503                FieldType::offset(self.paint_offset(), self.paint()),
3504            )),
3505            2usize => Some(Field::new(
3506                "transform_offset",
3507                FieldType::offset(self.transform_offset(), self.transform()),
3508            )),
3509            _ => None,
3510        }
3511    }
3512}
3513
3514#[cfg(feature = "experimental_traverse")]
3515#[allow(clippy::needless_lifetimes)]
3516impl<'a> std::fmt::Debug for PaintVarTransform<'a> {
3517    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3518        (self as &dyn SomeTable<'a>).fmt(f)
3519    }
3520}
3521
3522/// [Affine2x3](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) record
3523#[derive(Debug, Clone, Copy)]
3524#[doc(hidden)]
3525pub struct Affine2x3Marker {}
3526
3527impl Affine2x3Marker {
3528    pub fn xx_byte_range(&self) -> Range<usize> {
3529        let start = 0;
3530        start..start + Fixed::RAW_BYTE_LEN
3531    }
3532
3533    pub fn yx_byte_range(&self) -> Range<usize> {
3534        let start = self.xx_byte_range().end;
3535        start..start + Fixed::RAW_BYTE_LEN
3536    }
3537
3538    pub fn xy_byte_range(&self) -> Range<usize> {
3539        let start = self.yx_byte_range().end;
3540        start..start + Fixed::RAW_BYTE_LEN
3541    }
3542
3543    pub fn yy_byte_range(&self) -> Range<usize> {
3544        let start = self.xy_byte_range().end;
3545        start..start + Fixed::RAW_BYTE_LEN
3546    }
3547
3548    pub fn dx_byte_range(&self) -> Range<usize> {
3549        let start = self.yy_byte_range().end;
3550        start..start + Fixed::RAW_BYTE_LEN
3551    }
3552
3553    pub fn dy_byte_range(&self) -> Range<usize> {
3554        let start = self.dx_byte_range().end;
3555        start..start + Fixed::RAW_BYTE_LEN
3556    }
3557}
3558
3559impl MinByteRange for Affine2x3Marker {
3560    fn min_byte_range(&self) -> Range<usize> {
3561        0..self.dy_byte_range().end
3562    }
3563}
3564
3565impl<'a> FontRead<'a> for Affine2x3<'a> {
3566    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3567        let mut cursor = data.cursor();
3568        cursor.advance::<Fixed>();
3569        cursor.advance::<Fixed>();
3570        cursor.advance::<Fixed>();
3571        cursor.advance::<Fixed>();
3572        cursor.advance::<Fixed>();
3573        cursor.advance::<Fixed>();
3574        cursor.finish(Affine2x3Marker {})
3575    }
3576}
3577
3578/// [Affine2x3](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) record
3579pub type Affine2x3<'a> = TableRef<'a, Affine2x3Marker>;
3580
3581#[allow(clippy::needless_lifetimes)]
3582impl<'a> Affine2x3<'a> {
3583    /// x-component of transformed x-basis vector.
3584    pub fn xx(&self) -> Fixed {
3585        let range = self.shape.xx_byte_range();
3586        self.data.read_at(range.start).unwrap()
3587    }
3588
3589    /// y-component of transformed x-basis vector.
3590    pub fn yx(&self) -> Fixed {
3591        let range = self.shape.yx_byte_range();
3592        self.data.read_at(range.start).unwrap()
3593    }
3594
3595    /// x-component of transformed y-basis vector.
3596    pub fn xy(&self) -> Fixed {
3597        let range = self.shape.xy_byte_range();
3598        self.data.read_at(range.start).unwrap()
3599    }
3600
3601    /// y-component of transformed y-basis vector.
3602    pub fn yy(&self) -> Fixed {
3603        let range = self.shape.yy_byte_range();
3604        self.data.read_at(range.start).unwrap()
3605    }
3606
3607    /// Translation in x direction.
3608    pub fn dx(&self) -> Fixed {
3609        let range = self.shape.dx_byte_range();
3610        self.data.read_at(range.start).unwrap()
3611    }
3612
3613    /// Translation in y direction.
3614    pub fn dy(&self) -> Fixed {
3615        let range = self.shape.dy_byte_range();
3616        self.data.read_at(range.start).unwrap()
3617    }
3618}
3619
3620#[cfg(feature = "experimental_traverse")]
3621impl<'a> SomeTable<'a> for Affine2x3<'a> {
3622    fn type_name(&self) -> &str {
3623        "Affine2x3"
3624    }
3625    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3626        match idx {
3627            0usize => Some(Field::new("xx", self.xx())),
3628            1usize => Some(Field::new("yx", self.yx())),
3629            2usize => Some(Field::new("xy", self.xy())),
3630            3usize => Some(Field::new("yy", self.yy())),
3631            4usize => Some(Field::new("dx", self.dx())),
3632            5usize => Some(Field::new("dy", self.dy())),
3633            _ => None,
3634        }
3635    }
3636}
3637
3638#[cfg(feature = "experimental_traverse")]
3639#[allow(clippy::needless_lifetimes)]
3640impl<'a> std::fmt::Debug for Affine2x3<'a> {
3641    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3642        (self as &dyn SomeTable<'a>).fmt(f)
3643    }
3644}
3645
3646/// [VarAffine2x3](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) record
3647#[derive(Debug, Clone, Copy)]
3648#[doc(hidden)]
3649pub struct VarAffine2x3Marker {}
3650
3651impl VarAffine2x3Marker {
3652    pub fn xx_byte_range(&self) -> Range<usize> {
3653        let start = 0;
3654        start..start + Fixed::RAW_BYTE_LEN
3655    }
3656
3657    pub fn yx_byte_range(&self) -> Range<usize> {
3658        let start = self.xx_byte_range().end;
3659        start..start + Fixed::RAW_BYTE_LEN
3660    }
3661
3662    pub fn xy_byte_range(&self) -> Range<usize> {
3663        let start = self.yx_byte_range().end;
3664        start..start + Fixed::RAW_BYTE_LEN
3665    }
3666
3667    pub fn yy_byte_range(&self) -> Range<usize> {
3668        let start = self.xy_byte_range().end;
3669        start..start + Fixed::RAW_BYTE_LEN
3670    }
3671
3672    pub fn dx_byte_range(&self) -> Range<usize> {
3673        let start = self.yy_byte_range().end;
3674        start..start + Fixed::RAW_BYTE_LEN
3675    }
3676
3677    pub fn dy_byte_range(&self) -> Range<usize> {
3678        let start = self.dx_byte_range().end;
3679        start..start + Fixed::RAW_BYTE_LEN
3680    }
3681
3682    pub fn var_index_base_byte_range(&self) -> Range<usize> {
3683        let start = self.dy_byte_range().end;
3684        start..start + u32::RAW_BYTE_LEN
3685    }
3686}
3687
3688impl MinByteRange for VarAffine2x3Marker {
3689    fn min_byte_range(&self) -> Range<usize> {
3690        0..self.var_index_base_byte_range().end
3691    }
3692}
3693
3694impl<'a> FontRead<'a> for VarAffine2x3<'a> {
3695    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3696        let mut cursor = data.cursor();
3697        cursor.advance::<Fixed>();
3698        cursor.advance::<Fixed>();
3699        cursor.advance::<Fixed>();
3700        cursor.advance::<Fixed>();
3701        cursor.advance::<Fixed>();
3702        cursor.advance::<Fixed>();
3703        cursor.advance::<u32>();
3704        cursor.finish(VarAffine2x3Marker {})
3705    }
3706}
3707
3708/// [VarAffine2x3](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) record
3709pub type VarAffine2x3<'a> = TableRef<'a, VarAffine2x3Marker>;
3710
3711#[allow(clippy::needless_lifetimes)]
3712impl<'a> VarAffine2x3<'a> {
3713    /// x-component of transformed x-basis vector. For variation, use
3714    /// varIndexBase + 0.
3715    pub fn xx(&self) -> Fixed {
3716        let range = self.shape.xx_byte_range();
3717        self.data.read_at(range.start).unwrap()
3718    }
3719
3720    /// y-component of transformed x-basis vector. For variation, use
3721    /// varIndexBase + 1.
3722    pub fn yx(&self) -> Fixed {
3723        let range = self.shape.yx_byte_range();
3724        self.data.read_at(range.start).unwrap()
3725    }
3726
3727    /// x-component of transformed y-basis vector. For variation, use
3728    /// varIndexBase + 2.
3729    pub fn xy(&self) -> Fixed {
3730        let range = self.shape.xy_byte_range();
3731        self.data.read_at(range.start).unwrap()
3732    }
3733
3734    /// y-component of transformed y-basis vector. For variation, use
3735    /// varIndexBase + 3.
3736    pub fn yy(&self) -> Fixed {
3737        let range = self.shape.yy_byte_range();
3738        self.data.read_at(range.start).unwrap()
3739    }
3740
3741    /// Translation in x direction. For variation, use varIndexBase + 4.
3742    pub fn dx(&self) -> Fixed {
3743        let range = self.shape.dx_byte_range();
3744        self.data.read_at(range.start).unwrap()
3745    }
3746
3747    /// Translation in y direction. For variation, use varIndexBase + 5.
3748    pub fn dy(&self) -> Fixed {
3749        let range = self.shape.dy_byte_range();
3750        self.data.read_at(range.start).unwrap()
3751    }
3752
3753    /// Base index into DeltaSetIndexMap.
3754    pub fn var_index_base(&self) -> u32 {
3755        let range = self.shape.var_index_base_byte_range();
3756        self.data.read_at(range.start).unwrap()
3757    }
3758}
3759
3760#[cfg(feature = "experimental_traverse")]
3761impl<'a> SomeTable<'a> for VarAffine2x3<'a> {
3762    fn type_name(&self) -> &str {
3763        "VarAffine2x3"
3764    }
3765    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3766        match idx {
3767            0usize => Some(Field::new("xx", self.xx())),
3768            1usize => Some(Field::new("yx", self.yx())),
3769            2usize => Some(Field::new("xy", self.xy())),
3770            3usize => Some(Field::new("yy", self.yy())),
3771            4usize => Some(Field::new("dx", self.dx())),
3772            5usize => Some(Field::new("dy", self.dy())),
3773            6usize => Some(Field::new("var_index_base", self.var_index_base())),
3774            _ => None,
3775        }
3776    }
3777}
3778
3779#[cfg(feature = "experimental_traverse")]
3780#[allow(clippy::needless_lifetimes)]
3781impl<'a> std::fmt::Debug for VarAffine2x3<'a> {
3782    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3783        (self as &dyn SomeTable<'a>).fmt(f)
3784    }
3785}
3786
3787impl Format<u8> for PaintTranslateMarker {
3788    const FORMAT: u8 = 14;
3789}
3790
3791/// [PaintTranslate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-14-and-15-painttranslate-paintvartranslate) table
3792#[derive(Debug, Clone, Copy)]
3793#[doc(hidden)]
3794pub struct PaintTranslateMarker {}
3795
3796impl PaintTranslateMarker {
3797    pub fn format_byte_range(&self) -> Range<usize> {
3798        let start = 0;
3799        start..start + u8::RAW_BYTE_LEN
3800    }
3801
3802    pub fn paint_offset_byte_range(&self) -> Range<usize> {
3803        let start = self.format_byte_range().end;
3804        start..start + Offset24::RAW_BYTE_LEN
3805    }
3806
3807    pub fn dx_byte_range(&self) -> Range<usize> {
3808        let start = self.paint_offset_byte_range().end;
3809        start..start + FWord::RAW_BYTE_LEN
3810    }
3811
3812    pub fn dy_byte_range(&self) -> Range<usize> {
3813        let start = self.dx_byte_range().end;
3814        start..start + FWord::RAW_BYTE_LEN
3815    }
3816}
3817
3818impl MinByteRange for PaintTranslateMarker {
3819    fn min_byte_range(&self) -> Range<usize> {
3820        0..self.dy_byte_range().end
3821    }
3822}
3823
3824impl<'a> FontRead<'a> for PaintTranslate<'a> {
3825    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3826        let mut cursor = data.cursor();
3827        cursor.advance::<u8>();
3828        cursor.advance::<Offset24>();
3829        cursor.advance::<FWord>();
3830        cursor.advance::<FWord>();
3831        cursor.finish(PaintTranslateMarker {})
3832    }
3833}
3834
3835/// [PaintTranslate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-14-and-15-painttranslate-paintvartranslate) table
3836pub type PaintTranslate<'a> = TableRef<'a, PaintTranslateMarker>;
3837
3838#[allow(clippy::needless_lifetimes)]
3839impl<'a> PaintTranslate<'a> {
3840    /// Set to 14.
3841    pub fn format(&self) -> u8 {
3842        let range = self.shape.format_byte_range();
3843        self.data.read_at(range.start).unwrap()
3844    }
3845
3846    /// Offset to a Paint subtable.
3847    pub fn paint_offset(&self) -> Offset24 {
3848        let range = self.shape.paint_offset_byte_range();
3849        self.data.read_at(range.start).unwrap()
3850    }
3851
3852    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
3853    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
3854        let data = self.data;
3855        self.paint_offset().resolve(data)
3856    }
3857
3858    /// Translation in x direction.
3859    pub fn dx(&self) -> FWord {
3860        let range = self.shape.dx_byte_range();
3861        self.data.read_at(range.start).unwrap()
3862    }
3863
3864    /// Translation in y direction.
3865    pub fn dy(&self) -> FWord {
3866        let range = self.shape.dy_byte_range();
3867        self.data.read_at(range.start).unwrap()
3868    }
3869}
3870
3871#[cfg(feature = "experimental_traverse")]
3872impl<'a> SomeTable<'a> for PaintTranslate<'a> {
3873    fn type_name(&self) -> &str {
3874        "PaintTranslate"
3875    }
3876    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3877        match idx {
3878            0usize => Some(Field::new("format", self.format())),
3879            1usize => Some(Field::new(
3880                "paint_offset",
3881                FieldType::offset(self.paint_offset(), self.paint()),
3882            )),
3883            2usize => Some(Field::new("dx", self.dx())),
3884            3usize => Some(Field::new("dy", self.dy())),
3885            _ => None,
3886        }
3887    }
3888}
3889
3890#[cfg(feature = "experimental_traverse")]
3891#[allow(clippy::needless_lifetimes)]
3892impl<'a> std::fmt::Debug for PaintTranslate<'a> {
3893    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3894        (self as &dyn SomeTable<'a>).fmt(f)
3895    }
3896}
3897
3898impl Format<u8> for PaintVarTranslateMarker {
3899    const FORMAT: u8 = 15;
3900}
3901
3902/// [PaintVarTranslate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-14-and-15-painttranslate-paintvartranslate) table
3903#[derive(Debug, Clone, Copy)]
3904#[doc(hidden)]
3905pub struct PaintVarTranslateMarker {}
3906
3907impl PaintVarTranslateMarker {
3908    pub fn format_byte_range(&self) -> Range<usize> {
3909        let start = 0;
3910        start..start + u8::RAW_BYTE_LEN
3911    }
3912
3913    pub fn paint_offset_byte_range(&self) -> Range<usize> {
3914        let start = self.format_byte_range().end;
3915        start..start + Offset24::RAW_BYTE_LEN
3916    }
3917
3918    pub fn dx_byte_range(&self) -> Range<usize> {
3919        let start = self.paint_offset_byte_range().end;
3920        start..start + FWord::RAW_BYTE_LEN
3921    }
3922
3923    pub fn dy_byte_range(&self) -> Range<usize> {
3924        let start = self.dx_byte_range().end;
3925        start..start + FWord::RAW_BYTE_LEN
3926    }
3927
3928    pub fn var_index_base_byte_range(&self) -> Range<usize> {
3929        let start = self.dy_byte_range().end;
3930        start..start + u32::RAW_BYTE_LEN
3931    }
3932}
3933
3934impl MinByteRange for PaintVarTranslateMarker {
3935    fn min_byte_range(&self) -> Range<usize> {
3936        0..self.var_index_base_byte_range().end
3937    }
3938}
3939
3940impl<'a> FontRead<'a> for PaintVarTranslate<'a> {
3941    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3942        let mut cursor = data.cursor();
3943        cursor.advance::<u8>();
3944        cursor.advance::<Offset24>();
3945        cursor.advance::<FWord>();
3946        cursor.advance::<FWord>();
3947        cursor.advance::<u32>();
3948        cursor.finish(PaintVarTranslateMarker {})
3949    }
3950}
3951
3952/// [PaintVarTranslate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-14-and-15-painttranslate-paintvartranslate) table
3953pub type PaintVarTranslate<'a> = TableRef<'a, PaintVarTranslateMarker>;
3954
3955#[allow(clippy::needless_lifetimes)]
3956impl<'a> PaintVarTranslate<'a> {
3957    /// Set to 15.
3958    pub fn format(&self) -> u8 {
3959        let range = self.shape.format_byte_range();
3960        self.data.read_at(range.start).unwrap()
3961    }
3962
3963    /// Offset to a Paint subtable.
3964    pub fn paint_offset(&self) -> Offset24 {
3965        let range = self.shape.paint_offset_byte_range();
3966        self.data.read_at(range.start).unwrap()
3967    }
3968
3969    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
3970    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
3971        let data = self.data;
3972        self.paint_offset().resolve(data)
3973    }
3974
3975    /// Translation in x direction. For variation, use varIndexBase + 0.
3976    pub fn dx(&self) -> FWord {
3977        let range = self.shape.dx_byte_range();
3978        self.data.read_at(range.start).unwrap()
3979    }
3980
3981    /// Translation in y direction. For variation, use varIndexBase + 1.
3982    pub fn dy(&self) -> FWord {
3983        let range = self.shape.dy_byte_range();
3984        self.data.read_at(range.start).unwrap()
3985    }
3986
3987    /// Base index into DeltaSetIndexMap.
3988    pub fn var_index_base(&self) -> u32 {
3989        let range = self.shape.var_index_base_byte_range();
3990        self.data.read_at(range.start).unwrap()
3991    }
3992}
3993
3994#[cfg(feature = "experimental_traverse")]
3995impl<'a> SomeTable<'a> for PaintVarTranslate<'a> {
3996    fn type_name(&self) -> &str {
3997        "PaintVarTranslate"
3998    }
3999    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
4000        match idx {
4001            0usize => Some(Field::new("format", self.format())),
4002            1usize => Some(Field::new(
4003                "paint_offset",
4004                FieldType::offset(self.paint_offset(), self.paint()),
4005            )),
4006            2usize => Some(Field::new("dx", self.dx())),
4007            3usize => Some(Field::new("dy", self.dy())),
4008            4usize => Some(Field::new("var_index_base", self.var_index_base())),
4009            _ => None,
4010        }
4011    }
4012}
4013
4014#[cfg(feature = "experimental_traverse")]
4015#[allow(clippy::needless_lifetimes)]
4016impl<'a> std::fmt::Debug for PaintVarTranslate<'a> {
4017    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4018        (self as &dyn SomeTable<'a>).fmt(f)
4019    }
4020}
4021
4022impl Format<u8> for PaintScaleMarker {
4023    const FORMAT: u8 = 16;
4024}
4025
4026/// [PaintScale](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4027#[derive(Debug, Clone, Copy)]
4028#[doc(hidden)]
4029pub struct PaintScaleMarker {}
4030
4031impl PaintScaleMarker {
4032    pub fn format_byte_range(&self) -> Range<usize> {
4033        let start = 0;
4034        start..start + u8::RAW_BYTE_LEN
4035    }
4036
4037    pub fn paint_offset_byte_range(&self) -> Range<usize> {
4038        let start = self.format_byte_range().end;
4039        start..start + Offset24::RAW_BYTE_LEN
4040    }
4041
4042    pub fn scale_x_byte_range(&self) -> Range<usize> {
4043        let start = self.paint_offset_byte_range().end;
4044        start..start + F2Dot14::RAW_BYTE_LEN
4045    }
4046
4047    pub fn scale_y_byte_range(&self) -> Range<usize> {
4048        let start = self.scale_x_byte_range().end;
4049        start..start + F2Dot14::RAW_BYTE_LEN
4050    }
4051}
4052
4053impl MinByteRange for PaintScaleMarker {
4054    fn min_byte_range(&self) -> Range<usize> {
4055        0..self.scale_y_byte_range().end
4056    }
4057}
4058
4059impl<'a> FontRead<'a> for PaintScale<'a> {
4060    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4061        let mut cursor = data.cursor();
4062        cursor.advance::<u8>();
4063        cursor.advance::<Offset24>();
4064        cursor.advance::<F2Dot14>();
4065        cursor.advance::<F2Dot14>();
4066        cursor.finish(PaintScaleMarker {})
4067    }
4068}
4069
4070/// [PaintScale](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4071pub type PaintScale<'a> = TableRef<'a, PaintScaleMarker>;
4072
4073#[allow(clippy::needless_lifetimes)]
4074impl<'a> PaintScale<'a> {
4075    /// Set to 16.
4076    pub fn format(&self) -> u8 {
4077        let range = self.shape.format_byte_range();
4078        self.data.read_at(range.start).unwrap()
4079    }
4080
4081    /// Offset to a Paint subtable.
4082    pub fn paint_offset(&self) -> Offset24 {
4083        let range = self.shape.paint_offset_byte_range();
4084        self.data.read_at(range.start).unwrap()
4085    }
4086
4087    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
4088    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
4089        let data = self.data;
4090        self.paint_offset().resolve(data)
4091    }
4092
4093    /// Scale factor in x direction.
4094    pub fn scale_x(&self) -> F2Dot14 {
4095        let range = self.shape.scale_x_byte_range();
4096        self.data.read_at(range.start).unwrap()
4097    }
4098
4099    /// Scale factor in y direction.
4100    pub fn scale_y(&self) -> F2Dot14 {
4101        let range = self.shape.scale_y_byte_range();
4102        self.data.read_at(range.start).unwrap()
4103    }
4104}
4105
4106#[cfg(feature = "experimental_traverse")]
4107impl<'a> SomeTable<'a> for PaintScale<'a> {
4108    fn type_name(&self) -> &str {
4109        "PaintScale"
4110    }
4111    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
4112        match idx {
4113            0usize => Some(Field::new("format", self.format())),
4114            1usize => Some(Field::new(
4115                "paint_offset",
4116                FieldType::offset(self.paint_offset(), self.paint()),
4117            )),
4118            2usize => Some(Field::new("scale_x", self.scale_x())),
4119            3usize => Some(Field::new("scale_y", self.scale_y())),
4120            _ => None,
4121        }
4122    }
4123}
4124
4125#[cfg(feature = "experimental_traverse")]
4126#[allow(clippy::needless_lifetimes)]
4127impl<'a> std::fmt::Debug for PaintScale<'a> {
4128    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4129        (self as &dyn SomeTable<'a>).fmt(f)
4130    }
4131}
4132
4133impl Format<u8> for PaintVarScaleMarker {
4134    const FORMAT: u8 = 17;
4135}
4136
4137/// [PaintVarScale](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4138#[derive(Debug, Clone, Copy)]
4139#[doc(hidden)]
4140pub struct PaintVarScaleMarker {}
4141
4142impl PaintVarScaleMarker {
4143    pub fn format_byte_range(&self) -> Range<usize> {
4144        let start = 0;
4145        start..start + u8::RAW_BYTE_LEN
4146    }
4147
4148    pub fn paint_offset_byte_range(&self) -> Range<usize> {
4149        let start = self.format_byte_range().end;
4150        start..start + Offset24::RAW_BYTE_LEN
4151    }
4152
4153    pub fn scale_x_byte_range(&self) -> Range<usize> {
4154        let start = self.paint_offset_byte_range().end;
4155        start..start + F2Dot14::RAW_BYTE_LEN
4156    }
4157
4158    pub fn scale_y_byte_range(&self) -> Range<usize> {
4159        let start = self.scale_x_byte_range().end;
4160        start..start + F2Dot14::RAW_BYTE_LEN
4161    }
4162
4163    pub fn var_index_base_byte_range(&self) -> Range<usize> {
4164        let start = self.scale_y_byte_range().end;
4165        start..start + u32::RAW_BYTE_LEN
4166    }
4167}
4168
4169impl MinByteRange for PaintVarScaleMarker {
4170    fn min_byte_range(&self) -> Range<usize> {
4171        0..self.var_index_base_byte_range().end
4172    }
4173}
4174
4175impl<'a> FontRead<'a> for PaintVarScale<'a> {
4176    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4177        let mut cursor = data.cursor();
4178        cursor.advance::<u8>();
4179        cursor.advance::<Offset24>();
4180        cursor.advance::<F2Dot14>();
4181        cursor.advance::<F2Dot14>();
4182        cursor.advance::<u32>();
4183        cursor.finish(PaintVarScaleMarker {})
4184    }
4185}
4186
4187/// [PaintVarScale](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4188pub type PaintVarScale<'a> = TableRef<'a, PaintVarScaleMarker>;
4189
4190#[allow(clippy::needless_lifetimes)]
4191impl<'a> PaintVarScale<'a> {
4192    /// Set to 17.
4193    pub fn format(&self) -> u8 {
4194        let range = self.shape.format_byte_range();
4195        self.data.read_at(range.start).unwrap()
4196    }
4197
4198    /// Offset to a Paint subtable.
4199    pub fn paint_offset(&self) -> Offset24 {
4200        let range = self.shape.paint_offset_byte_range();
4201        self.data.read_at(range.start).unwrap()
4202    }
4203
4204    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
4205    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
4206        let data = self.data;
4207        self.paint_offset().resolve(data)
4208    }
4209
4210    /// Scale factor in x direction. For variation, use varIndexBase +
4211    /// 0.
4212    pub fn scale_x(&self) -> F2Dot14 {
4213        let range = self.shape.scale_x_byte_range();
4214        self.data.read_at(range.start).unwrap()
4215    }
4216
4217    /// Scale factor in y direction. For variation, use varIndexBase +
4218    /// 1.
4219    pub fn scale_y(&self) -> F2Dot14 {
4220        let range = self.shape.scale_y_byte_range();
4221        self.data.read_at(range.start).unwrap()
4222    }
4223
4224    /// Base index into DeltaSetIndexMap.
4225    pub fn var_index_base(&self) -> u32 {
4226        let range = self.shape.var_index_base_byte_range();
4227        self.data.read_at(range.start).unwrap()
4228    }
4229}
4230
4231#[cfg(feature = "experimental_traverse")]
4232impl<'a> SomeTable<'a> for PaintVarScale<'a> {
4233    fn type_name(&self) -> &str {
4234        "PaintVarScale"
4235    }
4236    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
4237        match idx {
4238            0usize => Some(Field::new("format", self.format())),
4239            1usize => Some(Field::new(
4240                "paint_offset",
4241                FieldType::offset(self.paint_offset(), self.paint()),
4242            )),
4243            2usize => Some(Field::new("scale_x", self.scale_x())),
4244            3usize => Some(Field::new("scale_y", self.scale_y())),
4245            4usize => Some(Field::new("var_index_base", self.var_index_base())),
4246            _ => None,
4247        }
4248    }
4249}
4250
4251#[cfg(feature = "experimental_traverse")]
4252#[allow(clippy::needless_lifetimes)]
4253impl<'a> std::fmt::Debug for PaintVarScale<'a> {
4254    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4255        (self as &dyn SomeTable<'a>).fmt(f)
4256    }
4257}
4258
4259impl Format<u8> for PaintScaleAroundCenterMarker {
4260    const FORMAT: u8 = 18;
4261}
4262
4263/// [PaintScaleAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4264#[derive(Debug, Clone, Copy)]
4265#[doc(hidden)]
4266pub struct PaintScaleAroundCenterMarker {}
4267
4268impl PaintScaleAroundCenterMarker {
4269    pub fn format_byte_range(&self) -> Range<usize> {
4270        let start = 0;
4271        start..start + u8::RAW_BYTE_LEN
4272    }
4273
4274    pub fn paint_offset_byte_range(&self) -> Range<usize> {
4275        let start = self.format_byte_range().end;
4276        start..start + Offset24::RAW_BYTE_LEN
4277    }
4278
4279    pub fn scale_x_byte_range(&self) -> Range<usize> {
4280        let start = self.paint_offset_byte_range().end;
4281        start..start + F2Dot14::RAW_BYTE_LEN
4282    }
4283
4284    pub fn scale_y_byte_range(&self) -> Range<usize> {
4285        let start = self.scale_x_byte_range().end;
4286        start..start + F2Dot14::RAW_BYTE_LEN
4287    }
4288
4289    pub fn center_x_byte_range(&self) -> Range<usize> {
4290        let start = self.scale_y_byte_range().end;
4291        start..start + FWord::RAW_BYTE_LEN
4292    }
4293
4294    pub fn center_y_byte_range(&self) -> Range<usize> {
4295        let start = self.center_x_byte_range().end;
4296        start..start + FWord::RAW_BYTE_LEN
4297    }
4298}
4299
4300impl MinByteRange for PaintScaleAroundCenterMarker {
4301    fn min_byte_range(&self) -> Range<usize> {
4302        0..self.center_y_byte_range().end
4303    }
4304}
4305
4306impl<'a> FontRead<'a> for PaintScaleAroundCenter<'a> {
4307    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4308        let mut cursor = data.cursor();
4309        cursor.advance::<u8>();
4310        cursor.advance::<Offset24>();
4311        cursor.advance::<F2Dot14>();
4312        cursor.advance::<F2Dot14>();
4313        cursor.advance::<FWord>();
4314        cursor.advance::<FWord>();
4315        cursor.finish(PaintScaleAroundCenterMarker {})
4316    }
4317}
4318
4319/// [PaintScaleAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4320pub type PaintScaleAroundCenter<'a> = TableRef<'a, PaintScaleAroundCenterMarker>;
4321
4322#[allow(clippy::needless_lifetimes)]
4323impl<'a> PaintScaleAroundCenter<'a> {
4324    /// Set to 18.
4325    pub fn format(&self) -> u8 {
4326        let range = self.shape.format_byte_range();
4327        self.data.read_at(range.start).unwrap()
4328    }
4329
4330    /// Offset to a Paint subtable.
4331    pub fn paint_offset(&self) -> Offset24 {
4332        let range = self.shape.paint_offset_byte_range();
4333        self.data.read_at(range.start).unwrap()
4334    }
4335
4336    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
4337    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
4338        let data = self.data;
4339        self.paint_offset().resolve(data)
4340    }
4341
4342    /// Scale factor in x direction.
4343    pub fn scale_x(&self) -> F2Dot14 {
4344        let range = self.shape.scale_x_byte_range();
4345        self.data.read_at(range.start).unwrap()
4346    }
4347
4348    /// Scale factor in y direction.
4349    pub fn scale_y(&self) -> F2Dot14 {
4350        let range = self.shape.scale_y_byte_range();
4351        self.data.read_at(range.start).unwrap()
4352    }
4353
4354    /// x coordinate for the center of scaling.
4355    pub fn center_x(&self) -> FWord {
4356        let range = self.shape.center_x_byte_range();
4357        self.data.read_at(range.start).unwrap()
4358    }
4359
4360    /// y coordinate for the center of scaling.
4361    pub fn center_y(&self) -> FWord {
4362        let range = self.shape.center_y_byte_range();
4363        self.data.read_at(range.start).unwrap()
4364    }
4365}
4366
4367#[cfg(feature = "experimental_traverse")]
4368impl<'a> SomeTable<'a> for PaintScaleAroundCenter<'a> {
4369    fn type_name(&self) -> &str {
4370        "PaintScaleAroundCenter"
4371    }
4372    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
4373        match idx {
4374            0usize => Some(Field::new("format", self.format())),
4375            1usize => Some(Field::new(
4376                "paint_offset",
4377                FieldType::offset(self.paint_offset(), self.paint()),
4378            )),
4379            2usize => Some(Field::new("scale_x", self.scale_x())),
4380            3usize => Some(Field::new("scale_y", self.scale_y())),
4381            4usize => Some(Field::new("center_x", self.center_x())),
4382            5usize => Some(Field::new("center_y", self.center_y())),
4383            _ => None,
4384        }
4385    }
4386}
4387
4388#[cfg(feature = "experimental_traverse")]
4389#[allow(clippy::needless_lifetimes)]
4390impl<'a> std::fmt::Debug for PaintScaleAroundCenter<'a> {
4391    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4392        (self as &dyn SomeTable<'a>).fmt(f)
4393    }
4394}
4395
4396impl Format<u8> for PaintVarScaleAroundCenterMarker {
4397    const FORMAT: u8 = 19;
4398}
4399
4400/// [PaintVarScaleAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4401#[derive(Debug, Clone, Copy)]
4402#[doc(hidden)]
4403pub struct PaintVarScaleAroundCenterMarker {}
4404
4405impl PaintVarScaleAroundCenterMarker {
4406    pub fn format_byte_range(&self) -> Range<usize> {
4407        let start = 0;
4408        start..start + u8::RAW_BYTE_LEN
4409    }
4410
4411    pub fn paint_offset_byte_range(&self) -> Range<usize> {
4412        let start = self.format_byte_range().end;
4413        start..start + Offset24::RAW_BYTE_LEN
4414    }
4415
4416    pub fn scale_x_byte_range(&self) -> Range<usize> {
4417        let start = self.paint_offset_byte_range().end;
4418        start..start + F2Dot14::RAW_BYTE_LEN
4419    }
4420
4421    pub fn scale_y_byte_range(&self) -> Range<usize> {
4422        let start = self.scale_x_byte_range().end;
4423        start..start + F2Dot14::RAW_BYTE_LEN
4424    }
4425
4426    pub fn center_x_byte_range(&self) -> Range<usize> {
4427        let start = self.scale_y_byte_range().end;
4428        start..start + FWord::RAW_BYTE_LEN
4429    }
4430
4431    pub fn center_y_byte_range(&self) -> Range<usize> {
4432        let start = self.center_x_byte_range().end;
4433        start..start + FWord::RAW_BYTE_LEN
4434    }
4435
4436    pub fn var_index_base_byte_range(&self) -> Range<usize> {
4437        let start = self.center_y_byte_range().end;
4438        start..start + u32::RAW_BYTE_LEN
4439    }
4440}
4441
4442impl MinByteRange for PaintVarScaleAroundCenterMarker {
4443    fn min_byte_range(&self) -> Range<usize> {
4444        0..self.var_index_base_byte_range().end
4445    }
4446}
4447
4448impl<'a> FontRead<'a> for PaintVarScaleAroundCenter<'a> {
4449    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4450        let mut cursor = data.cursor();
4451        cursor.advance::<u8>();
4452        cursor.advance::<Offset24>();
4453        cursor.advance::<F2Dot14>();
4454        cursor.advance::<F2Dot14>();
4455        cursor.advance::<FWord>();
4456        cursor.advance::<FWord>();
4457        cursor.advance::<u32>();
4458        cursor.finish(PaintVarScaleAroundCenterMarker {})
4459    }
4460}
4461
4462/// [PaintVarScaleAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4463pub type PaintVarScaleAroundCenter<'a> = TableRef<'a, PaintVarScaleAroundCenterMarker>;
4464
4465#[allow(clippy::needless_lifetimes)]
4466impl<'a> PaintVarScaleAroundCenter<'a> {
4467    /// Set to 19.
4468    pub fn format(&self) -> u8 {
4469        let range = self.shape.format_byte_range();
4470        self.data.read_at(range.start).unwrap()
4471    }
4472
4473    /// Offset to a Paint subtable.
4474    pub fn paint_offset(&self) -> Offset24 {
4475        let range = self.shape.paint_offset_byte_range();
4476        self.data.read_at(range.start).unwrap()
4477    }
4478
4479    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
4480    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
4481        let data = self.data;
4482        self.paint_offset().resolve(data)
4483    }
4484
4485    /// Scale factor in x direction. For variation, use varIndexBase +
4486    /// 0.
4487    pub fn scale_x(&self) -> F2Dot14 {
4488        let range = self.shape.scale_x_byte_range();
4489        self.data.read_at(range.start).unwrap()
4490    }
4491
4492    /// Scale factor in y direction. For variation, use varIndexBase +
4493    /// 1.
4494    pub fn scale_y(&self) -> F2Dot14 {
4495        let range = self.shape.scale_y_byte_range();
4496        self.data.read_at(range.start).unwrap()
4497    }
4498
4499    /// x coordinate for the center of scaling. For variation, use
4500    /// varIndexBase + 2.
4501    pub fn center_x(&self) -> FWord {
4502        let range = self.shape.center_x_byte_range();
4503        self.data.read_at(range.start).unwrap()
4504    }
4505
4506    /// y coordinate for the center of scaling. For variation, use
4507    /// varIndexBase + 3.
4508    pub fn center_y(&self) -> FWord {
4509        let range = self.shape.center_y_byte_range();
4510        self.data.read_at(range.start).unwrap()
4511    }
4512
4513    /// Base index into DeltaSetIndexMap.
4514    pub fn var_index_base(&self) -> u32 {
4515        let range = self.shape.var_index_base_byte_range();
4516        self.data.read_at(range.start).unwrap()
4517    }
4518}
4519
4520#[cfg(feature = "experimental_traverse")]
4521impl<'a> SomeTable<'a> for PaintVarScaleAroundCenter<'a> {
4522    fn type_name(&self) -> &str {
4523        "PaintVarScaleAroundCenter"
4524    }
4525    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
4526        match idx {
4527            0usize => Some(Field::new("format", self.format())),
4528            1usize => Some(Field::new(
4529                "paint_offset",
4530                FieldType::offset(self.paint_offset(), self.paint()),
4531            )),
4532            2usize => Some(Field::new("scale_x", self.scale_x())),
4533            3usize => Some(Field::new("scale_y", self.scale_y())),
4534            4usize => Some(Field::new("center_x", self.center_x())),
4535            5usize => Some(Field::new("center_y", self.center_y())),
4536            6usize => Some(Field::new("var_index_base", self.var_index_base())),
4537            _ => None,
4538        }
4539    }
4540}
4541
4542#[cfg(feature = "experimental_traverse")]
4543#[allow(clippy::needless_lifetimes)]
4544impl<'a> std::fmt::Debug for PaintVarScaleAroundCenter<'a> {
4545    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4546        (self as &dyn SomeTable<'a>).fmt(f)
4547    }
4548}
4549
4550impl Format<u8> for PaintScaleUniformMarker {
4551    const FORMAT: u8 = 20;
4552}
4553
4554/// [PaintScaleUniform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4555#[derive(Debug, Clone, Copy)]
4556#[doc(hidden)]
4557pub struct PaintScaleUniformMarker {}
4558
4559impl PaintScaleUniformMarker {
4560    pub fn format_byte_range(&self) -> Range<usize> {
4561        let start = 0;
4562        start..start + u8::RAW_BYTE_LEN
4563    }
4564
4565    pub fn paint_offset_byte_range(&self) -> Range<usize> {
4566        let start = self.format_byte_range().end;
4567        start..start + Offset24::RAW_BYTE_LEN
4568    }
4569
4570    pub fn scale_byte_range(&self) -> Range<usize> {
4571        let start = self.paint_offset_byte_range().end;
4572        start..start + F2Dot14::RAW_BYTE_LEN
4573    }
4574}
4575
4576impl MinByteRange for PaintScaleUniformMarker {
4577    fn min_byte_range(&self) -> Range<usize> {
4578        0..self.scale_byte_range().end
4579    }
4580}
4581
4582impl<'a> FontRead<'a> for PaintScaleUniform<'a> {
4583    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4584        let mut cursor = data.cursor();
4585        cursor.advance::<u8>();
4586        cursor.advance::<Offset24>();
4587        cursor.advance::<F2Dot14>();
4588        cursor.finish(PaintScaleUniformMarker {})
4589    }
4590}
4591
4592/// [PaintScaleUniform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4593pub type PaintScaleUniform<'a> = TableRef<'a, PaintScaleUniformMarker>;
4594
4595#[allow(clippy::needless_lifetimes)]
4596impl<'a> PaintScaleUniform<'a> {
4597    /// Set to 20.
4598    pub fn format(&self) -> u8 {
4599        let range = self.shape.format_byte_range();
4600        self.data.read_at(range.start).unwrap()
4601    }
4602
4603    /// Offset to a Paint subtable.
4604    pub fn paint_offset(&self) -> Offset24 {
4605        let range = self.shape.paint_offset_byte_range();
4606        self.data.read_at(range.start).unwrap()
4607    }
4608
4609    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
4610    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
4611        let data = self.data;
4612        self.paint_offset().resolve(data)
4613    }
4614
4615    /// Scale factor in x and y directions.
4616    pub fn scale(&self) -> F2Dot14 {
4617        let range = self.shape.scale_byte_range();
4618        self.data.read_at(range.start).unwrap()
4619    }
4620}
4621
4622#[cfg(feature = "experimental_traverse")]
4623impl<'a> SomeTable<'a> for PaintScaleUniform<'a> {
4624    fn type_name(&self) -> &str {
4625        "PaintScaleUniform"
4626    }
4627    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
4628        match idx {
4629            0usize => Some(Field::new("format", self.format())),
4630            1usize => Some(Field::new(
4631                "paint_offset",
4632                FieldType::offset(self.paint_offset(), self.paint()),
4633            )),
4634            2usize => Some(Field::new("scale", self.scale())),
4635            _ => None,
4636        }
4637    }
4638}
4639
4640#[cfg(feature = "experimental_traverse")]
4641#[allow(clippy::needless_lifetimes)]
4642impl<'a> std::fmt::Debug for PaintScaleUniform<'a> {
4643    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4644        (self as &dyn SomeTable<'a>).fmt(f)
4645    }
4646}
4647
4648impl Format<u8> for PaintVarScaleUniformMarker {
4649    const FORMAT: u8 = 21;
4650}
4651
4652/// [PaintVarScaleUniform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4653#[derive(Debug, Clone, Copy)]
4654#[doc(hidden)]
4655pub struct PaintVarScaleUniformMarker {}
4656
4657impl PaintVarScaleUniformMarker {
4658    pub fn format_byte_range(&self) -> Range<usize> {
4659        let start = 0;
4660        start..start + u8::RAW_BYTE_LEN
4661    }
4662
4663    pub fn paint_offset_byte_range(&self) -> Range<usize> {
4664        let start = self.format_byte_range().end;
4665        start..start + Offset24::RAW_BYTE_LEN
4666    }
4667
4668    pub fn scale_byte_range(&self) -> Range<usize> {
4669        let start = self.paint_offset_byte_range().end;
4670        start..start + F2Dot14::RAW_BYTE_LEN
4671    }
4672
4673    pub fn var_index_base_byte_range(&self) -> Range<usize> {
4674        let start = self.scale_byte_range().end;
4675        start..start + u32::RAW_BYTE_LEN
4676    }
4677}
4678
4679impl MinByteRange for PaintVarScaleUniformMarker {
4680    fn min_byte_range(&self) -> Range<usize> {
4681        0..self.var_index_base_byte_range().end
4682    }
4683}
4684
4685impl<'a> FontRead<'a> for PaintVarScaleUniform<'a> {
4686    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4687        let mut cursor = data.cursor();
4688        cursor.advance::<u8>();
4689        cursor.advance::<Offset24>();
4690        cursor.advance::<F2Dot14>();
4691        cursor.advance::<u32>();
4692        cursor.finish(PaintVarScaleUniformMarker {})
4693    }
4694}
4695
4696/// [PaintVarScaleUniform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4697pub type PaintVarScaleUniform<'a> = TableRef<'a, PaintVarScaleUniformMarker>;
4698
4699#[allow(clippy::needless_lifetimes)]
4700impl<'a> PaintVarScaleUniform<'a> {
4701    /// Set to 21.
4702    pub fn format(&self) -> u8 {
4703        let range = self.shape.format_byte_range();
4704        self.data.read_at(range.start).unwrap()
4705    }
4706
4707    /// Offset to a Paint subtable.
4708    pub fn paint_offset(&self) -> Offset24 {
4709        let range = self.shape.paint_offset_byte_range();
4710        self.data.read_at(range.start).unwrap()
4711    }
4712
4713    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
4714    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
4715        let data = self.data;
4716        self.paint_offset().resolve(data)
4717    }
4718
4719    /// Scale factor in x and y directions. For variation, use
4720    /// varIndexBase + 0.
4721    pub fn scale(&self) -> F2Dot14 {
4722        let range = self.shape.scale_byte_range();
4723        self.data.read_at(range.start).unwrap()
4724    }
4725
4726    /// Base index into DeltaSetIndexMap.
4727    pub fn var_index_base(&self) -> u32 {
4728        let range = self.shape.var_index_base_byte_range();
4729        self.data.read_at(range.start).unwrap()
4730    }
4731}
4732
4733#[cfg(feature = "experimental_traverse")]
4734impl<'a> SomeTable<'a> for PaintVarScaleUniform<'a> {
4735    fn type_name(&self) -> &str {
4736        "PaintVarScaleUniform"
4737    }
4738    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
4739        match idx {
4740            0usize => Some(Field::new("format", self.format())),
4741            1usize => Some(Field::new(
4742                "paint_offset",
4743                FieldType::offset(self.paint_offset(), self.paint()),
4744            )),
4745            2usize => Some(Field::new("scale", self.scale())),
4746            3usize => Some(Field::new("var_index_base", self.var_index_base())),
4747            _ => None,
4748        }
4749    }
4750}
4751
4752#[cfg(feature = "experimental_traverse")]
4753#[allow(clippy::needless_lifetimes)]
4754impl<'a> std::fmt::Debug for PaintVarScaleUniform<'a> {
4755    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4756        (self as &dyn SomeTable<'a>).fmt(f)
4757    }
4758}
4759
4760impl Format<u8> for PaintScaleUniformAroundCenterMarker {
4761    const FORMAT: u8 = 22;
4762}
4763
4764/// [PaintScaleUniformAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4765#[derive(Debug, Clone, Copy)]
4766#[doc(hidden)]
4767pub struct PaintScaleUniformAroundCenterMarker {}
4768
4769impl PaintScaleUniformAroundCenterMarker {
4770    pub fn format_byte_range(&self) -> Range<usize> {
4771        let start = 0;
4772        start..start + u8::RAW_BYTE_LEN
4773    }
4774
4775    pub fn paint_offset_byte_range(&self) -> Range<usize> {
4776        let start = self.format_byte_range().end;
4777        start..start + Offset24::RAW_BYTE_LEN
4778    }
4779
4780    pub fn scale_byte_range(&self) -> Range<usize> {
4781        let start = self.paint_offset_byte_range().end;
4782        start..start + F2Dot14::RAW_BYTE_LEN
4783    }
4784
4785    pub fn center_x_byte_range(&self) -> Range<usize> {
4786        let start = self.scale_byte_range().end;
4787        start..start + FWord::RAW_BYTE_LEN
4788    }
4789
4790    pub fn center_y_byte_range(&self) -> Range<usize> {
4791        let start = self.center_x_byte_range().end;
4792        start..start + FWord::RAW_BYTE_LEN
4793    }
4794}
4795
4796impl MinByteRange for PaintScaleUniformAroundCenterMarker {
4797    fn min_byte_range(&self) -> Range<usize> {
4798        0..self.center_y_byte_range().end
4799    }
4800}
4801
4802impl<'a> FontRead<'a> for PaintScaleUniformAroundCenter<'a> {
4803    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4804        let mut cursor = data.cursor();
4805        cursor.advance::<u8>();
4806        cursor.advance::<Offset24>();
4807        cursor.advance::<F2Dot14>();
4808        cursor.advance::<FWord>();
4809        cursor.advance::<FWord>();
4810        cursor.finish(PaintScaleUniformAroundCenterMarker {})
4811    }
4812}
4813
4814/// [PaintScaleUniformAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4815pub type PaintScaleUniformAroundCenter<'a> = TableRef<'a, PaintScaleUniformAroundCenterMarker>;
4816
4817#[allow(clippy::needless_lifetimes)]
4818impl<'a> PaintScaleUniformAroundCenter<'a> {
4819    /// Set to 22.
4820    pub fn format(&self) -> u8 {
4821        let range = self.shape.format_byte_range();
4822        self.data.read_at(range.start).unwrap()
4823    }
4824
4825    /// Offset to a Paint subtable.
4826    pub fn paint_offset(&self) -> Offset24 {
4827        let range = self.shape.paint_offset_byte_range();
4828        self.data.read_at(range.start).unwrap()
4829    }
4830
4831    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
4832    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
4833        let data = self.data;
4834        self.paint_offset().resolve(data)
4835    }
4836
4837    /// Scale factor in x and y directions.
4838    pub fn scale(&self) -> F2Dot14 {
4839        let range = self.shape.scale_byte_range();
4840        self.data.read_at(range.start).unwrap()
4841    }
4842
4843    /// x coordinate for the center of scaling.
4844    pub fn center_x(&self) -> FWord {
4845        let range = self.shape.center_x_byte_range();
4846        self.data.read_at(range.start).unwrap()
4847    }
4848
4849    /// y coordinate for the center of scaling.
4850    pub fn center_y(&self) -> FWord {
4851        let range = self.shape.center_y_byte_range();
4852        self.data.read_at(range.start).unwrap()
4853    }
4854}
4855
4856#[cfg(feature = "experimental_traverse")]
4857impl<'a> SomeTable<'a> for PaintScaleUniformAroundCenter<'a> {
4858    fn type_name(&self) -> &str {
4859        "PaintScaleUniformAroundCenter"
4860    }
4861    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
4862        match idx {
4863            0usize => Some(Field::new("format", self.format())),
4864            1usize => Some(Field::new(
4865                "paint_offset",
4866                FieldType::offset(self.paint_offset(), self.paint()),
4867            )),
4868            2usize => Some(Field::new("scale", self.scale())),
4869            3usize => Some(Field::new("center_x", self.center_x())),
4870            4usize => Some(Field::new("center_y", self.center_y())),
4871            _ => None,
4872        }
4873    }
4874}
4875
4876#[cfg(feature = "experimental_traverse")]
4877#[allow(clippy::needless_lifetimes)]
4878impl<'a> std::fmt::Debug for PaintScaleUniformAroundCenter<'a> {
4879    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4880        (self as &dyn SomeTable<'a>).fmt(f)
4881    }
4882}
4883
4884impl Format<u8> for PaintVarScaleUniformAroundCenterMarker {
4885    const FORMAT: u8 = 23;
4886}
4887
4888/// [PaintVarScaleUniformAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4889#[derive(Debug, Clone, Copy)]
4890#[doc(hidden)]
4891pub struct PaintVarScaleUniformAroundCenterMarker {}
4892
4893impl PaintVarScaleUniformAroundCenterMarker {
4894    pub fn format_byte_range(&self) -> Range<usize> {
4895        let start = 0;
4896        start..start + u8::RAW_BYTE_LEN
4897    }
4898
4899    pub fn paint_offset_byte_range(&self) -> Range<usize> {
4900        let start = self.format_byte_range().end;
4901        start..start + Offset24::RAW_BYTE_LEN
4902    }
4903
4904    pub fn scale_byte_range(&self) -> Range<usize> {
4905        let start = self.paint_offset_byte_range().end;
4906        start..start + F2Dot14::RAW_BYTE_LEN
4907    }
4908
4909    pub fn center_x_byte_range(&self) -> Range<usize> {
4910        let start = self.scale_byte_range().end;
4911        start..start + FWord::RAW_BYTE_LEN
4912    }
4913
4914    pub fn center_y_byte_range(&self) -> Range<usize> {
4915        let start = self.center_x_byte_range().end;
4916        start..start + FWord::RAW_BYTE_LEN
4917    }
4918
4919    pub fn var_index_base_byte_range(&self) -> Range<usize> {
4920        let start = self.center_y_byte_range().end;
4921        start..start + u32::RAW_BYTE_LEN
4922    }
4923}
4924
4925impl MinByteRange for PaintVarScaleUniformAroundCenterMarker {
4926    fn min_byte_range(&self) -> Range<usize> {
4927        0..self.var_index_base_byte_range().end
4928    }
4929}
4930
4931impl<'a> FontRead<'a> for PaintVarScaleUniformAroundCenter<'a> {
4932    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4933        let mut cursor = data.cursor();
4934        cursor.advance::<u8>();
4935        cursor.advance::<Offset24>();
4936        cursor.advance::<F2Dot14>();
4937        cursor.advance::<FWord>();
4938        cursor.advance::<FWord>();
4939        cursor.advance::<u32>();
4940        cursor.finish(PaintVarScaleUniformAroundCenterMarker {})
4941    }
4942}
4943
4944/// [PaintVarScaleUniformAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4945pub type PaintVarScaleUniformAroundCenter<'a> =
4946    TableRef<'a, PaintVarScaleUniformAroundCenterMarker>;
4947
4948#[allow(clippy::needless_lifetimes)]
4949impl<'a> PaintVarScaleUniformAroundCenter<'a> {
4950    /// Set to 23.
4951    pub fn format(&self) -> u8 {
4952        let range = self.shape.format_byte_range();
4953        self.data.read_at(range.start).unwrap()
4954    }
4955
4956    /// Offset to a Paint subtable.
4957    pub fn paint_offset(&self) -> Offset24 {
4958        let range = self.shape.paint_offset_byte_range();
4959        self.data.read_at(range.start).unwrap()
4960    }
4961
4962    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
4963    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
4964        let data = self.data;
4965        self.paint_offset().resolve(data)
4966    }
4967
4968    /// Scale factor in x and y directions. For variation, use
4969    /// varIndexBase + 0.
4970    pub fn scale(&self) -> F2Dot14 {
4971        let range = self.shape.scale_byte_range();
4972        self.data.read_at(range.start).unwrap()
4973    }
4974
4975    /// x coordinate for the center of scaling. For variation, use
4976    /// varIndexBase + 1.
4977    pub fn center_x(&self) -> FWord {
4978        let range = self.shape.center_x_byte_range();
4979        self.data.read_at(range.start).unwrap()
4980    }
4981
4982    /// y coordinate for the center of scaling. For variation, use
4983    /// varIndexBase + 2.
4984    pub fn center_y(&self) -> FWord {
4985        let range = self.shape.center_y_byte_range();
4986        self.data.read_at(range.start).unwrap()
4987    }
4988
4989    /// Base index into DeltaSetIndexMap.
4990    pub fn var_index_base(&self) -> u32 {
4991        let range = self.shape.var_index_base_byte_range();
4992        self.data.read_at(range.start).unwrap()
4993    }
4994}
4995
4996#[cfg(feature = "experimental_traverse")]
4997impl<'a> SomeTable<'a> for PaintVarScaleUniformAroundCenter<'a> {
4998    fn type_name(&self) -> &str {
4999        "PaintVarScaleUniformAroundCenter"
5000    }
5001    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
5002        match idx {
5003            0usize => Some(Field::new("format", self.format())),
5004            1usize => Some(Field::new(
5005                "paint_offset",
5006                FieldType::offset(self.paint_offset(), self.paint()),
5007            )),
5008            2usize => Some(Field::new("scale", self.scale())),
5009            3usize => Some(Field::new("center_x", self.center_x())),
5010            4usize => Some(Field::new("center_y", self.center_y())),
5011            5usize => Some(Field::new("var_index_base", self.var_index_base())),
5012            _ => None,
5013        }
5014    }
5015}
5016
5017#[cfg(feature = "experimental_traverse")]
5018#[allow(clippy::needless_lifetimes)]
5019impl<'a> std::fmt::Debug for PaintVarScaleUniformAroundCenter<'a> {
5020    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5021        (self as &dyn SomeTable<'a>).fmt(f)
5022    }
5023}
5024
5025impl Format<u8> for PaintRotateMarker {
5026    const FORMAT: u8 = 24;
5027}
5028
5029/// [PaintRotate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table
5030#[derive(Debug, Clone, Copy)]
5031#[doc(hidden)]
5032pub struct PaintRotateMarker {}
5033
5034impl PaintRotateMarker {
5035    pub fn format_byte_range(&self) -> Range<usize> {
5036        let start = 0;
5037        start..start + u8::RAW_BYTE_LEN
5038    }
5039
5040    pub fn paint_offset_byte_range(&self) -> Range<usize> {
5041        let start = self.format_byte_range().end;
5042        start..start + Offset24::RAW_BYTE_LEN
5043    }
5044
5045    pub fn angle_byte_range(&self) -> Range<usize> {
5046        let start = self.paint_offset_byte_range().end;
5047        start..start + F2Dot14::RAW_BYTE_LEN
5048    }
5049}
5050
5051impl MinByteRange for PaintRotateMarker {
5052    fn min_byte_range(&self) -> Range<usize> {
5053        0..self.angle_byte_range().end
5054    }
5055}
5056
5057impl<'a> FontRead<'a> for PaintRotate<'a> {
5058    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
5059        let mut cursor = data.cursor();
5060        cursor.advance::<u8>();
5061        cursor.advance::<Offset24>();
5062        cursor.advance::<F2Dot14>();
5063        cursor.finish(PaintRotateMarker {})
5064    }
5065}
5066
5067/// [PaintRotate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table
5068pub type PaintRotate<'a> = TableRef<'a, PaintRotateMarker>;
5069
5070#[allow(clippy::needless_lifetimes)]
5071impl<'a> PaintRotate<'a> {
5072    /// Set to 24.
5073    pub fn format(&self) -> u8 {
5074        let range = self.shape.format_byte_range();
5075        self.data.read_at(range.start).unwrap()
5076    }
5077
5078    /// Offset to a Paint subtable.
5079    pub fn paint_offset(&self) -> Offset24 {
5080        let range = self.shape.paint_offset_byte_range();
5081        self.data.read_at(range.start).unwrap()
5082    }
5083
5084    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
5085    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
5086        let data = self.data;
5087        self.paint_offset().resolve(data)
5088    }
5089
5090    /// Rotation angle, 180° in counter-clockwise degrees per 1.0 of
5091    /// value.
5092    pub fn angle(&self) -> F2Dot14 {
5093        let range = self.shape.angle_byte_range();
5094        self.data.read_at(range.start).unwrap()
5095    }
5096}
5097
5098#[cfg(feature = "experimental_traverse")]
5099impl<'a> SomeTable<'a> for PaintRotate<'a> {
5100    fn type_name(&self) -> &str {
5101        "PaintRotate"
5102    }
5103    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
5104        match idx {
5105            0usize => Some(Field::new("format", self.format())),
5106            1usize => Some(Field::new(
5107                "paint_offset",
5108                FieldType::offset(self.paint_offset(), self.paint()),
5109            )),
5110            2usize => Some(Field::new("angle", self.angle())),
5111            _ => None,
5112        }
5113    }
5114}
5115
5116#[cfg(feature = "experimental_traverse")]
5117#[allow(clippy::needless_lifetimes)]
5118impl<'a> std::fmt::Debug for PaintRotate<'a> {
5119    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5120        (self as &dyn SomeTable<'a>).fmt(f)
5121    }
5122}
5123
5124impl Format<u8> for PaintVarRotateMarker {
5125    const FORMAT: u8 = 25;
5126}
5127
5128/// [PaintVarRotate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table
5129#[derive(Debug, Clone, Copy)]
5130#[doc(hidden)]
5131pub struct PaintVarRotateMarker {}
5132
5133impl PaintVarRotateMarker {
5134    pub fn format_byte_range(&self) -> Range<usize> {
5135        let start = 0;
5136        start..start + u8::RAW_BYTE_LEN
5137    }
5138
5139    pub fn paint_offset_byte_range(&self) -> Range<usize> {
5140        let start = self.format_byte_range().end;
5141        start..start + Offset24::RAW_BYTE_LEN
5142    }
5143
5144    pub fn angle_byte_range(&self) -> Range<usize> {
5145        let start = self.paint_offset_byte_range().end;
5146        start..start + F2Dot14::RAW_BYTE_LEN
5147    }
5148
5149    pub fn var_index_base_byte_range(&self) -> Range<usize> {
5150        let start = self.angle_byte_range().end;
5151        start..start + u32::RAW_BYTE_LEN
5152    }
5153}
5154
5155impl MinByteRange for PaintVarRotateMarker {
5156    fn min_byte_range(&self) -> Range<usize> {
5157        0..self.var_index_base_byte_range().end
5158    }
5159}
5160
5161impl<'a> FontRead<'a> for PaintVarRotate<'a> {
5162    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
5163        let mut cursor = data.cursor();
5164        cursor.advance::<u8>();
5165        cursor.advance::<Offset24>();
5166        cursor.advance::<F2Dot14>();
5167        cursor.advance::<u32>();
5168        cursor.finish(PaintVarRotateMarker {})
5169    }
5170}
5171
5172/// [PaintVarRotate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table
5173pub type PaintVarRotate<'a> = TableRef<'a, PaintVarRotateMarker>;
5174
5175#[allow(clippy::needless_lifetimes)]
5176impl<'a> PaintVarRotate<'a> {
5177    /// Set to 25.
5178    pub fn format(&self) -> u8 {
5179        let range = self.shape.format_byte_range();
5180        self.data.read_at(range.start).unwrap()
5181    }
5182
5183    /// Offset to a Paint subtable.
5184    pub fn paint_offset(&self) -> Offset24 {
5185        let range = self.shape.paint_offset_byte_range();
5186        self.data.read_at(range.start).unwrap()
5187    }
5188
5189    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
5190    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
5191        let data = self.data;
5192        self.paint_offset().resolve(data)
5193    }
5194
5195    /// Rotation angle, 180° in counter-clockwise degrees per 1.0 of
5196    /// value. For variation, use varIndexBase + 0.
5197    pub fn angle(&self) -> F2Dot14 {
5198        let range = self.shape.angle_byte_range();
5199        self.data.read_at(range.start).unwrap()
5200    }
5201
5202    /// Base index into DeltaSetIndexMap.
5203    pub fn var_index_base(&self) -> u32 {
5204        let range = self.shape.var_index_base_byte_range();
5205        self.data.read_at(range.start).unwrap()
5206    }
5207}
5208
5209#[cfg(feature = "experimental_traverse")]
5210impl<'a> SomeTable<'a> for PaintVarRotate<'a> {
5211    fn type_name(&self) -> &str {
5212        "PaintVarRotate"
5213    }
5214    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
5215        match idx {
5216            0usize => Some(Field::new("format", self.format())),
5217            1usize => Some(Field::new(
5218                "paint_offset",
5219                FieldType::offset(self.paint_offset(), self.paint()),
5220            )),
5221            2usize => Some(Field::new("angle", self.angle())),
5222            3usize => Some(Field::new("var_index_base", self.var_index_base())),
5223            _ => None,
5224        }
5225    }
5226}
5227
5228#[cfg(feature = "experimental_traverse")]
5229#[allow(clippy::needless_lifetimes)]
5230impl<'a> std::fmt::Debug for PaintVarRotate<'a> {
5231    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5232        (self as &dyn SomeTable<'a>).fmt(f)
5233    }
5234}
5235
5236impl Format<u8> for PaintRotateAroundCenterMarker {
5237    const FORMAT: u8 = 26;
5238}
5239
5240/// [PaintRotateAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table
5241#[derive(Debug, Clone, Copy)]
5242#[doc(hidden)]
5243pub struct PaintRotateAroundCenterMarker {}
5244
5245impl PaintRotateAroundCenterMarker {
5246    pub fn format_byte_range(&self) -> Range<usize> {
5247        let start = 0;
5248        start..start + u8::RAW_BYTE_LEN
5249    }
5250
5251    pub fn paint_offset_byte_range(&self) -> Range<usize> {
5252        let start = self.format_byte_range().end;
5253        start..start + Offset24::RAW_BYTE_LEN
5254    }
5255
5256    pub fn angle_byte_range(&self) -> Range<usize> {
5257        let start = self.paint_offset_byte_range().end;
5258        start..start + F2Dot14::RAW_BYTE_LEN
5259    }
5260
5261    pub fn center_x_byte_range(&self) -> Range<usize> {
5262        let start = self.angle_byte_range().end;
5263        start..start + FWord::RAW_BYTE_LEN
5264    }
5265
5266    pub fn center_y_byte_range(&self) -> Range<usize> {
5267        let start = self.center_x_byte_range().end;
5268        start..start + FWord::RAW_BYTE_LEN
5269    }
5270}
5271
5272impl MinByteRange for PaintRotateAroundCenterMarker {
5273    fn min_byte_range(&self) -> Range<usize> {
5274        0..self.center_y_byte_range().end
5275    }
5276}
5277
5278impl<'a> FontRead<'a> for PaintRotateAroundCenter<'a> {
5279    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
5280        let mut cursor = data.cursor();
5281        cursor.advance::<u8>();
5282        cursor.advance::<Offset24>();
5283        cursor.advance::<F2Dot14>();
5284        cursor.advance::<FWord>();
5285        cursor.advance::<FWord>();
5286        cursor.finish(PaintRotateAroundCenterMarker {})
5287    }
5288}
5289
5290/// [PaintRotateAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table
5291pub type PaintRotateAroundCenter<'a> = TableRef<'a, PaintRotateAroundCenterMarker>;
5292
5293#[allow(clippy::needless_lifetimes)]
5294impl<'a> PaintRotateAroundCenter<'a> {
5295    /// Set to 26.
5296    pub fn format(&self) -> u8 {
5297        let range = self.shape.format_byte_range();
5298        self.data.read_at(range.start).unwrap()
5299    }
5300
5301    /// Offset to a Paint subtable.
5302    pub fn paint_offset(&self) -> Offset24 {
5303        let range = self.shape.paint_offset_byte_range();
5304        self.data.read_at(range.start).unwrap()
5305    }
5306
5307    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
5308    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
5309        let data = self.data;
5310        self.paint_offset().resolve(data)
5311    }
5312
5313    /// Rotation angle, 180° in counter-clockwise degrees per 1.0 of
5314    /// value.
5315    pub fn angle(&self) -> F2Dot14 {
5316        let range = self.shape.angle_byte_range();
5317        self.data.read_at(range.start).unwrap()
5318    }
5319
5320    /// x coordinate for the center of rotation.
5321    pub fn center_x(&self) -> FWord {
5322        let range = self.shape.center_x_byte_range();
5323        self.data.read_at(range.start).unwrap()
5324    }
5325
5326    /// y coordinate for the center of rotation.
5327    pub fn center_y(&self) -> FWord {
5328        let range = self.shape.center_y_byte_range();
5329        self.data.read_at(range.start).unwrap()
5330    }
5331}
5332
5333#[cfg(feature = "experimental_traverse")]
5334impl<'a> SomeTable<'a> for PaintRotateAroundCenter<'a> {
5335    fn type_name(&self) -> &str {
5336        "PaintRotateAroundCenter"
5337    }
5338    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
5339        match idx {
5340            0usize => Some(Field::new("format", self.format())),
5341            1usize => Some(Field::new(
5342                "paint_offset",
5343                FieldType::offset(self.paint_offset(), self.paint()),
5344            )),
5345            2usize => Some(Field::new("angle", self.angle())),
5346            3usize => Some(Field::new("center_x", self.center_x())),
5347            4usize => Some(Field::new("center_y", self.center_y())),
5348            _ => None,
5349        }
5350    }
5351}
5352
5353#[cfg(feature = "experimental_traverse")]
5354#[allow(clippy::needless_lifetimes)]
5355impl<'a> std::fmt::Debug for PaintRotateAroundCenter<'a> {
5356    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5357        (self as &dyn SomeTable<'a>).fmt(f)
5358    }
5359}
5360
5361impl Format<u8> for PaintVarRotateAroundCenterMarker {
5362    const FORMAT: u8 = 27;
5363}
5364
5365/// [PaintVarRotateAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table
5366#[derive(Debug, Clone, Copy)]
5367#[doc(hidden)]
5368pub struct PaintVarRotateAroundCenterMarker {}
5369
5370impl PaintVarRotateAroundCenterMarker {
5371    pub fn format_byte_range(&self) -> Range<usize> {
5372        let start = 0;
5373        start..start + u8::RAW_BYTE_LEN
5374    }
5375
5376    pub fn paint_offset_byte_range(&self) -> Range<usize> {
5377        let start = self.format_byte_range().end;
5378        start..start + Offset24::RAW_BYTE_LEN
5379    }
5380
5381    pub fn angle_byte_range(&self) -> Range<usize> {
5382        let start = self.paint_offset_byte_range().end;
5383        start..start + F2Dot14::RAW_BYTE_LEN
5384    }
5385
5386    pub fn center_x_byte_range(&self) -> Range<usize> {
5387        let start = self.angle_byte_range().end;
5388        start..start + FWord::RAW_BYTE_LEN
5389    }
5390
5391    pub fn center_y_byte_range(&self) -> Range<usize> {
5392        let start = self.center_x_byte_range().end;
5393        start..start + FWord::RAW_BYTE_LEN
5394    }
5395
5396    pub fn var_index_base_byte_range(&self) -> Range<usize> {
5397        let start = self.center_y_byte_range().end;
5398        start..start + u32::RAW_BYTE_LEN
5399    }
5400}
5401
5402impl MinByteRange for PaintVarRotateAroundCenterMarker {
5403    fn min_byte_range(&self) -> Range<usize> {
5404        0..self.var_index_base_byte_range().end
5405    }
5406}
5407
5408impl<'a> FontRead<'a> for PaintVarRotateAroundCenter<'a> {
5409    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
5410        let mut cursor = data.cursor();
5411        cursor.advance::<u8>();
5412        cursor.advance::<Offset24>();
5413        cursor.advance::<F2Dot14>();
5414        cursor.advance::<FWord>();
5415        cursor.advance::<FWord>();
5416        cursor.advance::<u32>();
5417        cursor.finish(PaintVarRotateAroundCenterMarker {})
5418    }
5419}
5420
5421/// [PaintVarRotateAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table
5422pub type PaintVarRotateAroundCenter<'a> = TableRef<'a, PaintVarRotateAroundCenterMarker>;
5423
5424#[allow(clippy::needless_lifetimes)]
5425impl<'a> PaintVarRotateAroundCenter<'a> {
5426    /// Set to 27.
5427    pub fn format(&self) -> u8 {
5428        let range = self.shape.format_byte_range();
5429        self.data.read_at(range.start).unwrap()
5430    }
5431
5432    /// Offset to a Paint subtable.
5433    pub fn paint_offset(&self) -> Offset24 {
5434        let range = self.shape.paint_offset_byte_range();
5435        self.data.read_at(range.start).unwrap()
5436    }
5437
5438    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
5439    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
5440        let data = self.data;
5441        self.paint_offset().resolve(data)
5442    }
5443
5444    /// Rotation angle, 180° in counter-clockwise degrees per 1.0 of
5445    /// value. For variation, use varIndexBase + 0.
5446    pub fn angle(&self) -> F2Dot14 {
5447        let range = self.shape.angle_byte_range();
5448        self.data.read_at(range.start).unwrap()
5449    }
5450
5451    /// x coordinate for the center of rotation. For variation, use
5452    /// varIndexBase + 1.
5453    pub fn center_x(&self) -> FWord {
5454        let range = self.shape.center_x_byte_range();
5455        self.data.read_at(range.start).unwrap()
5456    }
5457
5458    /// y coordinate for the center of rotation. For variation, use
5459    /// varIndexBase + 2.
5460    pub fn center_y(&self) -> FWord {
5461        let range = self.shape.center_y_byte_range();
5462        self.data.read_at(range.start).unwrap()
5463    }
5464
5465    /// Base index into DeltaSetIndexMap.
5466    pub fn var_index_base(&self) -> u32 {
5467        let range = self.shape.var_index_base_byte_range();
5468        self.data.read_at(range.start).unwrap()
5469    }
5470}
5471
5472#[cfg(feature = "experimental_traverse")]
5473impl<'a> SomeTable<'a> for PaintVarRotateAroundCenter<'a> {
5474    fn type_name(&self) -> &str {
5475        "PaintVarRotateAroundCenter"
5476    }
5477    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
5478        match idx {
5479            0usize => Some(Field::new("format", self.format())),
5480            1usize => Some(Field::new(
5481                "paint_offset",
5482                FieldType::offset(self.paint_offset(), self.paint()),
5483            )),
5484            2usize => Some(Field::new("angle", self.angle())),
5485            3usize => Some(Field::new("center_x", self.center_x())),
5486            4usize => Some(Field::new("center_y", self.center_y())),
5487            5usize => Some(Field::new("var_index_base", self.var_index_base())),
5488            _ => None,
5489        }
5490    }
5491}
5492
5493#[cfg(feature = "experimental_traverse")]
5494#[allow(clippy::needless_lifetimes)]
5495impl<'a> std::fmt::Debug for PaintVarRotateAroundCenter<'a> {
5496    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5497        (self as &dyn SomeTable<'a>).fmt(f)
5498    }
5499}
5500
5501impl Format<u8> for PaintSkewMarker {
5502    const FORMAT: u8 = 28;
5503}
5504
5505/// [PaintSkew](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table
5506#[derive(Debug, Clone, Copy)]
5507#[doc(hidden)]
5508pub struct PaintSkewMarker {}
5509
5510impl PaintSkewMarker {
5511    pub fn format_byte_range(&self) -> Range<usize> {
5512        let start = 0;
5513        start..start + u8::RAW_BYTE_LEN
5514    }
5515
5516    pub fn paint_offset_byte_range(&self) -> Range<usize> {
5517        let start = self.format_byte_range().end;
5518        start..start + Offset24::RAW_BYTE_LEN
5519    }
5520
5521    pub fn x_skew_angle_byte_range(&self) -> Range<usize> {
5522        let start = self.paint_offset_byte_range().end;
5523        start..start + F2Dot14::RAW_BYTE_LEN
5524    }
5525
5526    pub fn y_skew_angle_byte_range(&self) -> Range<usize> {
5527        let start = self.x_skew_angle_byte_range().end;
5528        start..start + F2Dot14::RAW_BYTE_LEN
5529    }
5530}
5531
5532impl MinByteRange for PaintSkewMarker {
5533    fn min_byte_range(&self) -> Range<usize> {
5534        0..self.y_skew_angle_byte_range().end
5535    }
5536}
5537
5538impl<'a> FontRead<'a> for PaintSkew<'a> {
5539    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
5540        let mut cursor = data.cursor();
5541        cursor.advance::<u8>();
5542        cursor.advance::<Offset24>();
5543        cursor.advance::<F2Dot14>();
5544        cursor.advance::<F2Dot14>();
5545        cursor.finish(PaintSkewMarker {})
5546    }
5547}
5548
5549/// [PaintSkew](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table
5550pub type PaintSkew<'a> = TableRef<'a, PaintSkewMarker>;
5551
5552#[allow(clippy::needless_lifetimes)]
5553impl<'a> PaintSkew<'a> {
5554    /// Set to 28.
5555    pub fn format(&self) -> u8 {
5556        let range = self.shape.format_byte_range();
5557        self.data.read_at(range.start).unwrap()
5558    }
5559
5560    /// Offset to a Paint subtable.
5561    pub fn paint_offset(&self) -> Offset24 {
5562        let range = self.shape.paint_offset_byte_range();
5563        self.data.read_at(range.start).unwrap()
5564    }
5565
5566    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
5567    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
5568        let data = self.data;
5569        self.paint_offset().resolve(data)
5570    }
5571
5572    /// Angle of skew in the direction of the x-axis, 180° in
5573    /// counter-clockwise degrees per 1.0 of value.
5574    pub fn x_skew_angle(&self) -> F2Dot14 {
5575        let range = self.shape.x_skew_angle_byte_range();
5576        self.data.read_at(range.start).unwrap()
5577    }
5578
5579    /// Angle of skew in the direction of the y-axis, 180° in
5580    /// counter-clockwise degrees per 1.0 of value.
5581    pub fn y_skew_angle(&self) -> F2Dot14 {
5582        let range = self.shape.y_skew_angle_byte_range();
5583        self.data.read_at(range.start).unwrap()
5584    }
5585}
5586
5587#[cfg(feature = "experimental_traverse")]
5588impl<'a> SomeTable<'a> for PaintSkew<'a> {
5589    fn type_name(&self) -> &str {
5590        "PaintSkew"
5591    }
5592    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
5593        match idx {
5594            0usize => Some(Field::new("format", self.format())),
5595            1usize => Some(Field::new(
5596                "paint_offset",
5597                FieldType::offset(self.paint_offset(), self.paint()),
5598            )),
5599            2usize => Some(Field::new("x_skew_angle", self.x_skew_angle())),
5600            3usize => Some(Field::new("y_skew_angle", self.y_skew_angle())),
5601            _ => None,
5602        }
5603    }
5604}
5605
5606#[cfg(feature = "experimental_traverse")]
5607#[allow(clippy::needless_lifetimes)]
5608impl<'a> std::fmt::Debug for PaintSkew<'a> {
5609    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5610        (self as &dyn SomeTable<'a>).fmt(f)
5611    }
5612}
5613
5614impl Format<u8> for PaintVarSkewMarker {
5615    const FORMAT: u8 = 29;
5616}
5617
5618/// [PaintVarSkew](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table
5619#[derive(Debug, Clone, Copy)]
5620#[doc(hidden)]
5621pub struct PaintVarSkewMarker {}
5622
5623impl PaintVarSkewMarker {
5624    pub fn format_byte_range(&self) -> Range<usize> {
5625        let start = 0;
5626        start..start + u8::RAW_BYTE_LEN
5627    }
5628
5629    pub fn paint_offset_byte_range(&self) -> Range<usize> {
5630        let start = self.format_byte_range().end;
5631        start..start + Offset24::RAW_BYTE_LEN
5632    }
5633
5634    pub fn x_skew_angle_byte_range(&self) -> Range<usize> {
5635        let start = self.paint_offset_byte_range().end;
5636        start..start + F2Dot14::RAW_BYTE_LEN
5637    }
5638
5639    pub fn y_skew_angle_byte_range(&self) -> Range<usize> {
5640        let start = self.x_skew_angle_byte_range().end;
5641        start..start + F2Dot14::RAW_BYTE_LEN
5642    }
5643
5644    pub fn var_index_base_byte_range(&self) -> Range<usize> {
5645        let start = self.y_skew_angle_byte_range().end;
5646        start..start + u32::RAW_BYTE_LEN
5647    }
5648}
5649
5650impl MinByteRange for PaintVarSkewMarker {
5651    fn min_byte_range(&self) -> Range<usize> {
5652        0..self.var_index_base_byte_range().end
5653    }
5654}
5655
5656impl<'a> FontRead<'a> for PaintVarSkew<'a> {
5657    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
5658        let mut cursor = data.cursor();
5659        cursor.advance::<u8>();
5660        cursor.advance::<Offset24>();
5661        cursor.advance::<F2Dot14>();
5662        cursor.advance::<F2Dot14>();
5663        cursor.advance::<u32>();
5664        cursor.finish(PaintVarSkewMarker {})
5665    }
5666}
5667
5668/// [PaintVarSkew](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table
5669pub type PaintVarSkew<'a> = TableRef<'a, PaintVarSkewMarker>;
5670
5671#[allow(clippy::needless_lifetimes)]
5672impl<'a> PaintVarSkew<'a> {
5673    /// Set to 29.
5674    pub fn format(&self) -> u8 {
5675        let range = self.shape.format_byte_range();
5676        self.data.read_at(range.start).unwrap()
5677    }
5678
5679    /// Offset to a Paint subtable.
5680    pub fn paint_offset(&self) -> Offset24 {
5681        let range = self.shape.paint_offset_byte_range();
5682        self.data.read_at(range.start).unwrap()
5683    }
5684
5685    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
5686    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
5687        let data = self.data;
5688        self.paint_offset().resolve(data)
5689    }
5690
5691    /// Angle of skew in the direction of the x-axis, 180° ┬░ in
5692    /// counter-clockwise degrees per 1.0 of value. For variation, use
5693    /// varIndexBase + 0.
5694    pub fn x_skew_angle(&self) -> F2Dot14 {
5695        let range = self.shape.x_skew_angle_byte_range();
5696        self.data.read_at(range.start).unwrap()
5697    }
5698
5699    /// Angle of skew in the direction of the y-axis, 180° in
5700    /// counter-clockwise degrees per 1.0 of value. For variation, use
5701    /// varIndexBase + 1.
5702    pub fn y_skew_angle(&self) -> F2Dot14 {
5703        let range = self.shape.y_skew_angle_byte_range();
5704        self.data.read_at(range.start).unwrap()
5705    }
5706
5707    /// Base index into DeltaSetIndexMap.
5708    pub fn var_index_base(&self) -> u32 {
5709        let range = self.shape.var_index_base_byte_range();
5710        self.data.read_at(range.start).unwrap()
5711    }
5712}
5713
5714#[cfg(feature = "experimental_traverse")]
5715impl<'a> SomeTable<'a> for PaintVarSkew<'a> {
5716    fn type_name(&self) -> &str {
5717        "PaintVarSkew"
5718    }
5719    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
5720        match idx {
5721            0usize => Some(Field::new("format", self.format())),
5722            1usize => Some(Field::new(
5723                "paint_offset",
5724                FieldType::offset(self.paint_offset(), self.paint()),
5725            )),
5726            2usize => Some(Field::new("x_skew_angle", self.x_skew_angle())),
5727            3usize => Some(Field::new("y_skew_angle", self.y_skew_angle())),
5728            4usize => Some(Field::new("var_index_base", self.var_index_base())),
5729            _ => None,
5730        }
5731    }
5732}
5733
5734#[cfg(feature = "experimental_traverse")]
5735#[allow(clippy::needless_lifetimes)]
5736impl<'a> std::fmt::Debug for PaintVarSkew<'a> {
5737    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5738        (self as &dyn SomeTable<'a>).fmt(f)
5739    }
5740}
5741
5742impl Format<u8> for PaintSkewAroundCenterMarker {
5743    const FORMAT: u8 = 30;
5744}
5745
5746/// [PaintSkewAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table
5747#[derive(Debug, Clone, Copy)]
5748#[doc(hidden)]
5749pub struct PaintSkewAroundCenterMarker {}
5750
5751impl PaintSkewAroundCenterMarker {
5752    pub fn format_byte_range(&self) -> Range<usize> {
5753        let start = 0;
5754        start..start + u8::RAW_BYTE_LEN
5755    }
5756
5757    pub fn paint_offset_byte_range(&self) -> Range<usize> {
5758        let start = self.format_byte_range().end;
5759        start..start + Offset24::RAW_BYTE_LEN
5760    }
5761
5762    pub fn x_skew_angle_byte_range(&self) -> Range<usize> {
5763        let start = self.paint_offset_byte_range().end;
5764        start..start + F2Dot14::RAW_BYTE_LEN
5765    }
5766
5767    pub fn y_skew_angle_byte_range(&self) -> Range<usize> {
5768        let start = self.x_skew_angle_byte_range().end;
5769        start..start + F2Dot14::RAW_BYTE_LEN
5770    }
5771
5772    pub fn center_x_byte_range(&self) -> Range<usize> {
5773        let start = self.y_skew_angle_byte_range().end;
5774        start..start + FWord::RAW_BYTE_LEN
5775    }
5776
5777    pub fn center_y_byte_range(&self) -> Range<usize> {
5778        let start = self.center_x_byte_range().end;
5779        start..start + FWord::RAW_BYTE_LEN
5780    }
5781}
5782
5783impl MinByteRange for PaintSkewAroundCenterMarker {
5784    fn min_byte_range(&self) -> Range<usize> {
5785        0..self.center_y_byte_range().end
5786    }
5787}
5788
5789impl<'a> FontRead<'a> for PaintSkewAroundCenter<'a> {
5790    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
5791        let mut cursor = data.cursor();
5792        cursor.advance::<u8>();
5793        cursor.advance::<Offset24>();
5794        cursor.advance::<F2Dot14>();
5795        cursor.advance::<F2Dot14>();
5796        cursor.advance::<FWord>();
5797        cursor.advance::<FWord>();
5798        cursor.finish(PaintSkewAroundCenterMarker {})
5799    }
5800}
5801
5802/// [PaintSkewAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table
5803pub type PaintSkewAroundCenter<'a> = TableRef<'a, PaintSkewAroundCenterMarker>;
5804
5805#[allow(clippy::needless_lifetimes)]
5806impl<'a> PaintSkewAroundCenter<'a> {
5807    /// Set to 30.
5808    pub fn format(&self) -> u8 {
5809        let range = self.shape.format_byte_range();
5810        self.data.read_at(range.start).unwrap()
5811    }
5812
5813    /// Offset to a Paint subtable.
5814    pub fn paint_offset(&self) -> Offset24 {
5815        let range = self.shape.paint_offset_byte_range();
5816        self.data.read_at(range.start).unwrap()
5817    }
5818
5819    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
5820    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
5821        let data = self.data;
5822        self.paint_offset().resolve(data)
5823    }
5824
5825    /// Angle of skew in the direction of the x-axis, 180° in
5826    /// counter-clockwise degrees per 1.0 of value.
5827    pub fn x_skew_angle(&self) -> F2Dot14 {
5828        let range = self.shape.x_skew_angle_byte_range();
5829        self.data.read_at(range.start).unwrap()
5830    }
5831
5832    /// Angle of skew in the direction of the y-axis, 180° in
5833    /// counter-clockwise degrees per 1.0 of value.
5834    pub fn y_skew_angle(&self) -> F2Dot14 {
5835        let range = self.shape.y_skew_angle_byte_range();
5836        self.data.read_at(range.start).unwrap()
5837    }
5838
5839    /// x coordinate for the center of rotation.
5840    pub fn center_x(&self) -> FWord {
5841        let range = self.shape.center_x_byte_range();
5842        self.data.read_at(range.start).unwrap()
5843    }
5844
5845    /// y coordinate for the center of rotation.
5846    pub fn center_y(&self) -> FWord {
5847        let range = self.shape.center_y_byte_range();
5848        self.data.read_at(range.start).unwrap()
5849    }
5850}
5851
5852#[cfg(feature = "experimental_traverse")]
5853impl<'a> SomeTable<'a> for PaintSkewAroundCenter<'a> {
5854    fn type_name(&self) -> &str {
5855        "PaintSkewAroundCenter"
5856    }
5857    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
5858        match idx {
5859            0usize => Some(Field::new("format", self.format())),
5860            1usize => Some(Field::new(
5861                "paint_offset",
5862                FieldType::offset(self.paint_offset(), self.paint()),
5863            )),
5864            2usize => Some(Field::new("x_skew_angle", self.x_skew_angle())),
5865            3usize => Some(Field::new("y_skew_angle", self.y_skew_angle())),
5866            4usize => Some(Field::new("center_x", self.center_x())),
5867            5usize => Some(Field::new("center_y", self.center_y())),
5868            _ => None,
5869        }
5870    }
5871}
5872
5873#[cfg(feature = "experimental_traverse")]
5874#[allow(clippy::needless_lifetimes)]
5875impl<'a> std::fmt::Debug for PaintSkewAroundCenter<'a> {
5876    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5877        (self as &dyn SomeTable<'a>).fmt(f)
5878    }
5879}
5880
5881impl Format<u8> for PaintVarSkewAroundCenterMarker {
5882    const FORMAT: u8 = 31;
5883}
5884
5885/// [PaintVarSkewAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table
5886#[derive(Debug, Clone, Copy)]
5887#[doc(hidden)]
5888pub struct PaintVarSkewAroundCenterMarker {}
5889
5890impl PaintVarSkewAroundCenterMarker {
5891    pub fn format_byte_range(&self) -> Range<usize> {
5892        let start = 0;
5893        start..start + u8::RAW_BYTE_LEN
5894    }
5895
5896    pub fn paint_offset_byte_range(&self) -> Range<usize> {
5897        let start = self.format_byte_range().end;
5898        start..start + Offset24::RAW_BYTE_LEN
5899    }
5900
5901    pub fn x_skew_angle_byte_range(&self) -> Range<usize> {
5902        let start = self.paint_offset_byte_range().end;
5903        start..start + F2Dot14::RAW_BYTE_LEN
5904    }
5905
5906    pub fn y_skew_angle_byte_range(&self) -> Range<usize> {
5907        let start = self.x_skew_angle_byte_range().end;
5908        start..start + F2Dot14::RAW_BYTE_LEN
5909    }
5910
5911    pub fn center_x_byte_range(&self) -> Range<usize> {
5912        let start = self.y_skew_angle_byte_range().end;
5913        start..start + FWord::RAW_BYTE_LEN
5914    }
5915
5916    pub fn center_y_byte_range(&self) -> Range<usize> {
5917        let start = self.center_x_byte_range().end;
5918        start..start + FWord::RAW_BYTE_LEN
5919    }
5920
5921    pub fn var_index_base_byte_range(&self) -> Range<usize> {
5922        let start = self.center_y_byte_range().end;
5923        start..start + u32::RAW_BYTE_LEN
5924    }
5925}
5926
5927impl MinByteRange for PaintVarSkewAroundCenterMarker {
5928    fn min_byte_range(&self) -> Range<usize> {
5929        0..self.var_index_base_byte_range().end
5930    }
5931}
5932
5933impl<'a> FontRead<'a> for PaintVarSkewAroundCenter<'a> {
5934    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
5935        let mut cursor = data.cursor();
5936        cursor.advance::<u8>();
5937        cursor.advance::<Offset24>();
5938        cursor.advance::<F2Dot14>();
5939        cursor.advance::<F2Dot14>();
5940        cursor.advance::<FWord>();
5941        cursor.advance::<FWord>();
5942        cursor.advance::<u32>();
5943        cursor.finish(PaintVarSkewAroundCenterMarker {})
5944    }
5945}
5946
5947/// [PaintVarSkewAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table
5948pub type PaintVarSkewAroundCenter<'a> = TableRef<'a, PaintVarSkewAroundCenterMarker>;
5949
5950#[allow(clippy::needless_lifetimes)]
5951impl<'a> PaintVarSkewAroundCenter<'a> {
5952    /// Set to 31.
5953    pub fn format(&self) -> u8 {
5954        let range = self.shape.format_byte_range();
5955        self.data.read_at(range.start).unwrap()
5956    }
5957
5958    /// Offset to a Paint subtable.
5959    pub fn paint_offset(&self) -> Offset24 {
5960        let range = self.shape.paint_offset_byte_range();
5961        self.data.read_at(range.start).unwrap()
5962    }
5963
5964    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
5965    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
5966        let data = self.data;
5967        self.paint_offset().resolve(data)
5968    }
5969
5970    /// Angle of skew in the direction of the x-axis, 180° in
5971    /// counter-clockwise degrees per 1.0 of value. For variation, use
5972    /// varIndexBase + 0.
5973    pub fn x_skew_angle(&self) -> F2Dot14 {
5974        let range = self.shape.x_skew_angle_byte_range();
5975        self.data.read_at(range.start).unwrap()
5976    }
5977
5978    /// Angle of skew in the direction of the y-axis, 180° in
5979    /// counter-clockwise degrees per 1.0 of value. For variation, use
5980    /// varIndexBase + 1.
5981    pub fn y_skew_angle(&self) -> F2Dot14 {
5982        let range = self.shape.y_skew_angle_byte_range();
5983        self.data.read_at(range.start).unwrap()
5984    }
5985
5986    /// x coordinate for the center of rotation. For variation, use
5987    /// varIndexBase + 2.
5988    pub fn center_x(&self) -> FWord {
5989        let range = self.shape.center_x_byte_range();
5990        self.data.read_at(range.start).unwrap()
5991    }
5992
5993    /// y coordinate for the center of rotation. For variation, use
5994    /// varIndexBase + 3.
5995    pub fn center_y(&self) -> FWord {
5996        let range = self.shape.center_y_byte_range();
5997        self.data.read_at(range.start).unwrap()
5998    }
5999
6000    /// Base index into DeltaSetIndexMap.
6001    pub fn var_index_base(&self) -> u32 {
6002        let range = self.shape.var_index_base_byte_range();
6003        self.data.read_at(range.start).unwrap()
6004    }
6005}
6006
6007#[cfg(feature = "experimental_traverse")]
6008impl<'a> SomeTable<'a> for PaintVarSkewAroundCenter<'a> {
6009    fn type_name(&self) -> &str {
6010        "PaintVarSkewAroundCenter"
6011    }
6012    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
6013        match idx {
6014            0usize => Some(Field::new("format", self.format())),
6015            1usize => Some(Field::new(
6016                "paint_offset",
6017                FieldType::offset(self.paint_offset(), self.paint()),
6018            )),
6019            2usize => Some(Field::new("x_skew_angle", self.x_skew_angle())),
6020            3usize => Some(Field::new("y_skew_angle", self.y_skew_angle())),
6021            4usize => Some(Field::new("center_x", self.center_x())),
6022            5usize => Some(Field::new("center_y", self.center_y())),
6023            6usize => Some(Field::new("var_index_base", self.var_index_base())),
6024            _ => None,
6025        }
6026    }
6027}
6028
6029#[cfg(feature = "experimental_traverse")]
6030#[allow(clippy::needless_lifetimes)]
6031impl<'a> std::fmt::Debug for PaintVarSkewAroundCenter<'a> {
6032    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6033        (self as &dyn SomeTable<'a>).fmt(f)
6034    }
6035}
6036
6037impl Format<u8> for PaintCompositeMarker {
6038    const FORMAT: u8 = 32;
6039}
6040
6041/// [PaintComposite](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite) table
6042#[derive(Debug, Clone, Copy)]
6043#[doc(hidden)]
6044pub struct PaintCompositeMarker {}
6045
6046impl PaintCompositeMarker {
6047    pub fn format_byte_range(&self) -> Range<usize> {
6048        let start = 0;
6049        start..start + u8::RAW_BYTE_LEN
6050    }
6051
6052    pub fn source_paint_offset_byte_range(&self) -> Range<usize> {
6053        let start = self.format_byte_range().end;
6054        start..start + Offset24::RAW_BYTE_LEN
6055    }
6056
6057    pub fn composite_mode_byte_range(&self) -> Range<usize> {
6058        let start = self.source_paint_offset_byte_range().end;
6059        start..start + CompositeMode::RAW_BYTE_LEN
6060    }
6061
6062    pub fn backdrop_paint_offset_byte_range(&self) -> Range<usize> {
6063        let start = self.composite_mode_byte_range().end;
6064        start..start + Offset24::RAW_BYTE_LEN
6065    }
6066}
6067
6068impl MinByteRange for PaintCompositeMarker {
6069    fn min_byte_range(&self) -> Range<usize> {
6070        0..self.backdrop_paint_offset_byte_range().end
6071    }
6072}
6073
6074impl<'a> FontRead<'a> for PaintComposite<'a> {
6075    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
6076        let mut cursor = data.cursor();
6077        cursor.advance::<u8>();
6078        cursor.advance::<Offset24>();
6079        cursor.advance::<CompositeMode>();
6080        cursor.advance::<Offset24>();
6081        cursor.finish(PaintCompositeMarker {})
6082    }
6083}
6084
6085/// [PaintComposite](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite) table
6086pub type PaintComposite<'a> = TableRef<'a, PaintCompositeMarker>;
6087
6088#[allow(clippy::needless_lifetimes)]
6089impl<'a> PaintComposite<'a> {
6090    /// Set to 32.
6091    pub fn format(&self) -> u8 {
6092        let range = self.shape.format_byte_range();
6093        self.data.read_at(range.start).unwrap()
6094    }
6095
6096    /// Offset to a source Paint table.
6097    pub fn source_paint_offset(&self) -> Offset24 {
6098        let range = self.shape.source_paint_offset_byte_range();
6099        self.data.read_at(range.start).unwrap()
6100    }
6101
6102    /// Attempt to resolve [`source_paint_offset`][Self::source_paint_offset].
6103    pub fn source_paint(&self) -> Result<Paint<'a>, ReadError> {
6104        let data = self.data;
6105        self.source_paint_offset().resolve(data)
6106    }
6107
6108    /// A CompositeMode enumeration value.
6109    pub fn composite_mode(&self) -> CompositeMode {
6110        let range = self.shape.composite_mode_byte_range();
6111        self.data.read_at(range.start).unwrap()
6112    }
6113
6114    /// Offset to a backdrop Paint table.
6115    pub fn backdrop_paint_offset(&self) -> Offset24 {
6116        let range = self.shape.backdrop_paint_offset_byte_range();
6117        self.data.read_at(range.start).unwrap()
6118    }
6119
6120    /// Attempt to resolve [`backdrop_paint_offset`][Self::backdrop_paint_offset].
6121    pub fn backdrop_paint(&self) -> Result<Paint<'a>, ReadError> {
6122        let data = self.data;
6123        self.backdrop_paint_offset().resolve(data)
6124    }
6125}
6126
6127#[cfg(feature = "experimental_traverse")]
6128impl<'a> SomeTable<'a> for PaintComposite<'a> {
6129    fn type_name(&self) -> &str {
6130        "PaintComposite"
6131    }
6132    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
6133        match idx {
6134            0usize => Some(Field::new("format", self.format())),
6135            1usize => Some(Field::new(
6136                "source_paint_offset",
6137                FieldType::offset(self.source_paint_offset(), self.source_paint()),
6138            )),
6139            2usize => Some(Field::new("composite_mode", self.composite_mode())),
6140            3usize => Some(Field::new(
6141                "backdrop_paint_offset",
6142                FieldType::offset(self.backdrop_paint_offset(), self.backdrop_paint()),
6143            )),
6144            _ => None,
6145        }
6146    }
6147}
6148
6149#[cfg(feature = "experimental_traverse")]
6150#[allow(clippy::needless_lifetimes)]
6151impl<'a> std::fmt::Debug for PaintComposite<'a> {
6152    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6153        (self as &dyn SomeTable<'a>).fmt(f)
6154    }
6155}
6156
6157/// [CompositeMode](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite) enumeration
6158#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
6159#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6160#[repr(u8)]
6161#[allow(clippy::manual_non_exhaustive)]
6162pub enum CompositeMode {
6163    Clear = 0,
6164    Src = 1,
6165    Dest = 2,
6166    #[default]
6167    SrcOver = 3,
6168    DestOver = 4,
6169    SrcIn = 5,
6170    DestIn = 6,
6171    SrcOut = 7,
6172    DestOut = 8,
6173    SrcAtop = 9,
6174    DestAtop = 10,
6175    Xor = 11,
6176    Plus = 12,
6177    Screen = 13,
6178    Overlay = 14,
6179    Darken = 15,
6180    Lighten = 16,
6181    ColorDodge = 17,
6182    ColorBurn = 18,
6183    HardLight = 19,
6184    SoftLight = 20,
6185    Difference = 21,
6186    Exclusion = 22,
6187    Multiply = 23,
6188    HslHue = 24,
6189    HslSaturation = 25,
6190    HslColor = 26,
6191    HslLuminosity = 27,
6192    #[doc(hidden)]
6193    /// If font data is malformed we will map unknown values to this variant
6194    Unknown,
6195}
6196
6197impl CompositeMode {
6198    /// Create from a raw scalar.
6199    ///
6200    /// This will never fail; unknown values will be mapped to the `Unknown` variant
6201    pub fn new(raw: u8) -> Self {
6202        match raw {
6203            0 => Self::Clear,
6204            1 => Self::Src,
6205            2 => Self::Dest,
6206            3 => Self::SrcOver,
6207            4 => Self::DestOver,
6208            5 => Self::SrcIn,
6209            6 => Self::DestIn,
6210            7 => Self::SrcOut,
6211            8 => Self::DestOut,
6212            9 => Self::SrcAtop,
6213            10 => Self::DestAtop,
6214            11 => Self::Xor,
6215            12 => Self::Plus,
6216            13 => Self::Screen,
6217            14 => Self::Overlay,
6218            15 => Self::Darken,
6219            16 => Self::Lighten,
6220            17 => Self::ColorDodge,
6221            18 => Self::ColorBurn,
6222            19 => Self::HardLight,
6223            20 => Self::SoftLight,
6224            21 => Self::Difference,
6225            22 => Self::Exclusion,
6226            23 => Self::Multiply,
6227            24 => Self::HslHue,
6228            25 => Self::HslSaturation,
6229            26 => Self::HslColor,
6230            27 => Self::HslLuminosity,
6231            _ => Self::Unknown,
6232        }
6233    }
6234}
6235
6236impl font_types::Scalar for CompositeMode {
6237    type Raw = <u8 as font_types::Scalar>::Raw;
6238    fn to_raw(self) -> Self::Raw {
6239        (self as u8).to_raw()
6240    }
6241    fn from_raw(raw: Self::Raw) -> Self {
6242        let t = <u8>::from_raw(raw);
6243        Self::new(t)
6244    }
6245}
6246
6247#[cfg(feature = "experimental_traverse")]
6248impl<'a> From<CompositeMode> for FieldType<'a> {
6249    fn from(src: CompositeMode) -> FieldType<'a> {
6250        (src as u8).into()
6251    }
6252}