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