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