1 // THIS FILE IS AUTOGENERATED.
2 // Any changes to this file will be overwritten.
3 // For more information about how codegen works, see font-codegen/README.md
4 
5 #[allow(unused_imports)]
6 use crate::codegen_prelude::*;
7 
8 /// [Class Definition Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-1)
9 /// [GPOS Version 1.0](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#gpos-header)
10 #[derive(Debug, Clone, Copy)]
11 #[doc(hidden)]
12 pub struct GposMarker {
13     feature_variations_offset_byte_start: Option<usize>,
14 }
15 
16 impl GposMarker {
version_byte_range(&self) -> Range<usize>17     fn version_byte_range(&self) -> Range<usize> {
18         let start = 0;
19         start..start + MajorMinor::RAW_BYTE_LEN
20     }
script_list_offset_byte_range(&self) -> Range<usize>21     fn script_list_offset_byte_range(&self) -> Range<usize> {
22         let start = self.version_byte_range().end;
23         start..start + Offset16::RAW_BYTE_LEN
24     }
feature_list_offset_byte_range(&self) -> Range<usize>25     fn feature_list_offset_byte_range(&self) -> Range<usize> {
26         let start = self.script_list_offset_byte_range().end;
27         start..start + Offset16::RAW_BYTE_LEN
28     }
lookup_list_offset_byte_range(&self) -> Range<usize>29     fn lookup_list_offset_byte_range(&self) -> Range<usize> {
30         let start = self.feature_list_offset_byte_range().end;
31         start..start + Offset16::RAW_BYTE_LEN
32     }
feature_variations_offset_byte_range(&self) -> Option<Range<usize>>33     fn feature_variations_offset_byte_range(&self) -> Option<Range<usize>> {
34         let start = self.feature_variations_offset_byte_start?;
35         Some(start..start + Offset32::RAW_BYTE_LEN)
36     }
37 }
38 
39 impl TopLevelTable for Gpos<'_> {
40     /// `GPOS`
41     const TAG: Tag = Tag::new(b"GPOS");
42 }
43 
44 impl<'a> FontRead<'a> for Gpos<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>45     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
46         let mut cursor = data.cursor();
47         let version: MajorMinor = cursor.read()?;
48         cursor.advance::<Offset16>();
49         cursor.advance::<Offset16>();
50         cursor.advance::<Offset16>();
51         let feature_variations_offset_byte_start = version
52             .compatible((1, 1))
53             .then(|| cursor.position())
54             .transpose()?;
55         version
56             .compatible((1, 1))
57             .then(|| cursor.advance::<Offset32>());
58         cursor.finish(GposMarker {
59             feature_variations_offset_byte_start,
60         })
61     }
62 }
63 
64 /// [Class Definition Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-1)
65 /// [GPOS Version 1.0](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#gpos-header)
66 pub type Gpos<'a> = TableRef<'a, GposMarker>;
67 
68 impl<'a> Gpos<'a> {
69     /// The major and minor version of the GPOS table, as a tuple (u16, u16)
version(&self) -> MajorMinor70     pub fn version(&self) -> MajorMinor {
71         let range = self.shape.version_byte_range();
72         self.data.read_at(range.start).unwrap()
73     }
74 
75     /// Offset to ScriptList table, from beginning of GPOS table
script_list_offset(&self) -> Offset1676     pub fn script_list_offset(&self) -> Offset16 {
77         let range = self.shape.script_list_offset_byte_range();
78         self.data.read_at(range.start).unwrap()
79     }
80 
81     /// Attempt to resolve [`script_list_offset`][Self::script_list_offset].
script_list(&self) -> Result<ScriptList<'a>, ReadError>82     pub fn script_list(&self) -> Result<ScriptList<'a>, ReadError> {
83         let data = self.data;
84         self.script_list_offset().resolve(data)
85     }
86 
87     /// Offset to FeatureList table, from beginning of GPOS table
feature_list_offset(&self) -> Offset1688     pub fn feature_list_offset(&self) -> Offset16 {
89         let range = self.shape.feature_list_offset_byte_range();
90         self.data.read_at(range.start).unwrap()
91     }
92 
93     /// Attempt to resolve [`feature_list_offset`][Self::feature_list_offset].
feature_list(&self) -> Result<FeatureList<'a>, ReadError>94     pub fn feature_list(&self) -> Result<FeatureList<'a>, ReadError> {
95         let data = self.data;
96         self.feature_list_offset().resolve(data)
97     }
98 
99     /// Offset to LookupList table, from beginning of GPOS table
lookup_list_offset(&self) -> Offset16100     pub fn lookup_list_offset(&self) -> Offset16 {
101         let range = self.shape.lookup_list_offset_byte_range();
102         self.data.read_at(range.start).unwrap()
103     }
104 
105     /// Attempt to resolve [`lookup_list_offset`][Self::lookup_list_offset].
lookup_list(&self) -> Result<PositionLookupList<'a>, ReadError>106     pub fn lookup_list(&self) -> Result<PositionLookupList<'a>, ReadError> {
107         let data = self.data;
108         self.lookup_list_offset().resolve(data)
109     }
110 
feature_variations_offset(&self) -> Option<Nullable<Offset32>>111     pub fn feature_variations_offset(&self) -> Option<Nullable<Offset32>> {
112         let range = self.shape.feature_variations_offset_byte_range()?;
113         Some(self.data.read_at(range.start).unwrap())
114     }
115 
116     /// Attempt to resolve [`feature_variations_offset`][Self::feature_variations_offset].
feature_variations(&self) -> Option<Result<FeatureVariations<'a>, ReadError>>117     pub fn feature_variations(&self) -> Option<Result<FeatureVariations<'a>, ReadError>> {
118         let data = self.data;
119         self.feature_variations_offset().map(|x| x.resolve(data))?
120     }
121 }
122 
123 #[cfg(feature = "traversal")]
124 impl<'a> SomeTable<'a> for Gpos<'a> {
type_name(&self) -> &str125     fn type_name(&self) -> &str {
126         "Gpos"
127     }
get_field(&self, idx: usize) -> Option<Field<'a>>128     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
129         let version = self.version();
130         match idx {
131             0usize => Some(Field::new("version", self.version())),
132             1usize => Some(Field::new(
133                 "script_list_offset",
134                 FieldType::offset(self.script_list_offset(), self.script_list()),
135             )),
136             2usize => Some(Field::new(
137                 "feature_list_offset",
138                 FieldType::offset(self.feature_list_offset(), self.feature_list()),
139             )),
140             3usize => Some(Field::new(
141                 "lookup_list_offset",
142                 FieldType::offset(self.lookup_list_offset(), self.lookup_list()),
143             )),
144             4usize if version.compatible((1, 1)) => Some(Field::new(
145                 "feature_variations_offset",
146                 FieldType::offset(
147                     self.feature_variations_offset().unwrap(),
148                     self.feature_variations().unwrap(),
149                 ),
150             )),
151             _ => None,
152         }
153     }
154 }
155 
156 #[cfg(feature = "traversal")]
157 impl<'a> std::fmt::Debug for Gpos<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result158     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
159         (self as &dyn SomeTable<'a>).fmt(f)
160     }
161 }
162 
163 /// A [GPOS Lookup](https://learn.microsoft.com/en-us/typography/opentype/spec/gpos#gsubLookupTypeEnum) subtable.
164 pub enum PositionLookup<'a> {
165     Single(Lookup<'a, SinglePos<'a>>),
166     Pair(Lookup<'a, PairPos<'a>>),
167     Cursive(Lookup<'a, CursivePosFormat1<'a>>),
168     MarkToBase(Lookup<'a, MarkBasePosFormat1<'a>>),
169     MarkToLig(Lookup<'a, MarkLigPosFormat1<'a>>),
170     MarkToMark(Lookup<'a, MarkMarkPosFormat1<'a>>),
171     Contextual(Lookup<'a, PositionSequenceContext<'a>>),
172     ChainContextual(Lookup<'a, PositionChainContext<'a>>),
173     Extension(Lookup<'a, ExtensionSubtable<'a>>),
174 }
175 
176 impl<'a> FontRead<'a> for PositionLookup<'a> {
read(bytes: FontData<'a>) -> Result<Self, ReadError>177     fn read(bytes: FontData<'a>) -> Result<Self, ReadError> {
178         let untyped = Lookup::read(bytes)?;
179         match untyped.lookup_type() {
180             1 => Ok(PositionLookup::Single(untyped.into_concrete())),
181             2 => Ok(PositionLookup::Pair(untyped.into_concrete())),
182             3 => Ok(PositionLookup::Cursive(untyped.into_concrete())),
183             4 => Ok(PositionLookup::MarkToBase(untyped.into_concrete())),
184             5 => Ok(PositionLookup::MarkToLig(untyped.into_concrete())),
185             6 => Ok(PositionLookup::MarkToMark(untyped.into_concrete())),
186             7 => Ok(PositionLookup::Contextual(untyped.into_concrete())),
187             8 => Ok(PositionLookup::ChainContextual(untyped.into_concrete())),
188             9 => Ok(PositionLookup::Extension(untyped.into_concrete())),
189             other => Err(ReadError::InvalidFormat(other.into())),
190         }
191     }
192 }
193 
194 impl<'a> PositionLookup<'a> {
195     #[allow(dead_code)]
196     /// Return the inner table, removing the specific generics.
197     ///
198     /// This lets us return a single concrete type we can call methods on.
of_unit_type(&self) -> Lookup<'a, ()>199     pub(crate) fn of_unit_type(&self) -> Lookup<'a, ()> {
200         match self {
201             PositionLookup::Single(inner) => inner.of_unit_type(),
202             PositionLookup::Pair(inner) => inner.of_unit_type(),
203             PositionLookup::Cursive(inner) => inner.of_unit_type(),
204             PositionLookup::MarkToBase(inner) => inner.of_unit_type(),
205             PositionLookup::MarkToLig(inner) => inner.of_unit_type(),
206             PositionLookup::MarkToMark(inner) => inner.of_unit_type(),
207             PositionLookup::Contextual(inner) => inner.of_unit_type(),
208             PositionLookup::ChainContextual(inner) => inner.of_unit_type(),
209             PositionLookup::Extension(inner) => inner.of_unit_type(),
210         }
211     }
212 }
213 
214 #[cfg(feature = "traversal")]
215 impl<'a> PositionLookup<'a> {
dyn_inner(&self) -> &(dyn SomeTable<'a> + 'a)216     fn dyn_inner(&self) -> &(dyn SomeTable<'a> + 'a) {
217         match self {
218             PositionLookup::Single(table) => table,
219             PositionLookup::Pair(table) => table,
220             PositionLookup::Cursive(table) => table,
221             PositionLookup::MarkToBase(table) => table,
222             PositionLookup::MarkToLig(table) => table,
223             PositionLookup::MarkToMark(table) => table,
224             PositionLookup::Contextual(table) => table,
225             PositionLookup::ChainContextual(table) => table,
226             PositionLookup::Extension(table) => table,
227         }
228     }
229 }
230 
231 #[cfg(feature = "traversal")]
232 impl<'a> SomeTable<'a> for PositionLookup<'a> {
get_field(&self, idx: usize) -> Option<Field<'a>>233     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
234         self.dyn_inner().get_field(idx)
235     }
type_name(&self) -> &str236     fn type_name(&self) -> &str {
237         self.dyn_inner().type_name()
238     }
239 }
240 
241 #[cfg(feature = "traversal")]
242 impl<'a> std::fmt::Debug for PositionLookup<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result243     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
244         self.dyn_inner().fmt(f)
245     }
246 }
247 
248 /// See [ValueRecord]
249 #[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
250 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
251 pub struct ValueFormat {
252     bits: u16,
253 }
254 
255 impl ValueFormat {
256     /// Includes horizontal adjustment for placement
257     pub const X_PLACEMENT: Self = Self { bits: 0x0001 };
258 
259     /// Includes vertical adjustment for placement
260     pub const Y_PLACEMENT: Self = Self { bits: 0x0002 };
261 
262     /// Includes horizontal adjustment for advance
263     pub const X_ADVANCE: Self = Self { bits: 0x0004 };
264 
265     /// Includes vertical adjustment for advance
266     pub const Y_ADVANCE: Self = Self { bits: 0x0008 };
267 
268     /// Includes Device table (non-variable font) / VariationIndex
269     /// table (variable font) for horizontal placement
270     pub const X_PLACEMENT_DEVICE: Self = Self { bits: 0x0010 };
271 
272     /// Includes Device table (non-variable font) / VariationIndex
273     /// table (variable font) for vertical placement
274     pub const Y_PLACEMENT_DEVICE: Self = Self { bits: 0x0020 };
275 
276     /// Includes Device table (non-variable font) / VariationIndex
277     /// table (variable font) for horizontal advance
278     pub const X_ADVANCE_DEVICE: Self = Self { bits: 0x0040 };
279 
280     /// Includes Device table (non-variable font) / VariationIndex
281     /// table (variable font) for vertical advance
282     pub const Y_ADVANCE_DEVICE: Self = Self { bits: 0x0080 };
283 }
284 
285 impl ValueFormat {
286     ///  Returns an empty set of flags.
287     #[inline]
empty() -> Self288     pub const fn empty() -> Self {
289         Self { bits: 0 }
290     }
291 
292     /// Returns the set containing all flags.
293     #[inline]
all() -> Self294     pub const fn all() -> Self {
295         Self {
296             bits: Self::X_PLACEMENT.bits
297                 | Self::Y_PLACEMENT.bits
298                 | Self::X_ADVANCE.bits
299                 | Self::Y_ADVANCE.bits
300                 | Self::X_PLACEMENT_DEVICE.bits
301                 | Self::Y_PLACEMENT_DEVICE.bits
302                 | Self::X_ADVANCE_DEVICE.bits
303                 | Self::Y_ADVANCE_DEVICE.bits,
304         }
305     }
306 
307     /// Returns the raw value of the flags currently stored.
308     #[inline]
bits(&self) -> u16309     pub const fn bits(&self) -> u16 {
310         self.bits
311     }
312 
313     /// Convert from underlying bit representation, unless that
314     /// representation contains bits that do not correspond to a flag.
315     #[inline]
from_bits(bits: u16) -> Option<Self>316     pub const fn from_bits(bits: u16) -> Option<Self> {
317         if (bits & !Self::all().bits()) == 0 {
318             Some(Self { bits })
319         } else {
320             None
321         }
322     }
323 
324     /// Convert from underlying bit representation, dropping any bits
325     /// that do not correspond to flags.
326     #[inline]
from_bits_truncate(bits: u16) -> Self327     pub const fn from_bits_truncate(bits: u16) -> Self {
328         Self {
329             bits: bits & Self::all().bits,
330         }
331     }
332 
333     /// Returns `true` if no flags are currently stored.
334     #[inline]
is_empty(&self) -> bool335     pub const fn is_empty(&self) -> bool {
336         self.bits() == Self::empty().bits()
337     }
338 
339     /// Returns `true` if there are flags common to both `self` and `other`.
340     #[inline]
intersects(&self, other: Self) -> bool341     pub const fn intersects(&self, other: Self) -> bool {
342         !(Self {
343             bits: self.bits & other.bits,
344         })
345         .is_empty()
346     }
347 
348     /// Returns `true` if all of the flags in `other` are contained within `self`.
349     #[inline]
contains(&self, other: Self) -> bool350     pub const fn contains(&self, other: Self) -> bool {
351         (self.bits & other.bits) == other.bits
352     }
353 
354     /// Inserts the specified flags in-place.
355     #[inline]
insert(&mut self, other: Self)356     pub fn insert(&mut self, other: Self) {
357         self.bits |= other.bits;
358     }
359 
360     /// Removes the specified flags in-place.
361     #[inline]
remove(&mut self, other: Self)362     pub fn remove(&mut self, other: Self) {
363         self.bits &= !other.bits;
364     }
365 
366     /// Toggles the specified flags in-place.
367     #[inline]
toggle(&mut self, other: Self)368     pub fn toggle(&mut self, other: Self) {
369         self.bits ^= other.bits;
370     }
371 
372     /// Returns the intersection between the flags in `self` and
373     /// `other`.
374     ///
375     /// Specifically, the returned set contains only the flags which are
376     /// present in *both* `self` *and* `other`.
377     ///
378     /// This is equivalent to using the `&` operator (e.g.
379     /// [`ops::BitAnd`]), as in `flags & other`.
380     ///
381     /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
382     #[inline]
383     #[must_use]
intersection(self, other: Self) -> Self384     pub const fn intersection(self, other: Self) -> Self {
385         Self {
386             bits: self.bits & other.bits,
387         }
388     }
389 
390     /// Returns the union of between the flags in `self` and `other`.
391     ///
392     /// Specifically, the returned set contains all flags which are
393     /// present in *either* `self` *or* `other`, including any which are
394     /// present in both.
395     ///
396     /// This is equivalent to using the `|` operator (e.g.
397     /// [`ops::BitOr`]), as in `flags | other`.
398     ///
399     /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
400     #[inline]
401     #[must_use]
union(self, other: Self) -> Self402     pub const fn union(self, other: Self) -> Self {
403         Self {
404             bits: self.bits | other.bits,
405         }
406     }
407 
408     /// Returns the difference between the flags in `self` and `other`.
409     ///
410     /// Specifically, the returned set contains all flags present in
411     /// `self`, except for the ones present in `other`.
412     ///
413     /// It is also conceptually equivalent to the "bit-clear" operation:
414     /// `flags & !other` (and this syntax is also supported).
415     ///
416     /// This is equivalent to using the `-` operator (e.g.
417     /// [`ops::Sub`]), as in `flags - other`.
418     ///
419     /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
420     #[inline]
421     #[must_use]
difference(self, other: Self) -> Self422     pub const fn difference(self, other: Self) -> Self {
423         Self {
424             bits: self.bits & !other.bits,
425         }
426     }
427 }
428 
429 impl std::ops::BitOr for ValueFormat {
430     type Output = Self;
431 
432     /// Returns the union of the two sets of flags.
433     #[inline]
bitor(self, other: ValueFormat) -> Self434     fn bitor(self, other: ValueFormat) -> Self {
435         Self {
436             bits: self.bits | other.bits,
437         }
438     }
439 }
440 
441 impl std::ops::BitOrAssign for ValueFormat {
442     /// Adds the set of flags.
443     #[inline]
bitor_assign(&mut self, other: Self)444     fn bitor_assign(&mut self, other: Self) {
445         self.bits |= other.bits;
446     }
447 }
448 
449 impl std::ops::BitXor for ValueFormat {
450     type Output = Self;
451 
452     /// Returns the left flags, but with all the right flags toggled.
453     #[inline]
bitxor(self, other: Self) -> Self454     fn bitxor(self, other: Self) -> Self {
455         Self {
456             bits: self.bits ^ other.bits,
457         }
458     }
459 }
460 
461 impl std::ops::BitXorAssign for ValueFormat {
462     /// Toggles the set of flags.
463     #[inline]
bitxor_assign(&mut self, other: Self)464     fn bitxor_assign(&mut self, other: Self) {
465         self.bits ^= other.bits;
466     }
467 }
468 
469 impl std::ops::BitAnd for ValueFormat {
470     type Output = Self;
471 
472     /// Returns the intersection between the two sets of flags.
473     #[inline]
bitand(self, other: Self) -> Self474     fn bitand(self, other: Self) -> Self {
475         Self {
476             bits: self.bits & other.bits,
477         }
478     }
479 }
480 
481 impl std::ops::BitAndAssign for ValueFormat {
482     /// Disables all flags disabled in the set.
483     #[inline]
bitand_assign(&mut self, other: Self)484     fn bitand_assign(&mut self, other: Self) {
485         self.bits &= other.bits;
486     }
487 }
488 
489 impl std::ops::Sub for ValueFormat {
490     type Output = Self;
491 
492     /// Returns the set difference of the two sets of flags.
493     #[inline]
sub(self, other: Self) -> Self494     fn sub(self, other: Self) -> Self {
495         Self {
496             bits: self.bits & !other.bits,
497         }
498     }
499 }
500 
501 impl std::ops::SubAssign for ValueFormat {
502     /// Disables all flags enabled in the set.
503     #[inline]
sub_assign(&mut self, other: Self)504     fn sub_assign(&mut self, other: Self) {
505         self.bits &= !other.bits;
506     }
507 }
508 
509 impl std::ops::Not for ValueFormat {
510     type Output = Self;
511 
512     /// Returns the complement of this set of flags.
513     #[inline]
not(self) -> Self514     fn not(self) -> Self {
515         Self { bits: !self.bits } & Self::all()
516     }
517 }
518 
519 impl std::fmt::Debug for ValueFormat {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result520     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
521         let members: &[(&str, Self)] = &[
522             ("X_PLACEMENT", Self::X_PLACEMENT),
523             ("Y_PLACEMENT", Self::Y_PLACEMENT),
524             ("X_ADVANCE", Self::X_ADVANCE),
525             ("Y_ADVANCE", Self::Y_ADVANCE),
526             ("X_PLACEMENT_DEVICE", Self::X_PLACEMENT_DEVICE),
527             ("Y_PLACEMENT_DEVICE", Self::Y_PLACEMENT_DEVICE),
528             ("X_ADVANCE_DEVICE", Self::X_ADVANCE_DEVICE),
529             ("Y_ADVANCE_DEVICE", Self::Y_ADVANCE_DEVICE),
530         ];
531         let mut first = true;
532         for (name, value) in members {
533             if self.contains(*value) {
534                 if !first {
535                     f.write_str(" | ")?;
536                 }
537                 first = false;
538                 f.write_str(name)?;
539             }
540         }
541         if first {
542             f.write_str("(empty)")?;
543         }
544         Ok(())
545     }
546 }
547 
548 impl std::fmt::Binary for ValueFormat {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result549     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
550         std::fmt::Binary::fmt(&self.bits, f)
551     }
552 }
553 
554 impl std::fmt::Octal for ValueFormat {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result555     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
556         std::fmt::Octal::fmt(&self.bits, f)
557     }
558 }
559 
560 impl std::fmt::LowerHex for ValueFormat {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result561     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
562         std::fmt::LowerHex::fmt(&self.bits, f)
563     }
564 }
565 
566 impl std::fmt::UpperHex for ValueFormat {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result567     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
568         std::fmt::UpperHex::fmt(&self.bits, f)
569     }
570 }
571 
572 impl font_types::Scalar for ValueFormat {
573     type Raw = <u16 as font_types::Scalar>::Raw;
to_raw(self) -> Self::Raw574     fn to_raw(self) -> Self::Raw {
575         self.bits().to_raw()
576     }
from_raw(raw: Self::Raw) -> Self577     fn from_raw(raw: Self::Raw) -> Self {
578         let t = <u16>::from_raw(raw);
579         Self::from_bits_truncate(t)
580     }
581 }
582 
583 #[cfg(feature = "traversal")]
584 impl<'a> From<ValueFormat> for FieldType<'a> {
from(src: ValueFormat) -> FieldType<'a>585     fn from(src: ValueFormat) -> FieldType<'a> {
586         src.bits().into()
587     }
588 }
589 
590 /// [Anchor Tables](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#anchor-tables)
591 /// position one glyph with respect to another.
592 #[derive(Clone)]
593 pub enum AnchorTable<'a> {
594     Format1(AnchorFormat1<'a>),
595     Format2(AnchorFormat2<'a>),
596     Format3(AnchorFormat3<'a>),
597 }
598 
599 impl<'a> AnchorTable<'a> {
600     /// Format identifier, = 1
anchor_format(&self) -> u16601     pub fn anchor_format(&self) -> u16 {
602         match self {
603             Self::Format1(item) => item.anchor_format(),
604             Self::Format2(item) => item.anchor_format(),
605             Self::Format3(item) => item.anchor_format(),
606         }
607     }
608 
609     /// Horizontal value, in design units
x_coordinate(&self) -> i16610     pub fn x_coordinate(&self) -> i16 {
611         match self {
612             Self::Format1(item) => item.x_coordinate(),
613             Self::Format2(item) => item.x_coordinate(),
614             Self::Format3(item) => item.x_coordinate(),
615         }
616     }
617 
618     /// Vertical value, in design units
y_coordinate(&self) -> i16619     pub fn y_coordinate(&self) -> i16 {
620         match self {
621             Self::Format1(item) => item.y_coordinate(),
622             Self::Format2(item) => item.y_coordinate(),
623             Self::Format3(item) => item.y_coordinate(),
624         }
625     }
626 }
627 
628 impl<'a> FontRead<'a> for AnchorTable<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>629     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
630         let format: u16 = data.read_at(0usize)?;
631         match format {
632             AnchorFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
633             AnchorFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
634             AnchorFormat3Marker::FORMAT => Ok(Self::Format3(FontRead::read(data)?)),
635             other => Err(ReadError::InvalidFormat(other.into())),
636         }
637     }
638 }
639 
640 #[cfg(feature = "traversal")]
641 impl<'a> AnchorTable<'a> {
dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>642     fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
643         match self {
644             Self::Format1(table) => table,
645             Self::Format2(table) => table,
646             Self::Format3(table) => table,
647         }
648     }
649 }
650 
651 #[cfg(feature = "traversal")]
652 impl<'a> std::fmt::Debug for AnchorTable<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result653     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
654         self.dyn_inner().fmt(f)
655     }
656 }
657 
658 #[cfg(feature = "traversal")]
659 impl<'a> SomeTable<'a> for AnchorTable<'a> {
type_name(&self) -> &str660     fn type_name(&self) -> &str {
661         self.dyn_inner().type_name()
662     }
get_field(&self, idx: usize) -> Option<Field<'a>>663     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
664         self.dyn_inner().get_field(idx)
665     }
666 }
667 
668 impl Format<u16> for AnchorFormat1Marker {
669     const FORMAT: u16 = 1;
670 }
671 
672 /// [Anchor Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#anchor-table-format-1-design-units): Design Units
673 #[derive(Debug, Clone, Copy)]
674 #[doc(hidden)]
675 pub struct AnchorFormat1Marker {}
676 
677 impl AnchorFormat1Marker {
anchor_format_byte_range(&self) -> Range<usize>678     fn anchor_format_byte_range(&self) -> Range<usize> {
679         let start = 0;
680         start..start + u16::RAW_BYTE_LEN
681     }
x_coordinate_byte_range(&self) -> Range<usize>682     fn x_coordinate_byte_range(&self) -> Range<usize> {
683         let start = self.anchor_format_byte_range().end;
684         start..start + i16::RAW_BYTE_LEN
685     }
y_coordinate_byte_range(&self) -> Range<usize>686     fn y_coordinate_byte_range(&self) -> Range<usize> {
687         let start = self.x_coordinate_byte_range().end;
688         start..start + i16::RAW_BYTE_LEN
689     }
690 }
691 
692 impl<'a> FontRead<'a> for AnchorFormat1<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>693     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
694         let mut cursor = data.cursor();
695         cursor.advance::<u16>();
696         cursor.advance::<i16>();
697         cursor.advance::<i16>();
698         cursor.finish(AnchorFormat1Marker {})
699     }
700 }
701 
702 /// [Anchor Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#anchor-table-format-1-design-units): Design Units
703 pub type AnchorFormat1<'a> = TableRef<'a, AnchorFormat1Marker>;
704 
705 impl<'a> AnchorFormat1<'a> {
706     /// Format identifier, = 1
anchor_format(&self) -> u16707     pub fn anchor_format(&self) -> u16 {
708         let range = self.shape.anchor_format_byte_range();
709         self.data.read_at(range.start).unwrap()
710     }
711 
712     /// Horizontal value, in design units
x_coordinate(&self) -> i16713     pub fn x_coordinate(&self) -> i16 {
714         let range = self.shape.x_coordinate_byte_range();
715         self.data.read_at(range.start).unwrap()
716     }
717 
718     /// Vertical value, in design units
y_coordinate(&self) -> i16719     pub fn y_coordinate(&self) -> i16 {
720         let range = self.shape.y_coordinate_byte_range();
721         self.data.read_at(range.start).unwrap()
722     }
723 }
724 
725 #[cfg(feature = "traversal")]
726 impl<'a> SomeTable<'a> for AnchorFormat1<'a> {
type_name(&self) -> &str727     fn type_name(&self) -> &str {
728         "AnchorFormat1"
729     }
get_field(&self, idx: usize) -> Option<Field<'a>>730     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
731         match idx {
732             0usize => Some(Field::new("anchor_format", self.anchor_format())),
733             1usize => Some(Field::new("x_coordinate", self.x_coordinate())),
734             2usize => Some(Field::new("y_coordinate", self.y_coordinate())),
735             _ => None,
736         }
737     }
738 }
739 
740 #[cfg(feature = "traversal")]
741 impl<'a> std::fmt::Debug for AnchorFormat1<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result742     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
743         (self as &dyn SomeTable<'a>).fmt(f)
744     }
745 }
746 
747 impl Format<u16> for AnchorFormat2Marker {
748     const FORMAT: u16 = 2;
749 }
750 
751 /// [Anchor Table Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#anchor-table-format-2-design-units-plus-contour-point): Design Units Plus Contour Point
752 #[derive(Debug, Clone, Copy)]
753 #[doc(hidden)]
754 pub struct AnchorFormat2Marker {}
755 
756 impl AnchorFormat2Marker {
anchor_format_byte_range(&self) -> Range<usize>757     fn anchor_format_byte_range(&self) -> Range<usize> {
758         let start = 0;
759         start..start + u16::RAW_BYTE_LEN
760     }
x_coordinate_byte_range(&self) -> Range<usize>761     fn x_coordinate_byte_range(&self) -> Range<usize> {
762         let start = self.anchor_format_byte_range().end;
763         start..start + i16::RAW_BYTE_LEN
764     }
y_coordinate_byte_range(&self) -> Range<usize>765     fn y_coordinate_byte_range(&self) -> Range<usize> {
766         let start = self.x_coordinate_byte_range().end;
767         start..start + i16::RAW_BYTE_LEN
768     }
anchor_point_byte_range(&self) -> Range<usize>769     fn anchor_point_byte_range(&self) -> Range<usize> {
770         let start = self.y_coordinate_byte_range().end;
771         start..start + u16::RAW_BYTE_LEN
772     }
773 }
774 
775 impl<'a> FontRead<'a> for AnchorFormat2<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>776     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
777         let mut cursor = data.cursor();
778         cursor.advance::<u16>();
779         cursor.advance::<i16>();
780         cursor.advance::<i16>();
781         cursor.advance::<u16>();
782         cursor.finish(AnchorFormat2Marker {})
783     }
784 }
785 
786 /// [Anchor Table Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#anchor-table-format-2-design-units-plus-contour-point): Design Units Plus Contour Point
787 pub type AnchorFormat2<'a> = TableRef<'a, AnchorFormat2Marker>;
788 
789 impl<'a> AnchorFormat2<'a> {
790     /// Format identifier, = 2
anchor_format(&self) -> u16791     pub fn anchor_format(&self) -> u16 {
792         let range = self.shape.anchor_format_byte_range();
793         self.data.read_at(range.start).unwrap()
794     }
795 
796     /// Horizontal value, in design units
x_coordinate(&self) -> i16797     pub fn x_coordinate(&self) -> i16 {
798         let range = self.shape.x_coordinate_byte_range();
799         self.data.read_at(range.start).unwrap()
800     }
801 
802     /// Vertical value, in design units
y_coordinate(&self) -> i16803     pub fn y_coordinate(&self) -> i16 {
804         let range = self.shape.y_coordinate_byte_range();
805         self.data.read_at(range.start).unwrap()
806     }
807 
808     /// Index to glyph contour point
anchor_point(&self) -> u16809     pub fn anchor_point(&self) -> u16 {
810         let range = self.shape.anchor_point_byte_range();
811         self.data.read_at(range.start).unwrap()
812     }
813 }
814 
815 #[cfg(feature = "traversal")]
816 impl<'a> SomeTable<'a> for AnchorFormat2<'a> {
type_name(&self) -> &str817     fn type_name(&self) -> &str {
818         "AnchorFormat2"
819     }
get_field(&self, idx: usize) -> Option<Field<'a>>820     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
821         match idx {
822             0usize => Some(Field::new("anchor_format", self.anchor_format())),
823             1usize => Some(Field::new("x_coordinate", self.x_coordinate())),
824             2usize => Some(Field::new("y_coordinate", self.y_coordinate())),
825             3usize => Some(Field::new("anchor_point", self.anchor_point())),
826             _ => None,
827         }
828     }
829 }
830 
831 #[cfg(feature = "traversal")]
832 impl<'a> std::fmt::Debug for AnchorFormat2<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result833     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
834         (self as &dyn SomeTable<'a>).fmt(f)
835     }
836 }
837 
838 impl Format<u16> for AnchorFormat3Marker {
839     const FORMAT: u16 = 3;
840 }
841 
842 /// [Anchor Table Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#anchor-table-format-3-design-units-plus-device-or-variationindex-tables): Design Units Plus Device or VariationIndex Tables
843 #[derive(Debug, Clone, Copy)]
844 #[doc(hidden)]
845 pub struct AnchorFormat3Marker {}
846 
847 impl AnchorFormat3Marker {
anchor_format_byte_range(&self) -> Range<usize>848     fn anchor_format_byte_range(&self) -> Range<usize> {
849         let start = 0;
850         start..start + u16::RAW_BYTE_LEN
851     }
x_coordinate_byte_range(&self) -> Range<usize>852     fn x_coordinate_byte_range(&self) -> Range<usize> {
853         let start = self.anchor_format_byte_range().end;
854         start..start + i16::RAW_BYTE_LEN
855     }
y_coordinate_byte_range(&self) -> Range<usize>856     fn y_coordinate_byte_range(&self) -> Range<usize> {
857         let start = self.x_coordinate_byte_range().end;
858         start..start + i16::RAW_BYTE_LEN
859     }
x_device_offset_byte_range(&self) -> Range<usize>860     fn x_device_offset_byte_range(&self) -> Range<usize> {
861         let start = self.y_coordinate_byte_range().end;
862         start..start + Offset16::RAW_BYTE_LEN
863     }
y_device_offset_byte_range(&self) -> Range<usize>864     fn y_device_offset_byte_range(&self) -> Range<usize> {
865         let start = self.x_device_offset_byte_range().end;
866         start..start + Offset16::RAW_BYTE_LEN
867     }
868 }
869 
870 impl<'a> FontRead<'a> for AnchorFormat3<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>871     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
872         let mut cursor = data.cursor();
873         cursor.advance::<u16>();
874         cursor.advance::<i16>();
875         cursor.advance::<i16>();
876         cursor.advance::<Offset16>();
877         cursor.advance::<Offset16>();
878         cursor.finish(AnchorFormat3Marker {})
879     }
880 }
881 
882 /// [Anchor Table Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#anchor-table-format-3-design-units-plus-device-or-variationindex-tables): Design Units Plus Device or VariationIndex Tables
883 pub type AnchorFormat3<'a> = TableRef<'a, AnchorFormat3Marker>;
884 
885 impl<'a> AnchorFormat3<'a> {
886     /// Format identifier, = 3
anchor_format(&self) -> u16887     pub fn anchor_format(&self) -> u16 {
888         let range = self.shape.anchor_format_byte_range();
889         self.data.read_at(range.start).unwrap()
890     }
891 
892     /// Horizontal value, in design units
x_coordinate(&self) -> i16893     pub fn x_coordinate(&self) -> i16 {
894         let range = self.shape.x_coordinate_byte_range();
895         self.data.read_at(range.start).unwrap()
896     }
897 
898     /// Vertical value, in design units
y_coordinate(&self) -> i16899     pub fn y_coordinate(&self) -> i16 {
900         let range = self.shape.y_coordinate_byte_range();
901         self.data.read_at(range.start).unwrap()
902     }
903 
904     /// Offset to Device table (non-variable font) / VariationIndex
905     /// table (variable font) for X coordinate, from beginning of
906     /// Anchor table (may be NULL)
x_device_offset(&self) -> Nullable<Offset16>907     pub fn x_device_offset(&self) -> Nullable<Offset16> {
908         let range = self.shape.x_device_offset_byte_range();
909         self.data.read_at(range.start).unwrap()
910     }
911 
912     /// Attempt to resolve [`x_device_offset`][Self::x_device_offset].
x_device(&self) -> Option<Result<DeviceOrVariationIndex<'a>, ReadError>>913     pub fn x_device(&self) -> Option<Result<DeviceOrVariationIndex<'a>, ReadError>> {
914         let data = self.data;
915         self.x_device_offset().resolve(data)
916     }
917 
918     /// Offset to Device table (non-variable font) / VariationIndex
919     /// table (variable font) for Y coordinate, from beginning of
920     /// Anchor table (may be NULL)
y_device_offset(&self) -> Nullable<Offset16>921     pub fn y_device_offset(&self) -> Nullable<Offset16> {
922         let range = self.shape.y_device_offset_byte_range();
923         self.data.read_at(range.start).unwrap()
924     }
925 
926     /// Attempt to resolve [`y_device_offset`][Self::y_device_offset].
y_device(&self) -> Option<Result<DeviceOrVariationIndex<'a>, ReadError>>927     pub fn y_device(&self) -> Option<Result<DeviceOrVariationIndex<'a>, ReadError>> {
928         let data = self.data;
929         self.y_device_offset().resolve(data)
930     }
931 }
932 
933 #[cfg(feature = "traversal")]
934 impl<'a> SomeTable<'a> for AnchorFormat3<'a> {
type_name(&self) -> &str935     fn type_name(&self) -> &str {
936         "AnchorFormat3"
937     }
get_field(&self, idx: usize) -> Option<Field<'a>>938     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
939         match idx {
940             0usize => Some(Field::new("anchor_format", self.anchor_format())),
941             1usize => Some(Field::new("x_coordinate", self.x_coordinate())),
942             2usize => Some(Field::new("y_coordinate", self.y_coordinate())),
943             3usize => Some(Field::new(
944                 "x_device_offset",
945                 FieldType::offset(self.x_device_offset(), self.x_device()),
946             )),
947             4usize => Some(Field::new(
948                 "y_device_offset",
949                 FieldType::offset(self.y_device_offset(), self.y_device()),
950             )),
951             _ => None,
952         }
953     }
954 }
955 
956 #[cfg(feature = "traversal")]
957 impl<'a> std::fmt::Debug for AnchorFormat3<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result958     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
959         (self as &dyn SomeTable<'a>).fmt(f)
960     }
961 }
962 
963 /// [Mark Array Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-array-table)
964 #[derive(Debug, Clone, Copy)]
965 #[doc(hidden)]
966 pub struct MarkArrayMarker {
967     mark_records_byte_len: usize,
968 }
969 
970 impl MarkArrayMarker {
mark_count_byte_range(&self) -> Range<usize>971     fn mark_count_byte_range(&self) -> Range<usize> {
972         let start = 0;
973         start..start + u16::RAW_BYTE_LEN
974     }
mark_records_byte_range(&self) -> Range<usize>975     fn mark_records_byte_range(&self) -> Range<usize> {
976         let start = self.mark_count_byte_range().end;
977         start..start + self.mark_records_byte_len
978     }
979 }
980 
981 impl<'a> FontRead<'a> for MarkArray<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>982     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
983         let mut cursor = data.cursor();
984         let mark_count: u16 = cursor.read()?;
985         let mark_records_byte_len = mark_count as usize * MarkRecord::RAW_BYTE_LEN;
986         cursor.advance_by(mark_records_byte_len);
987         cursor.finish(MarkArrayMarker {
988             mark_records_byte_len,
989         })
990     }
991 }
992 
993 /// [Mark Array Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-array-table)
994 pub type MarkArray<'a> = TableRef<'a, MarkArrayMarker>;
995 
996 impl<'a> MarkArray<'a> {
997     /// Number of MarkRecords
mark_count(&self) -> u16998     pub fn mark_count(&self) -> u16 {
999         let range = self.shape.mark_count_byte_range();
1000         self.data.read_at(range.start).unwrap()
1001     }
1002 
1003     /// Array of MarkRecords, ordered by corresponding glyphs in the
1004     /// associated mark Coverage table.
mark_records(&self) -> &'a [MarkRecord]1005     pub fn mark_records(&self) -> &'a [MarkRecord] {
1006         let range = self.shape.mark_records_byte_range();
1007         self.data.read_array(range).unwrap()
1008     }
1009 }
1010 
1011 #[cfg(feature = "traversal")]
1012 impl<'a> SomeTable<'a> for MarkArray<'a> {
type_name(&self) -> &str1013     fn type_name(&self) -> &str {
1014         "MarkArray"
1015     }
get_field(&self, idx: usize) -> Option<Field<'a>>1016     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1017         match idx {
1018             0usize => Some(Field::new("mark_count", self.mark_count())),
1019             1usize => Some(Field::new(
1020                 "mark_records",
1021                 traversal::FieldType::array_of_records(
1022                     stringify!(MarkRecord),
1023                     self.mark_records(),
1024                     self.offset_data(),
1025                 ),
1026             )),
1027             _ => None,
1028         }
1029     }
1030 }
1031 
1032 #[cfg(feature = "traversal")]
1033 impl<'a> std::fmt::Debug for MarkArray<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1034     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1035         (self as &dyn SomeTable<'a>).fmt(f)
1036     }
1037 }
1038 
1039 /// Part of [MarkArray]
1040 #[derive(Clone, Debug)]
1041 #[repr(C)]
1042 #[repr(packed)]
1043 pub struct MarkRecord {
1044     /// Class defined for the associated mark.
1045     pub mark_class: BigEndian<u16>,
1046     /// Offset to Anchor table, from beginning of MarkArray table.
1047     pub mark_anchor_offset: BigEndian<Offset16>,
1048 }
1049 
1050 impl MarkRecord {
1051     /// Class defined for the associated mark.
mark_class(&self) -> u161052     pub fn mark_class(&self) -> u16 {
1053         self.mark_class.get()
1054     }
1055 
1056     /// Offset to Anchor table, from beginning of MarkArray table.
mark_anchor_offset(&self) -> Offset161057     pub fn mark_anchor_offset(&self) -> Offset16 {
1058         self.mark_anchor_offset.get()
1059     }
1060 
1061     /// Offset to Anchor table, from beginning of MarkArray table.
1062     ///
1063     /// The `data` argument should be retrieved from the parent table
1064     /// By calling its `offset_data` method.
mark_anchor<'a>(&self, data: FontData<'a>) -> Result<AnchorTable<'a>, ReadError>1065     pub fn mark_anchor<'a>(&self, data: FontData<'a>) -> Result<AnchorTable<'a>, ReadError> {
1066         self.mark_anchor_offset().resolve(data)
1067     }
1068 }
1069 
1070 impl FixedSize for MarkRecord {
1071     const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN;
1072 }
1073 
1074 impl sealed::Sealed for MarkRecord {}
1075 
1076 /// SAFETY: see the [`FromBytes`] trait documentation.
1077 unsafe impl FromBytes for MarkRecord {
this_trait_should_only_be_implemented_in_generated_code()1078     fn this_trait_should_only_be_implemented_in_generated_code() {}
1079 }
1080 
1081 #[cfg(feature = "traversal")]
1082 impl<'a> SomeRecord<'a> for MarkRecord {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>1083     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
1084         RecordResolver {
1085             name: "MarkRecord",
1086             get_field: Box::new(move |idx, _data| match idx {
1087                 0usize => Some(Field::new("mark_class", self.mark_class())),
1088                 1usize => Some(Field::new(
1089                     "mark_anchor_offset",
1090                     FieldType::offset(self.mark_anchor_offset(), self.mark_anchor(_data)),
1091                 )),
1092                 _ => None,
1093             }),
1094             data,
1095         }
1096     }
1097 }
1098 
1099 /// [Lookup Type 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#lookup-type-1-single-adjustment-positioning-subtable): Single Adjustment Positioning Subtable
1100 #[derive(Clone)]
1101 pub enum SinglePos<'a> {
1102     Format1(SinglePosFormat1<'a>),
1103     Format2(SinglePosFormat2<'a>),
1104 }
1105 
1106 impl<'a> SinglePos<'a> {
1107     /// Format identifier: format = 1
pos_format(&self) -> u161108     pub fn pos_format(&self) -> u16 {
1109         match self {
1110             Self::Format1(item) => item.pos_format(),
1111             Self::Format2(item) => item.pos_format(),
1112         }
1113     }
1114 
1115     /// Offset to Coverage table, from beginning of SinglePos subtable.
coverage_offset(&self) -> Offset161116     pub fn coverage_offset(&self) -> Offset16 {
1117         match self {
1118             Self::Format1(item) => item.coverage_offset(),
1119             Self::Format2(item) => item.coverage_offset(),
1120         }
1121     }
1122 
1123     /// Defines the types of data in the ValueRecord.
value_format(&self) -> ValueFormat1124     pub fn value_format(&self) -> ValueFormat {
1125         match self {
1126             Self::Format1(item) => item.value_format(),
1127             Self::Format2(item) => item.value_format(),
1128         }
1129     }
1130 }
1131 
1132 impl<'a> FontRead<'a> for SinglePos<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1133     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1134         let format: u16 = data.read_at(0usize)?;
1135         match format {
1136             SinglePosFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
1137             SinglePosFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
1138             other => Err(ReadError::InvalidFormat(other.into())),
1139         }
1140     }
1141 }
1142 
1143 #[cfg(feature = "traversal")]
1144 impl<'a> SinglePos<'a> {
dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>1145     fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
1146         match self {
1147             Self::Format1(table) => table,
1148             Self::Format2(table) => table,
1149         }
1150     }
1151 }
1152 
1153 #[cfg(feature = "traversal")]
1154 impl<'a> std::fmt::Debug for SinglePos<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1155     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1156         self.dyn_inner().fmt(f)
1157     }
1158 }
1159 
1160 #[cfg(feature = "traversal")]
1161 impl<'a> SomeTable<'a> for SinglePos<'a> {
type_name(&self) -> &str1162     fn type_name(&self) -> &str {
1163         self.dyn_inner().type_name()
1164     }
get_field(&self, idx: usize) -> Option<Field<'a>>1165     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1166         self.dyn_inner().get_field(idx)
1167     }
1168 }
1169 
1170 impl Format<u16> for SinglePosFormat1Marker {
1171     const FORMAT: u16 = 1;
1172 }
1173 
1174 /// [Single Adjustment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#single-adjustment-positioning-format-1-single-positioning-value): Single Positioning Value
1175 #[derive(Debug, Clone, Copy)]
1176 #[doc(hidden)]
1177 pub struct SinglePosFormat1Marker {
1178     value_record_byte_len: usize,
1179 }
1180 
1181 impl SinglePosFormat1Marker {
pos_format_byte_range(&self) -> Range<usize>1182     fn pos_format_byte_range(&self) -> Range<usize> {
1183         let start = 0;
1184         start..start + u16::RAW_BYTE_LEN
1185     }
coverage_offset_byte_range(&self) -> Range<usize>1186     fn coverage_offset_byte_range(&self) -> Range<usize> {
1187         let start = self.pos_format_byte_range().end;
1188         start..start + Offset16::RAW_BYTE_LEN
1189     }
value_format_byte_range(&self) -> Range<usize>1190     fn value_format_byte_range(&self) -> Range<usize> {
1191         let start = self.coverage_offset_byte_range().end;
1192         start..start + ValueFormat::RAW_BYTE_LEN
1193     }
value_record_byte_range(&self) -> Range<usize>1194     fn value_record_byte_range(&self) -> Range<usize> {
1195         let start = self.value_format_byte_range().end;
1196         start..start + self.value_record_byte_len
1197     }
1198 }
1199 
1200 impl<'a> FontRead<'a> for SinglePosFormat1<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1201     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1202         let mut cursor = data.cursor();
1203         cursor.advance::<u16>();
1204         cursor.advance::<Offset16>();
1205         let value_format: ValueFormat = cursor.read()?;
1206         let value_record_byte_len = <ValueRecord as ComputeSize>::compute_size(&value_format);
1207         cursor.advance_by(value_record_byte_len);
1208         cursor.finish(SinglePosFormat1Marker {
1209             value_record_byte_len,
1210         })
1211     }
1212 }
1213 
1214 /// [Single Adjustment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#single-adjustment-positioning-format-1-single-positioning-value): Single Positioning Value
1215 pub type SinglePosFormat1<'a> = TableRef<'a, SinglePosFormat1Marker>;
1216 
1217 impl<'a> SinglePosFormat1<'a> {
1218     /// Format identifier: format = 1
pos_format(&self) -> u161219     pub fn pos_format(&self) -> u16 {
1220         let range = self.shape.pos_format_byte_range();
1221         self.data.read_at(range.start).unwrap()
1222     }
1223 
1224     /// Offset to Coverage table, from beginning of SinglePos subtable.
coverage_offset(&self) -> Offset161225     pub fn coverage_offset(&self) -> Offset16 {
1226         let range = self.shape.coverage_offset_byte_range();
1227         self.data.read_at(range.start).unwrap()
1228     }
1229 
1230     /// Attempt to resolve [`coverage_offset`][Self::coverage_offset].
coverage(&self) -> Result<CoverageTable<'a>, ReadError>1231     pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
1232         let data = self.data;
1233         self.coverage_offset().resolve(data)
1234     }
1235 
1236     /// Defines the types of data in the ValueRecord.
value_format(&self) -> ValueFormat1237     pub fn value_format(&self) -> ValueFormat {
1238         let range = self.shape.value_format_byte_range();
1239         self.data.read_at(range.start).unwrap()
1240     }
1241 
1242     /// Defines positioning value(s) — applied to all glyphs in the
1243     /// Coverage table.
value_record(&self) -> ValueRecord1244     pub fn value_record(&self) -> ValueRecord {
1245         let range = self.shape.value_record_byte_range();
1246         self.data
1247             .read_with_args(range, &self.value_format())
1248             .unwrap()
1249     }
1250 }
1251 
1252 #[cfg(feature = "traversal")]
1253 impl<'a> SomeTable<'a> for SinglePosFormat1<'a> {
type_name(&self) -> &str1254     fn type_name(&self) -> &str {
1255         "SinglePosFormat1"
1256     }
get_field(&self, idx: usize) -> Option<Field<'a>>1257     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1258         match idx {
1259             0usize => Some(Field::new("pos_format", self.pos_format())),
1260             1usize => Some(Field::new(
1261                 "coverage_offset",
1262                 FieldType::offset(self.coverage_offset(), self.coverage()),
1263             )),
1264             2usize => Some(Field::new("value_format", self.value_format())),
1265             3usize => Some(Field::new(
1266                 "value_record",
1267                 self.value_record().traversal_type(self.offset_data()),
1268             )),
1269             _ => None,
1270         }
1271     }
1272 }
1273 
1274 #[cfg(feature = "traversal")]
1275 impl<'a> std::fmt::Debug for SinglePosFormat1<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1276     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1277         (self as &dyn SomeTable<'a>).fmt(f)
1278     }
1279 }
1280 
1281 impl Format<u16> for SinglePosFormat2Marker {
1282     const FORMAT: u16 = 2;
1283 }
1284 
1285 /// [Single Adjustment Positioning Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#single-adjustment-positioning-format-2-array-of-positioning-values): Array of Positioning Values
1286 #[derive(Debug, Clone, Copy)]
1287 #[doc(hidden)]
1288 pub struct SinglePosFormat2Marker {
1289     value_records_byte_len: usize,
1290 }
1291 
1292 impl SinglePosFormat2Marker {
pos_format_byte_range(&self) -> Range<usize>1293     fn pos_format_byte_range(&self) -> Range<usize> {
1294         let start = 0;
1295         start..start + u16::RAW_BYTE_LEN
1296     }
coverage_offset_byte_range(&self) -> Range<usize>1297     fn coverage_offset_byte_range(&self) -> Range<usize> {
1298         let start = self.pos_format_byte_range().end;
1299         start..start + Offset16::RAW_BYTE_LEN
1300     }
value_format_byte_range(&self) -> Range<usize>1301     fn value_format_byte_range(&self) -> Range<usize> {
1302         let start = self.coverage_offset_byte_range().end;
1303         start..start + ValueFormat::RAW_BYTE_LEN
1304     }
value_count_byte_range(&self) -> Range<usize>1305     fn value_count_byte_range(&self) -> Range<usize> {
1306         let start = self.value_format_byte_range().end;
1307         start..start + u16::RAW_BYTE_LEN
1308     }
value_records_byte_range(&self) -> Range<usize>1309     fn value_records_byte_range(&self) -> Range<usize> {
1310         let start = self.value_count_byte_range().end;
1311         start..start + self.value_records_byte_len
1312     }
1313 }
1314 
1315 impl<'a> FontRead<'a> for SinglePosFormat2<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1316     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1317         let mut cursor = data.cursor();
1318         cursor.advance::<u16>();
1319         cursor.advance::<Offset16>();
1320         let value_format: ValueFormat = cursor.read()?;
1321         let value_count: u16 = cursor.read()?;
1322         let value_records_byte_len =
1323             value_count as usize * <ValueRecord as ComputeSize>::compute_size(&value_format);
1324         cursor.advance_by(value_records_byte_len);
1325         cursor.finish(SinglePosFormat2Marker {
1326             value_records_byte_len,
1327         })
1328     }
1329 }
1330 
1331 /// [Single Adjustment Positioning Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#single-adjustment-positioning-format-2-array-of-positioning-values): Array of Positioning Values
1332 pub type SinglePosFormat2<'a> = TableRef<'a, SinglePosFormat2Marker>;
1333 
1334 impl<'a> SinglePosFormat2<'a> {
1335     /// Format identifier: format = 2
pos_format(&self) -> u161336     pub fn pos_format(&self) -> u16 {
1337         let range = self.shape.pos_format_byte_range();
1338         self.data.read_at(range.start).unwrap()
1339     }
1340 
1341     /// Offset to Coverage table, from beginning of SinglePos subtable.
coverage_offset(&self) -> Offset161342     pub fn coverage_offset(&self) -> Offset16 {
1343         let range = self.shape.coverage_offset_byte_range();
1344         self.data.read_at(range.start).unwrap()
1345     }
1346 
1347     /// Attempt to resolve [`coverage_offset`][Self::coverage_offset].
coverage(&self) -> Result<CoverageTable<'a>, ReadError>1348     pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
1349         let data = self.data;
1350         self.coverage_offset().resolve(data)
1351     }
1352 
1353     /// Defines the types of data in the ValueRecords.
value_format(&self) -> ValueFormat1354     pub fn value_format(&self) -> ValueFormat {
1355         let range = self.shape.value_format_byte_range();
1356         self.data.read_at(range.start).unwrap()
1357     }
1358 
1359     /// Number of ValueRecords — must equal glyphCount in the
1360     /// Coverage table.
value_count(&self) -> u161361     pub fn value_count(&self) -> u16 {
1362         let range = self.shape.value_count_byte_range();
1363         self.data.read_at(range.start).unwrap()
1364     }
1365 
1366     /// Array of ValueRecords — positioning values applied to glyphs.
value_records(&self) -> ComputedArray<'a, ValueRecord>1367     pub fn value_records(&self) -> ComputedArray<'a, ValueRecord> {
1368         let range = self.shape.value_records_byte_range();
1369         self.data
1370             .read_with_args(range, &self.value_format())
1371             .unwrap()
1372     }
1373 }
1374 
1375 #[cfg(feature = "traversal")]
1376 impl<'a> SomeTable<'a> for SinglePosFormat2<'a> {
type_name(&self) -> &str1377     fn type_name(&self) -> &str {
1378         "SinglePosFormat2"
1379     }
get_field(&self, idx: usize) -> Option<Field<'a>>1380     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1381         match idx {
1382             0usize => Some(Field::new("pos_format", self.pos_format())),
1383             1usize => Some(Field::new(
1384                 "coverage_offset",
1385                 FieldType::offset(self.coverage_offset(), self.coverage()),
1386             )),
1387             2usize => Some(Field::new("value_format", self.value_format())),
1388             3usize => Some(Field::new("value_count", self.value_count())),
1389             4usize => Some(Field::new(
1390                 "value_records",
1391                 traversal::FieldType::computed_array(
1392                     "ValueRecord",
1393                     self.value_records(),
1394                     self.offset_data(),
1395                 ),
1396             )),
1397             _ => None,
1398         }
1399     }
1400 }
1401 
1402 #[cfg(feature = "traversal")]
1403 impl<'a> std::fmt::Debug for SinglePosFormat2<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1404     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1405         (self as &dyn SomeTable<'a>).fmt(f)
1406     }
1407 }
1408 
1409 /// [Lookup Type 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#lookup-type-1-single-adjustment-positioning-subtable): Single Adjustment Positioning Subtable
1410 #[derive(Clone)]
1411 pub enum PairPos<'a> {
1412     Format1(PairPosFormat1<'a>),
1413     Format2(PairPosFormat2<'a>),
1414 }
1415 
1416 impl<'a> PairPos<'a> {
1417     /// Format identifier: format = 1
pos_format(&self) -> u161418     pub fn pos_format(&self) -> u16 {
1419         match self {
1420             Self::Format1(item) => item.pos_format(),
1421             Self::Format2(item) => item.pos_format(),
1422         }
1423     }
1424 
1425     /// Offset to Coverage table, from beginning of PairPos subtable.
coverage_offset(&self) -> Offset161426     pub fn coverage_offset(&self) -> Offset16 {
1427         match self {
1428             Self::Format1(item) => item.coverage_offset(),
1429             Self::Format2(item) => item.coverage_offset(),
1430         }
1431     }
1432 
1433     /// Defines the types of data in valueRecord1 — for the first
1434     /// glyph in the pair (may be zero).
value_format1(&self) -> ValueFormat1435     pub fn value_format1(&self) -> ValueFormat {
1436         match self {
1437             Self::Format1(item) => item.value_format1(),
1438             Self::Format2(item) => item.value_format1(),
1439         }
1440     }
1441 
1442     /// Defines the types of data in valueRecord2 — for the second
1443     /// glyph in the pair (may be zero).
value_format2(&self) -> ValueFormat1444     pub fn value_format2(&self) -> ValueFormat {
1445         match self {
1446             Self::Format1(item) => item.value_format2(),
1447             Self::Format2(item) => item.value_format2(),
1448         }
1449     }
1450 }
1451 
1452 impl<'a> FontRead<'a> for PairPos<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1453     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1454         let format: u16 = data.read_at(0usize)?;
1455         match format {
1456             PairPosFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
1457             PairPosFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
1458             other => Err(ReadError::InvalidFormat(other.into())),
1459         }
1460     }
1461 }
1462 
1463 #[cfg(feature = "traversal")]
1464 impl<'a> PairPos<'a> {
dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>1465     fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
1466         match self {
1467             Self::Format1(table) => table,
1468             Self::Format2(table) => table,
1469         }
1470     }
1471 }
1472 
1473 #[cfg(feature = "traversal")]
1474 impl<'a> std::fmt::Debug for PairPos<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1475     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1476         self.dyn_inner().fmt(f)
1477     }
1478 }
1479 
1480 #[cfg(feature = "traversal")]
1481 impl<'a> SomeTable<'a> for PairPos<'a> {
type_name(&self) -> &str1482     fn type_name(&self) -> &str {
1483         self.dyn_inner().type_name()
1484     }
get_field(&self, idx: usize) -> Option<Field<'a>>1485     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1486         self.dyn_inner().get_field(idx)
1487     }
1488 }
1489 
1490 impl Format<u16> for PairPosFormat1Marker {
1491     const FORMAT: u16 = 1;
1492 }
1493 
1494 /// [Pair Adjustment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#pair-adjustment-positioning-format-1-adjustments-for-glyph-pairs): Adjustments for Glyph Pairs
1495 #[derive(Debug, Clone, Copy)]
1496 #[doc(hidden)]
1497 pub struct PairPosFormat1Marker {
1498     pair_set_offsets_byte_len: usize,
1499 }
1500 
1501 impl PairPosFormat1Marker {
pos_format_byte_range(&self) -> Range<usize>1502     fn pos_format_byte_range(&self) -> Range<usize> {
1503         let start = 0;
1504         start..start + u16::RAW_BYTE_LEN
1505     }
coverage_offset_byte_range(&self) -> Range<usize>1506     fn coverage_offset_byte_range(&self) -> Range<usize> {
1507         let start = self.pos_format_byte_range().end;
1508         start..start + Offset16::RAW_BYTE_LEN
1509     }
value_format1_byte_range(&self) -> Range<usize>1510     fn value_format1_byte_range(&self) -> Range<usize> {
1511         let start = self.coverage_offset_byte_range().end;
1512         start..start + ValueFormat::RAW_BYTE_LEN
1513     }
value_format2_byte_range(&self) -> Range<usize>1514     fn value_format2_byte_range(&self) -> Range<usize> {
1515         let start = self.value_format1_byte_range().end;
1516         start..start + ValueFormat::RAW_BYTE_LEN
1517     }
pair_set_count_byte_range(&self) -> Range<usize>1518     fn pair_set_count_byte_range(&self) -> Range<usize> {
1519         let start = self.value_format2_byte_range().end;
1520         start..start + u16::RAW_BYTE_LEN
1521     }
pair_set_offsets_byte_range(&self) -> Range<usize>1522     fn pair_set_offsets_byte_range(&self) -> Range<usize> {
1523         let start = self.pair_set_count_byte_range().end;
1524         start..start + self.pair_set_offsets_byte_len
1525     }
1526 }
1527 
1528 impl<'a> FontRead<'a> for PairPosFormat1<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1529     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1530         let mut cursor = data.cursor();
1531         cursor.advance::<u16>();
1532         cursor.advance::<Offset16>();
1533         cursor.advance::<ValueFormat>();
1534         cursor.advance::<ValueFormat>();
1535         let pair_set_count: u16 = cursor.read()?;
1536         let pair_set_offsets_byte_len = pair_set_count as usize * Offset16::RAW_BYTE_LEN;
1537         cursor.advance_by(pair_set_offsets_byte_len);
1538         cursor.finish(PairPosFormat1Marker {
1539             pair_set_offsets_byte_len,
1540         })
1541     }
1542 }
1543 
1544 /// [Pair Adjustment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#pair-adjustment-positioning-format-1-adjustments-for-glyph-pairs): Adjustments for Glyph Pairs
1545 pub type PairPosFormat1<'a> = TableRef<'a, PairPosFormat1Marker>;
1546 
1547 impl<'a> PairPosFormat1<'a> {
1548     /// Format identifier: format = 1
pos_format(&self) -> u161549     pub fn pos_format(&self) -> u16 {
1550         let range = self.shape.pos_format_byte_range();
1551         self.data.read_at(range.start).unwrap()
1552     }
1553 
1554     /// Offset to Coverage table, from beginning of PairPos subtable.
coverage_offset(&self) -> Offset161555     pub fn coverage_offset(&self) -> Offset16 {
1556         let range = self.shape.coverage_offset_byte_range();
1557         self.data.read_at(range.start).unwrap()
1558     }
1559 
1560     /// Attempt to resolve [`coverage_offset`][Self::coverage_offset].
coverage(&self) -> Result<CoverageTable<'a>, ReadError>1561     pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
1562         let data = self.data;
1563         self.coverage_offset().resolve(data)
1564     }
1565 
1566     /// Defines the types of data in valueRecord1 — for the first
1567     /// glyph in the pair (may be zero).
value_format1(&self) -> ValueFormat1568     pub fn value_format1(&self) -> ValueFormat {
1569         let range = self.shape.value_format1_byte_range();
1570         self.data.read_at(range.start).unwrap()
1571     }
1572 
1573     /// Defines the types of data in valueRecord2 — for the second
1574     /// glyph in the pair (may be zero).
value_format2(&self) -> ValueFormat1575     pub fn value_format2(&self) -> ValueFormat {
1576         let range = self.shape.value_format2_byte_range();
1577         self.data.read_at(range.start).unwrap()
1578     }
1579 
1580     /// Number of PairSet tables
pair_set_count(&self) -> u161581     pub fn pair_set_count(&self) -> u16 {
1582         let range = self.shape.pair_set_count_byte_range();
1583         self.data.read_at(range.start).unwrap()
1584     }
1585 
1586     /// Array of offsets to PairSet tables. Offsets are from beginning
1587     /// of PairPos subtable, ordered by Coverage Index.
pair_set_offsets(&self) -> &'a [BigEndian<Offset16>]1588     pub fn pair_set_offsets(&self) -> &'a [BigEndian<Offset16>] {
1589         let range = self.shape.pair_set_offsets_byte_range();
1590         self.data.read_array(range).unwrap()
1591     }
1592 
1593     /// A dynamically resolving wrapper for [`pair_set_offsets`][Self::pair_set_offsets].
pair_sets(&self) -> ArrayOfOffsets<'a, PairSet<'a>, Offset16>1594     pub fn pair_sets(&self) -> ArrayOfOffsets<'a, PairSet<'a>, Offset16> {
1595         let data = self.data;
1596         let offsets = self.pair_set_offsets();
1597         let args = (self.value_format1(), self.value_format2());
1598         ArrayOfOffsets::new(offsets, data, args)
1599     }
1600 }
1601 
1602 #[cfg(feature = "traversal")]
1603 impl<'a> SomeTable<'a> for PairPosFormat1<'a> {
type_name(&self) -> &str1604     fn type_name(&self) -> &str {
1605         "PairPosFormat1"
1606     }
get_field(&self, idx: usize) -> Option<Field<'a>>1607     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1608         match idx {
1609             0usize => Some(Field::new("pos_format", self.pos_format())),
1610             1usize => Some(Field::new(
1611                 "coverage_offset",
1612                 FieldType::offset(self.coverage_offset(), self.coverage()),
1613             )),
1614             2usize => Some(Field::new("value_format1", self.value_format1())),
1615             3usize => Some(Field::new("value_format2", self.value_format2())),
1616             4usize => Some(Field::new("pair_set_count", self.pair_set_count())),
1617             5usize => Some({
1618                 let data = self.data;
1619                 let args = (self.value_format1(), self.value_format2());
1620                 Field::new(
1621                     "pair_set_offsets",
1622                     FieldType::array_of_offsets(
1623                         better_type_name::<PairSet>(),
1624                         self.pair_set_offsets(),
1625                         move |off| {
1626                             let target = off.get().resolve_with_args::<PairSet>(data, &args);
1627                             FieldType::offset(off.get(), target)
1628                         },
1629                     ),
1630                 )
1631             }),
1632             _ => None,
1633         }
1634     }
1635 }
1636 
1637 #[cfg(feature = "traversal")]
1638 impl<'a> std::fmt::Debug for PairPosFormat1<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1639     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1640         (self as &dyn SomeTable<'a>).fmt(f)
1641     }
1642 }
1643 
1644 /// Part of [PairPosFormat1]
1645 #[derive(Debug, Clone, Copy)]
1646 #[doc(hidden)]
1647 pub struct PairSetMarker {
1648     value_format1: ValueFormat,
1649     value_format2: ValueFormat,
1650     pair_value_records_byte_len: usize,
1651 }
1652 
1653 impl PairSetMarker {
pair_value_count_byte_range(&self) -> Range<usize>1654     fn pair_value_count_byte_range(&self) -> Range<usize> {
1655         let start = 0;
1656         start..start + u16::RAW_BYTE_LEN
1657     }
pair_value_records_byte_range(&self) -> Range<usize>1658     fn pair_value_records_byte_range(&self) -> Range<usize> {
1659         let start = self.pair_value_count_byte_range().end;
1660         start..start + self.pair_value_records_byte_len
1661     }
1662 }
1663 
1664 impl ReadArgs for PairSet<'_> {
1665     type Args = (ValueFormat, ValueFormat);
1666 }
1667 
1668 impl<'a> FontReadWithArgs<'a> for PairSet<'a> {
read_with_args( data: FontData<'a>, args: &(ValueFormat, ValueFormat), ) -> Result<Self, ReadError>1669     fn read_with_args(
1670         data: FontData<'a>,
1671         args: &(ValueFormat, ValueFormat),
1672     ) -> Result<Self, ReadError> {
1673         let (value_format1, value_format2) = *args;
1674         let mut cursor = data.cursor();
1675         let pair_value_count: u16 = cursor.read()?;
1676         let pair_value_records_byte_len = pair_value_count as usize
1677             * <PairValueRecord as ComputeSize>::compute_size(&(value_format1, value_format2));
1678         cursor.advance_by(pair_value_records_byte_len);
1679         cursor.finish(PairSetMarker {
1680             value_format1,
1681             value_format2,
1682             pair_value_records_byte_len,
1683         })
1684     }
1685 }
1686 
1687 impl<'a> PairSet<'a> {
1688     /// A constructor that requires additional arguments.
1689     ///
1690     /// This type requires some external state in order to be
1691     /// parsed.
read( data: FontData<'a>, value_format1: ValueFormat, value_format2: ValueFormat, ) -> Result<Self, ReadError>1692     pub fn read(
1693         data: FontData<'a>,
1694         value_format1: ValueFormat,
1695         value_format2: ValueFormat,
1696     ) -> Result<Self, ReadError> {
1697         let args = (value_format1, value_format2);
1698         Self::read_with_args(data, &args)
1699     }
1700 }
1701 
1702 /// Part of [PairPosFormat1]
1703 pub type PairSet<'a> = TableRef<'a, PairSetMarker>;
1704 
1705 impl<'a> PairSet<'a> {
1706     /// Number of PairValueRecords
pair_value_count(&self) -> u161707     pub fn pair_value_count(&self) -> u16 {
1708         let range = self.shape.pair_value_count_byte_range();
1709         self.data.read_at(range.start).unwrap()
1710     }
1711 
1712     /// Array of PairValueRecords, ordered by glyph ID of the second
1713     /// glyph.
pair_value_records(&self) -> ComputedArray<'a, PairValueRecord>1714     pub fn pair_value_records(&self) -> ComputedArray<'a, PairValueRecord> {
1715         let range = self.shape.pair_value_records_byte_range();
1716         self.data
1717             .read_with_args(range, &(self.value_format1(), self.value_format2()))
1718             .unwrap()
1719     }
1720 
value_format1(&self) -> ValueFormat1721     pub(crate) fn value_format1(&self) -> ValueFormat {
1722         self.shape.value_format1
1723     }
1724 
value_format2(&self) -> ValueFormat1725     pub(crate) fn value_format2(&self) -> ValueFormat {
1726         self.shape.value_format2
1727     }
1728 }
1729 
1730 #[cfg(feature = "traversal")]
1731 impl<'a> SomeTable<'a> for PairSet<'a> {
type_name(&self) -> &str1732     fn type_name(&self) -> &str {
1733         "PairSet"
1734     }
get_field(&self, idx: usize) -> Option<Field<'a>>1735     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1736         match idx {
1737             0usize => Some(Field::new("pair_value_count", self.pair_value_count())),
1738             1usize => Some(Field::new(
1739                 "pair_value_records",
1740                 traversal::FieldType::computed_array(
1741                     "PairValueRecord",
1742                     self.pair_value_records(),
1743                     self.offset_data(),
1744                 ),
1745             )),
1746             _ => None,
1747         }
1748     }
1749 }
1750 
1751 #[cfg(feature = "traversal")]
1752 impl<'a> std::fmt::Debug for PairSet<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1753     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1754         (self as &dyn SomeTable<'a>).fmt(f)
1755     }
1756 }
1757 
1758 /// Part of [PairSet]
1759 #[derive(Clone, Debug)]
1760 pub struct PairValueRecord {
1761     /// Glyph ID of second glyph in the pair (first glyph is listed in
1762     /// the Coverage table).
1763     pub second_glyph: BigEndian<GlyphId>,
1764     /// Positioning data for the first glyph in the pair.
1765     pub value_record1: ValueRecord,
1766     /// Positioning data for the second glyph in the pair.
1767     pub value_record2: ValueRecord,
1768 }
1769 
1770 impl PairValueRecord {
1771     /// Glyph ID of second glyph in the pair (first glyph is listed in
1772     /// the Coverage table).
second_glyph(&self) -> GlyphId1773     pub fn second_glyph(&self) -> GlyphId {
1774         self.second_glyph.get()
1775     }
1776 
1777     /// Positioning data for the first glyph in the pair.
value_record1(&self) -> &ValueRecord1778     pub fn value_record1(&self) -> &ValueRecord {
1779         &self.value_record1
1780     }
1781 
1782     /// Positioning data for the second glyph in the pair.
value_record2(&self) -> &ValueRecord1783     pub fn value_record2(&self) -> &ValueRecord {
1784         &self.value_record2
1785     }
1786 }
1787 
1788 impl ReadArgs for PairValueRecord {
1789     type Args = (ValueFormat, ValueFormat);
1790 }
1791 
1792 impl ComputeSize for PairValueRecord {
compute_size(args: &(ValueFormat, ValueFormat)) -> usize1793     fn compute_size(args: &(ValueFormat, ValueFormat)) -> usize {
1794         let (value_format1, value_format2) = *args;
1795         GlyphId::RAW_BYTE_LEN
1796             + <ValueRecord as ComputeSize>::compute_size(&value_format1)
1797             + <ValueRecord as ComputeSize>::compute_size(&value_format2)
1798     }
1799 }
1800 
1801 impl<'a> FontReadWithArgs<'a> for PairValueRecord {
read_with_args( data: FontData<'a>, args: &(ValueFormat, ValueFormat), ) -> Result<Self, ReadError>1802     fn read_with_args(
1803         data: FontData<'a>,
1804         args: &(ValueFormat, ValueFormat),
1805     ) -> Result<Self, ReadError> {
1806         let mut cursor = data.cursor();
1807         let (value_format1, value_format2) = *args;
1808         Ok(Self {
1809             second_glyph: cursor.read_be()?,
1810             value_record1: cursor.read_with_args(&value_format1)?,
1811             value_record2: cursor.read_with_args(&value_format2)?,
1812         })
1813     }
1814 }
1815 
1816 impl<'a> PairValueRecord {
1817     /// A constructor that requires additional arguments.
1818     ///
1819     /// This type requires some external state in order to be
1820     /// parsed.
read( data: FontData<'a>, value_format1: ValueFormat, value_format2: ValueFormat, ) -> Result<Self, ReadError>1821     pub fn read(
1822         data: FontData<'a>,
1823         value_format1: ValueFormat,
1824         value_format2: ValueFormat,
1825     ) -> Result<Self, ReadError> {
1826         let args = (value_format1, value_format2);
1827         Self::read_with_args(data, &args)
1828     }
1829 }
1830 
1831 #[cfg(feature = "traversal")]
1832 impl<'a> SomeRecord<'a> for PairValueRecord {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>1833     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
1834         RecordResolver {
1835             name: "PairValueRecord",
1836             get_field: Box::new(move |idx, _data| match idx {
1837                 0usize => Some(Field::new("second_glyph", self.second_glyph())),
1838                 1usize => Some(Field::new(
1839                     "value_record1",
1840                     self.value_record1().traversal_type(_data),
1841                 )),
1842                 2usize => Some(Field::new(
1843                     "value_record2",
1844                     self.value_record2().traversal_type(_data),
1845                 )),
1846                 _ => None,
1847             }),
1848             data,
1849         }
1850     }
1851 }
1852 
1853 impl Format<u16> for PairPosFormat2Marker {
1854     const FORMAT: u16 = 2;
1855 }
1856 
1857 /// [Pair Adjustment Positioning Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#pair-adjustment-positioning-format-2-class-pair-adjustment): Class Pair Adjustment
1858 #[derive(Debug, Clone, Copy)]
1859 #[doc(hidden)]
1860 pub struct PairPosFormat2Marker {
1861     class1_records_byte_len: usize,
1862 }
1863 
1864 impl PairPosFormat2Marker {
pos_format_byte_range(&self) -> Range<usize>1865     fn pos_format_byte_range(&self) -> Range<usize> {
1866         let start = 0;
1867         start..start + u16::RAW_BYTE_LEN
1868     }
coverage_offset_byte_range(&self) -> Range<usize>1869     fn coverage_offset_byte_range(&self) -> Range<usize> {
1870         let start = self.pos_format_byte_range().end;
1871         start..start + Offset16::RAW_BYTE_LEN
1872     }
value_format1_byte_range(&self) -> Range<usize>1873     fn value_format1_byte_range(&self) -> Range<usize> {
1874         let start = self.coverage_offset_byte_range().end;
1875         start..start + ValueFormat::RAW_BYTE_LEN
1876     }
value_format2_byte_range(&self) -> Range<usize>1877     fn value_format2_byte_range(&self) -> Range<usize> {
1878         let start = self.value_format1_byte_range().end;
1879         start..start + ValueFormat::RAW_BYTE_LEN
1880     }
class_def1_offset_byte_range(&self) -> Range<usize>1881     fn class_def1_offset_byte_range(&self) -> Range<usize> {
1882         let start = self.value_format2_byte_range().end;
1883         start..start + Offset16::RAW_BYTE_LEN
1884     }
class_def2_offset_byte_range(&self) -> Range<usize>1885     fn class_def2_offset_byte_range(&self) -> Range<usize> {
1886         let start = self.class_def1_offset_byte_range().end;
1887         start..start + Offset16::RAW_BYTE_LEN
1888     }
class1_count_byte_range(&self) -> Range<usize>1889     fn class1_count_byte_range(&self) -> Range<usize> {
1890         let start = self.class_def2_offset_byte_range().end;
1891         start..start + u16::RAW_BYTE_LEN
1892     }
class2_count_byte_range(&self) -> Range<usize>1893     fn class2_count_byte_range(&self) -> Range<usize> {
1894         let start = self.class1_count_byte_range().end;
1895         start..start + u16::RAW_BYTE_LEN
1896     }
class1_records_byte_range(&self) -> Range<usize>1897     fn class1_records_byte_range(&self) -> Range<usize> {
1898         let start = self.class2_count_byte_range().end;
1899         start..start + self.class1_records_byte_len
1900     }
1901 }
1902 
1903 impl<'a> FontRead<'a> for PairPosFormat2<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1904     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1905         let mut cursor = data.cursor();
1906         cursor.advance::<u16>();
1907         cursor.advance::<Offset16>();
1908         let value_format1: ValueFormat = cursor.read()?;
1909         let value_format2: ValueFormat = cursor.read()?;
1910         cursor.advance::<Offset16>();
1911         cursor.advance::<Offset16>();
1912         let class1_count: u16 = cursor.read()?;
1913         let class2_count: u16 = cursor.read()?;
1914         let class1_records_byte_len = class1_count as usize
1915             * <Class1Record as ComputeSize>::compute_size(&(
1916                 class2_count,
1917                 value_format1,
1918                 value_format2,
1919             ));
1920         cursor.advance_by(class1_records_byte_len);
1921         cursor.finish(PairPosFormat2Marker {
1922             class1_records_byte_len,
1923         })
1924     }
1925 }
1926 
1927 /// [Pair Adjustment Positioning Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#pair-adjustment-positioning-format-2-class-pair-adjustment): Class Pair Adjustment
1928 pub type PairPosFormat2<'a> = TableRef<'a, PairPosFormat2Marker>;
1929 
1930 impl<'a> PairPosFormat2<'a> {
1931     /// Format identifier: format = 2
pos_format(&self) -> u161932     pub fn pos_format(&self) -> u16 {
1933         let range = self.shape.pos_format_byte_range();
1934         self.data.read_at(range.start).unwrap()
1935     }
1936 
1937     /// Offset to Coverage table, from beginning of PairPos subtable.
coverage_offset(&self) -> Offset161938     pub fn coverage_offset(&self) -> Offset16 {
1939         let range = self.shape.coverage_offset_byte_range();
1940         self.data.read_at(range.start).unwrap()
1941     }
1942 
1943     /// Attempt to resolve [`coverage_offset`][Self::coverage_offset].
coverage(&self) -> Result<CoverageTable<'a>, ReadError>1944     pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
1945         let data = self.data;
1946         self.coverage_offset().resolve(data)
1947     }
1948 
1949     /// ValueRecord definition — for the first glyph of the pair (may
1950     /// be zero).
value_format1(&self) -> ValueFormat1951     pub fn value_format1(&self) -> ValueFormat {
1952         let range = self.shape.value_format1_byte_range();
1953         self.data.read_at(range.start).unwrap()
1954     }
1955 
1956     /// ValueRecord definition — for the second glyph of the pair
1957     /// (may be zero).
value_format2(&self) -> ValueFormat1958     pub fn value_format2(&self) -> ValueFormat {
1959         let range = self.shape.value_format2_byte_range();
1960         self.data.read_at(range.start).unwrap()
1961     }
1962 
1963     /// Offset to ClassDef table, from beginning of PairPos subtable
1964     /// — for the first glyph of the pair.
class_def1_offset(&self) -> Offset161965     pub fn class_def1_offset(&self) -> Offset16 {
1966         let range = self.shape.class_def1_offset_byte_range();
1967         self.data.read_at(range.start).unwrap()
1968     }
1969 
1970     /// Attempt to resolve [`class_def1_offset`][Self::class_def1_offset].
class_def1(&self) -> Result<ClassDef<'a>, ReadError>1971     pub fn class_def1(&self) -> Result<ClassDef<'a>, ReadError> {
1972         let data = self.data;
1973         self.class_def1_offset().resolve(data)
1974     }
1975 
1976     /// Offset to ClassDef table, from beginning of PairPos subtable
1977     /// — for the second glyph of the pair.
class_def2_offset(&self) -> Offset161978     pub fn class_def2_offset(&self) -> Offset16 {
1979         let range = self.shape.class_def2_offset_byte_range();
1980         self.data.read_at(range.start).unwrap()
1981     }
1982 
1983     /// Attempt to resolve [`class_def2_offset`][Self::class_def2_offset].
class_def2(&self) -> Result<ClassDef<'a>, ReadError>1984     pub fn class_def2(&self) -> Result<ClassDef<'a>, ReadError> {
1985         let data = self.data;
1986         self.class_def2_offset().resolve(data)
1987     }
1988 
1989     /// Number of classes in classDef1 table — includes Class 0.
class1_count(&self) -> u161990     pub fn class1_count(&self) -> u16 {
1991         let range = self.shape.class1_count_byte_range();
1992         self.data.read_at(range.start).unwrap()
1993     }
1994 
1995     /// Number of classes in classDef2 table — includes Class 0.
class2_count(&self) -> u161996     pub fn class2_count(&self) -> u16 {
1997         let range = self.shape.class2_count_byte_range();
1998         self.data.read_at(range.start).unwrap()
1999     }
2000 
2001     /// Array of Class1 records, ordered by classes in classDef1.
class1_records(&self) -> ComputedArray<'a, Class1Record<'a>>2002     pub fn class1_records(&self) -> ComputedArray<'a, Class1Record<'a>> {
2003         let range = self.shape.class1_records_byte_range();
2004         self.data
2005             .read_with_args(
2006                 range,
2007                 &(
2008                     self.class2_count(),
2009                     self.value_format1(),
2010                     self.value_format2(),
2011                 ),
2012             )
2013             .unwrap()
2014     }
2015 }
2016 
2017 #[cfg(feature = "traversal")]
2018 impl<'a> SomeTable<'a> for PairPosFormat2<'a> {
type_name(&self) -> &str2019     fn type_name(&self) -> &str {
2020         "PairPosFormat2"
2021     }
get_field(&self, idx: usize) -> Option<Field<'a>>2022     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2023         match idx {
2024             0usize => Some(Field::new("pos_format", self.pos_format())),
2025             1usize => Some(Field::new(
2026                 "coverage_offset",
2027                 FieldType::offset(self.coverage_offset(), self.coverage()),
2028             )),
2029             2usize => Some(Field::new("value_format1", self.value_format1())),
2030             3usize => Some(Field::new("value_format2", self.value_format2())),
2031             4usize => Some(Field::new(
2032                 "class_def1_offset",
2033                 FieldType::offset(self.class_def1_offset(), self.class_def1()),
2034             )),
2035             5usize => Some(Field::new(
2036                 "class_def2_offset",
2037                 FieldType::offset(self.class_def2_offset(), self.class_def2()),
2038             )),
2039             6usize => Some(Field::new("class1_count", self.class1_count())),
2040             7usize => Some(Field::new("class2_count", self.class2_count())),
2041             8usize => Some(Field::new(
2042                 "class1_records",
2043                 traversal::FieldType::computed_array(
2044                     "Class1Record",
2045                     self.class1_records(),
2046                     self.offset_data(),
2047                 ),
2048             )),
2049             _ => None,
2050         }
2051     }
2052 }
2053 
2054 #[cfg(feature = "traversal")]
2055 impl<'a> std::fmt::Debug for PairPosFormat2<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2056     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2057         (self as &dyn SomeTable<'a>).fmt(f)
2058     }
2059 }
2060 
2061 /// Part of [PairPosFormat2]
2062 #[derive(Clone, Debug)]
2063 pub struct Class1Record<'a> {
2064     /// Array of Class2 records, ordered by classes in classDef2.
2065     pub class2_records: ComputedArray<'a, Class2Record>,
2066 }
2067 
2068 impl<'a> Class1Record<'a> {
2069     /// Array of Class2 records, ordered by classes in classDef2.
class2_records(&self) -> &ComputedArray<'a, Class2Record>2070     pub fn class2_records(&self) -> &ComputedArray<'a, Class2Record> {
2071         &self.class2_records
2072     }
2073 }
2074 
2075 impl ReadArgs for Class1Record<'_> {
2076     type Args = (u16, ValueFormat, ValueFormat);
2077 }
2078 
2079 impl ComputeSize for Class1Record<'_> {
compute_size(args: &(u16, ValueFormat, ValueFormat)) -> usize2080     fn compute_size(args: &(u16, ValueFormat, ValueFormat)) -> usize {
2081         let (class2_count, value_format1, value_format2) = *args;
2082         class2_count as usize
2083             * <Class2Record as ComputeSize>::compute_size(&(value_format1, value_format2))
2084     }
2085 }
2086 
2087 impl<'a> FontReadWithArgs<'a> for Class1Record<'a> {
read_with_args( data: FontData<'a>, args: &(u16, ValueFormat, ValueFormat), ) -> Result<Self, ReadError>2088     fn read_with_args(
2089         data: FontData<'a>,
2090         args: &(u16, ValueFormat, ValueFormat),
2091     ) -> Result<Self, ReadError> {
2092         let mut cursor = data.cursor();
2093         let (class2_count, value_format1, value_format2) = *args;
2094         Ok(Self {
2095             class2_records: cursor
2096                 .read_computed_array(class2_count as usize, &(value_format1, value_format2))?,
2097         })
2098     }
2099 }
2100 
2101 impl<'a> Class1Record<'a> {
2102     /// A constructor that requires additional arguments.
2103     ///
2104     /// This type requires some external state in order to be
2105     /// parsed.
read( data: FontData<'a>, class2_count: u16, value_format1: ValueFormat, value_format2: ValueFormat, ) -> Result<Self, ReadError>2106     pub fn read(
2107         data: FontData<'a>,
2108         class2_count: u16,
2109         value_format1: ValueFormat,
2110         value_format2: ValueFormat,
2111     ) -> Result<Self, ReadError> {
2112         let args = (class2_count, value_format1, value_format2);
2113         Self::read_with_args(data, &args)
2114     }
2115 }
2116 
2117 #[cfg(feature = "traversal")]
2118 impl<'a> SomeRecord<'a> for Class1Record<'a> {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>2119     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
2120         RecordResolver {
2121             name: "Class1Record",
2122             get_field: Box::new(move |idx, _data| match idx {
2123                 0usize => Some(Field::new(
2124                     "class2_records",
2125                     traversal::FieldType::computed_array(
2126                         "Class2Record",
2127                         self.class2_records().clone(),
2128                         FontData::new(&[]),
2129                     ),
2130                 )),
2131                 _ => None,
2132             }),
2133             data,
2134         }
2135     }
2136 }
2137 
2138 /// Part of [PairPosFormat2]
2139 #[derive(Clone, Debug)]
2140 pub struct Class2Record {
2141     /// Positioning for first glyph — empty if valueFormat1 = 0.
2142     pub value_record1: ValueRecord,
2143     /// Positioning for second glyph — empty if valueFormat2 = 0.
2144     pub value_record2: ValueRecord,
2145 }
2146 
2147 impl Class2Record {
2148     /// Positioning for first glyph — empty if valueFormat1 = 0.
value_record1(&self) -> &ValueRecord2149     pub fn value_record1(&self) -> &ValueRecord {
2150         &self.value_record1
2151     }
2152 
2153     /// Positioning for second glyph — empty if valueFormat2 = 0.
value_record2(&self) -> &ValueRecord2154     pub fn value_record2(&self) -> &ValueRecord {
2155         &self.value_record2
2156     }
2157 }
2158 
2159 impl ReadArgs for Class2Record {
2160     type Args = (ValueFormat, ValueFormat);
2161 }
2162 
2163 impl ComputeSize for Class2Record {
compute_size(args: &(ValueFormat, ValueFormat)) -> usize2164     fn compute_size(args: &(ValueFormat, ValueFormat)) -> usize {
2165         let (value_format1, value_format2) = *args;
2166         <ValueRecord as ComputeSize>::compute_size(&value_format1)
2167             + <ValueRecord as ComputeSize>::compute_size(&value_format2)
2168     }
2169 }
2170 
2171 impl<'a> FontReadWithArgs<'a> for Class2Record {
read_with_args( data: FontData<'a>, args: &(ValueFormat, ValueFormat), ) -> Result<Self, ReadError>2172     fn read_with_args(
2173         data: FontData<'a>,
2174         args: &(ValueFormat, ValueFormat),
2175     ) -> Result<Self, ReadError> {
2176         let mut cursor = data.cursor();
2177         let (value_format1, value_format2) = *args;
2178         Ok(Self {
2179             value_record1: cursor.read_with_args(&value_format1)?,
2180             value_record2: cursor.read_with_args(&value_format2)?,
2181         })
2182     }
2183 }
2184 
2185 impl<'a> Class2Record {
2186     /// A constructor that requires additional arguments.
2187     ///
2188     /// This type requires some external state in order to be
2189     /// parsed.
read( data: FontData<'a>, value_format1: ValueFormat, value_format2: ValueFormat, ) -> Result<Self, ReadError>2190     pub fn read(
2191         data: FontData<'a>,
2192         value_format1: ValueFormat,
2193         value_format2: ValueFormat,
2194     ) -> Result<Self, ReadError> {
2195         let args = (value_format1, value_format2);
2196         Self::read_with_args(data, &args)
2197     }
2198 }
2199 
2200 #[cfg(feature = "traversal")]
2201 impl<'a> SomeRecord<'a> for Class2Record {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>2202     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
2203         RecordResolver {
2204             name: "Class2Record",
2205             get_field: Box::new(move |idx, _data| match idx {
2206                 0usize => Some(Field::new(
2207                     "value_record1",
2208                     self.value_record1().traversal_type(_data),
2209                 )),
2210                 1usize => Some(Field::new(
2211                     "value_record2",
2212                     self.value_record2().traversal_type(_data),
2213                 )),
2214                 _ => None,
2215             }),
2216             data,
2217         }
2218     }
2219 }
2220 
2221 impl Format<u16> for CursivePosFormat1Marker {
2222     const FORMAT: u16 = 1;
2223 }
2224 
2225 /// [Cursive Attachment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#cursive-attachment-positioning-format1-cursive-attachment): Cursvie attachment
2226 #[derive(Debug, Clone, Copy)]
2227 #[doc(hidden)]
2228 pub struct CursivePosFormat1Marker {
2229     entry_exit_record_byte_len: usize,
2230 }
2231 
2232 impl CursivePosFormat1Marker {
pos_format_byte_range(&self) -> Range<usize>2233     fn pos_format_byte_range(&self) -> Range<usize> {
2234         let start = 0;
2235         start..start + u16::RAW_BYTE_LEN
2236     }
coverage_offset_byte_range(&self) -> Range<usize>2237     fn coverage_offset_byte_range(&self) -> Range<usize> {
2238         let start = self.pos_format_byte_range().end;
2239         start..start + Offset16::RAW_BYTE_LEN
2240     }
entry_exit_count_byte_range(&self) -> Range<usize>2241     fn entry_exit_count_byte_range(&self) -> Range<usize> {
2242         let start = self.coverage_offset_byte_range().end;
2243         start..start + u16::RAW_BYTE_LEN
2244     }
entry_exit_record_byte_range(&self) -> Range<usize>2245     fn entry_exit_record_byte_range(&self) -> Range<usize> {
2246         let start = self.entry_exit_count_byte_range().end;
2247         start..start + self.entry_exit_record_byte_len
2248     }
2249 }
2250 
2251 impl<'a> FontRead<'a> for CursivePosFormat1<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>2252     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2253         let mut cursor = data.cursor();
2254         cursor.advance::<u16>();
2255         cursor.advance::<Offset16>();
2256         let entry_exit_count: u16 = cursor.read()?;
2257         let entry_exit_record_byte_len = entry_exit_count as usize * EntryExitRecord::RAW_BYTE_LEN;
2258         cursor.advance_by(entry_exit_record_byte_len);
2259         cursor.finish(CursivePosFormat1Marker {
2260             entry_exit_record_byte_len,
2261         })
2262     }
2263 }
2264 
2265 /// [Cursive Attachment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#cursive-attachment-positioning-format1-cursive-attachment): Cursvie attachment
2266 pub type CursivePosFormat1<'a> = TableRef<'a, CursivePosFormat1Marker>;
2267 
2268 impl<'a> CursivePosFormat1<'a> {
2269     /// Format identifier: format = 1
pos_format(&self) -> u162270     pub fn pos_format(&self) -> u16 {
2271         let range = self.shape.pos_format_byte_range();
2272         self.data.read_at(range.start).unwrap()
2273     }
2274 
2275     /// Offset to Coverage table, from beginning of CursivePos subtable.
coverage_offset(&self) -> Offset162276     pub fn coverage_offset(&self) -> Offset16 {
2277         let range = self.shape.coverage_offset_byte_range();
2278         self.data.read_at(range.start).unwrap()
2279     }
2280 
2281     /// Attempt to resolve [`coverage_offset`][Self::coverage_offset].
coverage(&self) -> Result<CoverageTable<'a>, ReadError>2282     pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
2283         let data = self.data;
2284         self.coverage_offset().resolve(data)
2285     }
2286 
2287     /// Number of EntryExit records
entry_exit_count(&self) -> u162288     pub fn entry_exit_count(&self) -> u16 {
2289         let range = self.shape.entry_exit_count_byte_range();
2290         self.data.read_at(range.start).unwrap()
2291     }
2292 
2293     /// Array of EntryExit records, in Coverage index order.
entry_exit_record(&self) -> &'a [EntryExitRecord]2294     pub fn entry_exit_record(&self) -> &'a [EntryExitRecord] {
2295         let range = self.shape.entry_exit_record_byte_range();
2296         self.data.read_array(range).unwrap()
2297     }
2298 }
2299 
2300 #[cfg(feature = "traversal")]
2301 impl<'a> SomeTable<'a> for CursivePosFormat1<'a> {
type_name(&self) -> &str2302     fn type_name(&self) -> &str {
2303         "CursivePosFormat1"
2304     }
get_field(&self, idx: usize) -> Option<Field<'a>>2305     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2306         match idx {
2307             0usize => Some(Field::new("pos_format", self.pos_format())),
2308             1usize => Some(Field::new(
2309                 "coverage_offset",
2310                 FieldType::offset(self.coverage_offset(), self.coverage()),
2311             )),
2312             2usize => Some(Field::new("entry_exit_count", self.entry_exit_count())),
2313             3usize => Some(Field::new(
2314                 "entry_exit_record",
2315                 traversal::FieldType::array_of_records(
2316                     stringify!(EntryExitRecord),
2317                     self.entry_exit_record(),
2318                     self.offset_data(),
2319                 ),
2320             )),
2321             _ => None,
2322         }
2323     }
2324 }
2325 
2326 #[cfg(feature = "traversal")]
2327 impl<'a> std::fmt::Debug for CursivePosFormat1<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2328     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2329         (self as &dyn SomeTable<'a>).fmt(f)
2330     }
2331 }
2332 
2333 /// Part of [CursivePosFormat1]
2334 #[derive(Clone, Debug)]
2335 #[repr(C)]
2336 #[repr(packed)]
2337 pub struct EntryExitRecord {
2338     /// Offset to entryAnchor table, from beginning of CursivePos
2339     /// subtable (may be NULL).
2340     pub entry_anchor_offset: BigEndian<Nullable<Offset16>>,
2341     /// Offset to exitAnchor table, from beginning of CursivePos
2342     /// subtable (may be NULL).
2343     pub exit_anchor_offset: BigEndian<Nullable<Offset16>>,
2344 }
2345 
2346 impl EntryExitRecord {
2347     /// Offset to entryAnchor table, from beginning of CursivePos
2348     /// subtable (may be NULL).
entry_anchor_offset(&self) -> Nullable<Offset16>2349     pub fn entry_anchor_offset(&self) -> Nullable<Offset16> {
2350         self.entry_anchor_offset.get()
2351     }
2352 
2353     /// Offset to entryAnchor table, from beginning of CursivePos
2354     /// subtable (may be NULL).
2355     ///
2356     /// The `data` argument should be retrieved from the parent table
2357     /// By calling its `offset_data` method.
entry_anchor<'a>( &self, data: FontData<'a>, ) -> Option<Result<AnchorTable<'a>, ReadError>>2358     pub fn entry_anchor<'a>(
2359         &self,
2360         data: FontData<'a>,
2361     ) -> Option<Result<AnchorTable<'a>, ReadError>> {
2362         self.entry_anchor_offset().resolve(data)
2363     }
2364 
2365     /// Offset to exitAnchor table, from beginning of CursivePos
2366     /// subtable (may be NULL).
exit_anchor_offset(&self) -> Nullable<Offset16>2367     pub fn exit_anchor_offset(&self) -> Nullable<Offset16> {
2368         self.exit_anchor_offset.get()
2369     }
2370 
2371     /// Offset to exitAnchor table, from beginning of CursivePos
2372     /// subtable (may be NULL).
2373     ///
2374     /// The `data` argument should be retrieved from the parent table
2375     /// By calling its `offset_data` method.
exit_anchor<'a>( &self, data: FontData<'a>, ) -> Option<Result<AnchorTable<'a>, ReadError>>2376     pub fn exit_anchor<'a>(
2377         &self,
2378         data: FontData<'a>,
2379     ) -> Option<Result<AnchorTable<'a>, ReadError>> {
2380         self.exit_anchor_offset().resolve(data)
2381     }
2382 }
2383 
2384 impl FixedSize for EntryExitRecord {
2385     const RAW_BYTE_LEN: usize = Offset16::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN;
2386 }
2387 
2388 impl sealed::Sealed for EntryExitRecord {}
2389 
2390 /// SAFETY: see the [`FromBytes`] trait documentation.
2391 unsafe impl FromBytes for EntryExitRecord {
this_trait_should_only_be_implemented_in_generated_code()2392     fn this_trait_should_only_be_implemented_in_generated_code() {}
2393 }
2394 
2395 #[cfg(feature = "traversal")]
2396 impl<'a> SomeRecord<'a> for EntryExitRecord {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>2397     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
2398         RecordResolver {
2399             name: "EntryExitRecord",
2400             get_field: Box::new(move |idx, _data| match idx {
2401                 0usize => Some(Field::new(
2402                     "entry_anchor_offset",
2403                     FieldType::offset(self.entry_anchor_offset(), self.entry_anchor(_data)),
2404                 )),
2405                 1usize => Some(Field::new(
2406                     "exit_anchor_offset",
2407                     FieldType::offset(self.exit_anchor_offset(), self.exit_anchor(_data)),
2408                 )),
2409                 _ => None,
2410             }),
2411             data,
2412         }
2413     }
2414 }
2415 
2416 impl Format<u16> for MarkBasePosFormat1Marker {
2417     const FORMAT: u16 = 1;
2418 }
2419 
2420 /// [Mark-to-Base Attachment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-to-base-attachment-positioning-format-1-mark-to-base-attachment-point): Mark-to-base Attachment Point
2421 #[derive(Debug, Clone, Copy)]
2422 #[doc(hidden)]
2423 pub struct MarkBasePosFormat1Marker {}
2424 
2425 impl MarkBasePosFormat1Marker {
pos_format_byte_range(&self) -> Range<usize>2426     fn pos_format_byte_range(&self) -> Range<usize> {
2427         let start = 0;
2428         start..start + u16::RAW_BYTE_LEN
2429     }
mark_coverage_offset_byte_range(&self) -> Range<usize>2430     fn mark_coverage_offset_byte_range(&self) -> Range<usize> {
2431         let start = self.pos_format_byte_range().end;
2432         start..start + Offset16::RAW_BYTE_LEN
2433     }
base_coverage_offset_byte_range(&self) -> Range<usize>2434     fn base_coverage_offset_byte_range(&self) -> Range<usize> {
2435         let start = self.mark_coverage_offset_byte_range().end;
2436         start..start + Offset16::RAW_BYTE_LEN
2437     }
mark_class_count_byte_range(&self) -> Range<usize>2438     fn mark_class_count_byte_range(&self) -> Range<usize> {
2439         let start = self.base_coverage_offset_byte_range().end;
2440         start..start + u16::RAW_BYTE_LEN
2441     }
mark_array_offset_byte_range(&self) -> Range<usize>2442     fn mark_array_offset_byte_range(&self) -> Range<usize> {
2443         let start = self.mark_class_count_byte_range().end;
2444         start..start + Offset16::RAW_BYTE_LEN
2445     }
base_array_offset_byte_range(&self) -> Range<usize>2446     fn base_array_offset_byte_range(&self) -> Range<usize> {
2447         let start = self.mark_array_offset_byte_range().end;
2448         start..start + Offset16::RAW_BYTE_LEN
2449     }
2450 }
2451 
2452 impl<'a> FontRead<'a> for MarkBasePosFormat1<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>2453     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2454         let mut cursor = data.cursor();
2455         cursor.advance::<u16>();
2456         cursor.advance::<Offset16>();
2457         cursor.advance::<Offset16>();
2458         cursor.advance::<u16>();
2459         cursor.advance::<Offset16>();
2460         cursor.advance::<Offset16>();
2461         cursor.finish(MarkBasePosFormat1Marker {})
2462     }
2463 }
2464 
2465 /// [Mark-to-Base Attachment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-to-base-attachment-positioning-format-1-mark-to-base-attachment-point): Mark-to-base Attachment Point
2466 pub type MarkBasePosFormat1<'a> = TableRef<'a, MarkBasePosFormat1Marker>;
2467 
2468 impl<'a> MarkBasePosFormat1<'a> {
2469     /// Format identifier: format = 1
pos_format(&self) -> u162470     pub fn pos_format(&self) -> u16 {
2471         let range = self.shape.pos_format_byte_range();
2472         self.data.read_at(range.start).unwrap()
2473     }
2474 
2475     /// Offset to markCoverage table, from beginning of MarkBasePos
2476     /// subtable.
mark_coverage_offset(&self) -> Offset162477     pub fn mark_coverage_offset(&self) -> Offset16 {
2478         let range = self.shape.mark_coverage_offset_byte_range();
2479         self.data.read_at(range.start).unwrap()
2480     }
2481 
2482     /// Attempt to resolve [`mark_coverage_offset`][Self::mark_coverage_offset].
mark_coverage(&self) -> Result<CoverageTable<'a>, ReadError>2483     pub fn mark_coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
2484         let data = self.data;
2485         self.mark_coverage_offset().resolve(data)
2486     }
2487 
2488     /// Offset to baseCoverage table, from beginning of MarkBasePos
2489     /// subtable.
base_coverage_offset(&self) -> Offset162490     pub fn base_coverage_offset(&self) -> Offset16 {
2491         let range = self.shape.base_coverage_offset_byte_range();
2492         self.data.read_at(range.start).unwrap()
2493     }
2494 
2495     /// Attempt to resolve [`base_coverage_offset`][Self::base_coverage_offset].
base_coverage(&self) -> Result<CoverageTable<'a>, ReadError>2496     pub fn base_coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
2497         let data = self.data;
2498         self.base_coverage_offset().resolve(data)
2499     }
2500 
2501     /// Number of classes defined for marks
mark_class_count(&self) -> u162502     pub fn mark_class_count(&self) -> u16 {
2503         let range = self.shape.mark_class_count_byte_range();
2504         self.data.read_at(range.start).unwrap()
2505     }
2506 
2507     /// Offset to MarkArray table, from beginning of MarkBasePos
2508     /// subtable.
mark_array_offset(&self) -> Offset162509     pub fn mark_array_offset(&self) -> Offset16 {
2510         let range = self.shape.mark_array_offset_byte_range();
2511         self.data.read_at(range.start).unwrap()
2512     }
2513 
2514     /// Attempt to resolve [`mark_array_offset`][Self::mark_array_offset].
mark_array(&self) -> Result<MarkArray<'a>, ReadError>2515     pub fn mark_array(&self) -> Result<MarkArray<'a>, ReadError> {
2516         let data = self.data;
2517         self.mark_array_offset().resolve(data)
2518     }
2519 
2520     /// Offset to BaseArray table, from beginning of MarkBasePos
2521     /// subtable.
base_array_offset(&self) -> Offset162522     pub fn base_array_offset(&self) -> Offset16 {
2523         let range = self.shape.base_array_offset_byte_range();
2524         self.data.read_at(range.start).unwrap()
2525     }
2526 
2527     /// Attempt to resolve [`base_array_offset`][Self::base_array_offset].
base_array(&self) -> Result<BaseArray<'a>, ReadError>2528     pub fn base_array(&self) -> Result<BaseArray<'a>, ReadError> {
2529         let data = self.data;
2530         let args = self.mark_class_count();
2531         self.base_array_offset().resolve_with_args(data, &args)
2532     }
2533 }
2534 
2535 #[cfg(feature = "traversal")]
2536 impl<'a> SomeTable<'a> for MarkBasePosFormat1<'a> {
type_name(&self) -> &str2537     fn type_name(&self) -> &str {
2538         "MarkBasePosFormat1"
2539     }
get_field(&self, idx: usize) -> Option<Field<'a>>2540     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2541         match idx {
2542             0usize => Some(Field::new("pos_format", self.pos_format())),
2543             1usize => Some(Field::new(
2544                 "mark_coverage_offset",
2545                 FieldType::offset(self.mark_coverage_offset(), self.mark_coverage()),
2546             )),
2547             2usize => Some(Field::new(
2548                 "base_coverage_offset",
2549                 FieldType::offset(self.base_coverage_offset(), self.base_coverage()),
2550             )),
2551             3usize => Some(Field::new("mark_class_count", self.mark_class_count())),
2552             4usize => Some(Field::new(
2553                 "mark_array_offset",
2554                 FieldType::offset(self.mark_array_offset(), self.mark_array()),
2555             )),
2556             5usize => Some(Field::new(
2557                 "base_array_offset",
2558                 FieldType::offset(self.base_array_offset(), self.base_array()),
2559             )),
2560             _ => None,
2561         }
2562     }
2563 }
2564 
2565 #[cfg(feature = "traversal")]
2566 impl<'a> std::fmt::Debug for MarkBasePosFormat1<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2567     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2568         (self as &dyn SomeTable<'a>).fmt(f)
2569     }
2570 }
2571 
2572 /// Part of [MarkBasePosFormat1]
2573 #[derive(Debug, Clone, Copy)]
2574 #[doc(hidden)]
2575 pub struct BaseArrayMarker {
2576     mark_class_count: u16,
2577     base_records_byte_len: usize,
2578 }
2579 
2580 impl BaseArrayMarker {
base_count_byte_range(&self) -> Range<usize>2581     fn base_count_byte_range(&self) -> Range<usize> {
2582         let start = 0;
2583         start..start + u16::RAW_BYTE_LEN
2584     }
base_records_byte_range(&self) -> Range<usize>2585     fn base_records_byte_range(&self) -> Range<usize> {
2586         let start = self.base_count_byte_range().end;
2587         start..start + self.base_records_byte_len
2588     }
2589 }
2590 
2591 impl ReadArgs for BaseArray<'_> {
2592     type Args = u16;
2593 }
2594 
2595 impl<'a> FontReadWithArgs<'a> for BaseArray<'a> {
read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError>2596     fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> {
2597         let mark_class_count = *args;
2598         let mut cursor = data.cursor();
2599         let base_count: u16 = cursor.read()?;
2600         let base_records_byte_len =
2601             base_count as usize * <BaseRecord as ComputeSize>::compute_size(&mark_class_count);
2602         cursor.advance_by(base_records_byte_len);
2603         cursor.finish(BaseArrayMarker {
2604             mark_class_count,
2605             base_records_byte_len,
2606         })
2607     }
2608 }
2609 
2610 impl<'a> BaseArray<'a> {
2611     /// A constructor that requires additional arguments.
2612     ///
2613     /// This type requires some external state in order to be
2614     /// parsed.
read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError>2615     pub fn read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError> {
2616         let args = mark_class_count;
2617         Self::read_with_args(data, &args)
2618     }
2619 }
2620 
2621 /// Part of [MarkBasePosFormat1]
2622 pub type BaseArray<'a> = TableRef<'a, BaseArrayMarker>;
2623 
2624 impl<'a> BaseArray<'a> {
2625     /// Number of BaseRecords
base_count(&self) -> u162626     pub fn base_count(&self) -> u16 {
2627         let range = self.shape.base_count_byte_range();
2628         self.data.read_at(range.start).unwrap()
2629     }
2630 
2631     /// Array of BaseRecords, in order of baseCoverage Index.
base_records(&self) -> ComputedArray<'a, BaseRecord<'a>>2632     pub fn base_records(&self) -> ComputedArray<'a, BaseRecord<'a>> {
2633         let range = self.shape.base_records_byte_range();
2634         self.data
2635             .read_with_args(range, &self.mark_class_count())
2636             .unwrap()
2637     }
2638 
mark_class_count(&self) -> u162639     pub(crate) fn mark_class_count(&self) -> u16 {
2640         self.shape.mark_class_count
2641     }
2642 }
2643 
2644 #[cfg(feature = "traversal")]
2645 impl<'a> SomeTable<'a> for BaseArray<'a> {
type_name(&self) -> &str2646     fn type_name(&self) -> &str {
2647         "BaseArray"
2648     }
get_field(&self, idx: usize) -> Option<Field<'a>>2649     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2650         match idx {
2651             0usize => Some(Field::new("base_count", self.base_count())),
2652             1usize => Some(Field::new(
2653                 "base_records",
2654                 traversal::FieldType::computed_array(
2655                     "BaseRecord",
2656                     self.base_records(),
2657                     self.offset_data(),
2658                 ),
2659             )),
2660             _ => None,
2661         }
2662     }
2663 }
2664 
2665 #[cfg(feature = "traversal")]
2666 impl<'a> std::fmt::Debug for BaseArray<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2667     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2668         (self as &dyn SomeTable<'a>).fmt(f)
2669     }
2670 }
2671 
2672 /// Part of [BaseArray]
2673 #[derive(Clone, Debug)]
2674 pub struct BaseRecord<'a> {
2675     /// Array of offsets (one per mark class) to Anchor tables. Offsets
2676     /// are from beginning of BaseArray table, ordered by class
2677     /// (offsets may be NULL).
2678     pub base_anchor_offsets: &'a [BigEndian<Nullable<Offset16>>],
2679 }
2680 
2681 impl<'a> BaseRecord<'a> {
2682     /// Array of offsets (one per mark class) to Anchor tables. Offsets
2683     /// are from beginning of BaseArray table, ordered by class
2684     /// (offsets may be NULL).
base_anchor_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>]2685     pub fn base_anchor_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] {
2686         self.base_anchor_offsets
2687     }
2688 
2689     /// Array of offsets (one per mark class) to Anchor tables. Offsets
2690     /// are from beginning of BaseArray table, ordered by class
2691     /// (offsets may be NULL).
2692     ///
2693     /// The `data` argument should be retrieved from the parent table
2694     /// By calling its `offset_data` method.
base_anchors( &self, data: FontData<'a>, ) -> ArrayOfNullableOffsets<'a, AnchorTable<'a>, Offset16>2695     pub fn base_anchors(
2696         &self,
2697         data: FontData<'a>,
2698     ) -> ArrayOfNullableOffsets<'a, AnchorTable<'a>, Offset16> {
2699         let offsets = self.base_anchor_offsets();
2700         ArrayOfNullableOffsets::new(offsets, data, ())
2701     }
2702 }
2703 
2704 impl ReadArgs for BaseRecord<'_> {
2705     type Args = u16;
2706 }
2707 
2708 impl ComputeSize for BaseRecord<'_> {
compute_size(args: &u16) -> usize2709     fn compute_size(args: &u16) -> usize {
2710         let mark_class_count = *args;
2711         mark_class_count as usize * Offset16::RAW_BYTE_LEN
2712     }
2713 }
2714 
2715 impl<'a> FontReadWithArgs<'a> for BaseRecord<'a> {
read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError>2716     fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> {
2717         let mut cursor = data.cursor();
2718         let mark_class_count = *args;
2719         Ok(Self {
2720             base_anchor_offsets: cursor.read_array(mark_class_count as usize)?,
2721         })
2722     }
2723 }
2724 
2725 impl<'a> BaseRecord<'a> {
2726     /// A constructor that requires additional arguments.
2727     ///
2728     /// This type requires some external state in order to be
2729     /// parsed.
read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError>2730     pub fn read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError> {
2731         let args = mark_class_count;
2732         Self::read_with_args(data, &args)
2733     }
2734 }
2735 
2736 #[cfg(feature = "traversal")]
2737 impl<'a> SomeRecord<'a> for BaseRecord<'a> {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>2738     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
2739         RecordResolver {
2740             name: "BaseRecord",
2741             get_field: Box::new(move |idx, _data| match idx {
2742                 0usize => Some({
2743                     Field::new(
2744                         "base_anchor_offsets",
2745                         FieldType::array_of_offsets(
2746                             better_type_name::<AnchorTable>(),
2747                             self.base_anchor_offsets(),
2748                             move |off| {
2749                                 let target = off.get().resolve::<AnchorTable>(data);
2750                                 FieldType::offset(off.get(), target)
2751                             },
2752                         ),
2753                     )
2754                 }),
2755                 _ => None,
2756             }),
2757             data,
2758         }
2759     }
2760 }
2761 
2762 impl Format<u16> for MarkLigPosFormat1Marker {
2763     const FORMAT: u16 = 1;
2764 }
2765 
2766 /// [Mark-to-Ligature Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-to-ligature-attachment-positioning-format-1-mark-to-ligature-attachment): Mark-to-Ligature Attachment
2767 #[derive(Debug, Clone, Copy)]
2768 #[doc(hidden)]
2769 pub struct MarkLigPosFormat1Marker {}
2770 
2771 impl MarkLigPosFormat1Marker {
pos_format_byte_range(&self) -> Range<usize>2772     fn pos_format_byte_range(&self) -> Range<usize> {
2773         let start = 0;
2774         start..start + u16::RAW_BYTE_LEN
2775     }
mark_coverage_offset_byte_range(&self) -> Range<usize>2776     fn mark_coverage_offset_byte_range(&self) -> Range<usize> {
2777         let start = self.pos_format_byte_range().end;
2778         start..start + Offset16::RAW_BYTE_LEN
2779     }
ligature_coverage_offset_byte_range(&self) -> Range<usize>2780     fn ligature_coverage_offset_byte_range(&self) -> Range<usize> {
2781         let start = self.mark_coverage_offset_byte_range().end;
2782         start..start + Offset16::RAW_BYTE_LEN
2783     }
mark_class_count_byte_range(&self) -> Range<usize>2784     fn mark_class_count_byte_range(&self) -> Range<usize> {
2785         let start = self.ligature_coverage_offset_byte_range().end;
2786         start..start + u16::RAW_BYTE_LEN
2787     }
mark_array_offset_byte_range(&self) -> Range<usize>2788     fn mark_array_offset_byte_range(&self) -> Range<usize> {
2789         let start = self.mark_class_count_byte_range().end;
2790         start..start + Offset16::RAW_BYTE_LEN
2791     }
ligature_array_offset_byte_range(&self) -> Range<usize>2792     fn ligature_array_offset_byte_range(&self) -> Range<usize> {
2793         let start = self.mark_array_offset_byte_range().end;
2794         start..start + Offset16::RAW_BYTE_LEN
2795     }
2796 }
2797 
2798 impl<'a> FontRead<'a> for MarkLigPosFormat1<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>2799     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2800         let mut cursor = data.cursor();
2801         cursor.advance::<u16>();
2802         cursor.advance::<Offset16>();
2803         cursor.advance::<Offset16>();
2804         cursor.advance::<u16>();
2805         cursor.advance::<Offset16>();
2806         cursor.advance::<Offset16>();
2807         cursor.finish(MarkLigPosFormat1Marker {})
2808     }
2809 }
2810 
2811 /// [Mark-to-Ligature Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-to-ligature-attachment-positioning-format-1-mark-to-ligature-attachment): Mark-to-Ligature Attachment
2812 pub type MarkLigPosFormat1<'a> = TableRef<'a, MarkLigPosFormat1Marker>;
2813 
2814 impl<'a> MarkLigPosFormat1<'a> {
2815     /// Format identifier: format = 1
pos_format(&self) -> u162816     pub fn pos_format(&self) -> u16 {
2817         let range = self.shape.pos_format_byte_range();
2818         self.data.read_at(range.start).unwrap()
2819     }
2820 
2821     /// Offset to markCoverage table, from beginning of MarkLigPos
2822     /// subtable.
mark_coverage_offset(&self) -> Offset162823     pub fn mark_coverage_offset(&self) -> Offset16 {
2824         let range = self.shape.mark_coverage_offset_byte_range();
2825         self.data.read_at(range.start).unwrap()
2826     }
2827 
2828     /// Attempt to resolve [`mark_coverage_offset`][Self::mark_coverage_offset].
mark_coverage(&self) -> Result<CoverageTable<'a>, ReadError>2829     pub fn mark_coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
2830         let data = self.data;
2831         self.mark_coverage_offset().resolve(data)
2832     }
2833 
2834     /// Offset to ligatureCoverage table, from beginning of MarkLigPos
2835     /// subtable.
ligature_coverage_offset(&self) -> Offset162836     pub fn ligature_coverage_offset(&self) -> Offset16 {
2837         let range = self.shape.ligature_coverage_offset_byte_range();
2838         self.data.read_at(range.start).unwrap()
2839     }
2840 
2841     /// Attempt to resolve [`ligature_coverage_offset`][Self::ligature_coverage_offset].
ligature_coverage(&self) -> Result<CoverageTable<'a>, ReadError>2842     pub fn ligature_coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
2843         let data = self.data;
2844         self.ligature_coverage_offset().resolve(data)
2845     }
2846 
2847     /// Number of defined mark classes
mark_class_count(&self) -> u162848     pub fn mark_class_count(&self) -> u16 {
2849         let range = self.shape.mark_class_count_byte_range();
2850         self.data.read_at(range.start).unwrap()
2851     }
2852 
2853     /// Offset to MarkArray table, from beginning of MarkLigPos
2854     /// subtable.
mark_array_offset(&self) -> Offset162855     pub fn mark_array_offset(&self) -> Offset16 {
2856         let range = self.shape.mark_array_offset_byte_range();
2857         self.data.read_at(range.start).unwrap()
2858     }
2859 
2860     /// Attempt to resolve [`mark_array_offset`][Self::mark_array_offset].
mark_array(&self) -> Result<MarkArray<'a>, ReadError>2861     pub fn mark_array(&self) -> Result<MarkArray<'a>, ReadError> {
2862         let data = self.data;
2863         self.mark_array_offset().resolve(data)
2864     }
2865 
2866     /// Offset to LigatureArray table, from beginning of MarkLigPos
2867     /// subtable.
ligature_array_offset(&self) -> Offset162868     pub fn ligature_array_offset(&self) -> Offset16 {
2869         let range = self.shape.ligature_array_offset_byte_range();
2870         self.data.read_at(range.start).unwrap()
2871     }
2872 
2873     /// Attempt to resolve [`ligature_array_offset`][Self::ligature_array_offset].
ligature_array(&self) -> Result<LigatureArray<'a>, ReadError>2874     pub fn ligature_array(&self) -> Result<LigatureArray<'a>, ReadError> {
2875         let data = self.data;
2876         let args = self.mark_class_count();
2877         self.ligature_array_offset().resolve_with_args(data, &args)
2878     }
2879 }
2880 
2881 #[cfg(feature = "traversal")]
2882 impl<'a> SomeTable<'a> for MarkLigPosFormat1<'a> {
type_name(&self) -> &str2883     fn type_name(&self) -> &str {
2884         "MarkLigPosFormat1"
2885     }
get_field(&self, idx: usize) -> Option<Field<'a>>2886     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
2887         match idx {
2888             0usize => Some(Field::new("pos_format", self.pos_format())),
2889             1usize => Some(Field::new(
2890                 "mark_coverage_offset",
2891                 FieldType::offset(self.mark_coverage_offset(), self.mark_coverage()),
2892             )),
2893             2usize => Some(Field::new(
2894                 "ligature_coverage_offset",
2895                 FieldType::offset(self.ligature_coverage_offset(), self.ligature_coverage()),
2896             )),
2897             3usize => Some(Field::new("mark_class_count", self.mark_class_count())),
2898             4usize => Some(Field::new(
2899                 "mark_array_offset",
2900                 FieldType::offset(self.mark_array_offset(), self.mark_array()),
2901             )),
2902             5usize => Some(Field::new(
2903                 "ligature_array_offset",
2904                 FieldType::offset(self.ligature_array_offset(), self.ligature_array()),
2905             )),
2906             _ => None,
2907         }
2908     }
2909 }
2910 
2911 #[cfg(feature = "traversal")]
2912 impl<'a> std::fmt::Debug for MarkLigPosFormat1<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result2913     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2914         (self as &dyn SomeTable<'a>).fmt(f)
2915     }
2916 }
2917 
2918 /// Part of [MarkLigPosFormat1]
2919 #[derive(Debug, Clone, Copy)]
2920 #[doc(hidden)]
2921 pub struct LigatureArrayMarker {
2922     mark_class_count: u16,
2923     ligature_attach_offsets_byte_len: usize,
2924 }
2925 
2926 impl LigatureArrayMarker {
ligature_count_byte_range(&self) -> Range<usize>2927     fn ligature_count_byte_range(&self) -> Range<usize> {
2928         let start = 0;
2929         start..start + u16::RAW_BYTE_LEN
2930     }
ligature_attach_offsets_byte_range(&self) -> Range<usize>2931     fn ligature_attach_offsets_byte_range(&self) -> Range<usize> {
2932         let start = self.ligature_count_byte_range().end;
2933         start..start + self.ligature_attach_offsets_byte_len
2934     }
2935 }
2936 
2937 impl ReadArgs for LigatureArray<'_> {
2938     type Args = u16;
2939 }
2940 
2941 impl<'a> FontReadWithArgs<'a> for LigatureArray<'a> {
read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError>2942     fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> {
2943         let mark_class_count = *args;
2944         let mut cursor = data.cursor();
2945         let ligature_count: u16 = cursor.read()?;
2946         let ligature_attach_offsets_byte_len = ligature_count as usize * Offset16::RAW_BYTE_LEN;
2947         cursor.advance_by(ligature_attach_offsets_byte_len);
2948         cursor.finish(LigatureArrayMarker {
2949             mark_class_count,
2950             ligature_attach_offsets_byte_len,
2951         })
2952     }
2953 }
2954 
2955 impl<'a> LigatureArray<'a> {
2956     /// A constructor that requires additional arguments.
2957     ///
2958     /// This type requires some external state in order to be
2959     /// parsed.
read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError>2960     pub fn read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError> {
2961         let args = mark_class_count;
2962         Self::read_with_args(data, &args)
2963     }
2964 }
2965 
2966 /// Part of [MarkLigPosFormat1]
2967 pub type LigatureArray<'a> = TableRef<'a, LigatureArrayMarker>;
2968 
2969 impl<'a> LigatureArray<'a> {
2970     /// Number of LigatureAttach table offsets
ligature_count(&self) -> u162971     pub fn ligature_count(&self) -> u16 {
2972         let range = self.shape.ligature_count_byte_range();
2973         self.data.read_at(range.start).unwrap()
2974     }
2975 
2976     /// Array of offsets to LigatureAttach tables. Offsets are from
2977     /// beginning of LigatureArray table, ordered by ligatureCoverage
2978     /// index.
ligature_attach_offsets(&self) -> &'a [BigEndian<Offset16>]2979     pub fn ligature_attach_offsets(&self) -> &'a [BigEndian<Offset16>] {
2980         let range = self.shape.ligature_attach_offsets_byte_range();
2981         self.data.read_array(range).unwrap()
2982     }
2983 
2984     /// A dynamically resolving wrapper for [`ligature_attach_offsets`][Self::ligature_attach_offsets].
ligature_attaches(&self) -> ArrayOfOffsets<'a, LigatureAttach<'a>, Offset16>2985     pub fn ligature_attaches(&self) -> ArrayOfOffsets<'a, LigatureAttach<'a>, Offset16> {
2986         let data = self.data;
2987         let offsets = self.ligature_attach_offsets();
2988         let args = self.mark_class_count();
2989         ArrayOfOffsets::new(offsets, data, args)
2990     }
2991 
mark_class_count(&self) -> u162992     pub(crate) fn mark_class_count(&self) -> u16 {
2993         self.shape.mark_class_count
2994     }
2995 }
2996 
2997 #[cfg(feature = "traversal")]
2998 impl<'a> SomeTable<'a> for LigatureArray<'a> {
type_name(&self) -> &str2999     fn type_name(&self) -> &str {
3000         "LigatureArray"
3001     }
get_field(&self, idx: usize) -> Option<Field<'a>>3002     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3003         match idx {
3004             0usize => Some(Field::new("ligature_count", self.ligature_count())),
3005             1usize => Some({
3006                 let data = self.data;
3007                 let args = self.mark_class_count();
3008                 Field::new(
3009                     "ligature_attach_offsets",
3010                     FieldType::array_of_offsets(
3011                         better_type_name::<LigatureAttach>(),
3012                         self.ligature_attach_offsets(),
3013                         move |off| {
3014                             let target = off.get().resolve_with_args::<LigatureAttach>(data, &args);
3015                             FieldType::offset(off.get(), target)
3016                         },
3017                     ),
3018                 )
3019             }),
3020             _ => None,
3021         }
3022     }
3023 }
3024 
3025 #[cfg(feature = "traversal")]
3026 impl<'a> std::fmt::Debug for LigatureArray<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3027     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3028         (self as &dyn SomeTable<'a>).fmt(f)
3029     }
3030 }
3031 
3032 /// Part of [MarkLigPosFormat1]
3033 #[derive(Debug, Clone, Copy)]
3034 #[doc(hidden)]
3035 pub struct LigatureAttachMarker {
3036     mark_class_count: u16,
3037     component_records_byte_len: usize,
3038 }
3039 
3040 impl LigatureAttachMarker {
component_count_byte_range(&self) -> Range<usize>3041     fn component_count_byte_range(&self) -> Range<usize> {
3042         let start = 0;
3043         start..start + u16::RAW_BYTE_LEN
3044     }
component_records_byte_range(&self) -> Range<usize>3045     fn component_records_byte_range(&self) -> Range<usize> {
3046         let start = self.component_count_byte_range().end;
3047         start..start + self.component_records_byte_len
3048     }
3049 }
3050 
3051 impl ReadArgs for LigatureAttach<'_> {
3052     type Args = u16;
3053 }
3054 
3055 impl<'a> FontReadWithArgs<'a> for LigatureAttach<'a> {
read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError>3056     fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> {
3057         let mark_class_count = *args;
3058         let mut cursor = data.cursor();
3059         let component_count: u16 = cursor.read()?;
3060         let component_records_byte_len = component_count as usize
3061             * <ComponentRecord as ComputeSize>::compute_size(&mark_class_count);
3062         cursor.advance_by(component_records_byte_len);
3063         cursor.finish(LigatureAttachMarker {
3064             mark_class_count,
3065             component_records_byte_len,
3066         })
3067     }
3068 }
3069 
3070 impl<'a> LigatureAttach<'a> {
3071     /// A constructor that requires additional arguments.
3072     ///
3073     /// This type requires some external state in order to be
3074     /// parsed.
read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError>3075     pub fn read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError> {
3076         let args = mark_class_count;
3077         Self::read_with_args(data, &args)
3078     }
3079 }
3080 
3081 /// Part of [MarkLigPosFormat1]
3082 pub type LigatureAttach<'a> = TableRef<'a, LigatureAttachMarker>;
3083 
3084 impl<'a> LigatureAttach<'a> {
3085     /// Number of ComponentRecords in this ligature
component_count(&self) -> u163086     pub fn component_count(&self) -> u16 {
3087         let range = self.shape.component_count_byte_range();
3088         self.data.read_at(range.start).unwrap()
3089     }
3090 
3091     /// Array of Component records, ordered in writing direction.
component_records(&self) -> ComputedArray<'a, ComponentRecord<'a>>3092     pub fn component_records(&self) -> ComputedArray<'a, ComponentRecord<'a>> {
3093         let range = self.shape.component_records_byte_range();
3094         self.data
3095             .read_with_args(range, &self.mark_class_count())
3096             .unwrap()
3097     }
3098 
mark_class_count(&self) -> u163099     pub(crate) fn mark_class_count(&self) -> u16 {
3100         self.shape.mark_class_count
3101     }
3102 }
3103 
3104 #[cfg(feature = "traversal")]
3105 impl<'a> SomeTable<'a> for LigatureAttach<'a> {
type_name(&self) -> &str3106     fn type_name(&self) -> &str {
3107         "LigatureAttach"
3108     }
get_field(&self, idx: usize) -> Option<Field<'a>>3109     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3110         match idx {
3111             0usize => Some(Field::new("component_count", self.component_count())),
3112             1usize => Some(Field::new(
3113                 "component_records",
3114                 traversal::FieldType::computed_array(
3115                     "ComponentRecord",
3116                     self.component_records(),
3117                     self.offset_data(),
3118                 ),
3119             )),
3120             _ => None,
3121         }
3122     }
3123 }
3124 
3125 #[cfg(feature = "traversal")]
3126 impl<'a> std::fmt::Debug for LigatureAttach<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3127     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3128         (self as &dyn SomeTable<'a>).fmt(f)
3129     }
3130 }
3131 
3132 /// Part of [MarkLigPosFormat1]
3133 #[derive(Clone, Debug)]
3134 pub struct ComponentRecord<'a> {
3135     /// Array of offsets (one per class) to Anchor tables. Offsets are
3136     /// from beginning of LigatureAttach table, ordered by class
3137     /// (offsets may be NULL).
3138     pub ligature_anchor_offsets: &'a [BigEndian<Nullable<Offset16>>],
3139 }
3140 
3141 impl<'a> ComponentRecord<'a> {
3142     /// Array of offsets (one per class) to Anchor tables. Offsets are
3143     /// from beginning of LigatureAttach table, ordered by class
3144     /// (offsets may be NULL).
ligature_anchor_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>]3145     pub fn ligature_anchor_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] {
3146         self.ligature_anchor_offsets
3147     }
3148 
3149     /// Array of offsets (one per class) to Anchor tables. Offsets are
3150     /// from beginning of LigatureAttach table, ordered by class
3151     /// (offsets may be NULL).
3152     ///
3153     /// The `data` argument should be retrieved from the parent table
3154     /// By calling its `offset_data` method.
ligature_anchors( &self, data: FontData<'a>, ) -> ArrayOfNullableOffsets<'a, AnchorTable<'a>, Offset16>3155     pub fn ligature_anchors(
3156         &self,
3157         data: FontData<'a>,
3158     ) -> ArrayOfNullableOffsets<'a, AnchorTable<'a>, Offset16> {
3159         let offsets = self.ligature_anchor_offsets();
3160         ArrayOfNullableOffsets::new(offsets, data, ())
3161     }
3162 }
3163 
3164 impl ReadArgs for ComponentRecord<'_> {
3165     type Args = u16;
3166 }
3167 
3168 impl ComputeSize for ComponentRecord<'_> {
compute_size(args: &u16) -> usize3169     fn compute_size(args: &u16) -> usize {
3170         let mark_class_count = *args;
3171         mark_class_count as usize * Offset16::RAW_BYTE_LEN
3172     }
3173 }
3174 
3175 impl<'a> FontReadWithArgs<'a> for ComponentRecord<'a> {
read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError>3176     fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> {
3177         let mut cursor = data.cursor();
3178         let mark_class_count = *args;
3179         Ok(Self {
3180             ligature_anchor_offsets: cursor.read_array(mark_class_count as usize)?,
3181         })
3182     }
3183 }
3184 
3185 impl<'a> ComponentRecord<'a> {
3186     /// A constructor that requires additional arguments.
3187     ///
3188     /// This type requires some external state in order to be
3189     /// parsed.
read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError>3190     pub fn read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError> {
3191         let args = mark_class_count;
3192         Self::read_with_args(data, &args)
3193     }
3194 }
3195 
3196 #[cfg(feature = "traversal")]
3197 impl<'a> SomeRecord<'a> for ComponentRecord<'a> {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>3198     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
3199         RecordResolver {
3200             name: "ComponentRecord",
3201             get_field: Box::new(move |idx, _data| match idx {
3202                 0usize => Some({
3203                     Field::new(
3204                         "ligature_anchor_offsets",
3205                         FieldType::array_of_offsets(
3206                             better_type_name::<AnchorTable>(),
3207                             self.ligature_anchor_offsets(),
3208                             move |off| {
3209                                 let target = off.get().resolve::<AnchorTable>(data);
3210                                 FieldType::offset(off.get(), target)
3211                             },
3212                         ),
3213                     )
3214                 }),
3215                 _ => None,
3216             }),
3217             data,
3218         }
3219     }
3220 }
3221 
3222 impl Format<u16> for MarkMarkPosFormat1Marker {
3223     const FORMAT: u16 = 1;
3224 }
3225 
3226 /// [Mark-to-Mark Attachment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-to-mark-attachment-positioning-format-1-mark-to-mark-attachment): Mark-to-Mark Attachment
3227 #[derive(Debug, Clone, Copy)]
3228 #[doc(hidden)]
3229 pub struct MarkMarkPosFormat1Marker {}
3230 
3231 impl MarkMarkPosFormat1Marker {
pos_format_byte_range(&self) -> Range<usize>3232     fn pos_format_byte_range(&self) -> Range<usize> {
3233         let start = 0;
3234         start..start + u16::RAW_BYTE_LEN
3235     }
mark1_coverage_offset_byte_range(&self) -> Range<usize>3236     fn mark1_coverage_offset_byte_range(&self) -> Range<usize> {
3237         let start = self.pos_format_byte_range().end;
3238         start..start + Offset16::RAW_BYTE_LEN
3239     }
mark2_coverage_offset_byte_range(&self) -> Range<usize>3240     fn mark2_coverage_offset_byte_range(&self) -> Range<usize> {
3241         let start = self.mark1_coverage_offset_byte_range().end;
3242         start..start + Offset16::RAW_BYTE_LEN
3243     }
mark_class_count_byte_range(&self) -> Range<usize>3244     fn mark_class_count_byte_range(&self) -> Range<usize> {
3245         let start = self.mark2_coverage_offset_byte_range().end;
3246         start..start + u16::RAW_BYTE_LEN
3247     }
mark1_array_offset_byte_range(&self) -> Range<usize>3248     fn mark1_array_offset_byte_range(&self) -> Range<usize> {
3249         let start = self.mark_class_count_byte_range().end;
3250         start..start + Offset16::RAW_BYTE_LEN
3251     }
mark2_array_offset_byte_range(&self) -> Range<usize>3252     fn mark2_array_offset_byte_range(&self) -> Range<usize> {
3253         let start = self.mark1_array_offset_byte_range().end;
3254         start..start + Offset16::RAW_BYTE_LEN
3255     }
3256 }
3257 
3258 impl<'a> FontRead<'a> for MarkMarkPosFormat1<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>3259     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3260         let mut cursor = data.cursor();
3261         cursor.advance::<u16>();
3262         cursor.advance::<Offset16>();
3263         cursor.advance::<Offset16>();
3264         cursor.advance::<u16>();
3265         cursor.advance::<Offset16>();
3266         cursor.advance::<Offset16>();
3267         cursor.finish(MarkMarkPosFormat1Marker {})
3268     }
3269 }
3270 
3271 /// [Mark-to-Mark Attachment Positioning Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-to-mark-attachment-positioning-format-1-mark-to-mark-attachment): Mark-to-Mark Attachment
3272 pub type MarkMarkPosFormat1<'a> = TableRef<'a, MarkMarkPosFormat1Marker>;
3273 
3274 impl<'a> MarkMarkPosFormat1<'a> {
3275     /// Format identifier: format = 1
pos_format(&self) -> u163276     pub fn pos_format(&self) -> u16 {
3277         let range = self.shape.pos_format_byte_range();
3278         self.data.read_at(range.start).unwrap()
3279     }
3280 
3281     /// Offset to Combining Mark Coverage table, from beginning of
3282     /// MarkMarkPos subtable.
mark1_coverage_offset(&self) -> Offset163283     pub fn mark1_coverage_offset(&self) -> Offset16 {
3284         let range = self.shape.mark1_coverage_offset_byte_range();
3285         self.data.read_at(range.start).unwrap()
3286     }
3287 
3288     /// Attempt to resolve [`mark1_coverage_offset`][Self::mark1_coverage_offset].
mark1_coverage(&self) -> Result<CoverageTable<'a>, ReadError>3289     pub fn mark1_coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
3290         let data = self.data;
3291         self.mark1_coverage_offset().resolve(data)
3292     }
3293 
3294     /// Offset to Base Mark Coverage table, from beginning of
3295     /// MarkMarkPos subtable.
mark2_coverage_offset(&self) -> Offset163296     pub fn mark2_coverage_offset(&self) -> Offset16 {
3297         let range = self.shape.mark2_coverage_offset_byte_range();
3298         self.data.read_at(range.start).unwrap()
3299     }
3300 
3301     /// Attempt to resolve [`mark2_coverage_offset`][Self::mark2_coverage_offset].
mark2_coverage(&self) -> Result<CoverageTable<'a>, ReadError>3302     pub fn mark2_coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
3303         let data = self.data;
3304         self.mark2_coverage_offset().resolve(data)
3305     }
3306 
3307     /// Number of Combining Mark classes defined
mark_class_count(&self) -> u163308     pub fn mark_class_count(&self) -> u16 {
3309         let range = self.shape.mark_class_count_byte_range();
3310         self.data.read_at(range.start).unwrap()
3311     }
3312 
3313     /// Offset to MarkArray table for mark1, from beginning of
3314     /// MarkMarkPos subtable.
mark1_array_offset(&self) -> Offset163315     pub fn mark1_array_offset(&self) -> Offset16 {
3316         let range = self.shape.mark1_array_offset_byte_range();
3317         self.data.read_at(range.start).unwrap()
3318     }
3319 
3320     /// Attempt to resolve [`mark1_array_offset`][Self::mark1_array_offset].
mark1_array(&self) -> Result<MarkArray<'a>, ReadError>3321     pub fn mark1_array(&self) -> Result<MarkArray<'a>, ReadError> {
3322         let data = self.data;
3323         self.mark1_array_offset().resolve(data)
3324     }
3325 
3326     /// Offset to Mark2Array table for mark2, from beginning of
3327     /// MarkMarkPos subtable.
mark2_array_offset(&self) -> Offset163328     pub fn mark2_array_offset(&self) -> Offset16 {
3329         let range = self.shape.mark2_array_offset_byte_range();
3330         self.data.read_at(range.start).unwrap()
3331     }
3332 
3333     /// Attempt to resolve [`mark2_array_offset`][Self::mark2_array_offset].
mark2_array(&self) -> Result<Mark2Array<'a>, ReadError>3334     pub fn mark2_array(&self) -> Result<Mark2Array<'a>, ReadError> {
3335         let data = self.data;
3336         let args = self.mark_class_count();
3337         self.mark2_array_offset().resolve_with_args(data, &args)
3338     }
3339 }
3340 
3341 #[cfg(feature = "traversal")]
3342 impl<'a> SomeTable<'a> for MarkMarkPosFormat1<'a> {
type_name(&self) -> &str3343     fn type_name(&self) -> &str {
3344         "MarkMarkPosFormat1"
3345     }
get_field(&self, idx: usize) -> Option<Field<'a>>3346     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3347         match idx {
3348             0usize => Some(Field::new("pos_format", self.pos_format())),
3349             1usize => Some(Field::new(
3350                 "mark1_coverage_offset",
3351                 FieldType::offset(self.mark1_coverage_offset(), self.mark1_coverage()),
3352             )),
3353             2usize => Some(Field::new(
3354                 "mark2_coverage_offset",
3355                 FieldType::offset(self.mark2_coverage_offset(), self.mark2_coverage()),
3356             )),
3357             3usize => Some(Field::new("mark_class_count", self.mark_class_count())),
3358             4usize => Some(Field::new(
3359                 "mark1_array_offset",
3360                 FieldType::offset(self.mark1_array_offset(), self.mark1_array()),
3361             )),
3362             5usize => Some(Field::new(
3363                 "mark2_array_offset",
3364                 FieldType::offset(self.mark2_array_offset(), self.mark2_array()),
3365             )),
3366             _ => None,
3367         }
3368     }
3369 }
3370 
3371 #[cfg(feature = "traversal")]
3372 impl<'a> std::fmt::Debug for MarkMarkPosFormat1<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3373     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3374         (self as &dyn SomeTable<'a>).fmt(f)
3375     }
3376 }
3377 
3378 /// Part of [MarkMarkPosFormat1]Class2Record
3379 #[derive(Debug, Clone, Copy)]
3380 #[doc(hidden)]
3381 pub struct Mark2ArrayMarker {
3382     mark_class_count: u16,
3383     mark2_records_byte_len: usize,
3384 }
3385 
3386 impl Mark2ArrayMarker {
mark2_count_byte_range(&self) -> Range<usize>3387     fn mark2_count_byte_range(&self) -> Range<usize> {
3388         let start = 0;
3389         start..start + u16::RAW_BYTE_LEN
3390     }
mark2_records_byte_range(&self) -> Range<usize>3391     fn mark2_records_byte_range(&self) -> Range<usize> {
3392         let start = self.mark2_count_byte_range().end;
3393         start..start + self.mark2_records_byte_len
3394     }
3395 }
3396 
3397 impl ReadArgs for Mark2Array<'_> {
3398     type Args = u16;
3399 }
3400 
3401 impl<'a> FontReadWithArgs<'a> for Mark2Array<'a> {
read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError>3402     fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> {
3403         let mark_class_count = *args;
3404         let mut cursor = data.cursor();
3405         let mark2_count: u16 = cursor.read()?;
3406         let mark2_records_byte_len =
3407             mark2_count as usize * <Mark2Record as ComputeSize>::compute_size(&mark_class_count);
3408         cursor.advance_by(mark2_records_byte_len);
3409         cursor.finish(Mark2ArrayMarker {
3410             mark_class_count,
3411             mark2_records_byte_len,
3412         })
3413     }
3414 }
3415 
3416 impl<'a> Mark2Array<'a> {
3417     /// A constructor that requires additional arguments.
3418     ///
3419     /// This type requires some external state in order to be
3420     /// parsed.
read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError>3421     pub fn read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError> {
3422         let args = mark_class_count;
3423         Self::read_with_args(data, &args)
3424     }
3425 }
3426 
3427 /// Part of [MarkMarkPosFormat1]Class2Record
3428 pub type Mark2Array<'a> = TableRef<'a, Mark2ArrayMarker>;
3429 
3430 impl<'a> Mark2Array<'a> {
3431     /// Number of Mark2 records
mark2_count(&self) -> u163432     pub fn mark2_count(&self) -> u16 {
3433         let range = self.shape.mark2_count_byte_range();
3434         self.data.read_at(range.start).unwrap()
3435     }
3436 
3437     /// Array of Mark2Records, in Coverage order.
mark2_records(&self) -> ComputedArray<'a, Mark2Record<'a>>3438     pub fn mark2_records(&self) -> ComputedArray<'a, Mark2Record<'a>> {
3439         let range = self.shape.mark2_records_byte_range();
3440         self.data
3441             .read_with_args(range, &self.mark_class_count())
3442             .unwrap()
3443     }
3444 
mark_class_count(&self) -> u163445     pub(crate) fn mark_class_count(&self) -> u16 {
3446         self.shape.mark_class_count
3447     }
3448 }
3449 
3450 #[cfg(feature = "traversal")]
3451 impl<'a> SomeTable<'a> for Mark2Array<'a> {
type_name(&self) -> &str3452     fn type_name(&self) -> &str {
3453         "Mark2Array"
3454     }
get_field(&self, idx: usize) -> Option<Field<'a>>3455     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3456         match idx {
3457             0usize => Some(Field::new("mark2_count", self.mark2_count())),
3458             1usize => Some(Field::new(
3459                 "mark2_records",
3460                 traversal::FieldType::computed_array(
3461                     "Mark2Record",
3462                     self.mark2_records(),
3463                     self.offset_data(),
3464                 ),
3465             )),
3466             _ => None,
3467         }
3468     }
3469 }
3470 
3471 #[cfg(feature = "traversal")]
3472 impl<'a> std::fmt::Debug for Mark2Array<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3473     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3474         (self as &dyn SomeTable<'a>).fmt(f)
3475     }
3476 }
3477 
3478 /// Part of [MarkMarkPosFormat1]
3479 #[derive(Clone, Debug)]
3480 pub struct Mark2Record<'a> {
3481     /// Array of offsets (one per class) to Anchor tables. Offsets are
3482     /// from beginning of Mark2Array table, in class order (offsets may
3483     /// be NULL).
3484     pub mark2_anchor_offsets: &'a [BigEndian<Nullable<Offset16>>],
3485 }
3486 
3487 impl<'a> Mark2Record<'a> {
3488     /// Array of offsets (one per class) to Anchor tables. Offsets are
3489     /// from beginning of Mark2Array table, in class order (offsets may
3490     /// be NULL).
mark2_anchor_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>]3491     pub fn mark2_anchor_offsets(&self) -> &'a [BigEndian<Nullable<Offset16>>] {
3492         self.mark2_anchor_offsets
3493     }
3494 
3495     /// Array of offsets (one per class) to Anchor tables. Offsets are
3496     /// from beginning of Mark2Array table, in class order (offsets may
3497     /// be NULL).
3498     ///
3499     /// The `data` argument should be retrieved from the parent table
3500     /// By calling its `offset_data` method.
mark2_anchors( &self, data: FontData<'a>, ) -> ArrayOfNullableOffsets<'a, AnchorTable<'a>, Offset16>3501     pub fn mark2_anchors(
3502         &self,
3503         data: FontData<'a>,
3504     ) -> ArrayOfNullableOffsets<'a, AnchorTable<'a>, Offset16> {
3505         let offsets = self.mark2_anchor_offsets();
3506         ArrayOfNullableOffsets::new(offsets, data, ())
3507     }
3508 }
3509 
3510 impl ReadArgs for Mark2Record<'_> {
3511     type Args = u16;
3512 }
3513 
3514 impl ComputeSize for Mark2Record<'_> {
compute_size(args: &u16) -> usize3515     fn compute_size(args: &u16) -> usize {
3516         let mark_class_count = *args;
3517         mark_class_count as usize * Offset16::RAW_BYTE_LEN
3518     }
3519 }
3520 
3521 impl<'a> FontReadWithArgs<'a> for Mark2Record<'a> {
read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError>3522     fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> {
3523         let mut cursor = data.cursor();
3524         let mark_class_count = *args;
3525         Ok(Self {
3526             mark2_anchor_offsets: cursor.read_array(mark_class_count as usize)?,
3527         })
3528     }
3529 }
3530 
3531 impl<'a> Mark2Record<'a> {
3532     /// A constructor that requires additional arguments.
3533     ///
3534     /// This type requires some external state in order to be
3535     /// parsed.
read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError>3536     pub fn read(data: FontData<'a>, mark_class_count: u16) -> Result<Self, ReadError> {
3537         let args = mark_class_count;
3538         Self::read_with_args(data, &args)
3539     }
3540 }
3541 
3542 #[cfg(feature = "traversal")]
3543 impl<'a> SomeRecord<'a> for Mark2Record<'a> {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>3544     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
3545         RecordResolver {
3546             name: "Mark2Record",
3547             get_field: Box::new(move |idx, _data| match idx {
3548                 0usize => Some({
3549                     Field::new(
3550                         "mark2_anchor_offsets",
3551                         FieldType::array_of_offsets(
3552                             better_type_name::<AnchorTable>(),
3553                             self.mark2_anchor_offsets(),
3554                             move |off| {
3555                                 let target = off.get().resolve::<AnchorTable>(data);
3556                                 FieldType::offset(off.get(), target)
3557                             },
3558                         ),
3559                     )
3560                 }),
3561                 _ => None,
3562             }),
3563             data,
3564         }
3565     }
3566 }
3567 
3568 impl Format<u16> for ExtensionPosFormat1Marker {
3569     const FORMAT: u16 = 1;
3570 }
3571 
3572 /// [Extension Positioning Subtable Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#extension-positioning-subtable-format-1)
3573 #[derive(Debug)]
3574 #[doc(hidden)]
3575 pub struct ExtensionPosFormat1Marker<T = ()> {
3576     offset_type: std::marker::PhantomData<*const T>,
3577 }
3578 
3579 impl<T> ExtensionPosFormat1Marker<T> {
pos_format_byte_range(&self) -> Range<usize>3580     fn pos_format_byte_range(&self) -> Range<usize> {
3581         let start = 0;
3582         start..start + u16::RAW_BYTE_LEN
3583     }
extension_lookup_type_byte_range(&self) -> Range<usize>3584     fn extension_lookup_type_byte_range(&self) -> Range<usize> {
3585         let start = self.pos_format_byte_range().end;
3586         start..start + u16::RAW_BYTE_LEN
3587     }
extension_offset_byte_range(&self) -> Range<usize>3588     fn extension_offset_byte_range(&self) -> Range<usize> {
3589         let start = self.extension_lookup_type_byte_range().end;
3590         start..start + Offset32::RAW_BYTE_LEN
3591     }
3592 }
3593 
3594 impl<T> Clone for ExtensionPosFormat1Marker<T> {
clone(&self) -> Self3595     fn clone(&self) -> Self {
3596         *self
3597     }
3598 }
3599 
3600 impl<T> Copy for ExtensionPosFormat1Marker<T> {}
3601 
3602 impl<'a, T> FontRead<'a> for ExtensionPosFormat1<'a, T> {
read(data: FontData<'a>) -> Result<Self, ReadError>3603     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3604         let mut cursor = data.cursor();
3605         cursor.advance::<u16>();
3606         cursor.advance::<u16>();
3607         cursor.advance::<Offset32>();
3608         cursor.finish(ExtensionPosFormat1Marker {
3609             offset_type: std::marker::PhantomData,
3610         })
3611     }
3612 }
3613 
3614 impl<'a> ExtensionPosFormat1<'a, ()> {
3615     #[allow(dead_code)]
into_concrete<T>(self) -> ExtensionPosFormat1<'a, T>3616     pub(crate) fn into_concrete<T>(self) -> ExtensionPosFormat1<'a, T> {
3617         let TableRef { data, .. } = self;
3618         TableRef {
3619             shape: ExtensionPosFormat1Marker {
3620                 offset_type: std::marker::PhantomData,
3621             },
3622             data,
3623         }
3624     }
3625 }
3626 
3627 impl<'a, T> ExtensionPosFormat1<'a, T> {
3628     #[allow(dead_code)]
3629     /// Replace the specific generic type on this implementation with `()`
of_unit_type(&self) -> ExtensionPosFormat1<'a, ()>3630     pub(crate) fn of_unit_type(&self) -> ExtensionPosFormat1<'a, ()> {
3631         let TableRef { data, .. } = self;
3632         TableRef {
3633             shape: ExtensionPosFormat1Marker {
3634                 offset_type: std::marker::PhantomData,
3635             },
3636             data: *data,
3637         }
3638     }
3639 }
3640 
3641 /// [Extension Positioning Subtable Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#extension-positioning-subtable-format-1)
3642 pub type ExtensionPosFormat1<'a, T> = TableRef<'a, ExtensionPosFormat1Marker<T>>;
3643 
3644 impl<'a, T> ExtensionPosFormat1<'a, T> {
3645     /// Format identifier: format = 1
pos_format(&self) -> u163646     pub fn pos_format(&self) -> u16 {
3647         let range = self.shape.pos_format_byte_range();
3648         self.data.read_at(range.start).unwrap()
3649     }
3650 
3651     /// Lookup type of subtable referenced by extensionOffset (i.e. the
3652     /// extension subtable).
extension_lookup_type(&self) -> u163653     pub fn extension_lookup_type(&self) -> u16 {
3654         let range = self.shape.extension_lookup_type_byte_range();
3655         self.data.read_at(range.start).unwrap()
3656     }
3657 
3658     /// Offset to the extension subtable, of lookup type
3659     /// extensionLookupType, relative to the start of the
3660     /// ExtensionPosFormat1 subtable.
extension_offset(&self) -> Offset323661     pub fn extension_offset(&self) -> Offset32 {
3662         let range = self.shape.extension_offset_byte_range();
3663         self.data.read_at(range.start).unwrap()
3664     }
3665 
3666     /// Attempt to resolve [`extension_offset`][Self::extension_offset].
extension(&self) -> Result<T, ReadError> where T: FontRead<'a>,3667     pub fn extension(&self) -> Result<T, ReadError>
3668     where
3669         T: FontRead<'a>,
3670     {
3671         let data = self.data;
3672         self.extension_offset().resolve(data)
3673     }
3674 }
3675 
3676 #[cfg(feature = "traversal")]
3677 impl<'a, T: FontRead<'a> + SomeTable<'a> + 'a> SomeTable<'a> for ExtensionPosFormat1<'a, T> {
type_name(&self) -> &str3678     fn type_name(&self) -> &str {
3679         "ExtensionPosFormat1"
3680     }
get_field(&self, idx: usize) -> Option<Field<'a>>3681     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3682         match idx {
3683             0usize => Some(Field::new("pos_format", self.pos_format())),
3684             1usize => Some(Field::new(
3685                 "extension_lookup_type",
3686                 self.extension_lookup_type(),
3687             )),
3688             2usize => Some(Field::new(
3689                 "extension_offset",
3690                 FieldType::offset(self.extension_offset(), self.extension()),
3691             )),
3692             _ => None,
3693         }
3694     }
3695 }
3696 
3697 #[cfg(feature = "traversal")]
3698 impl<'a, T: FontRead<'a> + SomeTable<'a> + 'a> std::fmt::Debug for ExtensionPosFormat1<'a, T> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3699     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3700         (self as &dyn SomeTable<'a>).fmt(f)
3701     }
3702 }
3703 
3704 /// A [GPOS Extension Positioning](https://learn.microsoft.com/en-us/typography/opentype/spec/gpos#lookuptype-9-extension-positioning) subtable
3705 pub enum ExtensionSubtable<'a> {
3706     Single(ExtensionPosFormat1<'a, SinglePos<'a>>),
3707     Pair(ExtensionPosFormat1<'a, PairPos<'a>>),
3708     Cursive(ExtensionPosFormat1<'a, CursivePosFormat1<'a>>),
3709     MarkToBase(ExtensionPosFormat1<'a, MarkBasePosFormat1<'a>>),
3710     MarkToLig(ExtensionPosFormat1<'a, MarkLigPosFormat1<'a>>),
3711     MarkToMark(ExtensionPosFormat1<'a, MarkMarkPosFormat1<'a>>),
3712     Contextual(ExtensionPosFormat1<'a, PositionSequenceContext<'a>>),
3713     ChainContextual(ExtensionPosFormat1<'a, PositionChainContext<'a>>),
3714 }
3715 
3716 impl<'a> FontRead<'a> for ExtensionSubtable<'a> {
read(bytes: FontData<'a>) -> Result<Self, ReadError>3717     fn read(bytes: FontData<'a>) -> Result<Self, ReadError> {
3718         let untyped = ExtensionPosFormat1::read(bytes)?;
3719         match untyped.extension_lookup_type() {
3720             1 => Ok(ExtensionSubtable::Single(untyped.into_concrete())),
3721             2 => Ok(ExtensionSubtable::Pair(untyped.into_concrete())),
3722             3 => Ok(ExtensionSubtable::Cursive(untyped.into_concrete())),
3723             4 => Ok(ExtensionSubtable::MarkToBase(untyped.into_concrete())),
3724             5 => Ok(ExtensionSubtable::MarkToLig(untyped.into_concrete())),
3725             6 => Ok(ExtensionSubtable::MarkToMark(untyped.into_concrete())),
3726             7 => Ok(ExtensionSubtable::Contextual(untyped.into_concrete())),
3727             8 => Ok(ExtensionSubtable::ChainContextual(untyped.into_concrete())),
3728             other => Err(ReadError::InvalidFormat(other.into())),
3729         }
3730     }
3731 }
3732 
3733 impl<'a> ExtensionSubtable<'a> {
3734     #[allow(dead_code)]
3735     /// Return the inner table, removing the specific generics.
3736     ///
3737     /// This lets us return a single concrete type we can call methods on.
of_unit_type(&self) -> ExtensionPosFormat1<'a, ()>3738     pub(crate) fn of_unit_type(&self) -> ExtensionPosFormat1<'a, ()> {
3739         match self {
3740             ExtensionSubtable::Single(inner) => inner.of_unit_type(),
3741             ExtensionSubtable::Pair(inner) => inner.of_unit_type(),
3742             ExtensionSubtable::Cursive(inner) => inner.of_unit_type(),
3743             ExtensionSubtable::MarkToBase(inner) => inner.of_unit_type(),
3744             ExtensionSubtable::MarkToLig(inner) => inner.of_unit_type(),
3745             ExtensionSubtable::MarkToMark(inner) => inner.of_unit_type(),
3746             ExtensionSubtable::Contextual(inner) => inner.of_unit_type(),
3747             ExtensionSubtable::ChainContextual(inner) => inner.of_unit_type(),
3748         }
3749     }
3750 }
3751 
3752 #[cfg(feature = "traversal")]
3753 impl<'a> ExtensionSubtable<'a> {
dyn_inner(&self) -> &(dyn SomeTable<'a> + 'a)3754     fn dyn_inner(&self) -> &(dyn SomeTable<'a> + 'a) {
3755         match self {
3756             ExtensionSubtable::Single(table) => table,
3757             ExtensionSubtable::Pair(table) => table,
3758             ExtensionSubtable::Cursive(table) => table,
3759             ExtensionSubtable::MarkToBase(table) => table,
3760             ExtensionSubtable::MarkToLig(table) => table,
3761             ExtensionSubtable::MarkToMark(table) => table,
3762             ExtensionSubtable::Contextual(table) => table,
3763             ExtensionSubtable::ChainContextual(table) => table,
3764         }
3765     }
3766 }
3767 
3768 #[cfg(feature = "traversal")]
3769 impl<'a> SomeTable<'a> for ExtensionSubtable<'a> {
get_field(&self, idx: usize) -> Option<Field<'a>>3770     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
3771         self.dyn_inner().get_field(idx)
3772     }
type_name(&self) -> &str3773     fn type_name(&self) -> &str {
3774         self.dyn_inner().type_name()
3775     }
3776 }
3777 
3778 #[cfg(feature = "traversal")]
3779 impl<'a> std::fmt::Debug for ExtensionSubtable<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result3780     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3781         self.dyn_inner().fmt(f)
3782     }
3783 }
3784