1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8impl<'a> MinByteRange<'a> for Gdef<'a> {
9 fn min_byte_range(&self) -> Range<usize> {
10 0..self.mark_attach_class_def_offset_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 Gdef<'_> {
19 const TAG: Tag = Tag::new(b"GDEF");
21}
22
23impl ReadArgs for Gdef<'_> {
24 type Args = ();
25}
26
27impl<'a> FontRead<'a> for Gdef<'a> {
28 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
29 #[allow(clippy::absurd_extreme_comparisons)]
30 if data.len() < Self::MIN_SIZE {
31 return Err(ReadError::OutOfBounds);
32 }
33 Ok(Self { data })
34 }
35}
36
37#[derive(Clone)]
39pub struct Gdef<'a> {
40 data: FontData<'a>,
41}
42
43#[allow(clippy::needless_lifetimes)]
44impl<'a> Gdef<'a> {
45 pub const MIN_SIZE: usize = (MajorMinor::RAW_BYTE_LEN
46 + Offset16::RAW_BYTE_LEN
47 + Offset16::RAW_BYTE_LEN
48 + Offset16::RAW_BYTE_LEN
49 + Offset16::RAW_BYTE_LEN);
50 basic_table_impls!(impl_the_methods);
51
52 pub fn version(&self) -> MajorMinor {
54 let range = self.version_byte_range();
55 self.data.read_at(range.start).ok().unwrap()
56 }
57
58 pub fn glyph_class_def_offset(&self) -> Nullable<Offset16> {
61 let range = self.glyph_class_def_offset_byte_range();
62 self.data.read_at(range.start).ok().unwrap()
63 }
64
65 pub fn glyph_class_def(&self) -> Option<Result<ClassDef<'a>, ReadError>> {
67 let data = self.data;
68 self.glyph_class_def_offset().resolve(data)
69 }
70
71 pub fn attach_list_offset(&self) -> Nullable<Offset16> {
74 let range = self.attach_list_offset_byte_range();
75 self.data.read_at(range.start).ok().unwrap()
76 }
77
78 pub fn attach_list(&self) -> Option<Result<AttachList<'a>, ReadError>> {
80 let data = self.data;
81 self.attach_list_offset().resolve(data)
82 }
83
84 pub fn lig_caret_list_offset(&self) -> Nullable<Offset16> {
87 let range = self.lig_caret_list_offset_byte_range();
88 self.data.read_at(range.start).ok().unwrap()
89 }
90
91 pub fn lig_caret_list(&self) -> Option<Result<LigCaretList<'a>, ReadError>> {
93 let data = self.data;
94 self.lig_caret_list_offset().resolve(data)
95 }
96
97 pub fn mark_attach_class_def_offset(&self) -> Nullable<Offset16> {
100 let range = self.mark_attach_class_def_offset_byte_range();
101 self.data.read_at(range.start).ok().unwrap()
102 }
103
104 pub fn mark_attach_class_def(&self) -> Option<Result<ClassDef<'a>, ReadError>> {
106 let data = self.data;
107 self.mark_attach_class_def_offset().resolve(data)
108 }
109
110 pub fn mark_glyph_sets_def_offset(&self) -> Option<Nullable<Offset16>> {
113 let range = self.mark_glyph_sets_def_offset_byte_range();
114 (!range.is_empty())
115 .then(|| self.data.read_at(range.start).ok())
116 .flatten()
117 }
118
119 pub fn mark_glyph_sets_def(&self) -> Option<Result<MarkGlyphSets<'a>, ReadError>> {
121 let data = self.data;
122 self.mark_glyph_sets_def_offset().map(|x| x.resolve(data))?
123 }
124
125 pub fn item_var_store_offset(&self) -> Option<Nullable<Offset32>> {
128 let range = self.item_var_store_offset_byte_range();
129 (!range.is_empty())
130 .then(|| self.data.read_at(range.start).ok())
131 .flatten()
132 }
133
134 pub fn item_var_store(&self) -> Option<Result<ItemVariationStore<'a>, ReadError>> {
136 let data = self.data;
137 self.item_var_store_offset().map(|x| x.resolve(data))?
138 }
139
140 pub fn version_byte_range(&self) -> Range<usize> {
141 let start = 0;
142 let end = start + MajorMinor::RAW_BYTE_LEN;
143 start..end
144 }
145
146 pub fn glyph_class_def_offset_byte_range(&self) -> Range<usize> {
147 let start = self.version_byte_range().end;
148 let end = start + Offset16::RAW_BYTE_LEN;
149 start..end
150 }
151
152 pub fn attach_list_offset_byte_range(&self) -> Range<usize> {
153 let start = self.glyph_class_def_offset_byte_range().end;
154 let end = start + Offset16::RAW_BYTE_LEN;
155 start..end
156 }
157
158 pub fn lig_caret_list_offset_byte_range(&self) -> Range<usize> {
159 let start = self.attach_list_offset_byte_range().end;
160 let end = start + Offset16::RAW_BYTE_LEN;
161 start..end
162 }
163
164 pub fn mark_attach_class_def_offset_byte_range(&self) -> Range<usize> {
165 let start = self.lig_caret_list_offset_byte_range().end;
166 let end = start + Offset16::RAW_BYTE_LEN;
167 start..end
168 }
169
170 pub fn mark_glyph_sets_def_offset_byte_range(&self) -> Range<usize> {
171 let start = self.mark_attach_class_def_offset_byte_range().end;
172 let end = if self.version().compatible((1u16, 2u16)) {
173 start + Offset16::RAW_BYTE_LEN
174 } else {
175 start
176 };
177 start..end
178 }
179
180 pub fn item_var_store_offset_byte_range(&self) -> Range<usize> {
181 let start = self.mark_glyph_sets_def_offset_byte_range().end;
182 let end = if self.version().compatible((1u16, 3u16)) {
183 start + Offset32::RAW_BYTE_LEN
184 } else {
185 start
186 };
187 start..end
188 }
189}
190
191const _: () = assert!(FontData::default_data_long_enough(Gdef::MIN_SIZE));
192
193impl Default for Gdef<'_> {
194 fn default() -> Self {
195 Self {
196 data: FontData::default_table_data(),
197 }
198 }
199}
200
201#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
203#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
204#[repr(u16)]
205#[allow(clippy::manual_non_exhaustive)]
206pub enum GlyphClassDef {
207 #[default]
208 Base = 1,
209 Ligature = 2,
210 Mark = 3,
211 Component = 4,
212 #[doc(hidden)]
213 Unknown,
215}
216
217impl GlyphClassDef {
218 pub fn new(raw: u16) -> Self {
222 match raw {
223 1 => Self::Base,
224 2 => Self::Ligature,
225 3 => Self::Mark,
226 4 => Self::Component,
227 _ => Self::Unknown,
228 }
229 }
230}
231
232impl font_types::Scalar for GlyphClassDef {
233 type Raw = <u16 as font_types::Scalar>::Raw;
234 fn to_raw(self) -> Self::Raw {
235 (self as u16).to_raw()
236 }
237 fn from_raw(raw: Self::Raw) -> Self {
238 let t = <u16>::from_raw(raw);
239 Self::new(t)
240 }
241}
242
243impl<'a> MinByteRange<'a> for AttachList<'a> {
244 fn min_byte_range(&self) -> Range<usize> {
245 0..self.attach_point_offsets_byte_range().end
246 }
247 fn min_table_bytes(&self) -> &'a [u8] {
248 let range = self.min_byte_range();
249 self.data.as_bytes().get(range).unwrap_or_default()
250 }
251}
252
253impl ReadArgs for AttachList<'_> {
254 type Args = ();
255}
256
257impl<'a> FontRead<'a> for AttachList<'a> {
258 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
259 #[allow(clippy::absurd_extreme_comparisons)]
260 if data.len() < Self::MIN_SIZE {
261 return Err(ReadError::OutOfBounds);
262 }
263 Ok(Self { data })
264 }
265}
266
267#[derive(Clone)]
269pub struct AttachList<'a> {
270 data: FontData<'a>,
271}
272
273#[allow(clippy::needless_lifetimes)]
274impl<'a> AttachList<'a> {
275 pub const MIN_SIZE: usize = (Offset16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
276 basic_table_impls!(impl_the_methods);
277
278 pub fn coverage_offset(&self) -> Offset16 {
280 let range = self.coverage_offset_byte_range();
281 self.data.read_at(range.start).ok().unwrap()
282 }
283
284 pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
286 let data = self.data;
287 self.coverage_offset().resolve(data)
288 }
289
290 pub fn glyph_count(&self) -> u16 {
292 let range = self.glyph_count_byte_range();
293 self.data.read_at(range.start).ok().unwrap()
294 }
295
296 pub fn attach_point_offsets(&self) -> &'a [BigEndian<Offset16>] {
299 let range = self.attach_point_offsets_byte_range();
300 self.data.read_array(range).ok().unwrap_or_default()
301 }
302
303 pub fn attach_points(&self) -> ArrayOfOffsets<'a, AttachPoint<'a>, Offset16> {
305 let data = self.data;
306 let offsets = self.attach_point_offsets();
307 ArrayOfOffsets::new(offsets, data, ())
308 }
309
310 pub fn coverage_offset_byte_range(&self) -> Range<usize> {
311 let start = 0;
312 let end = start + Offset16::RAW_BYTE_LEN;
313 start..end
314 }
315
316 pub fn glyph_count_byte_range(&self) -> Range<usize> {
317 let start = self.coverage_offset_byte_range().end;
318 let end = start + u16::RAW_BYTE_LEN;
319 start..end
320 }
321
322 pub fn attach_point_offsets_byte_range(&self) -> Range<usize> {
323 let glyph_count = self.glyph_count();
324 let start = self.glyph_count_byte_range().end;
325 let end =
326 start + (transforms::to_usize(glyph_count)).saturating_mul(Offset16::RAW_BYTE_LEN);
327 start..end
328 }
329}
330
331const _: () = assert!(FontData::default_data_long_enough(AttachList::MIN_SIZE));
332
333impl Default for AttachList<'_> {
334 fn default() -> Self {
335 Self {
336 data: FontData::default_table_data(),
337 }
338 }
339}
340
341impl<'a> MinByteRange<'a> for AttachPoint<'a> {
342 fn min_byte_range(&self) -> Range<usize> {
343 0..self.point_indices_byte_range().end
344 }
345 fn min_table_bytes(&self) -> &'a [u8] {
346 let range = self.min_byte_range();
347 self.data.as_bytes().get(range).unwrap_or_default()
348 }
349}
350
351impl ReadArgs for AttachPoint<'_> {
352 type Args = ();
353}
354
355impl<'a> FontRead<'a> for AttachPoint<'a> {
356 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
357 #[allow(clippy::absurd_extreme_comparisons)]
358 if data.len() < Self::MIN_SIZE {
359 return Err(ReadError::OutOfBounds);
360 }
361 Ok(Self { data })
362 }
363}
364
365#[derive(Clone)]
367pub struct AttachPoint<'a> {
368 data: FontData<'a>,
369}
370
371#[allow(clippy::needless_lifetimes)]
372impl<'a> AttachPoint<'a> {
373 pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
374 basic_table_impls!(impl_the_methods);
375
376 pub fn point_count(&self) -> u16 {
378 let range = self.point_count_byte_range();
379 self.data.read_at(range.start).ok().unwrap()
380 }
381
382 pub fn point_indices(&self) -> &'a [BigEndian<u16>] {
384 let range = self.point_indices_byte_range();
385 self.data.read_array(range).ok().unwrap_or_default()
386 }
387
388 pub fn point_count_byte_range(&self) -> Range<usize> {
389 let start = 0;
390 let end = start + u16::RAW_BYTE_LEN;
391 start..end
392 }
393
394 pub fn point_indices_byte_range(&self) -> Range<usize> {
395 let point_count = self.point_count();
396 let start = self.point_count_byte_range().end;
397 let end = start + (transforms::to_usize(point_count)).saturating_mul(u16::RAW_BYTE_LEN);
398 start..end
399 }
400}
401
402const _: () = assert!(FontData::default_data_long_enough(AttachPoint::MIN_SIZE));
403
404impl Default for AttachPoint<'_> {
405 fn default() -> Self {
406 Self {
407 data: FontData::default_table_data(),
408 }
409 }
410}
411
412impl<'a> MinByteRange<'a> for LigCaretList<'a> {
413 fn min_byte_range(&self) -> Range<usize> {
414 0..self.lig_glyph_offsets_byte_range().end
415 }
416 fn min_table_bytes(&self) -> &'a [u8] {
417 let range = self.min_byte_range();
418 self.data.as_bytes().get(range).unwrap_or_default()
419 }
420}
421
422impl ReadArgs for LigCaretList<'_> {
423 type Args = ();
424}
425
426impl<'a> FontRead<'a> for LigCaretList<'a> {
427 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
428 #[allow(clippy::absurd_extreme_comparisons)]
429 if data.len() < Self::MIN_SIZE {
430 return Err(ReadError::OutOfBounds);
431 }
432 Ok(Self { data })
433 }
434}
435
436#[derive(Clone)]
438pub struct LigCaretList<'a> {
439 data: FontData<'a>,
440}
441
442#[allow(clippy::needless_lifetimes)]
443impl<'a> LigCaretList<'a> {
444 pub const MIN_SIZE: usize = (Offset16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
445 basic_table_impls!(impl_the_methods);
446
447 pub fn coverage_offset(&self) -> Offset16 {
449 let range = self.coverage_offset_byte_range();
450 self.data.read_at(range.start).ok().unwrap()
451 }
452
453 pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
455 let data = self.data;
456 self.coverage_offset().resolve(data)
457 }
458
459 pub fn lig_glyph_count(&self) -> u16 {
461 let range = self.lig_glyph_count_byte_range();
462 self.data.read_at(range.start).ok().unwrap()
463 }
464
465 pub fn lig_glyph_offsets(&self) -> &'a [BigEndian<Offset16>] {
468 let range = self.lig_glyph_offsets_byte_range();
469 self.data.read_array(range).ok().unwrap_or_default()
470 }
471
472 pub fn lig_glyphs(&self) -> ArrayOfOffsets<'a, LigGlyph<'a>, Offset16> {
474 let data = self.data;
475 let offsets = self.lig_glyph_offsets();
476 ArrayOfOffsets::new(offsets, data, ())
477 }
478
479 pub fn coverage_offset_byte_range(&self) -> Range<usize> {
480 let start = 0;
481 let end = start + Offset16::RAW_BYTE_LEN;
482 start..end
483 }
484
485 pub fn lig_glyph_count_byte_range(&self) -> Range<usize> {
486 let start = self.coverage_offset_byte_range().end;
487 let end = start + u16::RAW_BYTE_LEN;
488 start..end
489 }
490
491 pub fn lig_glyph_offsets_byte_range(&self) -> Range<usize> {
492 let lig_glyph_count = self.lig_glyph_count();
493 let start = self.lig_glyph_count_byte_range().end;
494 let end =
495 start + (transforms::to_usize(lig_glyph_count)).saturating_mul(Offset16::RAW_BYTE_LEN);
496 start..end
497 }
498}
499
500const _: () = assert!(FontData::default_data_long_enough(LigCaretList::MIN_SIZE));
501
502impl Default for LigCaretList<'_> {
503 fn default() -> Self {
504 Self {
505 data: FontData::default_table_data(),
506 }
507 }
508}
509
510impl<'a> MinByteRange<'a> for LigGlyph<'a> {
511 fn min_byte_range(&self) -> Range<usize> {
512 0..self.caret_value_offsets_byte_range().end
513 }
514 fn min_table_bytes(&self) -> &'a [u8] {
515 let range = self.min_byte_range();
516 self.data.as_bytes().get(range).unwrap_or_default()
517 }
518}
519
520impl ReadArgs for LigGlyph<'_> {
521 type Args = ();
522}
523
524impl<'a> FontRead<'a> for LigGlyph<'a> {
525 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
526 #[allow(clippy::absurd_extreme_comparisons)]
527 if data.len() < Self::MIN_SIZE {
528 return Err(ReadError::OutOfBounds);
529 }
530 Ok(Self { data })
531 }
532}
533
534#[derive(Clone)]
536pub struct LigGlyph<'a> {
537 data: FontData<'a>,
538}
539
540#[allow(clippy::needless_lifetimes)]
541impl<'a> LigGlyph<'a> {
542 pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
543 basic_table_impls!(impl_the_methods);
544
545 pub fn caret_count(&self) -> u16 {
547 let range = self.caret_count_byte_range();
548 self.data.read_at(range.start).ok().unwrap()
549 }
550
551 pub fn caret_value_offsets(&self) -> &'a [BigEndian<Offset16>] {
554 let range = self.caret_value_offsets_byte_range();
555 self.data.read_array(range).ok().unwrap_or_default()
556 }
557
558 pub fn caret_values(&self) -> ArrayOfOffsets<'a, CaretValue<'a>, Offset16> {
560 let data = self.data;
561 let offsets = self.caret_value_offsets();
562 ArrayOfOffsets::new(offsets, data, ())
563 }
564
565 pub fn caret_count_byte_range(&self) -> Range<usize> {
566 let start = 0;
567 let end = start + u16::RAW_BYTE_LEN;
568 start..end
569 }
570
571 pub fn caret_value_offsets_byte_range(&self) -> Range<usize> {
572 let caret_count = self.caret_count();
573 let start = self.caret_count_byte_range().end;
574 let end =
575 start + (transforms::to_usize(caret_count)).saturating_mul(Offset16::RAW_BYTE_LEN);
576 start..end
577 }
578}
579
580const _: () = assert!(FontData::default_data_long_enough(LigGlyph::MIN_SIZE));
581
582impl Default for LigGlyph<'_> {
583 fn default() -> Self {
584 Self {
585 data: FontData::default_table_data(),
586 }
587 }
588}
589
590#[derive(Clone)]
592pub enum CaretValue<'a> {
593 Format1(CaretValueFormat1<'a>),
594 Format2(CaretValueFormat2<'a>),
595 Format3(CaretValueFormat3<'a>),
596}
597
598impl Default for CaretValue<'_> {
599 fn default() -> Self {
600 Self::Format1(Default::default())
601 }
602}
603
604impl<'a> CaretValue<'a> {
605 pub fn offset_data(&self) -> FontData<'a> {
607 match self {
608 Self::Format1(item) => item.offset_data(),
609 Self::Format2(item) => item.offset_data(),
610 Self::Format3(item) => item.offset_data(),
611 }
612 }
613
614 pub fn caret_value_format(&self) -> u16 {
616 match self {
617 Self::Format1(item) => item.caret_value_format(),
618 Self::Format2(item) => item.caret_value_format(),
619 Self::Format3(item) => item.caret_value_format(),
620 }
621 }
622}
623
624impl ReadArgs for CaretValue<'_> {
625 type Args = ();
626}
627
628impl<'a> FontRead<'a> for CaretValue<'a> {
629 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
630 let format: u16 = data.read_at(0usize)?;
631 match format {
632 CaretValueFormat1::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
633 CaretValueFormat2::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
634 CaretValueFormat3::FORMAT => Ok(Self::Format3(FontRead::read(data)?)),
635 other => Err(ReadError::InvalidFormat(other.into())),
636 }
637 }
638}
639
640impl<'a> MinByteRange<'a> for CaretValue<'a> {
641 fn min_byte_range(&self) -> Range<usize> {
642 match self {
643 Self::Format1(item) => item.min_byte_range(),
644 Self::Format2(item) => item.min_byte_range(),
645 Self::Format3(item) => item.min_byte_range(),
646 }
647 }
648 fn min_table_bytes(&self) -> &'a [u8] {
649 match self {
650 Self::Format1(item) => item.min_table_bytes(),
651 Self::Format2(item) => item.min_table_bytes(),
652 Self::Format3(item) => item.min_table_bytes(),
653 }
654 }
655}
656
657impl Format<u16> for CaretValueFormat1<'_> {
658 const FORMAT: u16 = 1;
659}
660
661impl<'a> MinByteRange<'a> for CaretValueFormat1<'a> {
662 fn min_byte_range(&self) -> Range<usize> {
663 0..self.coordinate_byte_range().end
664 }
665 fn min_table_bytes(&self) -> &'a [u8] {
666 let range = self.min_byte_range();
667 self.data.as_bytes().get(range).unwrap_or_default()
668 }
669}
670
671impl ReadArgs for CaretValueFormat1<'_> {
672 type Args = ();
673}
674
675impl<'a> FontRead<'a> for CaretValueFormat1<'a> {
676 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
677 #[allow(clippy::absurd_extreme_comparisons)]
678 if data.len() < Self::MIN_SIZE {
679 return Err(ReadError::OutOfBounds);
680 }
681 Ok(Self { data })
682 }
683}
684
685#[derive(Clone)]
687pub struct CaretValueFormat1<'a> {
688 data: FontData<'a>,
689}
690
691#[allow(clippy::needless_lifetimes)]
692impl<'a> CaretValueFormat1<'a> {
693 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + i16::RAW_BYTE_LEN);
694 basic_table_impls!(impl_the_methods);
695
696 pub fn caret_value_format(&self) -> u16 {
698 let range = self.caret_value_format_byte_range();
699 self.data.read_at(range.start).ok().unwrap()
700 }
701
702 pub fn coordinate(&self) -> i16 {
704 let range = self.coordinate_byte_range();
705 self.data.read_at(range.start).ok().unwrap()
706 }
707
708 pub fn caret_value_format_byte_range(&self) -> Range<usize> {
709 let start = 0;
710 let end = start + u16::RAW_BYTE_LEN;
711 start..end
712 }
713
714 pub fn coordinate_byte_range(&self) -> Range<usize> {
715 let start = self.caret_value_format_byte_range().end;
716 let end = start + i16::RAW_BYTE_LEN;
717 start..end
718 }
719}
720
721const _: () = assert!(FontData::default_data_long_enough(
722 CaretValueFormat1::MIN_SIZE
723));
724
725impl Default for CaretValueFormat1<'_> {
726 fn default() -> Self {
727 Self {
728 data: FontData::default_format_1_u16_table_data(),
729 }
730 }
731}
732
733impl Format<u16> for CaretValueFormat2<'_> {
734 const FORMAT: u16 = 2;
735}
736
737impl<'a> MinByteRange<'a> for CaretValueFormat2<'a> {
738 fn min_byte_range(&self) -> Range<usize> {
739 0..self.caret_value_point_index_byte_range().end
740 }
741 fn min_table_bytes(&self) -> &'a [u8] {
742 let range = self.min_byte_range();
743 self.data.as_bytes().get(range).unwrap_or_default()
744 }
745}
746
747impl ReadArgs for CaretValueFormat2<'_> {
748 type Args = ();
749}
750
751impl<'a> FontRead<'a> for CaretValueFormat2<'a> {
752 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
753 #[allow(clippy::absurd_extreme_comparisons)]
754 if data.len() < Self::MIN_SIZE {
755 return Err(ReadError::OutOfBounds);
756 }
757 Ok(Self { data })
758 }
759}
760
761#[derive(Clone)]
763pub struct CaretValueFormat2<'a> {
764 data: FontData<'a>,
765}
766
767#[allow(clippy::needless_lifetimes)]
768impl<'a> CaretValueFormat2<'a> {
769 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
770 basic_table_impls!(impl_the_methods);
771
772 pub fn caret_value_format(&self) -> u16 {
774 let range = self.caret_value_format_byte_range();
775 self.data.read_at(range.start).ok().unwrap()
776 }
777
778 pub fn caret_value_point_index(&self) -> u16 {
780 let range = self.caret_value_point_index_byte_range();
781 self.data.read_at(range.start).ok().unwrap()
782 }
783
784 pub fn caret_value_format_byte_range(&self) -> Range<usize> {
785 let start = 0;
786 let end = start + u16::RAW_BYTE_LEN;
787 start..end
788 }
789
790 pub fn caret_value_point_index_byte_range(&self) -> Range<usize> {
791 let start = self.caret_value_format_byte_range().end;
792 let end = start + u16::RAW_BYTE_LEN;
793 start..end
794 }
795}
796
797impl Format<u16> for CaretValueFormat3<'_> {
798 const FORMAT: u16 = 3;
799}
800
801impl<'a> MinByteRange<'a> for CaretValueFormat3<'a> {
802 fn min_byte_range(&self) -> Range<usize> {
803 0..self.device_offset_byte_range().end
804 }
805 fn min_table_bytes(&self) -> &'a [u8] {
806 let range = self.min_byte_range();
807 self.data.as_bytes().get(range).unwrap_or_default()
808 }
809}
810
811impl ReadArgs for CaretValueFormat3<'_> {
812 type Args = ();
813}
814
815impl<'a> FontRead<'a> for CaretValueFormat3<'a> {
816 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
817 #[allow(clippy::absurd_extreme_comparisons)]
818 if data.len() < Self::MIN_SIZE {
819 return Err(ReadError::OutOfBounds);
820 }
821 Ok(Self { data })
822 }
823}
824
825#[derive(Clone)]
827pub struct CaretValueFormat3<'a> {
828 data: FontData<'a>,
829}
830
831#[allow(clippy::needless_lifetimes)]
832impl<'a> CaretValueFormat3<'a> {
833 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + i16::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN);
834 basic_table_impls!(impl_the_methods);
835
836 pub fn caret_value_format(&self) -> u16 {
838 let range = self.caret_value_format_byte_range();
839 self.data.read_at(range.start).ok().unwrap()
840 }
841
842 pub fn coordinate(&self) -> i16 {
844 let range = self.coordinate_byte_range();
845 self.data.read_at(range.start).ok().unwrap()
846 }
847
848 pub fn device_offset(&self) -> Offset16 {
852 let range = self.device_offset_byte_range();
853 self.data.read_at(range.start).ok().unwrap()
854 }
855
856 pub fn device(&self) -> Result<DeviceOrVariationIndex<'a>, ReadError> {
858 let data = self.data;
859 self.device_offset().resolve(data)
860 }
861
862 pub fn caret_value_format_byte_range(&self) -> Range<usize> {
863 let start = 0;
864 let end = start + u16::RAW_BYTE_LEN;
865 start..end
866 }
867
868 pub fn coordinate_byte_range(&self) -> Range<usize> {
869 let start = self.caret_value_format_byte_range().end;
870 let end = start + i16::RAW_BYTE_LEN;
871 start..end
872 }
873
874 pub fn device_offset_byte_range(&self) -> Range<usize> {
875 let start = self.coordinate_byte_range().end;
876 let end = start + Offset16::RAW_BYTE_LEN;
877 start..end
878 }
879}
880
881impl Format<u16> for MarkGlyphSets<'_> {
882 const FORMAT: u16 = 1;
883}
884
885impl<'a> MinByteRange<'a> for MarkGlyphSets<'a> {
886 fn min_byte_range(&self) -> Range<usize> {
887 0..self.coverage_offsets_byte_range().end
888 }
889 fn min_table_bytes(&self) -> &'a [u8] {
890 let range = self.min_byte_range();
891 self.data.as_bytes().get(range).unwrap_or_default()
892 }
893}
894
895impl ReadArgs for MarkGlyphSets<'_> {
896 type Args = ();
897}
898
899impl<'a> FontRead<'a> for MarkGlyphSets<'a> {
900 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
901 #[allow(clippy::absurd_extreme_comparisons)]
902 if data.len() < Self::MIN_SIZE {
903 return Err(ReadError::OutOfBounds);
904 }
905 Ok(Self { data })
906 }
907}
908
909#[derive(Clone)]
911pub struct MarkGlyphSets<'a> {
912 data: FontData<'a>,
913}
914
915#[allow(clippy::needless_lifetimes)]
916impl<'a> MarkGlyphSets<'a> {
917 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
918 basic_table_impls!(impl_the_methods);
919
920 pub fn format(&self) -> u16 {
922 let range = self.format_byte_range();
923 self.data.read_at(range.start).ok().unwrap()
924 }
925
926 pub fn mark_glyph_set_count(&self) -> u16 {
928 let range = self.mark_glyph_set_count_byte_range();
929 self.data.read_at(range.start).ok().unwrap()
930 }
931
932 pub fn coverage_offsets(&self) -> &'a [BigEndian<Offset32>] {
935 let range = self.coverage_offsets_byte_range();
936 self.data.read_array(range).ok().unwrap_or_default()
937 }
938
939 pub fn coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset32> {
941 let data = self.data;
942 let offsets = self.coverage_offsets();
943 ArrayOfOffsets::new(offsets, data, ())
944 }
945
946 pub fn format_byte_range(&self) -> Range<usize> {
947 let start = 0;
948 let end = start + u16::RAW_BYTE_LEN;
949 start..end
950 }
951
952 pub fn mark_glyph_set_count_byte_range(&self) -> Range<usize> {
953 let start = self.format_byte_range().end;
954 let end = start + u16::RAW_BYTE_LEN;
955 start..end
956 }
957
958 pub fn coverage_offsets_byte_range(&self) -> Range<usize> {
959 let mark_glyph_set_count = self.mark_glyph_set_count();
960 let start = self.mark_glyph_set_count_byte_range().end;
961 let end = start
962 + (transforms::to_usize(mark_glyph_set_count)).saturating_mul(Offset32::RAW_BYTE_LEN);
963 start..end
964 }
965}
966
967const _: () = assert!(FontData::default_data_long_enough(MarkGlyphSets::MIN_SIZE));
968
969impl Default for MarkGlyphSets<'_> {
970 fn default() -> Self {
971 Self {
972 data: FontData::default_format_1_u16_table_data(),
973 }
974 }
975}