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