Coverage Report

Created: 2025-07-23 06:50

/src/fontations/read-fonts/generated/generated_colr.rs
Line
Count
Source (jump to first uncovered line)
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)]
6
use 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)]
11
pub 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
19
impl ColrMarker {
20
371M
    pub fn version_byte_range(&self) -> Range<usize> {
21
371M
        let start = 0;
22
371M
        start..start + u16::RAW_BYTE_LEN
23
371M
    }
24
25
371M
    pub fn num_base_glyph_records_byte_range(&self) -> Range<usize> {
26
371M
        let start = self.version_byte_range().end;
27
371M
        start..start + u16::RAW_BYTE_LEN
28
371M
    }
29
30
186M
    pub fn base_glyph_records_offset_byte_range(&self) -> Range<usize> {
31
186M
        let start = self.num_base_glyph_records_byte_range().end;
32
186M
        start..start + Offset32::RAW_BYTE_LEN
33
186M
    }
34
35
951k
    pub fn layer_records_offset_byte_range(&self) -> Range<usize> {
36
951k
        let start = self.base_glyph_records_offset_byte_range().end;
37
951k
        start..start + Offset32::RAW_BYTE_LEN
38
951k
    }
39
40
475k
    pub fn num_layer_records_byte_range(&self) -> Range<usize> {
41
475k
        let start = self.layer_records_offset_byte_range().end;
42
475k
        start..start + u16::RAW_BYTE_LEN
43
475k
    }
44
45
188M
    pub fn base_glyph_list_offset_byte_range(&self) -> Option<Range<usize>> {
46
188M
        let start = self.base_glyph_list_offset_byte_start?;
47
186M
        Some(start..start + Offset32::RAW_BYTE_LEN)
48
188M
    }
49
50
696k
    pub fn layer_list_offset_byte_range(&self) -> Option<Range<usize>> {
51
696k
        let start = self.layer_list_offset_byte_start?;
52
696k
        Some(start..start + Offset32::RAW_BYTE_LEN)
53
696k
    }
54
55
6.76M
    pub fn clip_list_offset_byte_range(&self) -> Option<Range<usize>> {
56
6.76M
        let start = self.clip_list_offset_byte_start?;
57
6.76M
        Some(start..start + Offset32::RAW_BYTE_LEN)
58
6.76M
    }
59
60
6.74M
    pub fn var_index_map_offset_byte_range(&self) -> Option<Range<usize>> {
61
6.74M
        let start = self.var_index_map_offset_byte_start?;
62
6.74M
        Some(start..start + Offset32::RAW_BYTE_LEN)
63
6.74M
    }
64
65
6.74M
    pub fn item_variation_store_offset_byte_range(&self) -> Option<Range<usize>> {
66
6.74M
        let start = self.item_variation_store_offset_byte_start?;
67
6.74M
        Some(start..start + Offset32::RAW_BYTE_LEN)
68
6.74M
    }
69
}
70
71
impl MinByteRange for ColrMarker {
72
0
    fn min_byte_range(&self) -> Range<usize> {
73
0
        0..self.num_layer_records_byte_range().end
74
0
    }
75
}
76
77
impl TopLevelTable for Colr<'_> {
78
    /// `COLR`
79
    const TAG: Tag = Tag::new(b"COLR");
80
}
81
82
impl<'a> FontRead<'a> for Colr<'a> {
83
67.6k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
84
67.6k
        let mut cursor = data.cursor();
85
67.6k
        let version: u16 = cursor.read()?;
86
67.2k
        cursor.advance::<u16>();
87
67.2k
        cursor.advance::<Offset32>();
88
67.2k
        cursor.advance::<Offset32>();
89
67.2k
        cursor.advance::<u16>();
90
67.2k
        let base_glyph_list_offset_byte_start = version
91
67.2k
            .compatible(1u16)
92
67.2k
            .then(|| cursor.position())
93
67.2k
            .transpose()?;
94
65.8k
        version
95
65.8k
            .compatible(1u16)
96
65.8k
            .then(|| cursor.advance::<Offset32>());
97
65.8k
        let layer_list_offset_byte_start = version
98
65.8k
            .compatible(1u16)
99
65.8k
            .then(|| cursor.position())
100
65.8k
            .transpose()?;
101
65.5k
        version
102
65.5k
            .compatible(1u16)
103
65.5k
            .then(|| cursor.advance::<Offset32>());
104
65.5k
        let clip_list_offset_byte_start = version
105
65.5k
            .compatible(1u16)
106
65.5k
            .then(|| cursor.position())
107
65.5k
            .transpose()?;
108
65.1k
        version
109
65.1k
            .compatible(1u16)
110
65.1k
            .then(|| cursor.advance::<Offset32>());
111
65.1k
        let var_index_map_offset_byte_start = version
112
65.1k
            .compatible(1u16)
113
65.1k
            .then(|| cursor.position())
114
65.1k
            .transpose()?;
115
64.8k
        version
116
64.8k
            .compatible(1u16)
117
64.8k
            .then(|| cursor.advance::<Offset32>());
118
64.8k
        let item_variation_store_offset_byte_start = version
119
64.8k
            .compatible(1u16)
120
64.8k
            .then(|| cursor.position())
121
64.8k
            .transpose()?;
122
64.4k
        version
123
64.4k
            .compatible(1u16)
124
64.4k
            .then(|| cursor.advance::<Offset32>());
125
64.4k
        cursor.finish(ColrMarker {
126
64.4k
            base_glyph_list_offset_byte_start,
127
64.4k
            layer_list_offset_byte_start,
128
64.4k
            clip_list_offset_byte_start,
129
64.4k
            var_index_map_offset_byte_start,
130
64.4k
            item_variation_store_offset_byte_start,
131
64.4k
        })
132
67.6k
    }
133
}
134
135
/// [COLR (Color)](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#colr-header) table
136
pub type Colr<'a> = TableRef<'a, ColrMarker>;
137
138
#[allow(clippy::needless_lifetimes)]
139
impl<'a> Colr<'a> {
140
    /// Table version number - set to 0 or 1.
141
0
    pub fn version(&self) -> u16 {
142
0
        let range = self.shape.version_byte_range();
143
0
        self.data.read_at(range.start).unwrap()
144
0
    }
145
146
    /// Number of BaseGlyph records; may be 0 in a version 1 table.
147
185M
    pub fn num_base_glyph_records(&self) -> u16 {
148
185M
        let range = self.shape.num_base_glyph_records_byte_range();
149
185M
        self.data.read_at(range.start).unwrap()
150
185M
    }
151
152
    /// Offset to baseGlyphRecords array (may be NULL).
153
185M
    pub fn base_glyph_records_offset(&self) -> Nullable<Offset32> {
154
185M
        let range = self.shape.base_glyph_records_offset_byte_range();
155
185M
        self.data.read_at(range.start).unwrap()
156
185M
    }
157
158
    /// Attempt to resolve [`base_glyph_records_offset`][Self::base_glyph_records_offset].
159
185M
    pub fn base_glyph_records(&self) -> Option<Result<&'a [BaseGlyph], ReadError>> {
160
185M
        let data = self.data;
161
185M
        let args = self.num_base_glyph_records();
162
185M
        self.base_glyph_records_offset()
163
185M
            .resolve_with_args(data, &args)
164
185M
    }
165
166
    /// Offset to layerRecords array (may be NULL).
167
475k
    pub fn layer_records_offset(&self) -> Nullable<Offset32> {
168
475k
        let range = self.shape.layer_records_offset_byte_range();
169
475k
        self.data.read_at(range.start).unwrap()
170
475k
    }
171
172
    /// Attempt to resolve [`layer_records_offset`][Self::layer_records_offset].
173
475k
    pub fn layer_records(&self) -> Option<Result<&'a [Layer], ReadError>> {
174
475k
        let data = self.data;
175
475k
        let args = self.num_layer_records();
176
475k
        self.layer_records_offset().resolve_with_args(data, &args)
177
475k
    }
178
179
    /// Number of Layer records; may be 0 in a version 1 table.
180
475k
    pub fn num_layer_records(&self) -> u16 {
181
475k
        let range = self.shape.num_layer_records_byte_range();
182
475k
        self.data.read_at(range.start).unwrap()
183
475k
    }
184
185
    /// Offset to BaseGlyphList table.
186
188M
    pub fn base_glyph_list_offset(&self) -> Option<Nullable<Offset32>> {
187
188M
        let range = self.shape.base_glyph_list_offset_byte_range()?;
188
186M
        Some(self.data.read_at(range.start).unwrap())
189
188M
    }
190
191
    /// Attempt to resolve [`base_glyph_list_offset`][Self::base_glyph_list_offset].
192
188M
    pub fn base_glyph_list(&self) -> Option<Result<BaseGlyphList<'a>, ReadError>> {
193
188M
        let data = self.data;
194
188M
        self.base_glyph_list_offset().map(|x| x.resolve(data))?
195
188M
    }
196
197
    /// Offset to LayerList table (may be NULL).
198
696k
    pub fn layer_list_offset(&self) -> Option<Nullable<Offset32>> {
199
696k
        let range = self.shape.layer_list_offset_byte_range()?;
200
696k
        Some(self.data.read_at(range.start).unwrap())
201
696k
    }
202
203
    /// Attempt to resolve [`layer_list_offset`][Self::layer_list_offset].
204
696k
    pub fn layer_list(&self) -> Option<Result<LayerList<'a>, ReadError>> {
205
696k
        let data = self.data;
206
696k
        self.layer_list_offset().map(|x| x.resolve(data))?
207
696k
    }
208
209
    /// Offset to ClipList table (may be NULL).
210
6.76M
    pub fn clip_list_offset(&self) -> Option<Nullable<Offset32>> {
211
6.76M
        let range = self.shape.clip_list_offset_byte_range()?;
212
6.76M
        Some(self.data.read_at(range.start).unwrap())
213
6.76M
    }
214
215
    /// Attempt to resolve [`clip_list_offset`][Self::clip_list_offset].
216
6.76M
    pub fn clip_list(&self) -> Option<Result<ClipList<'a>, ReadError>> {
217
6.76M
        let data = self.data;
218
6.76M
        self.clip_list_offset().map(|x| x.resolve(data))?
219
6.76M
    }
220
221
    /// Offset to DeltaSetIndexMap table (may be NULL).
222
6.74M
    pub fn var_index_map_offset(&self) -> Option<Nullable<Offset32>> {
223
6.74M
        let range = self.shape.var_index_map_offset_byte_range()?;
224
6.74M
        Some(self.data.read_at(range.start).unwrap())
225
6.74M
    }
226
227
    /// Attempt to resolve [`var_index_map_offset`][Self::var_index_map_offset].
228
6.74M
    pub fn var_index_map(&self) -> Option<Result<DeltaSetIndexMap<'a>, ReadError>> {
229
6.74M
        let data = self.data;
230
6.74M
        self.var_index_map_offset().map(|x| x.resolve(data))?
231
6.74M
    }
232
233
    /// Offset to ItemVariationStore (may be NULL).
234
6.74M
    pub fn item_variation_store_offset(&self) -> Option<Nullable<Offset32>> {
235
6.74M
        let range = self.shape.item_variation_store_offset_byte_range()?;
236
6.74M
        Some(self.data.read_at(range.start).unwrap())
237
6.74M
    }
238
239
    /// Attempt to resolve [`item_variation_store_offset`][Self::item_variation_store_offset].
240
6.74M
    pub fn item_variation_store(&self) -> Option<Result<ItemVariationStore<'a>, ReadError>> {
241
6.74M
        let data = self.data;
242
6.74M
        self.item_variation_store_offset()
243
6.74M
            .map(|x| x.resolve(data))?
244
6.74M
    }
245
}
246
247
#[cfg(feature = "experimental_traverse")]
248
impl<'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)]
312
impl<'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
0
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
320
#[repr(C)]
321
#[repr(packed)]
322
pub 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
331
impl BaseGlyph {
332
    /// Glyph ID of the base glyph.
333
66.3M
    pub fn glyph_id(&self) -> GlyphId16 {
334
66.3M
        self.glyph_id.get()
335
66.3M
    }
336
337
    /// Index (base 0) into the layerRecords array.
338
70.8k
    pub fn first_layer_index(&self) -> u16 {
339
70.8k
        self.first_layer_index.get()
340
70.8k
    }
341
342
    /// Number of color layers associated with this glyph.
343
70.8k
    pub fn num_layers(&self) -> u16 {
344
70.8k
        self.num_layers.get()
345
70.8k
    }
346
}
347
348
impl 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")]
353
impl<'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
0
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
370
#[repr(C)]
371
#[repr(packed)]
372
pub 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
379
impl Layer {
380
    /// Glyph ID of the glyph used for a given layer.
381
418k
    pub fn glyph_id(&self) -> GlyphId16 {
382
418k
        self.glyph_id.get()
383
418k
    }
384
385
    /// Index (base 0) for a palette entry in the CPAL table.
386
418k
    pub fn palette_index(&self) -> u16 {
387
418k
        self.palette_index.get()
388
418k
    }
389
}
390
391
impl FixedSize for Layer {
392
    const RAW_BYTE_LEN: usize = GlyphId16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
393
}
394
395
#[cfg(feature = "experimental_traverse")]
396
impl<'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)]
413
pub struct BaseGlyphListMarker {
414
    base_glyph_paint_records_byte_len: usize,
415
}
416
417
impl BaseGlyphListMarker {
418
154M
    pub fn num_base_glyph_paint_records_byte_range(&self) -> Range<usize> {
419
154M
        let start = 0;
420
154M
        start..start + u32::RAW_BYTE_LEN
421
154M
    }
422
423
154M
    pub fn base_glyph_paint_records_byte_range(&self) -> Range<usize> {
424
154M
        let start = self.num_base_glyph_paint_records_byte_range().end;
425
154M
        start..start + self.base_glyph_paint_records_byte_len
426
154M
    }
427
}
428
429
impl MinByteRange for BaseGlyphListMarker {
430
0
    fn min_byte_range(&self) -> Range<usize> {
431
0
        0..self.base_glyph_paint_records_byte_range().end
432
0
    }
433
}
434
435
impl<'a> FontRead<'a> for BaseGlyphList<'a> {
436
164M
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
437
164M
        let mut cursor = data.cursor();
438
164M
        let num_base_glyph_paint_records: u32 = cursor.read()?;
439
163M
        let base_glyph_paint_records_byte_len = (num_base_glyph_paint_records as usize)
440
163M
            .checked_mul(BaseGlyphPaint::RAW_BYTE_LEN)
441
163M
            .ok_or(ReadError::OutOfBounds)?;
442
163M
        cursor.advance_by(base_glyph_paint_records_byte_len);
443
163M
        cursor.finish(BaseGlyphListMarker {
444
163M
            base_glyph_paint_records_byte_len,
445
163M
        })
446
164M
    }
447
}
448
449
/// [BaseGlyphList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table
450
pub type BaseGlyphList<'a> = TableRef<'a, BaseGlyphListMarker>;
451
452
#[allow(clippy::needless_lifetimes)]
453
impl<'a> BaseGlyphList<'a> {
454
0
    pub fn num_base_glyph_paint_records(&self) -> u32 {
455
0
        let range = self.shape.num_base_glyph_paint_records_byte_range();
456
0
        self.data.read_at(range.start).unwrap()
457
0
    }
458
459
154M
    pub fn base_glyph_paint_records(&self) -> &'a [BaseGlyphPaint] {
460
154M
        let range = self.shape.base_glyph_paint_records_byte_range();
461
154M
        self.data.read_array(range).unwrap()
462
154M
    }
463
}
464
465
#[cfg(feature = "experimental_traverse")]
466
impl<'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)]
491
impl<'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
0
#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
499
#[repr(C)]
500
#[repr(packed)]
501
pub 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
508
impl BaseGlyphPaint {
509
    /// Glyph ID of the base glyph.
510
437M
    pub fn glyph_id(&self) -> GlyphId16 {
511
437M
        self.glyph_id.get()
512
437M
    }
513
514
    /// Offset to a Paint table, from the beginning of the [`BaseGlyphList`] table.
515
15.3M
    pub fn paint_offset(&self) -> Offset32 {
516
15.3M
        self.paint_offset.get()
517
15.3M
    }
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
7.69M
    pub fn paint<'a>(&self, data: FontData<'a>) -> Result<Paint<'a>, ReadError> {
524
7.69M
        self.paint_offset().resolve(data)
525
7.69M
    }
526
}
527
528
impl FixedSize for BaseGlyphPaint {
529
    const RAW_BYTE_LEN: usize = GlyphId16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN;
530
}
531
532
#[cfg(feature = "experimental_traverse")]
533
impl<'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)]
553
pub struct LayerListMarker {
554
    paint_offsets_byte_len: usize,
555
}
556
557
impl LayerListMarker {
558
556k
    pub fn num_layers_byte_range(&self) -> Range<usize> {
559
556k
        let start = 0;
560
556k
        start..start + u32::RAW_BYTE_LEN
561
556k
    }
562
563
556k
    pub fn paint_offsets_byte_range(&self) -> Range<usize> {
564
556k
        let start = self.num_layers_byte_range().end;
565
556k
        start..start + self.paint_offsets_byte_len
566
556k
    }
567
}
568
569
impl MinByteRange for LayerListMarker {
570
0
    fn min_byte_range(&self) -> Range<usize> {
571
0
        0..self.paint_offsets_byte_range().end
572
0
    }
573
}
574
575
impl<'a> FontRead<'a> for LayerList<'a> {
576
685k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
577
685k
        let mut cursor = data.cursor();
578
685k
        let num_layers: u32 = cursor.read()?;
579
684k
        let paint_offsets_byte_len = (num_layers as usize)
580
684k
            .checked_mul(Offset32::RAW_BYTE_LEN)
581
684k
            .ok_or(ReadError::OutOfBounds)?;
582
684k
        cursor.advance_by(paint_offsets_byte_len);
583
684k
        cursor.finish(LayerListMarker {
584
684k
            paint_offsets_byte_len,
585
684k
        })
586
685k
    }
587
}
588
589
/// [LayerList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table
590
pub type LayerList<'a> = TableRef<'a, LayerListMarker>;
591
592
#[allow(clippy::needless_lifetimes)]
593
impl<'a> LayerList<'a> {
594
0
    pub fn num_layers(&self) -> u32 {
595
0
        let range = self.shape.num_layers_byte_range();
596
0
        self.data.read_at(range.start).unwrap()
597
0
    }
598
599
    /// Offsets to Paint tables.
600
556k
    pub fn paint_offsets(&self) -> &'a [BigEndian<Offset32>] {
601
556k
        let range = self.shape.paint_offsets_byte_range();
602
556k
        self.data.read_array(range).unwrap()
603
556k
    }
604
605
    /// A dynamically resolving wrapper for [`paint_offsets`][Self::paint_offsets].
606
0
    pub fn paints(&self) -> ArrayOfOffsets<'a, Paint<'a>, Offset32> {
607
0
        let data = self.data;
608
0
        let offsets = self.paint_offsets();
609
0
        ArrayOfOffsets::new(offsets, data, ())
610
0
    }
611
}
612
613
#[cfg(feature = "experimental_traverse")]
614
impl<'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)]
642
impl<'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)]
651
pub struct ClipListMarker {
652
    clips_byte_len: usize,
653
}
654
655
impl ClipListMarker {
656
3.52M
    pub fn format_byte_range(&self) -> Range<usize> {
657
3.52M
        let start = 0;
658
3.52M
        start..start + u8::RAW_BYTE_LEN
659
3.52M
    }
660
661
3.52M
    pub fn num_clips_byte_range(&self) -> Range<usize> {
662
3.52M
        let start = self.format_byte_range().end;
663
3.52M
        start..start + u32::RAW_BYTE_LEN
664
3.52M
    }
665
666
3.52M
    pub fn clips_byte_range(&self) -> Range<usize> {
667
3.52M
        let start = self.num_clips_byte_range().end;
668
3.52M
        start..start + self.clips_byte_len
669
3.52M
    }
670
}
671
672
impl MinByteRange for ClipListMarker {
673
0
    fn min_byte_range(&self) -> Range<usize> {
674
0
        0..self.clips_byte_range().end
675
0
    }
676
}
677
678
impl<'a> FontRead<'a> for ClipList<'a> {
679
6.07M
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
680
6.07M
        let mut cursor = data.cursor();
681
6.07M
        cursor.advance::<u8>();
682
6.07M
        let num_clips: u32 = cursor.read()?;
683
6.07M
        let clips_byte_len = (num_clips as usize)
684
6.07M
            .checked_mul(Clip::RAW_BYTE_LEN)
685
6.07M
            .ok_or(ReadError::OutOfBounds)?;
686
6.07M
        cursor.advance_by(clips_byte_len);
687
6.07M
        cursor.finish(ClipListMarker { clips_byte_len })
688
6.07M
    }
689
}
690
691
/// [ClipList](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) table
692
pub type ClipList<'a> = TableRef<'a, ClipListMarker>;
693
694
#[allow(clippy::needless_lifetimes)]
695
impl<'a> ClipList<'a> {
696
    /// Set to 1.
697
0
    pub fn format(&self) -> u8 {
698
0
        let range = self.shape.format_byte_range();
699
0
        self.data.read_at(range.start).unwrap()
700
0
    }
701
702
    /// Number of Clip records.
703
0
    pub fn num_clips(&self) -> u32 {
704
0
        let range = self.shape.num_clips_byte_range();
705
0
        self.data.read_at(range.start).unwrap()
706
0
    }
707
708
    /// Clip records. Sorted by startGlyphID.
709
3.52M
    pub fn clips(&self) -> &'a [Clip] {
710
3.52M
        let range = self.shape.clips_byte_range();
711
3.52M
        self.data.read_array(range).unwrap()
712
3.52M
    }
713
}
714
715
#[cfg(feature = "experimental_traverse")]
716
impl<'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)]
739
impl<'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
0
#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
747
#[repr(C)]
748
#[repr(packed)]
749
pub 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
758
impl Clip {
759
    /// First glyph ID in the range.
760
7.47M
    pub fn start_glyph_id(&self) -> GlyphId16 {
761
7.47M
        self.start_glyph_id.get()
762
7.47M
    }
763
764
    /// Last glyph ID in the range.
765
3.43M
    pub fn end_glyph_id(&self) -> GlyphId16 {
766
3.43M
        self.end_glyph_id.get()
767
3.43M
    }
768
769
    /// Offset to a ClipBox table, from the beginning of the [`ClipList`] table.
770
1.79M
    pub fn clip_box_offset(&self) -> Offset24 {
771
1.79M
        self.clip_box_offset.get()
772
1.79M
    }
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
1.79M
    pub fn clip_box<'a>(&self, data: FontData<'a>) -> Result<ClipBox<'a>, ReadError> {
779
1.79M
        self.clip_box_offset().resolve(data)
780
1.79M
    }
781
}
782
783
impl 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")]
789
impl<'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)]
809
pub enum ClipBox<'a> {
810
    Format1(ClipBoxFormat1<'a>),
811
    Format2(ClipBoxFormat2<'a>),
812
}
813
814
impl<'a> ClipBox<'a> {
815
    ///Return the `FontData` used to resolve offsets for this table.
816
0
    pub fn offset_data(&self) -> FontData<'a> {
817
0
        match self {
818
0
            Self::Format1(item) => item.offset_data(),
819
0
            Self::Format2(item) => item.offset_data(),
820
        }
821
0
    }
822
823
    /// Set to 1.
824
0
    pub fn format(&self) -> u8 {
825
0
        match self {
826
0
            Self::Format1(item) => item.format(),
827
0
            Self::Format2(item) => item.format(),
828
        }
829
0
    }
830
831
    /// Minimum x of clip box.
832
0
    pub fn x_min(&self) -> FWord {
833
0
        match self {
834
0
            Self::Format1(item) => item.x_min(),
835
0
            Self::Format2(item) => item.x_min(),
836
        }
837
0
    }
838
839
    /// Minimum y of clip box.
840
0
    pub fn y_min(&self) -> FWord {
841
0
        match self {
842
0
            Self::Format1(item) => item.y_min(),
843
0
            Self::Format2(item) => item.y_min(),
844
        }
845
0
    }
846
847
    /// Maximum x of clip box.
848
0
    pub fn x_max(&self) -> FWord {
849
0
        match self {
850
0
            Self::Format1(item) => item.x_max(),
851
0
            Self::Format2(item) => item.x_max(),
852
        }
853
0
    }
854
855
    /// Maximum y of clip box.
856
0
    pub fn y_max(&self) -> FWord {
857
0
        match self {
858
0
            Self::Format1(item) => item.y_max(),
859
0
            Self::Format2(item) => item.y_max(),
860
        }
861
0
    }
862
}
863
864
impl<'a> FontRead<'a> for ClipBox<'a> {
865
1.63M
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
866
1.63M
        let format: u8 = data.read_at(0usize)?;
867
1.63M
        match format {
868
1.52M
            ClipBoxFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
869
105k
            ClipBoxFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
870
12.1k
            other => Err(ReadError::InvalidFormat(other.into())),
871
        }
872
1.63M
    }
873
}
874
875
impl MinByteRange for ClipBox<'_> {
876
0
    fn min_byte_range(&self) -> Range<usize> {
877
0
        match self {
878
0
            Self::Format1(item) => item.min_byte_range(),
879
0
            Self::Format2(item) => item.min_byte_range(),
880
        }
881
0
    }
882
}
883
884
#[cfg(feature = "experimental_traverse")]
885
impl<'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")]
895
impl 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")]
902
impl<'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
911
impl 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)]
918
pub struct ClipBoxFormat1Marker {}
919
920
impl ClipBoxFormat1Marker {
921
6.08M
    pub fn format_byte_range(&self) -> Range<usize> {
922
6.08M
        let start = 0;
923
6.08M
        start..start + u8::RAW_BYTE_LEN
924
6.08M
    }
925
926
6.08M
    pub fn x_min_byte_range(&self) -> Range<usize> {
927
6.08M
        let start = self.format_byte_range().end;
928
6.08M
        start..start + FWord::RAW_BYTE_LEN
929
6.08M
    }
930
931
4.56M
    pub fn y_min_byte_range(&self) -> Range<usize> {
932
4.56M
        let start = self.x_min_byte_range().end;
933
4.56M
        start..start + FWord::RAW_BYTE_LEN
934
4.56M
    }
935
936
3.04M
    pub fn x_max_byte_range(&self) -> Range<usize> {
937
3.04M
        let start = self.y_min_byte_range().end;
938
3.04M
        start..start + FWord::RAW_BYTE_LEN
939
3.04M
    }
940
941
1.52M
    pub fn y_max_byte_range(&self) -> Range<usize> {
942
1.52M
        let start = self.x_max_byte_range().end;
943
1.52M
        start..start + FWord::RAW_BYTE_LEN
944
1.52M
    }
945
}
946
947
impl MinByteRange for ClipBoxFormat1Marker {
948
0
    fn min_byte_range(&self) -> Range<usize> {
949
0
        0..self.y_max_byte_range().end
950
0
    }
951
}
952
953
impl<'a> FontRead<'a> for ClipBoxFormat1<'a> {
954
1.52M
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
955
1.52M
        let mut cursor = data.cursor();
956
1.52M
        cursor.advance::<u8>();
957
1.52M
        cursor.advance::<FWord>();
958
1.52M
        cursor.advance::<FWord>();
959
1.52M
        cursor.advance::<FWord>();
960
1.52M
        cursor.advance::<FWord>();
961
1.52M
        cursor.finish(ClipBoxFormat1Marker {})
962
1.52M
    }
963
}
964
965
/// [ClipBoxFormat1](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record
966
pub type ClipBoxFormat1<'a> = TableRef<'a, ClipBoxFormat1Marker>;
967
968
#[allow(clippy::needless_lifetimes)]
969
impl<'a> ClipBoxFormat1<'a> {
970
    /// Set to 1.
971
0
    pub fn format(&self) -> u8 {
972
0
        let range = self.shape.format_byte_range();
973
0
        self.data.read_at(range.start).unwrap()
974
0
    }
975
976
    /// Minimum x of clip box.
977
1.52M
    pub fn x_min(&self) -> FWord {
978
1.52M
        let range = self.shape.x_min_byte_range();
979
1.52M
        self.data.read_at(range.start).unwrap()
980
1.52M
    }
981
982
    /// Minimum y of clip box.
983
1.52M
    pub fn y_min(&self) -> FWord {
984
1.52M
        let range = self.shape.y_min_byte_range();
985
1.52M
        self.data.read_at(range.start).unwrap()
986
1.52M
    }
987
988
    /// Maximum x of clip box.
989
1.52M
    pub fn x_max(&self) -> FWord {
990
1.52M
        let range = self.shape.x_max_byte_range();
991
1.52M
        self.data.read_at(range.start).unwrap()
992
1.52M
    }
993
994
    /// Maximum y of clip box.
995
1.52M
    pub fn y_max(&self) -> FWord {
996
1.52M
        let range = self.shape.y_max_byte_range();
997
1.52M
        self.data.read_at(range.start).unwrap()
998
1.52M
    }
999
}
1000
1001
#[cfg(feature = "experimental_traverse")]
1002
impl<'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)]
1020
impl<'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
1026
impl 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)]
1033
pub struct ClipBoxFormat2Marker {}
1034
1035
impl ClipBoxFormat2Marker {
1036
518k
    pub fn format_byte_range(&self) -> Range<usize> {
1037
518k
        let start = 0;
1038
518k
        start..start + u8::RAW_BYTE_LEN
1039
518k
    }
1040
1041
518k
    pub fn x_min_byte_range(&self) -> Range<usize> {
1042
518k
        let start = self.format_byte_range().end;
1043
518k
        start..start + FWord::RAW_BYTE_LEN
1044
518k
    }
1045
1046
414k
    pub fn y_min_byte_range(&self) -> Range<usize> {
1047
414k
        let start = self.x_min_byte_range().end;
1048
414k
        start..start + FWord::RAW_BYTE_LEN
1049
414k
    }
1050
1051
311k
    pub fn x_max_byte_range(&self) -> Range<usize> {
1052
311k
        let start = self.y_min_byte_range().end;
1053
311k
        start..start + FWord::RAW_BYTE_LEN
1054
311k
    }
1055
1056
207k
    pub fn y_max_byte_range(&self) -> Range<usize> {
1057
207k
        let start = self.x_max_byte_range().end;
1058
207k
        start..start + FWord::RAW_BYTE_LEN
1059
207k
    }
1060
1061
103k
    pub fn var_index_base_byte_range(&self) -> Range<usize> {
1062
103k
        let start = self.y_max_byte_range().end;
1063
103k
        start..start + u32::RAW_BYTE_LEN
1064
103k
    }
1065
}
1066
1067
impl MinByteRange for ClipBoxFormat2Marker {
1068
0
    fn min_byte_range(&self) -> Range<usize> {
1069
0
        0..self.var_index_base_byte_range().end
1070
0
    }
1071
}
1072
1073
impl<'a> FontRead<'a> for ClipBoxFormat2<'a> {
1074
105k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1075
105k
        let mut cursor = data.cursor();
1076
105k
        cursor.advance::<u8>();
1077
105k
        cursor.advance::<FWord>();
1078
105k
        cursor.advance::<FWord>();
1079
105k
        cursor.advance::<FWord>();
1080
105k
        cursor.advance::<FWord>();
1081
105k
        cursor.advance::<u32>();
1082
105k
        cursor.finish(ClipBoxFormat2Marker {})
1083
105k
    }
1084
}
1085
1086
/// [ClipBoxFormat2](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record
1087
pub type ClipBoxFormat2<'a> = TableRef<'a, ClipBoxFormat2Marker>;
1088
1089
#[allow(clippy::needless_lifetimes)]
1090
impl<'a> ClipBoxFormat2<'a> {
1091
    /// Set to 2.
1092
0
    pub fn format(&self) -> u8 {
1093
0
        let range = self.shape.format_byte_range();
1094
0
        self.data.read_at(range.start).unwrap()
1095
0
    }
1096
1097
    /// Minimum x of clip box. For variation, use varIndexBase + 0.
1098
103k
    pub fn x_min(&self) -> FWord {
1099
103k
        let range = self.shape.x_min_byte_range();
1100
103k
        self.data.read_at(range.start).unwrap()
1101
103k
    }
1102
1103
    /// Minimum y of clip box. For variation, use varIndexBase + 1.
1104
103k
    pub fn y_min(&self) -> FWord {
1105
103k
        let range = self.shape.y_min_byte_range();
1106
103k
        self.data.read_at(range.start).unwrap()
1107
103k
    }
1108
1109
    /// Maximum x of clip box. For variation, use varIndexBase + 2.
1110
103k
    pub fn x_max(&self) -> FWord {
1111
103k
        let range = self.shape.x_max_byte_range();
1112
103k
        self.data.read_at(range.start).unwrap()
1113
103k
    }
1114
1115
    /// Maximum y of clip box. For variation, use varIndexBase + 3.
1116
103k
    pub fn y_max(&self) -> FWord {
1117
103k
        let range = self.shape.y_max_byte_range();
1118
103k
        self.data.read_at(range.start).unwrap()
1119
103k
    }
1120
1121
    /// Base index into DeltaSetIndexMap.
1122
103k
    pub fn var_index_base(&self) -> u32 {
1123
103k
        let range = self.shape.var_index_base_byte_range();
1124
103k
        self.data.read_at(range.start).unwrap()
1125
103k
    }
1126
}
1127
1128
#[cfg(feature = "experimental_traverse")]
1129
impl<'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)]
1148
impl<'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
0
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
1156
#[repr(C)]
1157
#[repr(packed)]
1158
pub 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
1165
impl ColorIndex {
1166
    /// Index for a CPAL palette entry.
1167
0
    pub fn palette_index(&self) -> u16 {
1168
0
        self.palette_index.get()
1169
0
    }
1170
1171
    /// Alpha value.
1172
0
    pub fn alpha(&self) -> F2Dot14 {
1173
0
        self.alpha.get()
1174
0
    }
1175
}
1176
1177
impl FixedSize for ColorIndex {
1178
    const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN;
1179
}
1180
1181
#[cfg(feature = "experimental_traverse")]
1182
impl<'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
0
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
1198
#[repr(C)]
1199
#[repr(packed)]
1200
pub 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
1209
impl VarColorIndex {
1210
    /// Index for a CPAL palette entry.
1211
0
    pub fn palette_index(&self) -> u16 {
1212
0
        self.palette_index.get()
1213
0
    }
1214
1215
    /// Alpha value. For variation, use varIndexBase + 0.
1216
0
    pub fn alpha(&self) -> F2Dot14 {
1217
0
        self.alpha.get()
1218
0
    }
1219
1220
    /// Base index into DeltaSetIndexMap.
1221
0
    pub fn var_index_base(&self) -> u32 {
1222
0
        self.var_index_base.get()
1223
0
    }
1224
}
1225
1226
impl 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")]
1231
impl<'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
0
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
1248
#[repr(C)]
1249
#[repr(packed)]
1250
pub 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
1259
impl ColorStop {
1260
    /// Position on a color line.
1261
44.8M
    pub fn stop_offset(&self) -> F2Dot14 {
1262
44.8M
        self.stop_offset.get()
1263
44.8M
    }
1264
1265
    /// Index for a CPAL palette entry.
1266
44.8M
    pub fn palette_index(&self) -> u16 {
1267
44.8M
        self.palette_index.get()
1268
44.8M
    }
1269
1270
    /// Alpha value.
1271
44.8M
    pub fn alpha(&self) -> F2Dot14 {
1272
44.8M
        self.alpha.get()
1273
44.8M
    }
1274
}
1275
1276
impl 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")]
1281
impl<'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
0
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check::assert_impl::<_>
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
Unexecuted instantiation: read_fonts::tables::colr::_::{closure#0}::check
1298
#[repr(C)]
1299
#[repr(packed)]
1300
pub 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
1311
impl VarColorStop {
1312
    /// Position on a color line. For variation, use varIndexBase + 0.
1313
34.6M
    pub fn stop_offset(&self) -> F2Dot14 {
1314
34.6M
        self.stop_offset.get()
1315
34.6M
    }
1316
1317
    /// Index for a CPAL palette entry.
1318
34.6M
    pub fn palette_index(&self) -> u16 {
1319
34.6M
        self.palette_index.get()
1320
34.6M
    }
1321
1322
    /// Alpha value. For variation, use varIndexBase + 1.
1323
34.6M
    pub fn alpha(&self) -> F2Dot14 {
1324
34.6M
        self.alpha.get()
1325
34.6M
    }
1326
1327
    /// Base index into DeltaSetIndexMap.
1328
34.6M
    pub fn var_index_base(&self) -> u32 {
1329
34.6M
        self.var_index_base.get()
1330
34.6M
    }
1331
}
1332
1333
impl 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")]
1339
impl<'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)]
1358
pub struct ColorLineMarker {
1359
    color_stops_byte_len: usize,
1360
}
1361
1362
impl ColorLineMarker {
1363
689k
    pub fn extend_byte_range(&self) -> Range<usize> {
1364
689k
        let start = 0;
1365
689k
        start..start + Extend::RAW_BYTE_LEN
1366
689k
    }
1367
1368
344k
    pub fn num_stops_byte_range(&self) -> Range<usize> {
1369
344k
        let start = self.extend_byte_range().end;
1370
344k
        start..start + u16::RAW_BYTE_LEN
1371
344k
    }
1372
1373
344k
    pub fn color_stops_byte_range(&self) -> Range<usize> {
1374
344k
        let start = self.num_stops_byte_range().end;
1375
344k
        start..start + self.color_stops_byte_len
1376
344k
    }
1377
}
1378
1379
impl MinByteRange for ColorLineMarker {
1380
0
    fn min_byte_range(&self) -> Range<usize> {
1381
0
        0..self.color_stops_byte_range().end
1382
0
    }
1383
}
1384
1385
impl<'a> FontRead<'a> for ColorLine<'a> {
1386
365k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1387
365k
        let mut cursor = data.cursor();
1388
365k
        cursor.advance::<Extend>();
1389
365k
        let num_stops: u16 = cursor.read()?;
1390
362k
        let color_stops_byte_len = (num_stops as usize)
1391
362k
            .checked_mul(ColorStop::RAW_BYTE_LEN)
1392
362k
            .ok_or(ReadError::OutOfBounds)?;
1393
362k
        cursor.advance_by(color_stops_byte_len);
1394
362k
        cursor.finish(ColorLineMarker {
1395
362k
            color_stops_byte_len,
1396
362k
        })
1397
365k
    }
1398
}
1399
1400
/// [ColorLine](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) table
1401
pub type ColorLine<'a> = TableRef<'a, ColorLineMarker>;
1402
1403
#[allow(clippy::needless_lifetimes)]
1404
impl<'a> ColorLine<'a> {
1405
    /// An Extend enum value.
1406
344k
    pub fn extend(&self) -> Extend {
1407
344k
        let range = self.shape.extend_byte_range();
1408
344k
        self.data.read_at(range.start).unwrap()
1409
344k
    }
1410
1411
    /// Number of ColorStop records.
1412
0
    pub fn num_stops(&self) -> u16 {
1413
0
        let range = self.shape.num_stops_byte_range();
1414
0
        self.data.read_at(range.start).unwrap()
1415
0
    }
1416
1417
344k
    pub fn color_stops(&self) -> &'a [ColorStop] {
1418
344k
        let range = self.shape.color_stops_byte_range();
1419
344k
        self.data.read_array(range).unwrap()
1420
344k
    }
1421
}
1422
1423
#[cfg(feature = "experimental_traverse")]
1424
impl<'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)]
1447
impl<'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)]
1456
pub struct VarColorLineMarker {
1457
    color_stops_byte_len: usize,
1458
}
1459
1460
impl VarColorLineMarker {
1461
1.21M
    pub fn extend_byte_range(&self) -> Range<usize> {
1462
1.21M
        let start = 0;
1463
1.21M
        start..start + Extend::RAW_BYTE_LEN
1464
1.21M
    }
1465
1466
606k
    pub fn num_stops_byte_range(&self) -> Range<usize> {
1467
606k
        let start = self.extend_byte_range().end;
1468
606k
        start..start + u16::RAW_BYTE_LEN
1469
606k
    }
1470
1471
606k
    pub fn color_stops_byte_range(&self) -> Range<usize> {
1472
606k
        let start = self.num_stops_byte_range().end;
1473
606k
        start..start + self.color_stops_byte_len
1474
606k
    }
1475
}
1476
1477
impl MinByteRange for VarColorLineMarker {
1478
0
    fn min_byte_range(&self) -> Range<usize> {
1479
0
        0..self.color_stops_byte_range().end
1480
0
    }
1481
}
1482
1483
impl<'a> FontRead<'a> for VarColorLine<'a> {
1484
736k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1485
736k
        let mut cursor = data.cursor();
1486
736k
        cursor.advance::<Extend>();
1487
736k
        let num_stops: u16 = cursor.read()?;
1488
733k
        let color_stops_byte_len = (num_stops as usize)
1489
733k
            .checked_mul(VarColorStop::RAW_BYTE_LEN)
1490
733k
            .ok_or(ReadError::OutOfBounds)?;
1491
733k
        cursor.advance_by(color_stops_byte_len);
1492
733k
        cursor.finish(VarColorLineMarker {
1493
733k
            color_stops_byte_len,
1494
733k
        })
1495
736k
    }
1496
}
1497
1498
/// [VarColorLine](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) table
1499
pub type VarColorLine<'a> = TableRef<'a, VarColorLineMarker>;
1500
1501
#[allow(clippy::needless_lifetimes)]
1502
impl<'a> VarColorLine<'a> {
1503
    /// An Extend enum value.
1504
606k
    pub fn extend(&self) -> Extend {
1505
606k
        let range = self.shape.extend_byte_range();
1506
606k
        self.data.read_at(range.start).unwrap()
1507
606k
    }
1508
1509
    /// Number of ColorStop records.
1510
0
    pub fn num_stops(&self) -> u16 {
1511
0
        let range = self.shape.num_stops_byte_range();
1512
0
        self.data.read_at(range.start).unwrap()
1513
0
    }
1514
1515
    /// Allows for variations.
1516
606k
    pub fn color_stops(&self) -> &'a [VarColorStop] {
1517
606k
        let range = self.shape.color_stops_byte_range();
1518
606k
        self.data.read_array(range).unwrap()
1519
606k
    }
1520
}
1521
1522
#[cfg(feature = "experimental_traverse")]
1523
impl<'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)]
1546
impl<'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)]
1557
pub 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
1567
impl Extend {
1568
    /// Create from a raw scalar.
1569
    ///
1570
    /// This will never fail; unknown values will be mapped to the `Unknown` variant
1571
951k
    pub fn new(raw: u8) -> Self {
1572
951k
        match raw {
1573
327k
            0 => Self::Pad,
1574
335k
            1 => Self::Repeat,
1575
174k
            2 => Self::Reflect,
1576
112k
            _ => Self::Unknown,
1577
        }
1578
951k
    }
1579
}
1580
1581
impl font_types::Scalar for Extend {
1582
    type Raw = <u8 as font_types::Scalar>::Raw;
1583
0
    fn to_raw(self) -> Self::Raw {
1584
0
        (self as u8).to_raw()
1585
0
    }
1586
951k
    fn from_raw(raw: Self::Raw) -> Self {
1587
951k
        let t = <u8>::from_raw(raw);
1588
951k
        Self::new(t)
1589
951k
    }
1590
}
1591
1592
#[cfg(feature = "experimental_traverse")]
1593
impl<'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)]
1601
pub 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
1636
impl<'a> Paint<'a> {
1637
    ///Return the `FontData` used to resolve offsets for this table.
1638
0
    pub fn offset_data(&self) -> FontData<'a> {
1639
0
        match self {
1640
0
            Self::ColrLayers(item) => item.offset_data(),
1641
0
            Self::Solid(item) => item.offset_data(),
1642
0
            Self::VarSolid(item) => item.offset_data(),
1643
0
            Self::LinearGradient(item) => item.offset_data(),
1644
0
            Self::VarLinearGradient(item) => item.offset_data(),
1645
0
            Self::RadialGradient(item) => item.offset_data(),
1646
0
            Self::VarRadialGradient(item) => item.offset_data(),
1647
0
            Self::SweepGradient(item) => item.offset_data(),
1648
0
            Self::VarSweepGradient(item) => item.offset_data(),
1649
0
            Self::Glyph(item) => item.offset_data(),
1650
0
            Self::ColrGlyph(item) => item.offset_data(),
1651
0
            Self::Transform(item) => item.offset_data(),
1652
0
            Self::VarTransform(item) => item.offset_data(),
1653
0
            Self::Translate(item) => item.offset_data(),
1654
0
            Self::VarTranslate(item) => item.offset_data(),
1655
0
            Self::Scale(item) => item.offset_data(),
1656
0
            Self::VarScale(item) => item.offset_data(),
1657
0
            Self::ScaleAroundCenter(item) => item.offset_data(),
1658
0
            Self::VarScaleAroundCenter(item) => item.offset_data(),
1659
0
            Self::ScaleUniform(item) => item.offset_data(),
1660
0
            Self::VarScaleUniform(item) => item.offset_data(),
1661
0
            Self::ScaleUniformAroundCenter(item) => item.offset_data(),
1662
0
            Self::VarScaleUniformAroundCenter(item) => item.offset_data(),
1663
0
            Self::Rotate(item) => item.offset_data(),
1664
0
            Self::VarRotate(item) => item.offset_data(),
1665
0
            Self::RotateAroundCenter(item) => item.offset_data(),
1666
0
            Self::VarRotateAroundCenter(item) => item.offset_data(),
1667
0
            Self::Skew(item) => item.offset_data(),
1668
0
            Self::VarSkew(item) => item.offset_data(),
1669
0
            Self::SkewAroundCenter(item) => item.offset_data(),
1670
0
            Self::VarSkewAroundCenter(item) => item.offset_data(),
1671
0
            Self::Composite(item) => item.offset_data(),
1672
        }
1673
0
    }
1674
1675
    /// Set to 1.
1676
0
    pub fn format(&self) -> u8 {
1677
0
        match self {
1678
0
            Self::ColrLayers(item) => item.format(),
1679
0
            Self::Solid(item) => item.format(),
1680
0
            Self::VarSolid(item) => item.format(),
1681
0
            Self::LinearGradient(item) => item.format(),
1682
0
            Self::VarLinearGradient(item) => item.format(),
1683
0
            Self::RadialGradient(item) => item.format(),
1684
0
            Self::VarRadialGradient(item) => item.format(),
1685
0
            Self::SweepGradient(item) => item.format(),
1686
0
            Self::VarSweepGradient(item) => item.format(),
1687
0
            Self::Glyph(item) => item.format(),
1688
0
            Self::ColrGlyph(item) => item.format(),
1689
0
            Self::Transform(item) => item.format(),
1690
0
            Self::VarTransform(item) => item.format(),
1691
0
            Self::Translate(item) => item.format(),
1692
0
            Self::VarTranslate(item) => item.format(),
1693
0
            Self::Scale(item) => item.format(),
1694
0
            Self::VarScale(item) => item.format(),
1695
0
            Self::ScaleAroundCenter(item) => item.format(),
1696
0
            Self::VarScaleAroundCenter(item) => item.format(),
1697
0
            Self::ScaleUniform(item) => item.format(),
1698
0
            Self::VarScaleUniform(item) => item.format(),
1699
0
            Self::ScaleUniformAroundCenter(item) => item.format(),
1700
0
            Self::VarScaleUniformAroundCenter(item) => item.format(),
1701
0
            Self::Rotate(item) => item.format(),
1702
0
            Self::VarRotate(item) => item.format(),
1703
0
            Self::RotateAroundCenter(item) => item.format(),
1704
0
            Self::VarRotateAroundCenter(item) => item.format(),
1705
0
            Self::Skew(item) => item.format(),
1706
0
            Self::VarSkew(item) => item.format(),
1707
0
            Self::SkewAroundCenter(item) => item.format(),
1708
0
            Self::VarSkewAroundCenter(item) => item.format(),
1709
0
            Self::Composite(item) => item.format(),
1710
        }
1711
0
    }
1712
}
1713
1714
impl<'a> FontRead<'a> for Paint<'a> {
1715
12.0M
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1716
12.0M
        let format: u8 = data.read_at(0usize)?;
1717
12.0M
        match format {
1718
485k
            PaintColrLayersMarker::FORMAT => Ok(Self::ColrLayers(FontRead::read(data)?)),
1719
1.14M
            PaintSolidMarker::FORMAT => Ok(Self::Solid(FontRead::read(data)?)),
1720
534k
            PaintVarSolidMarker::FORMAT => Ok(Self::VarSolid(FontRead::read(data)?)),
1721
295k
            PaintLinearGradientMarker::FORMAT => Ok(Self::LinearGradient(FontRead::read(data)?)),
1722
74.8k
            PaintVarLinearGradientMarker::FORMAT => {
1723
74.8k
                Ok(Self::VarLinearGradient(FontRead::read(data)?))
1724
            }
1725
98.3k
            PaintRadialGradientMarker::FORMAT => Ok(Self::RadialGradient(FontRead::read(data)?)),
1726
168k
            PaintVarRadialGradientMarker::FORMAT => {
1727
168k
                Ok(Self::VarRadialGradient(FontRead::read(data)?))
1728
            }
1729
127k
            PaintSweepGradientMarker::FORMAT => Ok(Self::SweepGradient(FontRead::read(data)?)),
1730
644k
            PaintVarSweepGradientMarker::FORMAT => {
1731
644k
                Ok(Self::VarSweepGradient(FontRead::read(data)?))
1732
            }
1733
2.10M
            PaintGlyphMarker::FORMAT => Ok(Self::Glyph(FontRead::read(data)?)),
1734
112k
            PaintColrGlyphMarker::FORMAT => Ok(Self::ColrGlyph(FontRead::read(data)?)),
1735
25.5k
            PaintTransformMarker::FORMAT => Ok(Self::Transform(FontRead::read(data)?)),
1736
61.5k
            PaintVarTransformMarker::FORMAT => Ok(Self::VarTransform(FontRead::read(data)?)),
1737
21.5k
            PaintTranslateMarker::FORMAT => Ok(Self::Translate(FontRead::read(data)?)),
1738
58.8k
            PaintVarTranslateMarker::FORMAT => Ok(Self::VarTranslate(FontRead::read(data)?)),
1739
19.7k
            PaintScaleMarker::FORMAT => Ok(Self::Scale(FontRead::read(data)?)),
1740
184k
            PaintVarScaleMarker::FORMAT => Ok(Self::VarScale(FontRead::read(data)?)),
1741
17.5k
            PaintScaleAroundCenterMarker::FORMAT => {
1742
17.5k
                Ok(Self::ScaleAroundCenter(FontRead::read(data)?))
1743
            }
1744
32.5k
            PaintVarScaleAroundCenterMarker::FORMAT => {
1745
32.5k
                Ok(Self::VarScaleAroundCenter(FontRead::read(data)?))
1746
            }
1747
30.3k
            PaintScaleUniformMarker::FORMAT => Ok(Self::ScaleUniform(FontRead::read(data)?)),
1748
30.4k
            PaintVarScaleUniformMarker::FORMAT => Ok(Self::VarScaleUniform(FontRead::read(data)?)),
1749
463k
            PaintScaleUniformAroundCenterMarker::FORMAT => {
1750
463k
                Ok(Self::ScaleUniformAroundCenter(FontRead::read(data)?))
1751
            }
1752
41.5k
            PaintVarScaleUniformAroundCenterMarker::FORMAT => {
1753
41.5k
                Ok(Self::VarScaleUniformAroundCenter(FontRead::read(data)?))
1754
            }
1755
93.7k
            PaintRotateMarker::FORMAT => Ok(Self::Rotate(FontRead::read(data)?)),
1756
25.1k
            PaintVarRotateMarker::FORMAT => Ok(Self::VarRotate(FontRead::read(data)?)),
1757
32.7k
            PaintRotateAroundCenterMarker::FORMAT => {
1758
32.7k
                Ok(Self::RotateAroundCenter(FontRead::read(data)?))
1759
            }
1760
48.9k
            PaintVarRotateAroundCenterMarker::FORMAT => {
1761
48.9k
                Ok(Self::VarRotateAroundCenter(FontRead::read(data)?))
1762
            }
1763
30.4k
            PaintSkewMarker::FORMAT => Ok(Self::Skew(FontRead::read(data)?)),
1764
48.1k
            PaintVarSkewMarker::FORMAT => Ok(Self::VarSkew(FontRead::read(data)?)),
1765
21.2k
            PaintSkewAroundCenterMarker::FORMAT => {
1766
21.2k
                Ok(Self::SkewAroundCenter(FontRead::read(data)?))
1767
            }
1768
51.4k
            PaintVarSkewAroundCenterMarker::FORMAT => {
1769
51.4k
                Ok(Self::VarSkewAroundCenter(FontRead::read(data)?))
1770
            }
1771
526k
            PaintCompositeMarker::FORMAT => Ok(Self::Composite(FontRead::read(data)?)),
1772
4.39M
            other => Err(ReadError::InvalidFormat(other.into())),
1773
        }
1774
12.0M
    }
1775
}
1776
1777
impl MinByteRange for Paint<'_> {
1778
0
    fn min_byte_range(&self) -> Range<usize> {
1779
0
        match self {
1780
0
            Self::ColrLayers(item) => item.min_byte_range(),
1781
0
            Self::Solid(item) => item.min_byte_range(),
1782
0
            Self::VarSolid(item) => item.min_byte_range(),
1783
0
            Self::LinearGradient(item) => item.min_byte_range(),
1784
0
            Self::VarLinearGradient(item) => item.min_byte_range(),
1785
0
            Self::RadialGradient(item) => item.min_byte_range(),
1786
0
            Self::VarRadialGradient(item) => item.min_byte_range(),
1787
0
            Self::SweepGradient(item) => item.min_byte_range(),
1788
0
            Self::VarSweepGradient(item) => item.min_byte_range(),
1789
0
            Self::Glyph(item) => item.min_byte_range(),
1790
0
            Self::ColrGlyph(item) => item.min_byte_range(),
1791
0
            Self::Transform(item) => item.min_byte_range(),
1792
0
            Self::VarTransform(item) => item.min_byte_range(),
1793
0
            Self::Translate(item) => item.min_byte_range(),
1794
0
            Self::VarTranslate(item) => item.min_byte_range(),
1795
0
            Self::Scale(item) => item.min_byte_range(),
1796
0
            Self::VarScale(item) => item.min_byte_range(),
1797
0
            Self::ScaleAroundCenter(item) => item.min_byte_range(),
1798
0
            Self::VarScaleAroundCenter(item) => item.min_byte_range(),
1799
0
            Self::ScaleUniform(item) => item.min_byte_range(),
1800
0
            Self::VarScaleUniform(item) => item.min_byte_range(),
1801
0
            Self::ScaleUniformAroundCenter(item) => item.min_byte_range(),
1802
0
            Self::VarScaleUniformAroundCenter(item) => item.min_byte_range(),
1803
0
            Self::Rotate(item) => item.min_byte_range(),
1804
0
            Self::VarRotate(item) => item.min_byte_range(),
1805
0
            Self::RotateAroundCenter(item) => item.min_byte_range(),
1806
0
            Self::VarRotateAroundCenter(item) => item.min_byte_range(),
1807
0
            Self::Skew(item) => item.min_byte_range(),
1808
0
            Self::VarSkew(item) => item.min_byte_range(),
1809
0
            Self::SkewAroundCenter(item) => item.min_byte_range(),
1810
0
            Self::VarSkewAroundCenter(item) => item.min_byte_range(),
1811
0
            Self::Composite(item) => item.min_byte_range(),
1812
        }
1813
0
    }
1814
}
1815
1816
#[cfg(feature = "experimental_traverse")]
1817
impl<'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")]
1857
impl 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")]
1864
impl<'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
1873
impl 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)]
1880
pub struct PaintColrLayersMarker {}
1881
1882
impl PaintColrLayersMarker {
1883
965k
    pub fn format_byte_range(&self) -> Range<usize> {
1884
965k
        let start = 0;
1885
965k
        start..start + u8::RAW_BYTE_LEN
1886
965k
    }
1887
1888
965k
    pub fn num_layers_byte_range(&self) -> Range<usize> {
1889
965k
        let start = self.format_byte_range().end;
1890
965k
        start..start + u8::RAW_BYTE_LEN
1891
965k
    }
1892
1893
482k
    pub fn first_layer_index_byte_range(&self) -> Range<usize> {
1894
482k
        let start = self.num_layers_byte_range().end;
1895
482k
        start..start + u32::RAW_BYTE_LEN
1896
482k
    }
1897
}
1898
1899
impl MinByteRange for PaintColrLayersMarker {
1900
0
    fn min_byte_range(&self) -> Range<usize> {
1901
0
        0..self.first_layer_index_byte_range().end
1902
0
    }
1903
}
1904
1905
impl<'a> FontRead<'a> for PaintColrLayers<'a> {
1906
485k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1907
485k
        let mut cursor = data.cursor();
1908
485k
        cursor.advance::<u8>();
1909
485k
        cursor.advance::<u8>();
1910
485k
        cursor.advance::<u32>();
1911
485k
        cursor.finish(PaintColrLayersMarker {})
1912
485k
    }
1913
}
1914
1915
/// [PaintColrLayers](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-1-paintcolrlayers) table
1916
pub type PaintColrLayers<'a> = TableRef<'a, PaintColrLayersMarker>;
1917
1918
#[allow(clippy::needless_lifetimes)]
1919
impl<'a> PaintColrLayers<'a> {
1920
    /// Set to 1.
1921
0
    pub fn format(&self) -> u8 {
1922
0
        let range = self.shape.format_byte_range();
1923
0
        self.data.read_at(range.start).unwrap()
1924
0
    }
1925
1926
    /// Number of offsets to paint tables to read from LayerList.
1927
482k
    pub fn num_layers(&self) -> u8 {
1928
482k
        let range = self.shape.num_layers_byte_range();
1929
482k
        self.data.read_at(range.start).unwrap()
1930
482k
    }
1931
1932
    /// Index (base 0) into the LayerList.
1933
482k
    pub fn first_layer_index(&self) -> u32 {
1934
482k
        let range = self.shape.first_layer_index_byte_range();
1935
482k
        self.data.read_at(range.start).unwrap()
1936
482k
    }
1937
}
1938
1939
#[cfg(feature = "experimental_traverse")]
1940
impl<'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)]
1956
impl<'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
1962
impl 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)]
1969
pub struct PaintSolidMarker {}
1970
1971
impl PaintSolidMarker {
1972
2.29M
    pub fn format_byte_range(&self) -> Range<usize> {
1973
2.29M
        let start = 0;
1974
2.29M
        start..start + u8::RAW_BYTE_LEN
1975
2.29M
    }
1976
1977
2.29M
    pub fn palette_index_byte_range(&self) -> Range<usize> {
1978
2.29M
        let start = self.format_byte_range().end;
1979
2.29M
        start..start + u16::RAW_BYTE_LEN
1980
2.29M
    }
1981
1982
1.14M
    pub fn alpha_byte_range(&self) -> Range<usize> {
1983
1.14M
        let start = self.palette_index_byte_range().end;
1984
1.14M
        start..start + F2Dot14::RAW_BYTE_LEN
1985
1.14M
    }
1986
}
1987
1988
impl MinByteRange for PaintSolidMarker {
1989
0
    fn min_byte_range(&self) -> Range<usize> {
1990
0
        0..self.alpha_byte_range().end
1991
0
    }
1992
}
1993
1994
impl<'a> FontRead<'a> for PaintSolid<'a> {
1995
1.14M
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1996
1.14M
        let mut cursor = data.cursor();
1997
1.14M
        cursor.advance::<u8>();
1998
1.14M
        cursor.advance::<u16>();
1999
1.14M
        cursor.advance::<F2Dot14>();
2000
1.14M
        cursor.finish(PaintSolidMarker {})
2001
1.14M
    }
2002
}
2003
2004
/// [PaintSolid](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-2-and-3-paintsolid-paintvarsolid) table
2005
pub type PaintSolid<'a> = TableRef<'a, PaintSolidMarker>;
2006
2007
#[allow(clippy::needless_lifetimes)]
2008
impl<'a> PaintSolid<'a> {
2009
    /// Set to 2.
2010
0
    pub fn format(&self) -> u8 {
2011
0
        let range = self.shape.format_byte_range();
2012
0
        self.data.read_at(range.start).unwrap()
2013
0
    }
2014
2015
    /// Index for a CPAL palette entry.
2016
1.14M
    pub fn palette_index(&self) -> u16 {
2017
1.14M
        let range = self.shape.palette_index_byte_range();
2018
1.14M
        self.data.read_at(range.start).unwrap()
2019
1.14M
    }
2020
2021
    /// Alpha value.
2022
1.14M
    pub fn alpha(&self) -> F2Dot14 {
2023
1.14M
        let range = self.shape.alpha_byte_range();
2024
1.14M
        self.data.read_at(range.start).unwrap()
2025
1.14M
    }
2026
}
2027
2028
#[cfg(feature = "experimental_traverse")]
2029
impl<'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)]
2045
impl<'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
2051
impl 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)]
2058
pub struct PaintVarSolidMarker {}
2059
2060
impl PaintVarSolidMarker {
2061
1.58M
    pub fn format_byte_range(&self) -> Range<usize> {
2062
1.58M
        let start = 0;
2063
1.58M
        start..start + u8::RAW_BYTE_LEN
2064
1.58M
    }
2065
2066
1.58M
    pub fn palette_index_byte_range(&self) -> Range<usize> {
2067
1.58M
        let start = self.format_byte_range().end;
2068
1.58M
        start..start + u16::RAW_BYTE_LEN
2069
1.58M
    }
2070
2071
1.05M
    pub fn alpha_byte_range(&self) -> Range<usize> {
2072
1.05M
        let start = self.palette_index_byte_range().end;
2073
1.05M
        start..start + F2Dot14::RAW_BYTE_LEN
2074
1.05M
    }
2075
2076
528k
    pub fn var_index_base_byte_range(&self) -> Range<usize> {
2077
528k
        let start = self.alpha_byte_range().end;
2078
528k
        start..start + u32::RAW_BYTE_LEN
2079
528k
    }
2080
}
2081
2082
impl MinByteRange for PaintVarSolidMarker {
2083
0
    fn min_byte_range(&self) -> Range<usize> {
2084
0
        0..self.var_index_base_byte_range().end
2085
0
    }
2086
}
2087
2088
impl<'a> FontRead<'a> for PaintVarSolid<'a> {
2089
534k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2090
534k
        let mut cursor = data.cursor();
2091
534k
        cursor.advance::<u8>();
2092
534k
        cursor.advance::<u16>();
2093
534k
        cursor.advance::<F2Dot14>();
2094
534k
        cursor.advance::<u32>();
2095
534k
        cursor.finish(PaintVarSolidMarker {})
2096
534k
    }
2097
}
2098
2099
/// [PaintVarSolid](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-2-and-3-paintsolid-paintvarsolid) table
2100
pub type PaintVarSolid<'a> = TableRef<'a, PaintVarSolidMarker>;
2101
2102
#[allow(clippy::needless_lifetimes)]
2103
impl<'a> PaintVarSolid<'a> {
2104
    /// Set to 3.
2105
0
    pub fn format(&self) -> u8 {
2106
0
        let range = self.shape.format_byte_range();
2107
0
        self.data.read_at(range.start).unwrap()
2108
0
    }
2109
2110
    /// Index for a CPAL palette entry.
2111
528k
    pub fn palette_index(&self) -> u16 {
2112
528k
        let range = self.shape.palette_index_byte_range();
2113
528k
        self.data.read_at(range.start).unwrap()
2114
528k
    }
2115
2116
    /// Alpha value. For variation, use varIndexBase + 0.
2117
528k
    pub fn alpha(&self) -> F2Dot14 {
2118
528k
        let range = self.shape.alpha_byte_range();
2119
528k
        self.data.read_at(range.start).unwrap()
2120
528k
    }
2121
2122
    /// Base index into DeltaSetIndexMap.
2123
528k
    pub fn var_index_base(&self) -> u32 {
2124
528k
        let range = self.shape.var_index_base_byte_range();
2125
528k
        self.data.read_at(range.start).unwrap()
2126
528k
    }
2127
}
2128
2129
#[cfg(feature = "experimental_traverse")]
2130
impl<'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)]
2147
impl<'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
2153
impl 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)]
2160
pub struct PaintLinearGradientMarker {}
2161
2162
impl PaintLinearGradientMarker {
2163
1.59M
    pub fn format_byte_range(&self) -> Range<usize> {
2164
1.59M
        let start = 0;
2165
1.59M
        start..start + u8::RAW_BYTE_LEN
2166
1.59M
    }
2167
2168
1.59M
    pub fn color_line_offset_byte_range(&self) -> Range<usize> {
2169
1.59M
        let start = self.format_byte_range().end;
2170
1.59M
        start..start + Offset24::RAW_BYTE_LEN
2171
1.59M
    }
2172
2173
1.30M
    pub fn x0_byte_range(&self) -> Range<usize> {
2174
1.30M
        let start = self.color_line_offset_byte_range().end;
2175
1.30M
        start..start + FWord::RAW_BYTE_LEN
2176
1.30M
    }
2177
2178
1.08M
    pub fn y0_byte_range(&self) -> Range<usize> {
2179
1.08M
        let start = self.x0_byte_range().end;
2180
1.08M
        start..start + FWord::RAW_BYTE_LEN
2181
1.08M
    }
2182
2183
871k
    pub fn x1_byte_range(&self) -> Range<usize> {
2184
871k
        let start = self.y0_byte_range().end;
2185
871k
        start..start + FWord::RAW_BYTE_LEN
2186
871k
    }
2187
2188
653k
    pub fn y1_byte_range(&self) -> Range<usize> {
2189
653k
        let start = self.x1_byte_range().end;
2190
653k
        start..start + FWord::RAW_BYTE_LEN
2191
653k
    }
2192
2193
435k
    pub fn x2_byte_range(&self) -> Range<usize> {
2194
435k
        let start = self.y1_byte_range().end;
2195
435k
        start..start + FWord::RAW_BYTE_LEN
2196
435k
    }
2197
2198
217k
    pub fn y2_byte_range(&self) -> Range<usize> {
2199
217k
        let start = self.x2_byte_range().end;
2200
217k
        start..start + FWord::RAW_BYTE_LEN
2201
217k
    }
2202
}
2203
2204
impl MinByteRange for PaintLinearGradientMarker {
2205
0
    fn min_byte_range(&self) -> Range<usize> {
2206
0
        0..self.y2_byte_range().end
2207
0
    }
2208
}
2209
2210
impl<'a> FontRead<'a> for PaintLinearGradient<'a> {
2211
295k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2212
295k
        let mut cursor = data.cursor();
2213
295k
        cursor.advance::<u8>();
2214
295k
        cursor.advance::<Offset24>();
2215
295k
        cursor.advance::<FWord>();
2216
295k
        cursor.advance::<FWord>();
2217
295k
        cursor.advance::<FWord>();
2218
295k
        cursor.advance::<FWord>();
2219
295k
        cursor.advance::<FWord>();
2220
295k
        cursor.advance::<FWord>();
2221
295k
        cursor.finish(PaintLinearGradientMarker {})
2222
295k
    }
2223
}
2224
2225
/// [PaintLinearGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-4-and-5-paintlineargradient-paintvarlineargradient) table
2226
pub type PaintLinearGradient<'a> = TableRef<'a, PaintLinearGradientMarker>;
2227
2228
#[allow(clippy::needless_lifetimes)]
2229
impl<'a> PaintLinearGradient<'a> {
2230
    /// Set to 4.
2231
0
    pub fn format(&self) -> u8 {
2232
0
        let range = self.shape.format_byte_range();
2233
0
        self.data.read_at(range.start).unwrap()
2234
0
    }
2235
2236
    /// Offset to ColorLine table.
2237
293k
    pub fn color_line_offset(&self) -> Offset24 {
2238
293k
        let range = self.shape.color_line_offset_byte_range();
2239
293k
        self.data.read_at(range.start).unwrap()
2240
293k
    }
2241
2242
    /// Attempt to resolve [`color_line_offset`][Self::color_line_offset].
2243
293k
    pub fn color_line(&self) -> Result<ColorLine<'a>, ReadError> {
2244
293k
        let data = self.data;
2245
293k
        self.color_line_offset().resolve(data)
2246
293k
    }
2247
2248
    /// Start point (p₀) x coordinate.
2249
217k
    pub fn x0(&self) -> FWord {
2250
217k
        let range = self.shape.x0_byte_range();
2251
217k
        self.data.read_at(range.start).unwrap()
2252
217k
    }
2253
2254
    /// Start point (p₀) y coordinate.
2255
217k
    pub fn y0(&self) -> FWord {
2256
217k
        let range = self.shape.y0_byte_range();
2257
217k
        self.data.read_at(range.start).unwrap()
2258
217k
    }
2259
2260
    /// End point (p₁) x coordinate.
2261
217k
    pub fn x1(&self) -> FWord {
2262
217k
        let range = self.shape.x1_byte_range();
2263
217k
        self.data.read_at(range.start).unwrap()
2264
217k
    }
2265
2266
    /// End point (p₁) y coordinate.
2267
217k
    pub fn y1(&self) -> FWord {
2268
217k
        let range = self.shape.y1_byte_range();
2269
217k
        self.data.read_at(range.start).unwrap()
2270
217k
    }
2271
2272
    /// Rotation point (p₂) x coordinate.
2273
217k
    pub fn x2(&self) -> FWord {
2274
217k
        let range = self.shape.x2_byte_range();
2275
217k
        self.data.read_at(range.start).unwrap()
2276
217k
    }
2277
2278
    /// Rotation point (p₂) y coordinate.
2279
217k
    pub fn y2(&self) -> FWord {
2280
217k
        let range = self.shape.y2_byte_range();
2281
217k
        self.data.read_at(range.start).unwrap()
2282
217k
    }
2283
}
2284
2285
#[cfg(feature = "experimental_traverse")]
2286
impl<'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)]
2310
impl<'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
2316
impl 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)]
2323
pub struct PaintVarLinearGradientMarker {}
2324
2325
impl PaintVarLinearGradientMarker {
2326
443k
    pub fn format_byte_range(&self) -> Range<usize> {
2327
443k
        let start = 0;
2328
443k
        start..start + u8::RAW_BYTE_LEN
2329
443k
    }
2330
2331
443k
    pub fn color_line_offset_byte_range(&self) -> Range<usize> {
2332
443k
        let start = self.format_byte_range().end;
2333
443k
        start..start + Offset24::RAW_BYTE_LEN
2334
443k
    }
2335
2336
369k
    pub fn x0_byte_range(&self) -> Range<usize> {
2337
369k
        let start = self.color_line_offset_byte_range().end;
2338
369k
        start..start + FWord::RAW_BYTE_LEN
2339
369k
    }
2340
2341
316k
    pub fn y0_byte_range(&self) -> Range<usize> {
2342
316k
        let start = self.x0_byte_range().end;
2343
316k
        start..start + FWord::RAW_BYTE_LEN
2344
316k
    }
2345
2346
263k
    pub fn x1_byte_range(&self) -> Range<usize> {
2347
263k
        let start = self.y0_byte_range().end;
2348
263k
        start..start + FWord::RAW_BYTE_LEN
2349
263k
    }
2350
2351
211k
    pub fn y1_byte_range(&self) -> Range<usize> {
2352
211k
        let start = self.x1_byte_range().end;
2353
211k
        start..start + FWord::RAW_BYTE_LEN
2354
211k
    }
2355
2356
158k
    pub fn x2_byte_range(&self) -> Range<usize> {
2357
158k
        let start = self.y1_byte_range().end;
2358
158k
        start..start + FWord::RAW_BYTE_LEN
2359
158k
    }
2360
2361
105k
    pub fn y2_byte_range(&self) -> Range<usize> {
2362
105k
        let start = self.x2_byte_range().end;
2363
105k
        start..start + FWord::RAW_BYTE_LEN
2364
105k
    }
2365
2366
52.7k
    pub fn var_index_base_byte_range(&self) -> Range<usize> {
2367
52.7k
        let start = self.y2_byte_range().end;
2368
52.7k
        start..start + u32::RAW_BYTE_LEN
2369
52.7k
    }
2370
}
2371
2372
impl MinByteRange for PaintVarLinearGradientMarker {
2373
0
    fn min_byte_range(&self) -> Range<usize> {
2374
0
        0..self.var_index_base_byte_range().end
2375
0
    }
2376
}
2377
2378
impl<'a> FontRead<'a> for PaintVarLinearGradient<'a> {
2379
74.8k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2380
74.8k
        let mut cursor = data.cursor();
2381
74.8k
        cursor.advance::<u8>();
2382
74.8k
        cursor.advance::<Offset24>();
2383
74.8k
        cursor.advance::<FWord>();
2384
74.8k
        cursor.advance::<FWord>();
2385
74.8k
        cursor.advance::<FWord>();
2386
74.8k
        cursor.advance::<FWord>();
2387
74.8k
        cursor.advance::<FWord>();
2388
74.8k
        cursor.advance::<FWord>();
2389
74.8k
        cursor.advance::<u32>();
2390
74.8k
        cursor.finish(PaintVarLinearGradientMarker {})
2391
74.8k
    }
2392
}
2393
2394
/// [PaintVarLinearGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-4-and-5-paintlineargradient-paintvarlineargradient) table
2395
pub type PaintVarLinearGradient<'a> = TableRef<'a, PaintVarLinearGradientMarker>;
2396
2397
#[allow(clippy::needless_lifetimes)]
2398
impl<'a> PaintVarLinearGradient<'a> {
2399
    /// Set to 5.
2400
0
    pub fn format(&self) -> u8 {
2401
0
        let range = self.shape.format_byte_range();
2402
0
        self.data.read_at(range.start).unwrap()
2403
0
    }
2404
2405
    /// Offset to VarColorLine table.
2406
73.8k
    pub fn color_line_offset(&self) -> Offset24 {
2407
73.8k
        let range = self.shape.color_line_offset_byte_range();
2408
73.8k
        self.data.read_at(range.start).unwrap()
2409
73.8k
    }
2410
2411
    /// Attempt to resolve [`color_line_offset`][Self::color_line_offset].
2412
73.8k
    pub fn color_line(&self) -> Result<VarColorLine<'a>, ReadError> {
2413
73.8k
        let data = self.data;
2414
73.8k
        self.color_line_offset().resolve(data)
2415
73.8k
    }
2416
2417
    /// Start point (p₀) x coordinate. For variation, use
2418
    /// varIndexBase + 0.
2419
52.7k
    pub fn x0(&self) -> FWord {
2420
52.7k
        let range = self.shape.x0_byte_range();
2421
52.7k
        self.data.read_at(range.start).unwrap()
2422
52.7k
    }
2423
2424
    /// Start point (p₀) y coordinate. For variation, use
2425
    /// varIndexBase + 1.
2426
52.7k
    pub fn y0(&self) -> FWord {
2427
52.7k
        let range = self.shape.y0_byte_range();
2428
52.7k
        self.data.read_at(range.start).unwrap()
2429
52.7k
    }
2430
2431
    /// End point (p₁) x coordinate. For variation, use varIndexBase
2432
    /// + 2.
2433
52.7k
    pub fn x1(&self) -> FWord {
2434
52.7k
        let range = self.shape.x1_byte_range();
2435
52.7k
        self.data.read_at(range.start).unwrap()
2436
52.7k
    }
2437
2438
    /// End point (p₁) y coordinate. For variation, use varIndexBase
2439
    /// + 3.
2440
52.7k
    pub fn y1(&self) -> FWord {
2441
52.7k
        let range = self.shape.y1_byte_range();
2442
52.7k
        self.data.read_at(range.start).unwrap()
2443
52.7k
    }
2444
2445
    /// Rotation point (p₂) x coordinate. For variation, use
2446
    /// varIndexBase + 4.
2447
52.7k
    pub fn x2(&self) -> FWord {
2448
52.7k
        let range = self.shape.x2_byte_range();
2449
52.7k
        self.data.read_at(range.start).unwrap()
2450
52.7k
    }
2451
2452
    /// Rotation point (p₂) y coordinate. For variation, use
2453
    /// varIndexBase + 5.
2454
52.7k
    pub fn y2(&self) -> FWord {
2455
52.7k
        let range = self.shape.y2_byte_range();
2456
52.7k
        self.data.read_at(range.start).unwrap()
2457
52.7k
    }
2458
2459
    /// Base index into DeltaSetIndexMap.
2460
52.7k
    pub fn var_index_base(&self) -> u32 {
2461
52.7k
        let range = self.shape.var_index_base_byte_range();
2462
52.7k
        self.data.read_at(range.start).unwrap()
2463
52.7k
    }
2464
}
2465
2466
#[cfg(feature = "experimental_traverse")]
2467
impl<'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)]
2492
impl<'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
2498
impl 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)]
2505
pub struct PaintRadialGradientMarker {}
2506
2507
impl PaintRadialGradientMarker {
2508
429k
    pub fn format_byte_range(&self) -> Range<usize> {
2509
429k
        let start = 0;
2510
429k
        start..start + u8::RAW_BYTE_LEN
2511
429k
    }
2512
2513
429k
    pub fn color_line_offset_byte_range(&self) -> Range<usize> {
2514
429k
        let start = self.format_byte_range().end;
2515
429k
        start..start + Offset24::RAW_BYTE_LEN
2516
429k
    }
2517
2518
332k
    pub fn x0_byte_range(&self) -> Range<usize> {
2519
332k
        let start = self.color_line_offset_byte_range().end;
2520
332k
        start..start + FWord::RAW_BYTE_LEN
2521
332k
    }
2522
2523
277k
    pub fn y0_byte_range(&self) -> Range<usize> {
2524
277k
        let start = self.x0_byte_range().end;
2525
277k
        start..start + FWord::RAW_BYTE_LEN
2526
277k
    }
2527
2528
221k
    pub fn radius0_byte_range(&self) -> Range<usize> {
2529
221k
        let start = self.y0_byte_range().end;
2530
221k
        start..start + UfWord::RAW_BYTE_LEN
2531
221k
    }
2532
2533
166k
    pub fn x1_byte_range(&self) -> Range<usize> {
2534
166k
        let start = self.radius0_byte_range().end;
2535
166k
        start..start + FWord::RAW_BYTE_LEN
2536
166k
    }
2537
2538
110k
    pub fn y1_byte_range(&self) -> Range<usize> {
2539
110k
        let start = self.x1_byte_range().end;
2540
110k
        start..start + FWord::RAW_BYTE_LEN
2541
110k
    }
2542
2543
55.4k
    pub fn radius1_byte_range(&self) -> Range<usize> {
2544
55.4k
        let start = self.y1_byte_range().end;
2545
55.4k
        start..start + UfWord::RAW_BYTE_LEN
2546
55.4k
    }
2547
}
2548
2549
impl MinByteRange for PaintRadialGradientMarker {
2550
0
    fn min_byte_range(&self) -> Range<usize> {
2551
0
        0..self.radius1_byte_range().end
2552
0
    }
2553
}
2554
2555
impl<'a> FontRead<'a> for PaintRadialGradient<'a> {
2556
98.3k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2557
98.3k
        let mut cursor = data.cursor();
2558
98.3k
        cursor.advance::<u8>();
2559
98.3k
        cursor.advance::<Offset24>();
2560
98.3k
        cursor.advance::<FWord>();
2561
98.3k
        cursor.advance::<FWord>();
2562
98.3k
        cursor.advance::<UfWord>();
2563
98.3k
        cursor.advance::<FWord>();
2564
98.3k
        cursor.advance::<FWord>();
2565
98.3k
        cursor.advance::<UfWord>();
2566
98.3k
        cursor.finish(PaintRadialGradientMarker {})
2567
98.3k
    }
2568
}
2569
2570
/// [PaintRadialGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-6-and-7-paintradialgradient-paintvarradialgradient) table
2571
pub type PaintRadialGradient<'a> = TableRef<'a, PaintRadialGradientMarker>;
2572
2573
#[allow(clippy::needless_lifetimes)]
2574
impl<'a> PaintRadialGradient<'a> {
2575
    /// Set to 6.
2576
0
    pub fn format(&self) -> u8 {
2577
0
        let range = self.shape.format_byte_range();
2578
0
        self.data.read_at(range.start).unwrap()
2579
0
    }
2580
2581
    /// Offset to ColorLine table.
2582
97.2k
    pub fn color_line_offset(&self) -> Offset24 {
2583
97.2k
        let range = self.shape.color_line_offset_byte_range();
2584
97.2k
        self.data.read_at(range.start).unwrap()
2585
97.2k
    }
2586
2587
    /// Attempt to resolve [`color_line_offset`][Self::color_line_offset].
2588
97.2k
    pub fn color_line(&self) -> Result<ColorLine<'a>, ReadError> {
2589
97.2k
        let data = self.data;
2590
97.2k
        self.color_line_offset().resolve(data)
2591
97.2k
    }
2592
2593
    /// Start circle center x coordinate.
2594
55.4k
    pub fn x0(&self) -> FWord {
2595
55.4k
        let range = self.shape.x0_byte_range();
2596
55.4k
        self.data.read_at(range.start).unwrap()
2597
55.4k
    }
2598
2599
    /// Start circle center y coordinate.
2600
55.4k
    pub fn y0(&self) -> FWord {
2601
55.4k
        let range = self.shape.y0_byte_range();
2602
55.4k
        self.data.read_at(range.start).unwrap()
2603
55.4k
    }
2604
2605
    /// Start circle radius.
2606
55.4k
    pub fn radius0(&self) -> UfWord {
2607
55.4k
        let range = self.shape.radius0_byte_range();
2608
55.4k
        self.data.read_at(range.start).unwrap()
2609
55.4k
    }
2610
2611
    /// End circle center x coordinate.
2612
55.4k
    pub fn x1(&self) -> FWord {
2613
55.4k
        let range = self.shape.x1_byte_range();
2614
55.4k
        self.data.read_at(range.start).unwrap()
2615
55.4k
    }
2616
2617
    /// End circle center y coordinate.
2618
55.4k
    pub fn y1(&self) -> FWord {
2619
55.4k
        let range = self.shape.y1_byte_range();
2620
55.4k
        self.data.read_at(range.start).unwrap()
2621
55.4k
    }
2622
2623
    /// End circle radius.
2624
55.4k
    pub fn radius1(&self) -> UfWord {
2625
55.4k
        let range = self.shape.radius1_byte_range();
2626
55.4k
        self.data.read_at(range.start).unwrap()
2627
55.4k
    }
2628
}
2629
2630
#[cfg(feature = "experimental_traverse")]
2631
impl<'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)]
2655
impl<'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
2661
impl 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)]
2668
pub struct PaintVarRadialGradientMarker {}
2669
2670
impl PaintVarRadialGradientMarker {
2671
869k
    pub fn format_byte_range(&self) -> Range<usize> {
2672
869k
        let start = 0;
2673
869k
        start..start + u8::RAW_BYTE_LEN
2674
869k
    }
2675
2676
869k
    pub fn color_line_offset_byte_range(&self) -> Range<usize> {
2677
869k
        let start = self.format_byte_range().end;
2678
869k
        start..start + Offset24::RAW_BYTE_LEN
2679
869k
    }
2680
2681
701k
    pub fn x0_byte_range(&self) -> Range<usize> {
2682
701k
        let start = self.color_line_offset_byte_range().end;
2683
701k
        start..start + FWord::RAW_BYTE_LEN
2684
701k
    }
2685
2686
601k
    pub fn y0_byte_range(&self) -> Range<usize> {
2687
601k
        let start = self.x0_byte_range().end;
2688
601k
        start..start + FWord::RAW_BYTE_LEN
2689
601k
    }
2690
2691
501k
    pub fn radius0_byte_range(&self) -> Range<usize> {
2692
501k
        let start = self.y0_byte_range().end;
2693
501k
        start..start + UfWord::RAW_BYTE_LEN
2694
501k
    }
2695
2696
401k
    pub fn x1_byte_range(&self) -> Range<usize> {
2697
401k
        let start = self.radius0_byte_range().end;
2698
401k
        start..start + FWord::RAW_BYTE_LEN
2699
401k
    }
2700
2701
300k
    pub fn y1_byte_range(&self) -> Range<usize> {
2702
300k
        let start = self.x1_byte_range().end;
2703
300k
        start..start + FWord::RAW_BYTE_LEN
2704
300k
    }
2705
2706
200k
    pub fn radius1_byte_range(&self) -> Range<usize> {
2707
200k
        let start = self.y1_byte_range().end;
2708
200k
        start..start + UfWord::RAW_BYTE_LEN
2709
200k
    }
2710
2711
100k
    pub fn var_index_base_byte_range(&self) -> Range<usize> {
2712
100k
        let start = self.radius1_byte_range().end;
2713
100k
        start..start + u32::RAW_BYTE_LEN
2714
100k
    }
2715
}
2716
2717
impl MinByteRange for PaintVarRadialGradientMarker {
2718
0
    fn min_byte_range(&self) -> Range<usize> {
2719
0
        0..self.var_index_base_byte_range().end
2720
0
    }
2721
}
2722
2723
impl<'a> FontRead<'a> for PaintVarRadialGradient<'a> {
2724
168k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2725
168k
        let mut cursor = data.cursor();
2726
168k
        cursor.advance::<u8>();
2727
168k
        cursor.advance::<Offset24>();
2728
168k
        cursor.advance::<FWord>();
2729
168k
        cursor.advance::<FWord>();
2730
168k
        cursor.advance::<UfWord>();
2731
168k
        cursor.advance::<FWord>();
2732
168k
        cursor.advance::<FWord>();
2733
168k
        cursor.advance::<UfWord>();
2734
168k
        cursor.advance::<u32>();
2735
168k
        cursor.finish(PaintVarRadialGradientMarker {})
2736
168k
    }
2737
}
2738
2739
/// [PaintVarRadialGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-6-and-7-paintradialgradient-paintvarradialgradient) table
2740
pub type PaintVarRadialGradient<'a> = TableRef<'a, PaintVarRadialGradientMarker>;
2741
2742
#[allow(clippy::needless_lifetimes)]
2743
impl<'a> PaintVarRadialGradient<'a> {
2744
    /// Set to 7.
2745
0
    pub fn format(&self) -> u8 {
2746
0
        let range = self.shape.format_byte_range();
2747
0
        self.data.read_at(range.start).unwrap()
2748
0
    }
2749
2750
    /// Offset to VarColorLine table.
2751
167k
    pub fn color_line_offset(&self) -> Offset24 {
2752
167k
        let range = self.shape.color_line_offset_byte_range();
2753
167k
        self.data.read_at(range.start).unwrap()
2754
167k
    }
2755
2756
    /// Attempt to resolve [`color_line_offset`][Self::color_line_offset].
2757
167k
    pub fn color_line(&self) -> Result<VarColorLine<'a>, ReadError> {
2758
167k
        let data = self.data;
2759
167k
        self.color_line_offset().resolve(data)
2760
167k
    }
2761
2762
    /// Start circle center x coordinate. For variation, use
2763
    /// varIndexBase + 0.
2764
100k
    pub fn x0(&self) -> FWord {
2765
100k
        let range = self.shape.x0_byte_range();
2766
100k
        self.data.read_at(range.start).unwrap()
2767
100k
    }
2768
2769
    /// Start circle center y coordinate. For variation, use
2770
    /// varIndexBase + 1.
2771
100k
    pub fn y0(&self) -> FWord {
2772
100k
        let range = self.shape.y0_byte_range();
2773
100k
        self.data.read_at(range.start).unwrap()
2774
100k
    }
2775
2776
    /// Start circle radius. For variation, use varIndexBase + 2.
2777
100k
    pub fn radius0(&self) -> UfWord {
2778
100k
        let range = self.shape.radius0_byte_range();
2779
100k
        self.data.read_at(range.start).unwrap()
2780
100k
    }
2781
2782
    /// End circle center x coordinate. For variation, use varIndexBase
2783
    /// + 3.
2784
100k
    pub fn x1(&self) -> FWord {
2785
100k
        let range = self.shape.x1_byte_range();
2786
100k
        self.data.read_at(range.start).unwrap()
2787
100k
    }
2788
2789
    /// End circle center y coordinate. For variation, use varIndexBase
2790
    /// + 4.
2791
100k
    pub fn y1(&self) -> FWord {
2792
100k
        let range = self.shape.y1_byte_range();
2793
100k
        self.data.read_at(range.start).unwrap()
2794
100k
    }
2795
2796
    /// End circle radius. For variation, use varIndexBase + 5.
2797
100k
    pub fn radius1(&self) -> UfWord {
2798
100k
        let range = self.shape.radius1_byte_range();
2799
100k
        self.data.read_at(range.start).unwrap()
2800
100k
    }
2801
2802
    /// Base index into DeltaSetIndexMap.
2803
100k
    pub fn var_index_base(&self) -> u32 {
2804
100k
        let range = self.shape.var_index_base_byte_range();
2805
100k
        self.data.read_at(range.start).unwrap()
2806
100k
    }
2807
}
2808
2809
#[cfg(feature = "experimental_traverse")]
2810
impl<'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)]
2835
impl<'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
2841
impl 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)]
2848
pub struct PaintSweepGradientMarker {}
2849
2850
impl PaintSweepGradientMarker {
2851
412k
    pub fn format_byte_range(&self) -> Range<usize> {
2852
412k
        let start = 0;
2853
412k
        start..start + u8::RAW_BYTE_LEN
2854
412k
    }
2855
2856
412k
    pub fn color_line_offset_byte_range(&self) -> Range<usize> {
2857
412k
        let start = self.format_byte_range().end;
2858
412k
        start..start + Offset24::RAW_BYTE_LEN
2859
412k
    }
2860
2861
285k
    pub fn center_x_byte_range(&self) -> Range<usize> {
2862
285k
        let start = self.color_line_offset_byte_range().end;
2863
285k
        start..start + FWord::RAW_BYTE_LEN
2864
285k
    }
2865
2866
214k
    pub fn center_y_byte_range(&self) -> Range<usize> {
2867
214k
        let start = self.center_x_byte_range().end;
2868
214k
        start..start + FWord::RAW_BYTE_LEN
2869
214k
    }
2870
2871
142k
    pub fn start_angle_byte_range(&self) -> Range<usize> {
2872
142k
        let start = self.center_y_byte_range().end;
2873
142k
        start..start + F2Dot14::RAW_BYTE_LEN
2874
142k
    }
2875
2876
71.4k
    pub fn end_angle_byte_range(&self) -> Range<usize> {
2877
71.4k
        let start = self.start_angle_byte_range().end;
2878
71.4k
        start..start + F2Dot14::RAW_BYTE_LEN
2879
71.4k
    }
2880
}
2881
2882
impl MinByteRange for PaintSweepGradientMarker {
2883
0
    fn min_byte_range(&self) -> Range<usize> {
2884
0
        0..self.end_angle_byte_range().end
2885
0
    }
2886
}
2887
2888
impl<'a> FontRead<'a> for PaintSweepGradient<'a> {
2889
127k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2890
127k
        let mut cursor = data.cursor();
2891
127k
        cursor.advance::<u8>();
2892
127k
        cursor.advance::<Offset24>();
2893
127k
        cursor.advance::<FWord>();
2894
127k
        cursor.advance::<FWord>();
2895
127k
        cursor.advance::<F2Dot14>();
2896
127k
        cursor.advance::<F2Dot14>();
2897
127k
        cursor.finish(PaintSweepGradientMarker {})
2898
127k
    }
2899
}
2900
2901
/// [PaintSweepGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-8-and-9-paintsweepgradient-paintvarsweepgradient) table
2902
pub type PaintSweepGradient<'a> = TableRef<'a, PaintSweepGradientMarker>;
2903
2904
#[allow(clippy::needless_lifetimes)]
2905
impl<'a> PaintSweepGradient<'a> {
2906
    /// Set to 8.
2907
0
    pub fn format(&self) -> u8 {
2908
0
        let range = self.shape.format_byte_range();
2909
0
        self.data.read_at(range.start).unwrap()
2910
0
    }
2911
2912
    /// Offset to ColorLine table.
2913
126k
    pub fn color_line_offset(&self) -> Offset24 {
2914
126k
        let range = self.shape.color_line_offset_byte_range();
2915
126k
        self.data.read_at(range.start).unwrap()
2916
126k
    }
2917
2918
    /// Attempt to resolve [`color_line_offset`][Self::color_line_offset].
2919
126k
    pub fn color_line(&self) -> Result<ColorLine<'a>, ReadError> {
2920
126k
        let data = self.data;
2921
126k
        self.color_line_offset().resolve(data)
2922
126k
    }
2923
2924
    /// Center x coordinate.
2925
71.4k
    pub fn center_x(&self) -> FWord {
2926
71.4k
        let range = self.shape.center_x_byte_range();
2927
71.4k
        self.data.read_at(range.start).unwrap()
2928
71.4k
    }
2929
2930
    /// Center y coordinate.
2931
71.4k
    pub fn center_y(&self) -> FWord {
2932
71.4k
        let range = self.shape.center_y_byte_range();
2933
71.4k
        self.data.read_at(range.start).unwrap()
2934
71.4k
    }
2935
2936
    /// Start of the angular range of the gradient, 180° in
2937
    /// counter-clockwise degrees per 1.0 of value.
2938
71.4k
    pub fn start_angle(&self) -> F2Dot14 {
2939
71.4k
        let range = self.shape.start_angle_byte_range();
2940
71.4k
        self.data.read_at(range.start).unwrap()
2941
71.4k
    }
2942
2943
    /// End of the angular range of the gradient, 180° in
2944
    /// counter-clockwise degrees per 1.0 of value.
2945
71.4k
    pub fn end_angle(&self) -> F2Dot14 {
2946
71.4k
        let range = self.shape.end_angle_byte_range();
2947
71.4k
        self.data.read_at(range.start).unwrap()
2948
71.4k
    }
2949
}
2950
2951
#[cfg(feature = "experimental_traverse")]
2952
impl<'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)]
2974
impl<'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
2980
impl 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)]
2987
pub struct PaintVarSweepGradientMarker {}
2988
2989
impl PaintVarSweepGradientMarker {
2990
2.91M
    pub fn format_byte_range(&self) -> Range<usize> {
2991
2.91M
        let start = 0;
2992
2.91M
        start..start + u8::RAW_BYTE_LEN
2993
2.91M
    }
2994
2995
2.91M
    pub fn color_line_offset_byte_range(&self) -> Range<usize> {
2996
2.91M
        let start = self.format_byte_range().end;
2997
2.91M
        start..start + Offset24::RAW_BYTE_LEN
2998
2.91M
    }
2999
3000
2.26M
    pub fn center_x_byte_range(&self) -> Range<usize> {
3001
2.26M
        let start = self.color_line_offset_byte_range().end;
3002
2.26M
        start..start + FWord::RAW_BYTE_LEN
3003
2.26M
    }
3004
3005
1.81M
    pub fn center_y_byte_range(&self) -> Range<usize> {
3006
1.81M
        let start = self.center_x_byte_range().end;
3007
1.81M
        start..start + FWord::RAW_BYTE_LEN
3008
1.81M
    }
3009
3010
1.36M
    pub fn start_angle_byte_range(&self) -> Range<usize> {
3011
1.36M
        let start = self.center_y_byte_range().end;
3012
1.36M
        start..start + F2Dot14::RAW_BYTE_LEN
3013
1.36M
    }
3014
3015
906k
    pub fn end_angle_byte_range(&self) -> Range<usize> {
3016
906k
        let start = self.start_angle_byte_range().end;
3017
906k
        start..start + F2Dot14::RAW_BYTE_LEN
3018
906k
    }
3019
3020
453k
    pub fn var_index_base_byte_range(&self) -> Range<usize> {
3021
453k
        let start = self.end_angle_byte_range().end;
3022
453k
        start..start + u32::RAW_BYTE_LEN
3023
453k
    }
3024
}
3025
3026
impl MinByteRange for PaintVarSweepGradientMarker {
3027
0
    fn min_byte_range(&self) -> Range<usize> {
3028
0
        0..self.var_index_base_byte_range().end
3029
0
    }
3030
}
3031
3032
impl<'a> FontRead<'a> for PaintVarSweepGradient<'a> {
3033
644k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3034
644k
        let mut cursor = data.cursor();
3035
644k
        cursor.advance::<u8>();
3036
644k
        cursor.advance::<Offset24>();
3037
644k
        cursor.advance::<FWord>();
3038
644k
        cursor.advance::<FWord>();
3039
644k
        cursor.advance::<F2Dot14>();
3040
644k
        cursor.advance::<F2Dot14>();
3041
644k
        cursor.advance::<u32>();
3042
644k
        cursor.finish(PaintVarSweepGradientMarker {})
3043
644k
    }
3044
}
3045
3046
/// [PaintVarSweepGradient](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-8-and-9-paintsweepgradient-paintvarsweepgradient) table
3047
pub type PaintVarSweepGradient<'a> = TableRef<'a, PaintVarSweepGradientMarker>;
3048
3049
#[allow(clippy::needless_lifetimes)]
3050
impl<'a> PaintVarSweepGradient<'a> {
3051
    /// Set to 9.
3052
0
    pub fn format(&self) -> u8 {
3053
0
        let range = self.shape.format_byte_range();
3054
0
        self.data.read_at(range.start).unwrap()
3055
0
    }
3056
3057
    /// Offset to VarColorLine table.
3058
643k
    pub fn color_line_offset(&self) -> Offset24 {
3059
643k
        let range = self.shape.color_line_offset_byte_range();
3060
643k
        self.data.read_at(range.start).unwrap()
3061
643k
    }
3062
3063
    /// Attempt to resolve [`color_line_offset`][Self::color_line_offset].
3064
643k
    pub fn color_line(&self) -> Result<VarColorLine<'a>, ReadError> {
3065
643k
        let data = self.data;
3066
643k
        self.color_line_offset().resolve(data)
3067
643k
    }
3068
3069
    /// Center x coordinate. For variation, use varIndexBase + 0.
3070
453k
    pub fn center_x(&self) -> FWord {
3071
453k
        let range = self.shape.center_x_byte_range();
3072
453k
        self.data.read_at(range.start).unwrap()
3073
453k
    }
3074
3075
    /// Center y coordinate. For variation, use varIndexBase + 1.
3076
453k
    pub fn center_y(&self) -> FWord {
3077
453k
        let range = self.shape.center_y_byte_range();
3078
453k
        self.data.read_at(range.start).unwrap()
3079
453k
    }
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
453k
    pub fn start_angle(&self) -> F2Dot14 {
3085
453k
        let range = self.shape.start_angle_byte_range();
3086
453k
        self.data.read_at(range.start).unwrap()
3087
453k
    }
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
453k
    pub fn end_angle(&self) -> F2Dot14 {
3093
453k
        let range = self.shape.end_angle_byte_range();
3094
453k
        self.data.read_at(range.start).unwrap()
3095
453k
    }
3096
3097
    /// Base index into DeltaSetIndexMap.
3098
453k
    pub fn var_index_base(&self) -> u32 {
3099
453k
        let range = self.shape.var_index_base_byte_range();
3100
453k
        self.data.read_at(range.start).unwrap()
3101
453k
    }
3102
}
3103
3104
#[cfg(feature = "experimental_traverse")]
3105
impl<'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)]
3128
impl<'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
3134
impl 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)]
3141
pub struct PaintGlyphMarker {}
3142
3143
impl PaintGlyphMarker {
3144
4.22M
    pub fn format_byte_range(&self) -> Range<usize> {
3145
4.22M
        let start = 0;
3146
4.22M
        start..start + u8::RAW_BYTE_LEN
3147
4.22M
    }
3148
3149
4.22M
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
3150
4.22M
        let start = self.format_byte_range().end;
3151
4.22M
        start..start + Offset24::RAW_BYTE_LEN
3152
4.22M
    }
3153
3154
2.11M
    pub fn glyph_id_byte_range(&self) -> Range<usize> {
3155
2.11M
        let start = self.paint_offset_byte_range().end;
3156
2.11M
        start..start + GlyphId16::RAW_BYTE_LEN
3157
2.11M
    }
3158
}
3159
3160
impl MinByteRange for PaintGlyphMarker {
3161
0
    fn min_byte_range(&self) -> Range<usize> {
3162
0
        0..self.glyph_id_byte_range().end
3163
0
    }
3164
}
3165
3166
impl<'a> FontRead<'a> for PaintGlyph<'a> {
3167
2.10M
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3168
2.10M
        let mut cursor = data.cursor();
3169
2.10M
        cursor.advance::<u8>();
3170
2.10M
        cursor.advance::<Offset24>();
3171
2.10M
        cursor.advance::<GlyphId16>();
3172
2.10M
        cursor.finish(PaintGlyphMarker {})
3173
2.10M
    }
3174
}
3175
3176
/// [PaintGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-10-paintglyph) table
3177
pub type PaintGlyph<'a> = TableRef<'a, PaintGlyphMarker>;
3178
3179
#[allow(clippy::needless_lifetimes)]
3180
impl<'a> PaintGlyph<'a> {
3181
    /// Set to 10.
3182
0
    pub fn format(&self) -> u8 {
3183
0
        let range = self.shape.format_byte_range();
3184
0
        self.data.read_at(range.start).unwrap()
3185
0
    }
3186
3187
    /// Offset to a Paint table.
3188
2.11M
    pub fn paint_offset(&self) -> Offset24 {
3189
2.11M
        let range = self.shape.paint_offset_byte_range();
3190
2.11M
        self.data.read_at(range.start).unwrap()
3191
2.11M
    }
3192
3193
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
3194
2.11M
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
3195
2.11M
        let data = self.data;
3196
2.11M
        self.paint_offset().resolve(data)
3197
2.11M
    }
3198
3199
    /// Glyph ID for the source outline.
3200
2.11M
    pub fn glyph_id(&self) -> GlyphId16 {
3201
2.11M
        let range = self.shape.glyph_id_byte_range();
3202
2.11M
        self.data.read_at(range.start).unwrap()
3203
2.11M
    }
3204
}
3205
3206
#[cfg(feature = "experimental_traverse")]
3207
impl<'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)]
3226
impl<'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
3232
impl 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)]
3239
pub struct PaintColrGlyphMarker {}
3240
3241
impl PaintColrGlyphMarker {
3242
109k
    pub fn format_byte_range(&self) -> Range<usize> {
3243
109k
        let start = 0;
3244
109k
        start..start + u8::RAW_BYTE_LEN
3245
109k
    }
3246
3247
109k
    pub fn glyph_id_byte_range(&self) -> Range<usize> {
3248
109k
        let start = self.format_byte_range().end;
3249
109k
        start..start + GlyphId16::RAW_BYTE_LEN
3250
109k
    }
3251
}
3252
3253
impl MinByteRange for PaintColrGlyphMarker {
3254
0
    fn min_byte_range(&self) -> Range<usize> {
3255
0
        0..self.glyph_id_byte_range().end
3256
0
    }
3257
}
3258
3259
impl<'a> FontRead<'a> for PaintColrGlyph<'a> {
3260
112k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3261
112k
        let mut cursor = data.cursor();
3262
112k
        cursor.advance::<u8>();
3263
112k
        cursor.advance::<GlyphId16>();
3264
112k
        cursor.finish(PaintColrGlyphMarker {})
3265
112k
    }
3266
}
3267
3268
/// [PaintColrGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-11-paintcolrglyph) table
3269
pub type PaintColrGlyph<'a> = TableRef<'a, PaintColrGlyphMarker>;
3270
3271
#[allow(clippy::needless_lifetimes)]
3272
impl<'a> PaintColrGlyph<'a> {
3273
    /// Set to 11.
3274
0
    pub fn format(&self) -> u8 {
3275
0
        let range = self.shape.format_byte_range();
3276
0
        self.data.read_at(range.start).unwrap()
3277
0
    }
3278
3279
    /// Glyph ID for a BaseGlyphList base glyph.
3280
109k
    pub fn glyph_id(&self) -> GlyphId16 {
3281
109k
        let range = self.shape.glyph_id_byte_range();
3282
109k
        self.data.read_at(range.start).unwrap()
3283
109k
    }
3284
}
3285
3286
#[cfg(feature = "experimental_traverse")]
3287
impl<'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)]
3302
impl<'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
3308
impl 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)]
3315
pub struct PaintTransformMarker {}
3316
3317
impl PaintTransformMarker {
3318
39.1k
    pub fn format_byte_range(&self) -> Range<usize> {
3319
39.1k
        let start = 0;
3320
39.1k
        start..start + u8::RAW_BYTE_LEN
3321
39.1k
    }
3322
3323
39.1k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
3324
39.1k
        let start = self.format_byte_range().end;
3325
39.1k
        start..start + Offset24::RAW_BYTE_LEN
3326
39.1k
    }
3327
3328
24.3k
    pub fn transform_offset_byte_range(&self) -> Range<usize> {
3329
24.3k
        let start = self.paint_offset_byte_range().end;
3330
24.3k
        start..start + Offset24::RAW_BYTE_LEN
3331
24.3k
    }
3332
}
3333
3334
impl MinByteRange for PaintTransformMarker {
3335
0
    fn min_byte_range(&self) -> Range<usize> {
3336
0
        0..self.transform_offset_byte_range().end
3337
0
    }
3338
}
3339
3340
impl<'a> FontRead<'a> for PaintTransform<'a> {
3341
25.5k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3342
25.5k
        let mut cursor = data.cursor();
3343
25.5k
        cursor.advance::<u8>();
3344
25.5k
        cursor.advance::<Offset24>();
3345
25.5k
        cursor.advance::<Offset24>();
3346
25.5k
        cursor.finish(PaintTransformMarker {})
3347
25.5k
    }
3348
}
3349
3350
/// [PaintTransform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) table
3351
pub type PaintTransform<'a> = TableRef<'a, PaintTransformMarker>;
3352
3353
#[allow(clippy::needless_lifetimes)]
3354
impl<'a> PaintTransform<'a> {
3355
    /// Set to 12.
3356
0
    pub fn format(&self) -> u8 {
3357
0
        let range = self.shape.format_byte_range();
3358
0
        self.data.read_at(range.start).unwrap()
3359
0
    }
3360
3361
    /// Offset to a Paint subtable.
3362
14.7k
    pub fn paint_offset(&self) -> Offset24 {
3363
14.7k
        let range = self.shape.paint_offset_byte_range();
3364
14.7k
        self.data.read_at(range.start).unwrap()
3365
14.7k
    }
3366
3367
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
3368
14.7k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
3369
14.7k
        let data = self.data;
3370
14.7k
        self.paint_offset().resolve(data)
3371
14.7k
    }
3372
3373
    /// Offset to an Affine2x3 table.
3374
24.3k
    pub fn transform_offset(&self) -> Offset24 {
3375
24.3k
        let range = self.shape.transform_offset_byte_range();
3376
24.3k
        self.data.read_at(range.start).unwrap()
3377
24.3k
    }
3378
3379
    /// Attempt to resolve [`transform_offset`][Self::transform_offset].
3380
24.3k
    pub fn transform(&self) -> Result<Affine2x3<'a>, ReadError> {
3381
24.3k
        let data = self.data;
3382
24.3k
        self.transform_offset().resolve(data)
3383
24.3k
    }
3384
}
3385
3386
#[cfg(feature = "experimental_traverse")]
3387
impl<'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)]
3409
impl<'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
3415
impl 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)]
3422
pub struct PaintVarTransformMarker {}
3423
3424
impl PaintVarTransformMarker {
3425
96.4k
    pub fn format_byte_range(&self) -> Range<usize> {
3426
96.4k
        let start = 0;
3427
96.4k
        start..start + u8::RAW_BYTE_LEN
3428
96.4k
    }
3429
3430
96.4k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
3431
96.4k
        let start = self.format_byte_range().end;
3432
96.4k
        start..start + Offset24::RAW_BYTE_LEN
3433
96.4k
    }
3434
3435
51.8k
    pub fn transform_offset_byte_range(&self) -> Range<usize> {
3436
51.8k
        let start = self.paint_offset_byte_range().end;
3437
51.8k
        start..start + Offset24::RAW_BYTE_LEN
3438
51.8k
    }
3439
}
3440
3441
impl MinByteRange for PaintVarTransformMarker {
3442
0
    fn min_byte_range(&self) -> Range<usize> {
3443
0
        0..self.transform_offset_byte_range().end
3444
0
    }
3445
}
3446
3447
impl<'a> FontRead<'a> for PaintVarTransform<'a> {
3448
61.5k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3449
61.5k
        let mut cursor = data.cursor();
3450
61.5k
        cursor.advance::<u8>();
3451
61.5k
        cursor.advance::<Offset24>();
3452
61.5k
        cursor.advance::<Offset24>();
3453
61.5k
        cursor.finish(PaintVarTransformMarker {})
3454
61.5k
    }
3455
}
3456
3457
/// [PaintVarTransform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) table
3458
pub type PaintVarTransform<'a> = TableRef<'a, PaintVarTransformMarker>;
3459
3460
#[allow(clippy::needless_lifetimes)]
3461
impl<'a> PaintVarTransform<'a> {
3462
    /// Set to 13.
3463
0
    pub fn format(&self) -> u8 {
3464
0
        let range = self.shape.format_byte_range();
3465
0
        self.data.read_at(range.start).unwrap()
3466
0
    }
3467
3468
    /// Offset to a Paint subtable.
3469
44.5k
    pub fn paint_offset(&self) -> Offset24 {
3470
44.5k
        let range = self.shape.paint_offset_byte_range();
3471
44.5k
        self.data.read_at(range.start).unwrap()
3472
44.5k
    }
3473
3474
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
3475
44.5k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
3476
44.5k
        let data = self.data;
3477
44.5k
        self.paint_offset().resolve(data)
3478
44.5k
    }
3479
3480
    /// Offset to a VarAffine2x3 table.
3481
51.8k
    pub fn transform_offset(&self) -> Offset24 {
3482
51.8k
        let range = self.shape.transform_offset_byte_range();
3483
51.8k
        self.data.read_at(range.start).unwrap()
3484
51.8k
    }
3485
3486
    /// Attempt to resolve [`transform_offset`][Self::transform_offset].
3487
51.8k
    pub fn transform(&self) -> Result<VarAffine2x3<'a>, ReadError> {
3488
51.8k
        let data = self.data;
3489
51.8k
        self.transform_offset().resolve(data)
3490
51.8k
    }
3491
}
3492
3493
#[cfg(feature = "experimental_traverse")]
3494
impl<'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)]
3516
impl<'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)]
3525
pub struct Affine2x3Marker {}
3526
3527
impl Affine2x3Marker {
3528
25.9k
    pub fn xx_byte_range(&self) -> Range<usize> {
3529
25.9k
        let start = 0;
3530
25.9k
        start..start + Fixed::RAW_BYTE_LEN
3531
25.9k
    }
3532
3533
21.6k
    pub fn yx_byte_range(&self) -> Range<usize> {
3534
21.6k
        let start = self.xx_byte_range().end;
3535
21.6k
        start..start + Fixed::RAW_BYTE_LEN
3536
21.6k
    }
3537
3538
17.3k
    pub fn xy_byte_range(&self) -> Range<usize> {
3539
17.3k
        let start = self.yx_byte_range().end;
3540
17.3k
        start..start + Fixed::RAW_BYTE_LEN
3541
17.3k
    }
3542
3543
12.9k
    pub fn yy_byte_range(&self) -> Range<usize> {
3544
12.9k
        let start = self.xy_byte_range().end;
3545
12.9k
        start..start + Fixed::RAW_BYTE_LEN
3546
12.9k
    }
3547
3548
8.66k
    pub fn dx_byte_range(&self) -> Range<usize> {
3549
8.66k
        let start = self.yy_byte_range().end;
3550
8.66k
        start..start + Fixed::RAW_BYTE_LEN
3551
8.66k
    }
3552
3553
4.33k
    pub fn dy_byte_range(&self) -> Range<usize> {
3554
4.33k
        let start = self.dx_byte_range().end;
3555
4.33k
        start..start + Fixed::RAW_BYTE_LEN
3556
4.33k
    }
3557
}
3558
3559
impl MinByteRange for Affine2x3Marker {
3560
0
    fn min_byte_range(&self) -> Range<usize> {
3561
0
        0..self.dy_byte_range().end
3562
0
    }
3563
}
3564
3565
impl<'a> FontRead<'a> for Affine2x3<'a> {
3566
16.0k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3567
16.0k
        let mut cursor = data.cursor();
3568
16.0k
        cursor.advance::<Fixed>();
3569
16.0k
        cursor.advance::<Fixed>();
3570
16.0k
        cursor.advance::<Fixed>();
3571
16.0k
        cursor.advance::<Fixed>();
3572
16.0k
        cursor.advance::<Fixed>();
3573
16.0k
        cursor.advance::<Fixed>();
3574
16.0k
        cursor.finish(Affine2x3Marker {})
3575
16.0k
    }
3576
}
3577
3578
/// [Affine2x3](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) record
3579
pub type Affine2x3<'a> = TableRef<'a, Affine2x3Marker>;
3580
3581
#[allow(clippy::needless_lifetimes)]
3582
impl<'a> Affine2x3<'a> {
3583
    /// x-component of transformed x-basis vector.
3584
4.33k
    pub fn xx(&self) -> Fixed {
3585
4.33k
        let range = self.shape.xx_byte_range();
3586
4.33k
        self.data.read_at(range.start).unwrap()
3587
4.33k
    }
3588
3589
    /// y-component of transformed x-basis vector.
3590
4.33k
    pub fn yx(&self) -> Fixed {
3591
4.33k
        let range = self.shape.yx_byte_range();
3592
4.33k
        self.data.read_at(range.start).unwrap()
3593
4.33k
    }
3594
3595
    /// x-component of transformed y-basis vector.
3596
4.33k
    pub fn xy(&self) -> Fixed {
3597
4.33k
        let range = self.shape.xy_byte_range();
3598
4.33k
        self.data.read_at(range.start).unwrap()
3599
4.33k
    }
3600
3601
    /// y-component of transformed y-basis vector.
3602
4.33k
    pub fn yy(&self) -> Fixed {
3603
4.33k
        let range = self.shape.yy_byte_range();
3604
4.33k
        self.data.read_at(range.start).unwrap()
3605
4.33k
    }
3606
3607
    /// Translation in x direction.
3608
4.33k
    pub fn dx(&self) -> Fixed {
3609
4.33k
        let range = self.shape.dx_byte_range();
3610
4.33k
        self.data.read_at(range.start).unwrap()
3611
4.33k
    }
3612
3613
    /// Translation in y direction.
3614
4.33k
    pub fn dy(&self) -> Fixed {
3615
4.33k
        let range = self.shape.dy_byte_range();
3616
4.33k
        self.data.read_at(range.start).unwrap()
3617
4.33k
    }
3618
}
3619
3620
#[cfg(feature = "experimental_traverse")]
3621
impl<'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)]
3640
impl<'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)]
3649
pub struct VarAffine2x3Marker {}
3650
3651
impl VarAffine2x3Marker {
3652
220k
    pub fn xx_byte_range(&self) -> Range<usize> {
3653
220k
        let start = 0;
3654
220k
        start..start + Fixed::RAW_BYTE_LEN
3655
220k
    }
3656
3657
189k
    pub fn yx_byte_range(&self) -> Range<usize> {
3658
189k
        let start = self.xx_byte_range().end;
3659
189k
        start..start + Fixed::RAW_BYTE_LEN
3660
189k
    }
3661
3662
157k
    pub fn xy_byte_range(&self) -> Range<usize> {
3663
157k
        let start = self.yx_byte_range().end;
3664
157k
        start..start + Fixed::RAW_BYTE_LEN
3665
157k
    }
3666
3667
126k
    pub fn yy_byte_range(&self) -> Range<usize> {
3668
126k
        let start = self.xy_byte_range().end;
3669
126k
        start..start + Fixed::RAW_BYTE_LEN
3670
126k
    }
3671
3672
94.5k
    pub fn dx_byte_range(&self) -> Range<usize> {
3673
94.5k
        let start = self.yy_byte_range().end;
3674
94.5k
        start..start + Fixed::RAW_BYTE_LEN
3675
94.5k
    }
3676
3677
63.0k
    pub fn dy_byte_range(&self) -> Range<usize> {
3678
63.0k
        let start = self.dx_byte_range().end;
3679
63.0k
        start..start + Fixed::RAW_BYTE_LEN
3680
63.0k
    }
3681
3682
31.5k
    pub fn var_index_base_byte_range(&self) -> Range<usize> {
3683
31.5k
        let start = self.dy_byte_range().end;
3684
31.5k
        start..start + u32::RAW_BYTE_LEN
3685
31.5k
    }
3686
}
3687
3688
impl MinByteRange for VarAffine2x3Marker {
3689
0
    fn min_byte_range(&self) -> Range<usize> {
3690
0
        0..self.var_index_base_byte_range().end
3691
0
    }
3692
}
3693
3694
impl<'a> FontRead<'a> for VarAffine2x3<'a> {
3695
45.6k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3696
45.6k
        let mut cursor = data.cursor();
3697
45.6k
        cursor.advance::<Fixed>();
3698
45.6k
        cursor.advance::<Fixed>();
3699
45.6k
        cursor.advance::<Fixed>();
3700
45.6k
        cursor.advance::<Fixed>();
3701
45.6k
        cursor.advance::<Fixed>();
3702
45.6k
        cursor.advance::<Fixed>();
3703
45.6k
        cursor.advance::<u32>();
3704
45.6k
        cursor.finish(VarAffine2x3Marker {})
3705
45.6k
    }
3706
}
3707
3708
/// [VarAffine2x3](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-12-and-13-painttransform-paintvartransform) record
3709
pub type VarAffine2x3<'a> = TableRef<'a, VarAffine2x3Marker>;
3710
3711
#[allow(clippy::needless_lifetimes)]
3712
impl<'a> VarAffine2x3<'a> {
3713
    /// x-component of transformed x-basis vector. For variation, use
3714
    /// varIndexBase + 0.
3715
31.5k
    pub fn xx(&self) -> Fixed {
3716
31.5k
        let range = self.shape.xx_byte_range();
3717
31.5k
        self.data.read_at(range.start).unwrap()
3718
31.5k
    }
3719
3720
    /// y-component of transformed x-basis vector. For variation, use
3721
    /// varIndexBase + 1.
3722
31.5k
    pub fn yx(&self) -> Fixed {
3723
31.5k
        let range = self.shape.yx_byte_range();
3724
31.5k
        self.data.read_at(range.start).unwrap()
3725
31.5k
    }
3726
3727
    /// x-component of transformed y-basis vector. For variation, use
3728
    /// varIndexBase + 2.
3729
31.5k
    pub fn xy(&self) -> Fixed {
3730
31.5k
        let range = self.shape.xy_byte_range();
3731
31.5k
        self.data.read_at(range.start).unwrap()
3732
31.5k
    }
3733
3734
    /// y-component of transformed y-basis vector. For variation, use
3735
    /// varIndexBase + 3.
3736
31.5k
    pub fn yy(&self) -> Fixed {
3737
31.5k
        let range = self.shape.yy_byte_range();
3738
31.5k
        self.data.read_at(range.start).unwrap()
3739
31.5k
    }
3740
3741
    /// Translation in x direction. For variation, use varIndexBase + 4.
3742
31.5k
    pub fn dx(&self) -> Fixed {
3743
31.5k
        let range = self.shape.dx_byte_range();
3744
31.5k
        self.data.read_at(range.start).unwrap()
3745
31.5k
    }
3746
3747
    /// Translation in y direction. For variation, use varIndexBase + 5.
3748
31.5k
    pub fn dy(&self) -> Fixed {
3749
31.5k
        let range = self.shape.dy_byte_range();
3750
31.5k
        self.data.read_at(range.start).unwrap()
3751
31.5k
    }
3752
3753
    /// Base index into DeltaSetIndexMap.
3754
31.5k
    pub fn var_index_base(&self) -> u32 {
3755
31.5k
        let range = self.shape.var_index_base_byte_range();
3756
31.5k
        self.data.read_at(range.start).unwrap()
3757
31.5k
    }
3758
}
3759
3760
#[cfg(feature = "experimental_traverse")]
3761
impl<'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)]
3781
impl<'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
3787
impl 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)]
3794
pub struct PaintTranslateMarker {}
3795
3796
impl PaintTranslateMarker {
3797
61.7k
    pub fn format_byte_range(&self) -> Range<usize> {
3798
61.7k
        let start = 0;
3799
61.7k
        start..start + u8::RAW_BYTE_LEN
3800
61.7k
    }
3801
3802
61.7k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
3803
61.7k
        let start = self.format_byte_range().end;
3804
61.7k
        start..start + Offset24::RAW_BYTE_LEN
3805
61.7k
    }
3806
3807
41.1k
    pub fn dx_byte_range(&self) -> Range<usize> {
3808
41.1k
        let start = self.paint_offset_byte_range().end;
3809
41.1k
        start..start + FWord::RAW_BYTE_LEN
3810
41.1k
    }
3811
3812
20.5k
    pub fn dy_byte_range(&self) -> Range<usize> {
3813
20.5k
        let start = self.dx_byte_range().end;
3814
20.5k
        start..start + FWord::RAW_BYTE_LEN
3815
20.5k
    }
3816
}
3817
3818
impl MinByteRange for PaintTranslateMarker {
3819
0
    fn min_byte_range(&self) -> Range<usize> {
3820
0
        0..self.dy_byte_range().end
3821
0
    }
3822
}
3823
3824
impl<'a> FontRead<'a> for PaintTranslate<'a> {
3825
21.5k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3826
21.5k
        let mut cursor = data.cursor();
3827
21.5k
        cursor.advance::<u8>();
3828
21.5k
        cursor.advance::<Offset24>();
3829
21.5k
        cursor.advance::<FWord>();
3830
21.5k
        cursor.advance::<FWord>();
3831
21.5k
        cursor.finish(PaintTranslateMarker {})
3832
21.5k
    }
3833
}
3834
3835
/// [PaintTranslate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-14-and-15-painttranslate-paintvartranslate) table
3836
pub type PaintTranslate<'a> = TableRef<'a, PaintTranslateMarker>;
3837
3838
#[allow(clippy::needless_lifetimes)]
3839
impl<'a> PaintTranslate<'a> {
3840
    /// Set to 14.
3841
0
    pub fn format(&self) -> u8 {
3842
0
        let range = self.shape.format_byte_range();
3843
0
        self.data.read_at(range.start).unwrap()
3844
0
    }
3845
3846
    /// Offset to a Paint subtable.
3847
20.5k
    pub fn paint_offset(&self) -> Offset24 {
3848
20.5k
        let range = self.shape.paint_offset_byte_range();
3849
20.5k
        self.data.read_at(range.start).unwrap()
3850
20.5k
    }
3851
3852
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
3853
20.5k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
3854
20.5k
        let data = self.data;
3855
20.5k
        self.paint_offset().resolve(data)
3856
20.5k
    }
3857
3858
    /// Translation in x direction.
3859
20.5k
    pub fn dx(&self) -> FWord {
3860
20.5k
        let range = self.shape.dx_byte_range();
3861
20.5k
        self.data.read_at(range.start).unwrap()
3862
20.5k
    }
3863
3864
    /// Translation in y direction.
3865
20.5k
    pub fn dy(&self) -> FWord {
3866
20.5k
        let range = self.shape.dy_byte_range();
3867
20.5k
        self.data.read_at(range.start).unwrap()
3868
20.5k
    }
3869
}
3870
3871
#[cfg(feature = "experimental_traverse")]
3872
impl<'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)]
3892
impl<'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
3898
impl 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)]
3905
pub struct PaintVarTranslateMarker {}
3906
3907
impl PaintVarTranslateMarker {
3908
231k
    pub fn format_byte_range(&self) -> Range<usize> {
3909
231k
        let start = 0;
3910
231k
        start..start + u8::RAW_BYTE_LEN
3911
231k
    }
3912
3913
231k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
3914
231k
        let start = self.format_byte_range().end;
3915
231k
        start..start + Offset24::RAW_BYTE_LEN
3916
231k
    }
3917
3918
173k
    pub fn dx_byte_range(&self) -> Range<usize> {
3919
173k
        let start = self.paint_offset_byte_range().end;
3920
173k
        start..start + FWord::RAW_BYTE_LEN
3921
173k
    }
3922
3923
115k
    pub fn dy_byte_range(&self) -> Range<usize> {
3924
115k
        let start = self.dx_byte_range().end;
3925
115k
        start..start + FWord::RAW_BYTE_LEN
3926
115k
    }
3927
3928
57.8k
    pub fn var_index_base_byte_range(&self) -> Range<usize> {
3929
57.8k
        let start = self.dy_byte_range().end;
3930
57.8k
        start..start + u32::RAW_BYTE_LEN
3931
57.8k
    }
3932
}
3933
3934
impl MinByteRange for PaintVarTranslateMarker {
3935
0
    fn min_byte_range(&self) -> Range<usize> {
3936
0
        0..self.var_index_base_byte_range().end
3937
0
    }
3938
}
3939
3940
impl<'a> FontRead<'a> for PaintVarTranslate<'a> {
3941
58.8k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3942
58.8k
        let mut cursor = data.cursor();
3943
58.8k
        cursor.advance::<u8>();
3944
58.8k
        cursor.advance::<Offset24>();
3945
58.8k
        cursor.advance::<FWord>();
3946
58.8k
        cursor.advance::<FWord>();
3947
58.8k
        cursor.advance::<u32>();
3948
58.8k
        cursor.finish(PaintVarTranslateMarker {})
3949
58.8k
    }
3950
}
3951
3952
/// [PaintVarTranslate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-14-and-15-painttranslate-paintvartranslate) table
3953
pub type PaintVarTranslate<'a> = TableRef<'a, PaintVarTranslateMarker>;
3954
3955
#[allow(clippy::needless_lifetimes)]
3956
impl<'a> PaintVarTranslate<'a> {
3957
    /// Set to 15.
3958
0
    pub fn format(&self) -> u8 {
3959
0
        let range = self.shape.format_byte_range();
3960
0
        self.data.read_at(range.start).unwrap()
3961
0
    }
3962
3963
    /// Offset to a Paint subtable.
3964
57.8k
    pub fn paint_offset(&self) -> Offset24 {
3965
57.8k
        let range = self.shape.paint_offset_byte_range();
3966
57.8k
        self.data.read_at(range.start).unwrap()
3967
57.8k
    }
3968
3969
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
3970
57.8k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
3971
57.8k
        let data = self.data;
3972
57.8k
        self.paint_offset().resolve(data)
3973
57.8k
    }
3974
3975
    /// Translation in x direction. For variation, use varIndexBase + 0.
3976
57.8k
    pub fn dx(&self) -> FWord {
3977
57.8k
        let range = self.shape.dx_byte_range();
3978
57.8k
        self.data.read_at(range.start).unwrap()
3979
57.8k
    }
3980
3981
    /// Translation in y direction. For variation, use varIndexBase + 1.
3982
57.8k
    pub fn dy(&self) -> FWord {
3983
57.8k
        let range = self.shape.dy_byte_range();
3984
57.8k
        self.data.read_at(range.start).unwrap()
3985
57.8k
    }
3986
3987
    /// Base index into DeltaSetIndexMap.
3988
57.8k
    pub fn var_index_base(&self) -> u32 {
3989
57.8k
        let range = self.shape.var_index_base_byte_range();
3990
57.8k
        self.data.read_at(range.start).unwrap()
3991
57.8k
    }
3992
}
3993
3994
#[cfg(feature = "experimental_traverse")]
3995
impl<'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)]
4016
impl<'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
4022
impl 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)]
4029
pub struct PaintScaleMarker {}
4030
4031
impl PaintScaleMarker {
4032
53.9k
    pub fn format_byte_range(&self) -> Range<usize> {
4033
53.9k
        let start = 0;
4034
53.9k
        start..start + u8::RAW_BYTE_LEN
4035
53.9k
    }
4036
4037
53.9k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
4038
53.9k
        let start = self.format_byte_range().end;
4039
53.9k
        start..start + Offset24::RAW_BYTE_LEN
4040
53.9k
    }
4041
4042
35.9k
    pub fn scale_x_byte_range(&self) -> Range<usize> {
4043
35.9k
        let start = self.paint_offset_byte_range().end;
4044
35.9k
        start..start + F2Dot14::RAW_BYTE_LEN
4045
35.9k
    }
4046
4047
17.9k
    pub fn scale_y_byte_range(&self) -> Range<usize> {
4048
17.9k
        let start = self.scale_x_byte_range().end;
4049
17.9k
        start..start + F2Dot14::RAW_BYTE_LEN
4050
17.9k
    }
4051
}
4052
4053
impl MinByteRange for PaintScaleMarker {
4054
0
    fn min_byte_range(&self) -> Range<usize> {
4055
0
        0..self.scale_y_byte_range().end
4056
0
    }
4057
}
4058
4059
impl<'a> FontRead<'a> for PaintScale<'a> {
4060
19.7k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4061
19.7k
        let mut cursor = data.cursor();
4062
19.7k
        cursor.advance::<u8>();
4063
19.7k
        cursor.advance::<Offset24>();
4064
19.7k
        cursor.advance::<F2Dot14>();
4065
19.7k
        cursor.advance::<F2Dot14>();
4066
19.7k
        cursor.finish(PaintScaleMarker {})
4067
19.7k
    }
4068
}
4069
4070
/// [PaintScale](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4071
pub type PaintScale<'a> = TableRef<'a, PaintScaleMarker>;
4072
4073
#[allow(clippy::needless_lifetimes)]
4074
impl<'a> PaintScale<'a> {
4075
    /// Set to 16.
4076
0
    pub fn format(&self) -> u8 {
4077
0
        let range = self.shape.format_byte_range();
4078
0
        self.data.read_at(range.start).unwrap()
4079
0
    }
4080
4081
    /// Offset to a Paint subtable.
4082
17.9k
    pub fn paint_offset(&self) -> Offset24 {
4083
17.9k
        let range = self.shape.paint_offset_byte_range();
4084
17.9k
        self.data.read_at(range.start).unwrap()
4085
17.9k
    }
4086
4087
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
4088
17.9k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
4089
17.9k
        let data = self.data;
4090
17.9k
        self.paint_offset().resolve(data)
4091
17.9k
    }
4092
4093
    /// Scale factor in x direction.
4094
17.9k
    pub fn scale_x(&self) -> F2Dot14 {
4095
17.9k
        let range = self.shape.scale_x_byte_range();
4096
17.9k
        self.data.read_at(range.start).unwrap()
4097
17.9k
    }
4098
4099
    /// Scale factor in y direction.
4100
17.9k
    pub fn scale_y(&self) -> F2Dot14 {
4101
17.9k
        let range = self.shape.scale_y_byte_range();
4102
17.9k
        self.data.read_at(range.start).unwrap()
4103
17.9k
    }
4104
}
4105
4106
#[cfg(feature = "experimental_traverse")]
4107
impl<'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)]
4127
impl<'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
4133
impl 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)]
4140
pub struct PaintVarScaleMarker {}
4141
4142
impl PaintVarScaleMarker {
4143
726k
    pub fn format_byte_range(&self) -> Range<usize> {
4144
726k
        let start = 0;
4145
726k
        start..start + u8::RAW_BYTE_LEN
4146
726k
    }
4147
4148
726k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
4149
726k
        let start = self.format_byte_range().end;
4150
726k
        start..start + Offset24::RAW_BYTE_LEN
4151
726k
    }
4152
4153
544k
    pub fn scale_x_byte_range(&self) -> Range<usize> {
4154
544k
        let start = self.paint_offset_byte_range().end;
4155
544k
        start..start + F2Dot14::RAW_BYTE_LEN
4156
544k
    }
4157
4158
363k
    pub fn scale_y_byte_range(&self) -> Range<usize> {
4159
363k
        let start = self.scale_x_byte_range().end;
4160
363k
        start..start + F2Dot14::RAW_BYTE_LEN
4161
363k
    }
4162
4163
181k
    pub fn var_index_base_byte_range(&self) -> Range<usize> {
4164
181k
        let start = self.scale_y_byte_range().end;
4165
181k
        start..start + u32::RAW_BYTE_LEN
4166
181k
    }
4167
}
4168
4169
impl MinByteRange for PaintVarScaleMarker {
4170
0
    fn min_byte_range(&self) -> Range<usize> {
4171
0
        0..self.var_index_base_byte_range().end
4172
0
    }
4173
}
4174
4175
impl<'a> FontRead<'a> for PaintVarScale<'a> {
4176
184k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4177
184k
        let mut cursor = data.cursor();
4178
184k
        cursor.advance::<u8>();
4179
184k
        cursor.advance::<Offset24>();
4180
184k
        cursor.advance::<F2Dot14>();
4181
184k
        cursor.advance::<F2Dot14>();
4182
184k
        cursor.advance::<u32>();
4183
184k
        cursor.finish(PaintVarScaleMarker {})
4184
184k
    }
4185
}
4186
4187
/// [PaintVarScale](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4188
pub type PaintVarScale<'a> = TableRef<'a, PaintVarScaleMarker>;
4189
4190
#[allow(clippy::needless_lifetimes)]
4191
impl<'a> PaintVarScale<'a> {
4192
    /// Set to 17.
4193
0
    pub fn format(&self) -> u8 {
4194
0
        let range = self.shape.format_byte_range();
4195
0
        self.data.read_at(range.start).unwrap()
4196
0
    }
4197
4198
    /// Offset to a Paint subtable.
4199
181k
    pub fn paint_offset(&self) -> Offset24 {
4200
181k
        let range = self.shape.paint_offset_byte_range();
4201
181k
        self.data.read_at(range.start).unwrap()
4202
181k
    }
4203
4204
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
4205
181k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
4206
181k
        let data = self.data;
4207
181k
        self.paint_offset().resolve(data)
4208
181k
    }
4209
4210
    /// Scale factor in x direction. For variation, use varIndexBase +
4211
    /// 0.
4212
181k
    pub fn scale_x(&self) -> F2Dot14 {
4213
181k
        let range = self.shape.scale_x_byte_range();
4214
181k
        self.data.read_at(range.start).unwrap()
4215
181k
    }
4216
4217
    /// Scale factor in y direction. For variation, use varIndexBase +
4218
    /// 1.
4219
181k
    pub fn scale_y(&self) -> F2Dot14 {
4220
181k
        let range = self.shape.scale_y_byte_range();
4221
181k
        self.data.read_at(range.start).unwrap()
4222
181k
    }
4223
4224
    /// Base index into DeltaSetIndexMap.
4225
181k
    pub fn var_index_base(&self) -> u32 {
4226
181k
        let range = self.shape.var_index_base_byte_range();
4227
181k
        self.data.read_at(range.start).unwrap()
4228
181k
    }
4229
}
4230
4231
#[cfg(feature = "experimental_traverse")]
4232
impl<'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)]
4253
impl<'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
4259
impl 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)]
4266
pub struct PaintScaleAroundCenterMarker {}
4267
4268
impl PaintScaleAroundCenterMarker {
4269
82.8k
    pub fn format_byte_range(&self) -> Range<usize> {
4270
82.8k
        let start = 0;
4271
82.8k
        start..start + u8::RAW_BYTE_LEN
4272
82.8k
    }
4273
4274
82.8k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
4275
82.8k
        let start = self.format_byte_range().end;
4276
82.8k
        start..start + Offset24::RAW_BYTE_LEN
4277
82.8k
    }
4278
4279
66.3k
    pub fn scale_x_byte_range(&self) -> Range<usize> {
4280
66.3k
        let start = self.paint_offset_byte_range().end;
4281
66.3k
        start..start + F2Dot14::RAW_BYTE_LEN
4282
66.3k
    }
4283
4284
49.7k
    pub fn scale_y_byte_range(&self) -> Range<usize> {
4285
49.7k
        let start = self.scale_x_byte_range().end;
4286
49.7k
        start..start + F2Dot14::RAW_BYTE_LEN
4287
49.7k
    }
4288
4289
33.1k
    pub fn center_x_byte_range(&self) -> Range<usize> {
4290
33.1k
        let start = self.scale_y_byte_range().end;
4291
33.1k
        start..start + FWord::RAW_BYTE_LEN
4292
33.1k
    }
4293
4294
16.5k
    pub fn center_y_byte_range(&self) -> Range<usize> {
4295
16.5k
        let start = self.center_x_byte_range().end;
4296
16.5k
        start..start + FWord::RAW_BYTE_LEN
4297
16.5k
    }
4298
}
4299
4300
impl MinByteRange for PaintScaleAroundCenterMarker {
4301
0
    fn min_byte_range(&self) -> Range<usize> {
4302
0
        0..self.center_y_byte_range().end
4303
0
    }
4304
}
4305
4306
impl<'a> FontRead<'a> for PaintScaleAroundCenter<'a> {
4307
17.5k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4308
17.5k
        let mut cursor = data.cursor();
4309
17.5k
        cursor.advance::<u8>();
4310
17.5k
        cursor.advance::<Offset24>();
4311
17.5k
        cursor.advance::<F2Dot14>();
4312
17.5k
        cursor.advance::<F2Dot14>();
4313
17.5k
        cursor.advance::<FWord>();
4314
17.5k
        cursor.advance::<FWord>();
4315
17.5k
        cursor.finish(PaintScaleAroundCenterMarker {})
4316
17.5k
    }
4317
}
4318
4319
/// [PaintScaleAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4320
pub type PaintScaleAroundCenter<'a> = TableRef<'a, PaintScaleAroundCenterMarker>;
4321
4322
#[allow(clippy::needless_lifetimes)]
4323
impl<'a> PaintScaleAroundCenter<'a> {
4324
    /// Set to 18.
4325
0
    pub fn format(&self) -> u8 {
4326
0
        let range = self.shape.format_byte_range();
4327
0
        self.data.read_at(range.start).unwrap()
4328
0
    }
4329
4330
    /// Offset to a Paint subtable.
4331
16.5k
    pub fn paint_offset(&self) -> Offset24 {
4332
16.5k
        let range = self.shape.paint_offset_byte_range();
4333
16.5k
        self.data.read_at(range.start).unwrap()
4334
16.5k
    }
4335
4336
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
4337
16.5k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
4338
16.5k
        let data = self.data;
4339
16.5k
        self.paint_offset().resolve(data)
4340
16.5k
    }
4341
4342
    /// Scale factor in x direction.
4343
16.5k
    pub fn scale_x(&self) -> F2Dot14 {
4344
16.5k
        let range = self.shape.scale_x_byte_range();
4345
16.5k
        self.data.read_at(range.start).unwrap()
4346
16.5k
    }
4347
4348
    /// Scale factor in y direction.
4349
16.5k
    pub fn scale_y(&self) -> F2Dot14 {
4350
16.5k
        let range = self.shape.scale_y_byte_range();
4351
16.5k
        self.data.read_at(range.start).unwrap()
4352
16.5k
    }
4353
4354
    /// x coordinate for the center of scaling.
4355
16.5k
    pub fn center_x(&self) -> FWord {
4356
16.5k
        let range = self.shape.center_x_byte_range();
4357
16.5k
        self.data.read_at(range.start).unwrap()
4358
16.5k
    }
4359
4360
    /// y coordinate for the center of scaling.
4361
16.5k
    pub fn center_y(&self) -> FWord {
4362
16.5k
        let range = self.shape.center_y_byte_range();
4363
16.5k
        self.data.read_at(range.start).unwrap()
4364
16.5k
    }
4365
}
4366
4367
#[cfg(feature = "experimental_traverse")]
4368
impl<'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)]
4390
impl<'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
4396
impl 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)]
4403
pub struct PaintVarScaleAroundCenterMarker {}
4404
4405
impl PaintVarScaleAroundCenterMarker {
4406
163k
    pub fn format_byte_range(&self) -> Range<usize> {
4407
163k
        let start = 0;
4408
163k
        start..start + u8::RAW_BYTE_LEN
4409
163k
    }
4410
4411
163k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
4412
163k
        let start = self.format_byte_range().end;
4413
163k
        start..start + Offset24::RAW_BYTE_LEN
4414
163k
    }
4415
4416
136k
    pub fn scale_x_byte_range(&self) -> Range<usize> {
4417
136k
        let start = self.paint_offset_byte_range().end;
4418
136k
        start..start + F2Dot14::RAW_BYTE_LEN
4419
136k
    }
4420
4421
108k
    pub fn scale_y_byte_range(&self) -> Range<usize> {
4422
108k
        let start = self.scale_x_byte_range().end;
4423
108k
        start..start + F2Dot14::RAW_BYTE_LEN
4424
108k
    }
4425
4426
81.7k
    pub fn center_x_byte_range(&self) -> Range<usize> {
4427
81.7k
        let start = self.scale_y_byte_range().end;
4428
81.7k
        start..start + FWord::RAW_BYTE_LEN
4429
81.7k
    }
4430
4431
54.4k
    pub fn center_y_byte_range(&self) -> Range<usize> {
4432
54.4k
        let start = self.center_x_byte_range().end;
4433
54.4k
        start..start + FWord::RAW_BYTE_LEN
4434
54.4k
    }
4435
4436
27.2k
    pub fn var_index_base_byte_range(&self) -> Range<usize> {
4437
27.2k
        let start = self.center_y_byte_range().end;
4438
27.2k
        start..start + u32::RAW_BYTE_LEN
4439
27.2k
    }
4440
}
4441
4442
impl MinByteRange for PaintVarScaleAroundCenterMarker {
4443
0
    fn min_byte_range(&self) -> Range<usize> {
4444
0
        0..self.var_index_base_byte_range().end
4445
0
    }
4446
}
4447
4448
impl<'a> FontRead<'a> for PaintVarScaleAroundCenter<'a> {
4449
32.5k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4450
32.5k
        let mut cursor = data.cursor();
4451
32.5k
        cursor.advance::<u8>();
4452
32.5k
        cursor.advance::<Offset24>();
4453
32.5k
        cursor.advance::<F2Dot14>();
4454
32.5k
        cursor.advance::<F2Dot14>();
4455
32.5k
        cursor.advance::<FWord>();
4456
32.5k
        cursor.advance::<FWord>();
4457
32.5k
        cursor.advance::<u32>();
4458
32.5k
        cursor.finish(PaintVarScaleAroundCenterMarker {})
4459
32.5k
    }
4460
}
4461
4462
/// [PaintVarScaleAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4463
pub type PaintVarScaleAroundCenter<'a> = TableRef<'a, PaintVarScaleAroundCenterMarker>;
4464
4465
#[allow(clippy::needless_lifetimes)]
4466
impl<'a> PaintVarScaleAroundCenter<'a> {
4467
    /// Set to 19.
4468
0
    pub fn format(&self) -> u8 {
4469
0
        let range = self.shape.format_byte_range();
4470
0
        self.data.read_at(range.start).unwrap()
4471
0
    }
4472
4473
    /// Offset to a Paint subtable.
4474
27.2k
    pub fn paint_offset(&self) -> Offset24 {
4475
27.2k
        let range = self.shape.paint_offset_byte_range();
4476
27.2k
        self.data.read_at(range.start).unwrap()
4477
27.2k
    }
4478
4479
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
4480
27.2k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
4481
27.2k
        let data = self.data;
4482
27.2k
        self.paint_offset().resolve(data)
4483
27.2k
    }
4484
4485
    /// Scale factor in x direction. For variation, use varIndexBase +
4486
    /// 0.
4487
27.2k
    pub fn scale_x(&self) -> F2Dot14 {
4488
27.2k
        let range = self.shape.scale_x_byte_range();
4489
27.2k
        self.data.read_at(range.start).unwrap()
4490
27.2k
    }
4491
4492
    /// Scale factor in y direction. For variation, use varIndexBase +
4493
    /// 1.
4494
27.2k
    pub fn scale_y(&self) -> F2Dot14 {
4495
27.2k
        let range = self.shape.scale_y_byte_range();
4496
27.2k
        self.data.read_at(range.start).unwrap()
4497
27.2k
    }
4498
4499
    /// x coordinate for the center of scaling. For variation, use
4500
    /// varIndexBase + 2.
4501
27.2k
    pub fn center_x(&self) -> FWord {
4502
27.2k
        let range = self.shape.center_x_byte_range();
4503
27.2k
        self.data.read_at(range.start).unwrap()
4504
27.2k
    }
4505
4506
    /// y coordinate for the center of scaling. For variation, use
4507
    /// varIndexBase + 3.
4508
27.2k
    pub fn center_y(&self) -> FWord {
4509
27.2k
        let range = self.shape.center_y_byte_range();
4510
27.2k
        self.data.read_at(range.start).unwrap()
4511
27.2k
    }
4512
4513
    /// Base index into DeltaSetIndexMap.
4514
27.2k
    pub fn var_index_base(&self) -> u32 {
4515
27.2k
        let range = self.shape.var_index_base_byte_range();
4516
27.2k
        self.data.read_at(range.start).unwrap()
4517
27.2k
    }
4518
}
4519
4520
#[cfg(feature = "experimental_traverse")]
4521
impl<'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)]
4544
impl<'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
4550
impl 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)]
4557
pub struct PaintScaleUniformMarker {}
4558
4559
impl PaintScaleUniformMarker {
4560
58.1k
    pub fn format_byte_range(&self) -> Range<usize> {
4561
58.1k
        let start = 0;
4562
58.1k
        start..start + u8::RAW_BYTE_LEN
4563
58.1k
    }
4564
4565
58.1k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
4566
58.1k
        let start = self.format_byte_range().end;
4567
58.1k
        start..start + Offset24::RAW_BYTE_LEN
4568
58.1k
    }
4569
4570
29.0k
    pub fn scale_byte_range(&self) -> Range<usize> {
4571
29.0k
        let start = self.paint_offset_byte_range().end;
4572
29.0k
        start..start + F2Dot14::RAW_BYTE_LEN
4573
29.0k
    }
4574
}
4575
4576
impl MinByteRange for PaintScaleUniformMarker {
4577
0
    fn min_byte_range(&self) -> Range<usize> {
4578
0
        0..self.scale_byte_range().end
4579
0
    }
4580
}
4581
4582
impl<'a> FontRead<'a> for PaintScaleUniform<'a> {
4583
30.3k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4584
30.3k
        let mut cursor = data.cursor();
4585
30.3k
        cursor.advance::<u8>();
4586
30.3k
        cursor.advance::<Offset24>();
4587
30.3k
        cursor.advance::<F2Dot14>();
4588
30.3k
        cursor.finish(PaintScaleUniformMarker {})
4589
30.3k
    }
4590
}
4591
4592
/// [PaintScaleUniform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4593
pub type PaintScaleUniform<'a> = TableRef<'a, PaintScaleUniformMarker>;
4594
4595
#[allow(clippy::needless_lifetimes)]
4596
impl<'a> PaintScaleUniform<'a> {
4597
    /// Set to 20.
4598
0
    pub fn format(&self) -> u8 {
4599
0
        let range = self.shape.format_byte_range();
4600
0
        self.data.read_at(range.start).unwrap()
4601
0
    }
4602
4603
    /// Offset to a Paint subtable.
4604
29.0k
    pub fn paint_offset(&self) -> Offset24 {
4605
29.0k
        let range = self.shape.paint_offset_byte_range();
4606
29.0k
        self.data.read_at(range.start).unwrap()
4607
29.0k
    }
4608
4609
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
4610
29.0k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
4611
29.0k
        let data = self.data;
4612
29.0k
        self.paint_offset().resolve(data)
4613
29.0k
    }
4614
4615
    /// Scale factor in x and y directions.
4616
29.0k
    pub fn scale(&self) -> F2Dot14 {
4617
29.0k
        let range = self.shape.scale_byte_range();
4618
29.0k
        self.data.read_at(range.start).unwrap()
4619
29.0k
    }
4620
}
4621
4622
#[cfg(feature = "experimental_traverse")]
4623
impl<'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)]
4642
impl<'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
4648
impl 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)]
4655
pub struct PaintVarScaleUniformMarker {}
4656
4657
impl PaintVarScaleUniformMarker {
4658
81.5k
    pub fn format_byte_range(&self) -> Range<usize> {
4659
81.5k
        let start = 0;
4660
81.5k
        start..start + u8::RAW_BYTE_LEN
4661
81.5k
    }
4662
4663
81.5k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
4664
81.5k
        let start = self.format_byte_range().end;
4665
81.5k
        start..start + Offset24::RAW_BYTE_LEN
4666
81.5k
    }
4667
4668
54.3k
    pub fn scale_byte_range(&self) -> Range<usize> {
4669
54.3k
        let start = self.paint_offset_byte_range().end;
4670
54.3k
        start..start + F2Dot14::RAW_BYTE_LEN
4671
54.3k
    }
4672
4673
27.1k
    pub fn var_index_base_byte_range(&self) -> Range<usize> {
4674
27.1k
        let start = self.scale_byte_range().end;
4675
27.1k
        start..start + u32::RAW_BYTE_LEN
4676
27.1k
    }
4677
}
4678
4679
impl MinByteRange for PaintVarScaleUniformMarker {
4680
0
    fn min_byte_range(&self) -> Range<usize> {
4681
0
        0..self.var_index_base_byte_range().end
4682
0
    }
4683
}
4684
4685
impl<'a> FontRead<'a> for PaintVarScaleUniform<'a> {
4686
30.4k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4687
30.4k
        let mut cursor = data.cursor();
4688
30.4k
        cursor.advance::<u8>();
4689
30.4k
        cursor.advance::<Offset24>();
4690
30.4k
        cursor.advance::<F2Dot14>();
4691
30.4k
        cursor.advance::<u32>();
4692
30.4k
        cursor.finish(PaintVarScaleUniformMarker {})
4693
30.4k
    }
4694
}
4695
4696
/// [PaintVarScaleUniform](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4697
pub type PaintVarScaleUniform<'a> = TableRef<'a, PaintVarScaleUniformMarker>;
4698
4699
#[allow(clippy::needless_lifetimes)]
4700
impl<'a> PaintVarScaleUniform<'a> {
4701
    /// Set to 21.
4702
0
    pub fn format(&self) -> u8 {
4703
0
        let range = self.shape.format_byte_range();
4704
0
        self.data.read_at(range.start).unwrap()
4705
0
    }
4706
4707
    /// Offset to a Paint subtable.
4708
27.1k
    pub fn paint_offset(&self) -> Offset24 {
4709
27.1k
        let range = self.shape.paint_offset_byte_range();
4710
27.1k
        self.data.read_at(range.start).unwrap()
4711
27.1k
    }
4712
4713
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
4714
27.1k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
4715
27.1k
        let data = self.data;
4716
27.1k
        self.paint_offset().resolve(data)
4717
27.1k
    }
4718
4719
    /// Scale factor in x and y directions. For variation, use
4720
    /// varIndexBase + 0.
4721
27.1k
    pub fn scale(&self) -> F2Dot14 {
4722
27.1k
        let range = self.shape.scale_byte_range();
4723
27.1k
        self.data.read_at(range.start).unwrap()
4724
27.1k
    }
4725
4726
    /// Base index into DeltaSetIndexMap.
4727
27.1k
    pub fn var_index_base(&self) -> u32 {
4728
27.1k
        let range = self.shape.var_index_base_byte_range();
4729
27.1k
        self.data.read_at(range.start).unwrap()
4730
27.1k
    }
4731
}
4732
4733
#[cfg(feature = "experimental_traverse")]
4734
impl<'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)]
4754
impl<'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
4760
impl 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)]
4767
pub struct PaintScaleUniformAroundCenterMarker {}
4768
4769
impl PaintScaleUniformAroundCenterMarker {
4770
1.85M
    pub fn format_byte_range(&self) -> Range<usize> {
4771
1.85M
        let start = 0;
4772
1.85M
        start..start + u8::RAW_BYTE_LEN
4773
1.85M
    }
4774
4775
1.85M
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
4776
1.85M
        let start = self.format_byte_range().end;
4777
1.85M
        start..start + Offset24::RAW_BYTE_LEN
4778
1.85M
    }
4779
4780
1.38M
    pub fn scale_byte_range(&self) -> Range<usize> {
4781
1.38M
        let start = self.paint_offset_byte_range().end;
4782
1.38M
        start..start + F2Dot14::RAW_BYTE_LEN
4783
1.38M
    }
4784
4785
925k
    pub fn center_x_byte_range(&self) -> Range<usize> {
4786
925k
        let start = self.scale_byte_range().end;
4787
925k
        start..start + FWord::RAW_BYTE_LEN
4788
925k
    }
4789
4790
462k
    pub fn center_y_byte_range(&self) -> Range<usize> {
4791
462k
        let start = self.center_x_byte_range().end;
4792
462k
        start..start + FWord::RAW_BYTE_LEN
4793
462k
    }
4794
}
4795
4796
impl MinByteRange for PaintScaleUniformAroundCenterMarker {
4797
0
    fn min_byte_range(&self) -> Range<usize> {
4798
0
        0..self.center_y_byte_range().end
4799
0
    }
4800
}
4801
4802
impl<'a> FontRead<'a> for PaintScaleUniformAroundCenter<'a> {
4803
463k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4804
463k
        let mut cursor = data.cursor();
4805
463k
        cursor.advance::<u8>();
4806
463k
        cursor.advance::<Offset24>();
4807
463k
        cursor.advance::<F2Dot14>();
4808
463k
        cursor.advance::<FWord>();
4809
463k
        cursor.advance::<FWord>();
4810
463k
        cursor.finish(PaintScaleUniformAroundCenterMarker {})
4811
463k
    }
4812
}
4813
4814
/// [PaintScaleUniformAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4815
pub type PaintScaleUniformAroundCenter<'a> = TableRef<'a, PaintScaleUniformAroundCenterMarker>;
4816
4817
#[allow(clippy::needless_lifetimes)]
4818
impl<'a> PaintScaleUniformAroundCenter<'a> {
4819
    /// Set to 22.
4820
0
    pub fn format(&self) -> u8 {
4821
0
        let range = self.shape.format_byte_range();
4822
0
        self.data.read_at(range.start).unwrap()
4823
0
    }
4824
4825
    /// Offset to a Paint subtable.
4826
462k
    pub fn paint_offset(&self) -> Offset24 {
4827
462k
        let range = self.shape.paint_offset_byte_range();
4828
462k
        self.data.read_at(range.start).unwrap()
4829
462k
    }
4830
4831
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
4832
462k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
4833
462k
        let data = self.data;
4834
462k
        self.paint_offset().resolve(data)
4835
462k
    }
4836
4837
    /// Scale factor in x and y directions.
4838
462k
    pub fn scale(&self) -> F2Dot14 {
4839
462k
        let range = self.shape.scale_byte_range();
4840
462k
        self.data.read_at(range.start).unwrap()
4841
462k
    }
4842
4843
    /// x coordinate for the center of scaling.
4844
462k
    pub fn center_x(&self) -> FWord {
4845
462k
        let range = self.shape.center_x_byte_range();
4846
462k
        self.data.read_at(range.start).unwrap()
4847
462k
    }
4848
4849
    /// y coordinate for the center of scaling.
4850
462k
    pub fn center_y(&self) -> FWord {
4851
462k
        let range = self.shape.center_y_byte_range();
4852
462k
        self.data.read_at(range.start).unwrap()
4853
462k
    }
4854
}
4855
4856
#[cfg(feature = "experimental_traverse")]
4857
impl<'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)]
4878
impl<'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
4884
impl 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)]
4891
pub struct PaintVarScaleUniformAroundCenterMarker {}
4892
4893
impl PaintVarScaleUniformAroundCenterMarker {
4894
201k
    pub fn format_byte_range(&self) -> Range<usize> {
4895
201k
        let start = 0;
4896
201k
        start..start + u8::RAW_BYTE_LEN
4897
201k
    }
4898
4899
201k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
4900
201k
        let start = self.format_byte_range().end;
4901
201k
        start..start + Offset24::RAW_BYTE_LEN
4902
201k
    }
4903
4904
160k
    pub fn scale_byte_range(&self) -> Range<usize> {
4905
160k
        let start = self.paint_offset_byte_range().end;
4906
160k
        start..start + F2Dot14::RAW_BYTE_LEN
4907
160k
    }
4908
4909
120k
    pub fn center_x_byte_range(&self) -> Range<usize> {
4910
120k
        let start = self.scale_byte_range().end;
4911
120k
        start..start + FWord::RAW_BYTE_LEN
4912
120k
    }
4913
4914
80.4k
    pub fn center_y_byte_range(&self) -> Range<usize> {
4915
80.4k
        let start = self.center_x_byte_range().end;
4916
80.4k
        start..start + FWord::RAW_BYTE_LEN
4917
80.4k
    }
4918
4919
40.2k
    pub fn var_index_base_byte_range(&self) -> Range<usize> {
4920
40.2k
        let start = self.center_y_byte_range().end;
4921
40.2k
        start..start + u32::RAW_BYTE_LEN
4922
40.2k
    }
4923
}
4924
4925
impl MinByteRange for PaintVarScaleUniformAroundCenterMarker {
4926
0
    fn min_byte_range(&self) -> Range<usize> {
4927
0
        0..self.var_index_base_byte_range().end
4928
0
    }
4929
}
4930
4931
impl<'a> FontRead<'a> for PaintVarScaleUniformAroundCenter<'a> {
4932
41.5k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
4933
41.5k
        let mut cursor = data.cursor();
4934
41.5k
        cursor.advance::<u8>();
4935
41.5k
        cursor.advance::<Offset24>();
4936
41.5k
        cursor.advance::<F2Dot14>();
4937
41.5k
        cursor.advance::<FWord>();
4938
41.5k
        cursor.advance::<FWord>();
4939
41.5k
        cursor.advance::<u32>();
4940
41.5k
        cursor.finish(PaintVarScaleUniformAroundCenterMarker {})
4941
41.5k
    }
4942
}
4943
4944
/// [PaintVarScaleUniformAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-16-to-23-paintscale-and-variant-scaling-formats) table
4945
pub type PaintVarScaleUniformAroundCenter<'a> =
4946
    TableRef<'a, PaintVarScaleUniformAroundCenterMarker>;
4947
4948
#[allow(clippy::needless_lifetimes)]
4949
impl<'a> PaintVarScaleUniformAroundCenter<'a> {
4950
    /// Set to 23.
4951
0
    pub fn format(&self) -> u8 {
4952
0
        let range = self.shape.format_byte_range();
4953
0
        self.data.read_at(range.start).unwrap()
4954
0
    }
4955
4956
    /// Offset to a Paint subtable.
4957
40.2k
    pub fn paint_offset(&self) -> Offset24 {
4958
40.2k
        let range = self.shape.paint_offset_byte_range();
4959
40.2k
        self.data.read_at(range.start).unwrap()
4960
40.2k
    }
4961
4962
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
4963
40.2k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
4964
40.2k
        let data = self.data;
4965
40.2k
        self.paint_offset().resolve(data)
4966
40.2k
    }
4967
4968
    /// Scale factor in x and y directions. For variation, use
4969
    /// varIndexBase + 0.
4970
40.2k
    pub fn scale(&self) -> F2Dot14 {
4971
40.2k
        let range = self.shape.scale_byte_range();
4972
40.2k
        self.data.read_at(range.start).unwrap()
4973
40.2k
    }
4974
4975
    /// x coordinate for the center of scaling. For variation, use
4976
    /// varIndexBase + 1.
4977
40.2k
    pub fn center_x(&self) -> FWord {
4978
40.2k
        let range = self.shape.center_x_byte_range();
4979
40.2k
        self.data.read_at(range.start).unwrap()
4980
40.2k
    }
4981
4982
    /// y coordinate for the center of scaling. For variation, use
4983
    /// varIndexBase + 2.
4984
40.2k
    pub fn center_y(&self) -> FWord {
4985
40.2k
        let range = self.shape.center_y_byte_range();
4986
40.2k
        self.data.read_at(range.start).unwrap()
4987
40.2k
    }
4988
4989
    /// Base index into DeltaSetIndexMap.
4990
40.2k
    pub fn var_index_base(&self) -> u32 {
4991
40.2k
        let range = self.shape.var_index_base_byte_range();
4992
40.2k
        self.data.read_at(range.start).unwrap()
4993
40.2k
    }
4994
}
4995
4996
#[cfg(feature = "experimental_traverse")]
4997
impl<'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)]
5019
impl<'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
5025
impl 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)]
5032
pub struct PaintRotateMarker {}
5033
5034
impl PaintRotateMarker {
5035
182k
    pub fn format_byte_range(&self) -> Range<usize> {
5036
182k
        let start = 0;
5037
182k
        start..start + u8::RAW_BYTE_LEN
5038
182k
    }
5039
5040
182k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
5041
182k
        let start = self.format_byte_range().end;
5042
182k
        start..start + Offset24::RAW_BYTE_LEN
5043
182k
    }
5044
5045
91.2k
    pub fn angle_byte_range(&self) -> Range<usize> {
5046
91.2k
        let start = self.paint_offset_byte_range().end;
5047
91.2k
        start..start + F2Dot14::RAW_BYTE_LEN
5048
91.2k
    }
5049
}
5050
5051
impl MinByteRange for PaintRotateMarker {
5052
0
    fn min_byte_range(&self) -> Range<usize> {
5053
0
        0..self.angle_byte_range().end
5054
0
    }
5055
}
5056
5057
impl<'a> FontRead<'a> for PaintRotate<'a> {
5058
93.7k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
5059
93.7k
        let mut cursor = data.cursor();
5060
93.7k
        cursor.advance::<u8>();
5061
93.7k
        cursor.advance::<Offset24>();
5062
93.7k
        cursor.advance::<F2Dot14>();
5063
93.7k
        cursor.finish(PaintRotateMarker {})
5064
93.7k
    }
5065
}
5066
5067
/// [PaintRotate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table
5068
pub type PaintRotate<'a> = TableRef<'a, PaintRotateMarker>;
5069
5070
#[allow(clippy::needless_lifetimes)]
5071
impl<'a> PaintRotate<'a> {
5072
    /// Set to 24.
5073
0
    pub fn format(&self) -> u8 {
5074
0
        let range = self.shape.format_byte_range();
5075
0
        self.data.read_at(range.start).unwrap()
5076
0
    }
5077
5078
    /// Offset to a Paint subtable.
5079
91.2k
    pub fn paint_offset(&self) -> Offset24 {
5080
91.2k
        let range = self.shape.paint_offset_byte_range();
5081
91.2k
        self.data.read_at(range.start).unwrap()
5082
91.2k
    }
5083
5084
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
5085
91.2k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
5086
91.2k
        let data = self.data;
5087
91.2k
        self.paint_offset().resolve(data)
5088
91.2k
    }
5089
5090
    /// Rotation angle, 180° in counter-clockwise degrees per 1.0 of
5091
    /// value.
5092
91.2k
    pub fn angle(&self) -> F2Dot14 {
5093
91.2k
        let range = self.shape.angle_byte_range();
5094
91.2k
        self.data.read_at(range.start).unwrap()
5095
91.2k
    }
5096
}
5097
5098
#[cfg(feature = "experimental_traverse")]
5099
impl<'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)]
5118
impl<'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
5124
impl 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)]
5131
pub struct PaintVarRotateMarker {}
5132
5133
impl PaintVarRotateMarker {
5134
66.8k
    pub fn format_byte_range(&self) -> Range<usize> {
5135
66.8k
        let start = 0;
5136
66.8k
        start..start + u8::RAW_BYTE_LEN
5137
66.8k
    }
5138
5139
66.8k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
5140
66.8k
        let start = self.format_byte_range().end;
5141
66.8k
        start..start + Offset24::RAW_BYTE_LEN
5142
66.8k
    }
5143
5144
44.5k
    pub fn angle_byte_range(&self) -> Range<usize> {
5145
44.5k
        let start = self.paint_offset_byte_range().end;
5146
44.5k
        start..start + F2Dot14::RAW_BYTE_LEN
5147
44.5k
    }
5148
5149
22.2k
    pub fn var_index_base_byte_range(&self) -> Range<usize> {
5150
22.2k
        let start = self.angle_byte_range().end;
5151
22.2k
        start..start + u32::RAW_BYTE_LEN
5152
22.2k
    }
5153
}
5154
5155
impl MinByteRange for PaintVarRotateMarker {
5156
0
    fn min_byte_range(&self) -> Range<usize> {
5157
0
        0..self.var_index_base_byte_range().end
5158
0
    }
5159
}
5160
5161
impl<'a> FontRead<'a> for PaintVarRotate<'a> {
5162
25.1k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
5163
25.1k
        let mut cursor = data.cursor();
5164
25.1k
        cursor.advance::<u8>();
5165
25.1k
        cursor.advance::<Offset24>();
5166
25.1k
        cursor.advance::<F2Dot14>();
5167
25.1k
        cursor.advance::<u32>();
5168
25.1k
        cursor.finish(PaintVarRotateMarker {})
5169
25.1k
    }
5170
}
5171
5172
/// [PaintVarRotate](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table
5173
pub type PaintVarRotate<'a> = TableRef<'a, PaintVarRotateMarker>;
5174
5175
#[allow(clippy::needless_lifetimes)]
5176
impl<'a> PaintVarRotate<'a> {
5177
    /// Set to 25.
5178
0
    pub fn format(&self) -> u8 {
5179
0
        let range = self.shape.format_byte_range();
5180
0
        self.data.read_at(range.start).unwrap()
5181
0
    }
5182
5183
    /// Offset to a Paint subtable.
5184
22.2k
    pub fn paint_offset(&self) -> Offset24 {
5185
22.2k
        let range = self.shape.paint_offset_byte_range();
5186
22.2k
        self.data.read_at(range.start).unwrap()
5187
22.2k
    }
5188
5189
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
5190
22.2k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
5191
22.2k
        let data = self.data;
5192
22.2k
        self.paint_offset().resolve(data)
5193
22.2k
    }
5194
5195
    /// Rotation angle, 180° in counter-clockwise degrees per 1.0 of
5196
    /// value. For variation, use varIndexBase + 0.
5197
22.2k
    pub fn angle(&self) -> F2Dot14 {
5198
22.2k
        let range = self.shape.angle_byte_range();
5199
22.2k
        self.data.read_at(range.start).unwrap()
5200
22.2k
    }
5201
5202
    /// Base index into DeltaSetIndexMap.
5203
22.2k
    pub fn var_index_base(&self) -> u32 {
5204
22.2k
        let range = self.shape.var_index_base_byte_range();
5205
22.2k
        self.data.read_at(range.start).unwrap()
5206
22.2k
    }
5207
}
5208
5209
#[cfg(feature = "experimental_traverse")]
5210
impl<'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)]
5230
impl<'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
5236
impl 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)]
5243
pub struct PaintRotateAroundCenterMarker {}
5244
5245
impl PaintRotateAroundCenterMarker {
5246
129k
    pub fn format_byte_range(&self) -> Range<usize> {
5247
129k
        let start = 0;
5248
129k
        start..start + u8::RAW_BYTE_LEN
5249
129k
    }
5250
5251
129k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
5252
129k
        let start = self.format_byte_range().end;
5253
129k
        start..start + Offset24::RAW_BYTE_LEN
5254
129k
    }
5255
5256
97.2k
    pub fn angle_byte_range(&self) -> Range<usize> {
5257
97.2k
        let start = self.paint_offset_byte_range().end;
5258
97.2k
        start..start + F2Dot14::RAW_BYTE_LEN
5259
97.2k
    }
5260
5261
64.8k
    pub fn center_x_byte_range(&self) -> Range<usize> {
5262
64.8k
        let start = self.angle_byte_range().end;
5263
64.8k
        start..start + FWord::RAW_BYTE_LEN
5264
64.8k
    }
5265
5266
32.4k
    pub fn center_y_byte_range(&self) -> Range<usize> {
5267
32.4k
        let start = self.center_x_byte_range().end;
5268
32.4k
        start..start + FWord::RAW_BYTE_LEN
5269
32.4k
    }
5270
}
5271
5272
impl MinByteRange for PaintRotateAroundCenterMarker {
5273
0
    fn min_byte_range(&self) -> Range<usize> {
5274
0
        0..self.center_y_byte_range().end
5275
0
    }
5276
}
5277
5278
impl<'a> FontRead<'a> for PaintRotateAroundCenter<'a> {
5279
32.7k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
5280
32.7k
        let mut cursor = data.cursor();
5281
32.7k
        cursor.advance::<u8>();
5282
32.7k
        cursor.advance::<Offset24>();
5283
32.7k
        cursor.advance::<F2Dot14>();
5284
32.7k
        cursor.advance::<FWord>();
5285
32.7k
        cursor.advance::<FWord>();
5286
32.7k
        cursor.finish(PaintRotateAroundCenterMarker {})
5287
32.7k
    }
5288
}
5289
5290
/// [PaintRotateAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table
5291
pub type PaintRotateAroundCenter<'a> = TableRef<'a, PaintRotateAroundCenterMarker>;
5292
5293
#[allow(clippy::needless_lifetimes)]
5294
impl<'a> PaintRotateAroundCenter<'a> {
5295
    /// Set to 26.
5296
0
    pub fn format(&self) -> u8 {
5297
0
        let range = self.shape.format_byte_range();
5298
0
        self.data.read_at(range.start).unwrap()
5299
0
    }
5300
5301
    /// Offset to a Paint subtable.
5302
32.4k
    pub fn paint_offset(&self) -> Offset24 {
5303
32.4k
        let range = self.shape.paint_offset_byte_range();
5304
32.4k
        self.data.read_at(range.start).unwrap()
5305
32.4k
    }
5306
5307
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
5308
32.4k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
5309
32.4k
        let data = self.data;
5310
32.4k
        self.paint_offset().resolve(data)
5311
32.4k
    }
5312
5313
    /// Rotation angle, 180° in counter-clockwise degrees per 1.0 of
5314
    /// value.
5315
32.4k
    pub fn angle(&self) -> F2Dot14 {
5316
32.4k
        let range = self.shape.angle_byte_range();
5317
32.4k
        self.data.read_at(range.start).unwrap()
5318
32.4k
    }
5319
5320
    /// x coordinate for the center of rotation.
5321
32.4k
    pub fn center_x(&self) -> FWord {
5322
32.4k
        let range = self.shape.center_x_byte_range();
5323
32.4k
        self.data.read_at(range.start).unwrap()
5324
32.4k
    }
5325
5326
    /// y coordinate for the center of rotation.
5327
32.4k
    pub fn center_y(&self) -> FWord {
5328
32.4k
        let range = self.shape.center_y_byte_range();
5329
32.4k
        self.data.read_at(range.start).unwrap()
5330
32.4k
    }
5331
}
5332
5333
#[cfg(feature = "experimental_traverse")]
5334
impl<'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)]
5355
impl<'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
5361
impl 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)]
5368
pub struct PaintVarRotateAroundCenterMarker {}
5369
5370
impl PaintVarRotateAroundCenterMarker {
5371
210k
    pub fn format_byte_range(&self) -> Range<usize> {
5372
210k
        let start = 0;
5373
210k
        start..start + u8::RAW_BYTE_LEN
5374
210k
    }
5375
5376
210k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
5377
210k
        let start = self.format_byte_range().end;
5378
210k
        start..start + Offset24::RAW_BYTE_LEN
5379
210k
    }
5380
5381
168k
    pub fn angle_byte_range(&self) -> Range<usize> {
5382
168k
        let start = self.paint_offset_byte_range().end;
5383
168k
        start..start + F2Dot14::RAW_BYTE_LEN
5384
168k
    }
5385
5386
126k
    pub fn center_x_byte_range(&self) -> Range<usize> {
5387
126k
        let start = self.angle_byte_range().end;
5388
126k
        start..start + FWord::RAW_BYTE_LEN
5389
126k
    }
5390
5391
84.3k
    pub fn center_y_byte_range(&self) -> Range<usize> {
5392
84.3k
        let start = self.center_x_byte_range().end;
5393
84.3k
        start..start + FWord::RAW_BYTE_LEN
5394
84.3k
    }
5395
5396
42.1k
    pub fn var_index_base_byte_range(&self) -> Range<usize> {
5397
42.1k
        let start = self.center_y_byte_range().end;
5398
42.1k
        start..start + u32::RAW_BYTE_LEN
5399
42.1k
    }
5400
}
5401
5402
impl MinByteRange for PaintVarRotateAroundCenterMarker {
5403
0
    fn min_byte_range(&self) -> Range<usize> {
5404
0
        0..self.var_index_base_byte_range().end
5405
0
    }
5406
}
5407
5408
impl<'a> FontRead<'a> for PaintVarRotateAroundCenter<'a> {
5409
48.9k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
5410
48.9k
        let mut cursor = data.cursor();
5411
48.9k
        cursor.advance::<u8>();
5412
48.9k
        cursor.advance::<Offset24>();
5413
48.9k
        cursor.advance::<F2Dot14>();
5414
48.9k
        cursor.advance::<FWord>();
5415
48.9k
        cursor.advance::<FWord>();
5416
48.9k
        cursor.advance::<u32>();
5417
48.9k
        cursor.finish(PaintVarRotateAroundCenterMarker {})
5418
48.9k
    }
5419
}
5420
5421
/// [PaintVarRotateAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter) table
5422
pub type PaintVarRotateAroundCenter<'a> = TableRef<'a, PaintVarRotateAroundCenterMarker>;
5423
5424
#[allow(clippy::needless_lifetimes)]
5425
impl<'a> PaintVarRotateAroundCenter<'a> {
5426
    /// Set to 27.
5427
0
    pub fn format(&self) -> u8 {
5428
0
        let range = self.shape.format_byte_range();
5429
0
        self.data.read_at(range.start).unwrap()
5430
0
    }
5431
5432
    /// Offset to a Paint subtable.
5433
42.1k
    pub fn paint_offset(&self) -> Offset24 {
5434
42.1k
        let range = self.shape.paint_offset_byte_range();
5435
42.1k
        self.data.read_at(range.start).unwrap()
5436
42.1k
    }
5437
5438
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
5439
42.1k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
5440
42.1k
        let data = self.data;
5441
42.1k
        self.paint_offset().resolve(data)
5442
42.1k
    }
5443
5444
    /// Rotation angle, 180° in counter-clockwise degrees per 1.0 of
5445
    /// value. For variation, use varIndexBase + 0.
5446
42.1k
    pub fn angle(&self) -> F2Dot14 {
5447
42.1k
        let range = self.shape.angle_byte_range();
5448
42.1k
        self.data.read_at(range.start).unwrap()
5449
42.1k
    }
5450
5451
    /// x coordinate for the center of rotation. For variation, use
5452
    /// varIndexBase + 1.
5453
42.1k
    pub fn center_x(&self) -> FWord {
5454
42.1k
        let range = self.shape.center_x_byte_range();
5455
42.1k
        self.data.read_at(range.start).unwrap()
5456
42.1k
    }
5457
5458
    /// y coordinate for the center of rotation. For variation, use
5459
    /// varIndexBase + 2.
5460
42.1k
    pub fn center_y(&self) -> FWord {
5461
42.1k
        let range = self.shape.center_y_byte_range();
5462
42.1k
        self.data.read_at(range.start).unwrap()
5463
42.1k
    }
5464
5465
    /// Base index into DeltaSetIndexMap.
5466
42.1k
    pub fn var_index_base(&self) -> u32 {
5467
42.1k
        let range = self.shape.var_index_base_byte_range();
5468
42.1k
        self.data.read_at(range.start).unwrap()
5469
42.1k
    }
5470
}
5471
5472
#[cfg(feature = "experimental_traverse")]
5473
impl<'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)]
5495
impl<'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
5501
impl 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)]
5508
pub struct PaintSkewMarker {}
5509
5510
impl PaintSkewMarker {
5511
86.5k
    pub fn format_byte_range(&self) -> Range<usize> {
5512
86.5k
        let start = 0;
5513
86.5k
        start..start + u8::RAW_BYTE_LEN
5514
86.5k
    }
5515
5516
86.5k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
5517
86.5k
        let start = self.format_byte_range().end;
5518
86.5k
        start..start + Offset24::RAW_BYTE_LEN
5519
86.5k
    }
5520
5521
57.7k
    pub fn x_skew_angle_byte_range(&self) -> Range<usize> {
5522
57.7k
        let start = self.paint_offset_byte_range().end;
5523
57.7k
        start..start + F2Dot14::RAW_BYTE_LEN
5524
57.7k
    }
5525
5526
28.8k
    pub fn y_skew_angle_byte_range(&self) -> Range<usize> {
5527
28.8k
        let start = self.x_skew_angle_byte_range().end;
5528
28.8k
        start..start + F2Dot14::RAW_BYTE_LEN
5529
28.8k
    }
5530
}
5531
5532
impl MinByteRange for PaintSkewMarker {
5533
0
    fn min_byte_range(&self) -> Range<usize> {
5534
0
        0..self.y_skew_angle_byte_range().end
5535
0
    }
5536
}
5537
5538
impl<'a> FontRead<'a> for PaintSkew<'a> {
5539
30.4k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
5540
30.4k
        let mut cursor = data.cursor();
5541
30.4k
        cursor.advance::<u8>();
5542
30.4k
        cursor.advance::<Offset24>();
5543
30.4k
        cursor.advance::<F2Dot14>();
5544
30.4k
        cursor.advance::<F2Dot14>();
5545
30.4k
        cursor.finish(PaintSkewMarker {})
5546
30.4k
    }
5547
}
5548
5549
/// [PaintSkew](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table
5550
pub type PaintSkew<'a> = TableRef<'a, PaintSkewMarker>;
5551
5552
#[allow(clippy::needless_lifetimes)]
5553
impl<'a> PaintSkew<'a> {
5554
    /// Set to 28.
5555
0
    pub fn format(&self) -> u8 {
5556
0
        let range = self.shape.format_byte_range();
5557
0
        self.data.read_at(range.start).unwrap()
5558
0
    }
5559
5560
    /// Offset to a Paint subtable.
5561
28.8k
    pub fn paint_offset(&self) -> Offset24 {
5562
28.8k
        let range = self.shape.paint_offset_byte_range();
5563
28.8k
        self.data.read_at(range.start).unwrap()
5564
28.8k
    }
5565
5566
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
5567
28.8k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
5568
28.8k
        let data = self.data;
5569
28.8k
        self.paint_offset().resolve(data)
5570
28.8k
    }
5571
5572
    /// Angle of skew in the direction of the x-axis, 180° in
5573
    /// counter-clockwise degrees per 1.0 of value.
5574
28.8k
    pub fn x_skew_angle(&self) -> F2Dot14 {
5575
28.8k
        let range = self.shape.x_skew_angle_byte_range();
5576
28.8k
        self.data.read_at(range.start).unwrap()
5577
28.8k
    }
5578
5579
    /// Angle of skew in the direction of the y-axis, 180° in
5580
    /// counter-clockwise degrees per 1.0 of value.
5581
28.8k
    pub fn y_skew_angle(&self) -> F2Dot14 {
5582
28.8k
        let range = self.shape.y_skew_angle_byte_range();
5583
28.8k
        self.data.read_at(range.start).unwrap()
5584
28.8k
    }
5585
}
5586
5587
#[cfg(feature = "experimental_traverse")]
5588
impl<'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)]
5608
impl<'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
5614
impl 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)]
5621
pub struct PaintVarSkewMarker {}
5622
5623
impl PaintVarSkewMarker {
5624
184k
    pub fn format_byte_range(&self) -> Range<usize> {
5625
184k
        let start = 0;
5626
184k
        start..start + u8::RAW_BYTE_LEN
5627
184k
    }
5628
5629
184k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
5630
184k
        let start = self.format_byte_range().end;
5631
184k
        start..start + Offset24::RAW_BYTE_LEN
5632
184k
    }
5633
5634
138k
    pub fn x_skew_angle_byte_range(&self) -> Range<usize> {
5635
138k
        let start = self.paint_offset_byte_range().end;
5636
138k
        start..start + F2Dot14::RAW_BYTE_LEN
5637
138k
    }
5638
5639
92.2k
    pub fn y_skew_angle_byte_range(&self) -> Range<usize> {
5640
92.2k
        let start = self.x_skew_angle_byte_range().end;
5641
92.2k
        start..start + F2Dot14::RAW_BYTE_LEN
5642
92.2k
    }
5643
5644
46.1k
    pub fn var_index_base_byte_range(&self) -> Range<usize> {
5645
46.1k
        let start = self.y_skew_angle_byte_range().end;
5646
46.1k
        start..start + u32::RAW_BYTE_LEN
5647
46.1k
    }
5648
}
5649
5650
impl MinByteRange for PaintVarSkewMarker {
5651
0
    fn min_byte_range(&self) -> Range<usize> {
5652
0
        0..self.var_index_base_byte_range().end
5653
0
    }
5654
}
5655
5656
impl<'a> FontRead<'a> for PaintVarSkew<'a> {
5657
48.1k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
5658
48.1k
        let mut cursor = data.cursor();
5659
48.1k
        cursor.advance::<u8>();
5660
48.1k
        cursor.advance::<Offset24>();
5661
48.1k
        cursor.advance::<F2Dot14>();
5662
48.1k
        cursor.advance::<F2Dot14>();
5663
48.1k
        cursor.advance::<u32>();
5664
48.1k
        cursor.finish(PaintVarSkewMarker {})
5665
48.1k
    }
5666
}
5667
5668
/// [PaintVarSkew](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table
5669
pub type PaintVarSkew<'a> = TableRef<'a, PaintVarSkewMarker>;
5670
5671
#[allow(clippy::needless_lifetimes)]
5672
impl<'a> PaintVarSkew<'a> {
5673
    /// Set to 29.
5674
0
    pub fn format(&self) -> u8 {
5675
0
        let range = self.shape.format_byte_range();
5676
0
        self.data.read_at(range.start).unwrap()
5677
0
    }
5678
5679
    /// Offset to a Paint subtable.
5680
46.1k
    pub fn paint_offset(&self) -> Offset24 {
5681
46.1k
        let range = self.shape.paint_offset_byte_range();
5682
46.1k
        self.data.read_at(range.start).unwrap()
5683
46.1k
    }
5684
5685
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
5686
46.1k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
5687
46.1k
        let data = self.data;
5688
46.1k
        self.paint_offset().resolve(data)
5689
46.1k
    }
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
46.1k
    pub fn x_skew_angle(&self) -> F2Dot14 {
5695
46.1k
        let range = self.shape.x_skew_angle_byte_range();
5696
46.1k
        self.data.read_at(range.start).unwrap()
5697
46.1k
    }
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
46.1k
    pub fn y_skew_angle(&self) -> F2Dot14 {
5703
46.1k
        let range = self.shape.y_skew_angle_byte_range();
5704
46.1k
        self.data.read_at(range.start).unwrap()
5705
46.1k
    }
5706
5707
    /// Base index into DeltaSetIndexMap.
5708
46.1k
    pub fn var_index_base(&self) -> u32 {
5709
46.1k
        let range = self.shape.var_index_base_byte_range();
5710
46.1k
        self.data.read_at(range.start).unwrap()
5711
46.1k
    }
5712
}
5713
5714
#[cfg(feature = "experimental_traverse")]
5715
impl<'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)]
5736
impl<'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
5742
impl 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)]
5749
pub struct PaintSkewAroundCenterMarker {}
5750
5751
impl PaintSkewAroundCenterMarker {
5752
101k
    pub fn format_byte_range(&self) -> Range<usize> {
5753
101k
        let start = 0;
5754
101k
        start..start + u8::RAW_BYTE_LEN
5755
101k
    }
5756
5757
101k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
5758
101k
        let start = self.format_byte_range().end;
5759
101k
        start..start + Offset24::RAW_BYTE_LEN
5760
101k
    }
5761
5762
81.0k
    pub fn x_skew_angle_byte_range(&self) -> Range<usize> {
5763
81.0k
        let start = self.paint_offset_byte_range().end;
5764
81.0k
        start..start + F2Dot14::RAW_BYTE_LEN
5765
81.0k
    }
5766
5767
60.7k
    pub fn y_skew_angle_byte_range(&self) -> Range<usize> {
5768
60.7k
        let start = self.x_skew_angle_byte_range().end;
5769
60.7k
        start..start + F2Dot14::RAW_BYTE_LEN
5770
60.7k
    }
5771
5772
40.5k
    pub fn center_x_byte_range(&self) -> Range<usize> {
5773
40.5k
        let start = self.y_skew_angle_byte_range().end;
5774
40.5k
        start..start + FWord::RAW_BYTE_LEN
5775
40.5k
    }
5776
5777
20.2k
    pub fn center_y_byte_range(&self) -> Range<usize> {
5778
20.2k
        let start = self.center_x_byte_range().end;
5779
20.2k
        start..start + FWord::RAW_BYTE_LEN
5780
20.2k
    }
5781
}
5782
5783
impl MinByteRange for PaintSkewAroundCenterMarker {
5784
0
    fn min_byte_range(&self) -> Range<usize> {
5785
0
        0..self.center_y_byte_range().end
5786
0
    }
5787
}
5788
5789
impl<'a> FontRead<'a> for PaintSkewAroundCenter<'a> {
5790
21.2k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
5791
21.2k
        let mut cursor = data.cursor();
5792
21.2k
        cursor.advance::<u8>();
5793
21.2k
        cursor.advance::<Offset24>();
5794
21.2k
        cursor.advance::<F2Dot14>();
5795
21.2k
        cursor.advance::<F2Dot14>();
5796
21.2k
        cursor.advance::<FWord>();
5797
21.2k
        cursor.advance::<FWord>();
5798
21.2k
        cursor.finish(PaintSkewAroundCenterMarker {})
5799
21.2k
    }
5800
}
5801
5802
/// [PaintSkewAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table
5803
pub type PaintSkewAroundCenter<'a> = TableRef<'a, PaintSkewAroundCenterMarker>;
5804
5805
#[allow(clippy::needless_lifetimes)]
5806
impl<'a> PaintSkewAroundCenter<'a> {
5807
    /// Set to 30.
5808
0
    pub fn format(&self) -> u8 {
5809
0
        let range = self.shape.format_byte_range();
5810
0
        self.data.read_at(range.start).unwrap()
5811
0
    }
5812
5813
    /// Offset to a Paint subtable.
5814
20.2k
    pub fn paint_offset(&self) -> Offset24 {
5815
20.2k
        let range = self.shape.paint_offset_byte_range();
5816
20.2k
        self.data.read_at(range.start).unwrap()
5817
20.2k
    }
5818
5819
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
5820
20.2k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
5821
20.2k
        let data = self.data;
5822
20.2k
        self.paint_offset().resolve(data)
5823
20.2k
    }
5824
5825
    /// Angle of skew in the direction of the x-axis, 180° in
5826
    /// counter-clockwise degrees per 1.0 of value.
5827
20.2k
    pub fn x_skew_angle(&self) -> F2Dot14 {
5828
20.2k
        let range = self.shape.x_skew_angle_byte_range();
5829
20.2k
        self.data.read_at(range.start).unwrap()
5830
20.2k
    }
5831
5832
    /// Angle of skew in the direction of the y-axis, 180° in
5833
    /// counter-clockwise degrees per 1.0 of value.
5834
20.2k
    pub fn y_skew_angle(&self) -> F2Dot14 {
5835
20.2k
        let range = self.shape.y_skew_angle_byte_range();
5836
20.2k
        self.data.read_at(range.start).unwrap()
5837
20.2k
    }
5838
5839
    /// x coordinate for the center of rotation.
5840
20.2k
    pub fn center_x(&self) -> FWord {
5841
20.2k
        let range = self.shape.center_x_byte_range();
5842
20.2k
        self.data.read_at(range.start).unwrap()
5843
20.2k
    }
5844
5845
    /// y coordinate for the center of rotation.
5846
20.2k
    pub fn center_y(&self) -> FWord {
5847
20.2k
        let range = self.shape.center_y_byte_range();
5848
20.2k
        self.data.read_at(range.start).unwrap()
5849
20.2k
    }
5850
}
5851
5852
#[cfg(feature = "experimental_traverse")]
5853
impl<'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)]
5875
impl<'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
5881
impl 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)]
5888
pub struct PaintVarSkewAroundCenterMarker {}
5889
5890
impl PaintVarSkewAroundCenterMarker {
5891
253k
    pub fn format_byte_range(&self) -> Range<usize> {
5892
253k
        let start = 0;
5893
253k
        start..start + u8::RAW_BYTE_LEN
5894
253k
    }
5895
5896
253k
    pub fn paint_offset_byte_range(&self) -> Range<usize> {
5897
253k
        let start = self.format_byte_range().end;
5898
253k
        start..start + Offset24::RAW_BYTE_LEN
5899
253k
    }
5900
5901
211k
    pub fn x_skew_angle_byte_range(&self) -> Range<usize> {
5902
211k
        let start = self.paint_offset_byte_range().end;
5903
211k
        start..start + F2Dot14::RAW_BYTE_LEN
5904
211k
    }
5905
5906
168k
    pub fn y_skew_angle_byte_range(&self) -> Range<usize> {
5907
168k
        let start = self.x_skew_angle_byte_range().end;
5908
168k
        start..start + F2Dot14::RAW_BYTE_LEN
5909
168k
    }
5910
5911
126k
    pub fn center_x_byte_range(&self) -> Range<usize> {
5912
126k
        let start = self.y_skew_angle_byte_range().end;
5913
126k
        start..start + FWord::RAW_BYTE_LEN
5914
126k
    }
5915
5916
84.4k
    pub fn center_y_byte_range(&self) -> Range<usize> {
5917
84.4k
        let start = self.center_x_byte_range().end;
5918
84.4k
        start..start + FWord::RAW_BYTE_LEN
5919
84.4k
    }
5920
5921
42.2k
    pub fn var_index_base_byte_range(&self) -> Range<usize> {
5922
42.2k
        let start = self.center_y_byte_range().end;
5923
42.2k
        start..start + u32::RAW_BYTE_LEN
5924
42.2k
    }
5925
}
5926
5927
impl MinByteRange for PaintVarSkewAroundCenterMarker {
5928
0
    fn min_byte_range(&self) -> Range<usize> {
5929
0
        0..self.var_index_base_byte_range().end
5930
0
    }
5931
}
5932
5933
impl<'a> FontRead<'a> for PaintVarSkewAroundCenter<'a> {
5934
51.4k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
5935
51.4k
        let mut cursor = data.cursor();
5936
51.4k
        cursor.advance::<u8>();
5937
51.4k
        cursor.advance::<Offset24>();
5938
51.4k
        cursor.advance::<F2Dot14>();
5939
51.4k
        cursor.advance::<F2Dot14>();
5940
51.4k
        cursor.advance::<FWord>();
5941
51.4k
        cursor.advance::<FWord>();
5942
51.4k
        cursor.advance::<u32>();
5943
51.4k
        cursor.finish(PaintVarSkewAroundCenterMarker {})
5944
51.4k
    }
5945
}
5946
5947
/// [PaintVarSkewAroundCenter](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#formats-28-to-31-paintskew-paintvarskew-paintskewaroundcenter-paintvarskewaroundcenter) table
5948
pub type PaintVarSkewAroundCenter<'a> = TableRef<'a, PaintVarSkewAroundCenterMarker>;
5949
5950
#[allow(clippy::needless_lifetimes)]
5951
impl<'a> PaintVarSkewAroundCenter<'a> {
5952
    /// Set to 31.
5953
0
    pub fn format(&self) -> u8 {
5954
0
        let range = self.shape.format_byte_range();
5955
0
        self.data.read_at(range.start).unwrap()
5956
0
    }
5957
5958
    /// Offset to a Paint subtable.
5959
42.2k
    pub fn paint_offset(&self) -> Offset24 {
5960
42.2k
        let range = self.shape.paint_offset_byte_range();
5961
42.2k
        self.data.read_at(range.start).unwrap()
5962
42.2k
    }
5963
5964
    /// Attempt to resolve [`paint_offset`][Self::paint_offset].
5965
42.2k
    pub fn paint(&self) -> Result<Paint<'a>, ReadError> {
5966
42.2k
        let data = self.data;
5967
42.2k
        self.paint_offset().resolve(data)
5968
42.2k
    }
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
42.2k
    pub fn x_skew_angle(&self) -> F2Dot14 {
5974
42.2k
        let range = self.shape.x_skew_angle_byte_range();
5975
42.2k
        self.data.read_at(range.start).unwrap()
5976
42.2k
    }
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
42.2k
    pub fn y_skew_angle(&self) -> F2Dot14 {
5982
42.2k
        let range = self.shape.y_skew_angle_byte_range();
5983
42.2k
        self.data.read_at(range.start).unwrap()
5984
42.2k
    }
5985
5986
    /// x coordinate for the center of rotation. For variation, use
5987
    /// varIndexBase + 2.
5988
42.2k
    pub fn center_x(&self) -> FWord {
5989
42.2k
        let range = self.shape.center_x_byte_range();
5990
42.2k
        self.data.read_at(range.start).unwrap()
5991
42.2k
    }
5992
5993
    /// y coordinate for the center of rotation. For variation, use
5994
    /// varIndexBase + 3.
5995
42.2k
    pub fn center_y(&self) -> FWord {
5996
42.2k
        let range = self.shape.center_y_byte_range();
5997
42.2k
        self.data.read_at(range.start).unwrap()
5998
42.2k
    }
5999
6000
    /// Base index into DeltaSetIndexMap.
6001
42.2k
    pub fn var_index_base(&self) -> u32 {
6002
42.2k
        let range = self.shape.var_index_base_byte_range();
6003
42.2k
        self.data.read_at(range.start).unwrap()
6004
42.2k
    }
6005
}
6006
6007
#[cfg(feature = "experimental_traverse")]
6008
impl<'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)]
6031
impl<'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
6037
impl 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)]
6044
pub struct PaintCompositeMarker {}
6045
6046
impl PaintCompositeMarker {
6047
1.47M
    pub fn format_byte_range(&self) -> Range<usize> {
6048
1.47M
        let start = 0;
6049
1.47M
        start..start + u8::RAW_BYTE_LEN
6050
1.47M
    }
6051
6052
1.47M
    pub fn source_paint_offset_byte_range(&self) -> Range<usize> {
6053
1.47M
        let start = self.format_byte_range().end;
6054
1.47M
        start..start + Offset24::RAW_BYTE_LEN
6055
1.47M
    }
6056
6057
944k
    pub fn composite_mode_byte_range(&self) -> Range<usize> {
6058
944k
        let start = self.source_paint_offset_byte_range().end;
6059
944k
        start..start + CompositeMode::RAW_BYTE_LEN
6060
944k
    }
6061
6062
472k
    pub fn backdrop_paint_offset_byte_range(&self) -> Range<usize> {
6063
472k
        let start = self.composite_mode_byte_range().end;
6064
472k
        start..start + Offset24::RAW_BYTE_LEN
6065
472k
    }
6066
}
6067
6068
impl MinByteRange for PaintCompositeMarker {
6069
0
    fn min_byte_range(&self) -> Range<usize> {
6070
0
        0..self.backdrop_paint_offset_byte_range().end
6071
0
    }
6072
}
6073
6074
impl<'a> FontRead<'a> for PaintComposite<'a> {
6075
526k
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
6076
526k
        let mut cursor = data.cursor();
6077
526k
        cursor.advance::<u8>();
6078
526k
        cursor.advance::<Offset24>();
6079
526k
        cursor.advance::<CompositeMode>();
6080
526k
        cursor.advance::<Offset24>();
6081
526k
        cursor.finish(PaintCompositeMarker {})
6082
526k
    }
6083
}
6084
6085
/// [PaintComposite](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite) table
6086
pub type PaintComposite<'a> = TableRef<'a, PaintCompositeMarker>;
6087
6088
#[allow(clippy::needless_lifetimes)]
6089
impl<'a> PaintComposite<'a> {
6090
    /// Set to 32.
6091
0
    pub fn format(&self) -> u8 {
6092
0
        let range = self.shape.format_byte_range();
6093
0
        self.data.read_at(range.start).unwrap()
6094
0
    }
6095
6096
    /// Offset to a source Paint table.
6097
529k
    pub fn source_paint_offset(&self) -> Offset24 {
6098
529k
        let range = self.shape.source_paint_offset_byte_range();
6099
529k
        self.data.read_at(range.start).unwrap()
6100
529k
    }
6101
6102
    /// Attempt to resolve [`source_paint_offset`][Self::source_paint_offset].
6103
529k
    pub fn source_paint(&self) -> Result<Paint<'a>, ReadError> {
6104
529k
        let data = self.data;
6105
529k
        self.source_paint_offset().resolve(data)
6106
529k
    }
6107
6108
    /// A CompositeMode enumeration value.
6109
472k
    pub fn composite_mode(&self) -> CompositeMode {
6110
472k
        let range = self.shape.composite_mode_byte_range();
6111
472k
        self.data.read_at(range.start).unwrap()
6112
472k
    }
6113
6114
    /// Offset to a backdrop Paint table.
6115
472k
    pub fn backdrop_paint_offset(&self) -> Offset24 {
6116
472k
        let range = self.shape.backdrop_paint_offset_byte_range();
6117
472k
        self.data.read_at(range.start).unwrap()
6118
472k
    }
6119
6120
    /// Attempt to resolve [`backdrop_paint_offset`][Self::backdrop_paint_offset].
6121
472k
    pub fn backdrop_paint(&self) -> Result<Paint<'a>, ReadError> {
6122
472k
        let data = self.data;
6123
472k
        self.backdrop_paint_offset().resolve(data)
6124
472k
    }
6125
}
6126
6127
#[cfg(feature = "experimental_traverse")]
6128
impl<'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)]
6151
impl<'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)]
6162
pub 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
6197
impl CompositeMode {
6198
    /// Create from a raw scalar.
6199
    ///
6200
    /// This will never fail; unknown values will be mapped to the `Unknown` variant
6201
472k
    pub fn new(raw: u8) -> Self {
6202
472k
        match raw {
6203
16.8k
            0 => Self::Clear,
6204
11.3k
            1 => Self::Src,
6205
12.2k
            2 => Self::Dest,
6206
46.6k
            3 => Self::SrcOver,
6207
209k
            4 => Self::DestOver,
6208
12.1k
            5 => Self::SrcIn,
6209
11.4k
            6 => Self::DestIn,
6210
11.3k
            7 => Self::SrcOut,
6211
12.5k
            8 => Self::DestOut,
6212
11.4k
            9 => Self::SrcAtop,
6213
405
            10 => Self::DestAtop,
6214
6.36k
            11 => Self::Xor,
6215
6.08k
            12 => Self::Plus,
6216
6.08k
            13 => Self::Screen,
6217
6.08k
            14 => Self::Overlay,
6218
6.05k
            15 => Self::Darken,
6219
5.97k
            16 => Self::Lighten,
6220
5.95k
            17 => Self::ColorDodge,
6221
6.03k
            18 => Self::ColorBurn,
6222
7.27k
            19 => Self::HardLight,
6223
6.04k
            20 => Self::SoftLight,
6224
6.05k
            21 => Self::Difference,
6225
6.31k
            22 => Self::Exclusion,
6226
6.06k
            23 => Self::Multiply,
6227
6.06k
            24 => Self::HslHue,
6228
5.34k
            25 => Self::HslSaturation,
6229
7.85k
            26 => Self::HslColor,
6230
7.71k
            27 => Self::HslLuminosity,
6231
9.18k
            _ => Self::Unknown,
6232
        }
6233
472k
    }
6234
}
6235
6236
impl font_types::Scalar for CompositeMode {
6237
    type Raw = <u8 as font_types::Scalar>::Raw;
6238
0
    fn to_raw(self) -> Self::Raw {
6239
0
        (self as u8).to_raw()
6240
0
    }
6241
472k
    fn from_raw(raw: Self::Raw) -> Self {
6242
472k
        let t = <u8>::from_raw(raw);
6243
472k
        Self::new(t)
6244
472k
    }
6245
}
6246
6247
#[cfg(feature = "experimental_traverse")]
6248
impl<'a> From<CompositeMode> for FieldType<'a> {
6249
    fn from(src: CompositeMode) -> FieldType<'a> {
6250
        (src as u8).into()
6251
    }
6252
}