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 /// [GDEF](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#gdef-header) 1.0
9 #[derive(Debug, Clone, Copy)]
10 #[doc(hidden)]
11 pub struct GdefMarker {
12     mark_glyph_sets_def_offset_byte_start: Option<usize>,
13     item_var_store_offset_byte_start: Option<usize>,
14 }
15 
16 impl GdefMarker {
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     }
glyph_class_def_offset_byte_range(&self) -> Range<usize>21     fn glyph_class_def_offset_byte_range(&self) -> Range<usize> {
22         let start = self.version_byte_range().end;
23         start..start + Offset16::RAW_BYTE_LEN
24     }
attach_list_offset_byte_range(&self) -> Range<usize>25     fn attach_list_offset_byte_range(&self) -> Range<usize> {
26         let start = self.glyph_class_def_offset_byte_range().end;
27         start..start + Offset16::RAW_BYTE_LEN
28     }
lig_caret_list_offset_byte_range(&self) -> Range<usize>29     fn lig_caret_list_offset_byte_range(&self) -> Range<usize> {
30         let start = self.attach_list_offset_byte_range().end;
31         start..start + Offset16::RAW_BYTE_LEN
32     }
mark_attach_class_def_offset_byte_range(&self) -> Range<usize>33     fn mark_attach_class_def_offset_byte_range(&self) -> Range<usize> {
34         let start = self.lig_caret_list_offset_byte_range().end;
35         start..start + Offset16::RAW_BYTE_LEN
36     }
mark_glyph_sets_def_offset_byte_range(&self) -> Option<Range<usize>>37     fn mark_glyph_sets_def_offset_byte_range(&self) -> Option<Range<usize>> {
38         let start = self.mark_glyph_sets_def_offset_byte_start?;
39         Some(start..start + Offset16::RAW_BYTE_LEN)
40     }
item_var_store_offset_byte_range(&self) -> Option<Range<usize>>41     fn item_var_store_offset_byte_range(&self) -> Option<Range<usize>> {
42         let start = self.item_var_store_offset_byte_start?;
43         Some(start..start + Offset32::RAW_BYTE_LEN)
44     }
45 }
46 
47 impl TopLevelTable for Gdef<'_> {
48     /// `GDEF`
49     const TAG: Tag = Tag::new(b"GDEF");
50 }
51 
52 impl<'a> FontRead<'a> for Gdef<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>53     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
54         let mut cursor = data.cursor();
55         let version: MajorMinor = cursor.read()?;
56         cursor.advance::<Offset16>();
57         cursor.advance::<Offset16>();
58         cursor.advance::<Offset16>();
59         cursor.advance::<Offset16>();
60         let mark_glyph_sets_def_offset_byte_start = version
61             .compatible((1, 2))
62             .then(|| cursor.position())
63             .transpose()?;
64         version
65             .compatible((1, 2))
66             .then(|| cursor.advance::<Offset16>());
67         let item_var_store_offset_byte_start = version
68             .compatible((1, 3))
69             .then(|| cursor.position())
70             .transpose()?;
71         version
72             .compatible((1, 3))
73             .then(|| cursor.advance::<Offset32>());
74         cursor.finish(GdefMarker {
75             mark_glyph_sets_def_offset_byte_start,
76             item_var_store_offset_byte_start,
77         })
78     }
79 }
80 
81 /// [GDEF](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#gdef-header) 1.0
82 pub type Gdef<'a> = TableRef<'a, GdefMarker>;
83 
84 impl<'a> Gdef<'a> {
85     /// The major/minor version of the GDEF table
version(&self) -> MajorMinor86     pub fn version(&self) -> MajorMinor {
87         let range = self.shape.version_byte_range();
88         self.data.read_at(range.start).unwrap()
89     }
90 
91     /// Offset to class definition table for glyph type, from beginning
92     /// of GDEF header (may be NULL)
glyph_class_def_offset(&self) -> Nullable<Offset16>93     pub fn glyph_class_def_offset(&self) -> Nullable<Offset16> {
94         let range = self.shape.glyph_class_def_offset_byte_range();
95         self.data.read_at(range.start).unwrap()
96     }
97 
98     /// Attempt to resolve [`glyph_class_def_offset`][Self::glyph_class_def_offset].
glyph_class_def(&self) -> Option<Result<ClassDef<'a>, ReadError>>99     pub fn glyph_class_def(&self) -> Option<Result<ClassDef<'a>, ReadError>> {
100         let data = self.data;
101         self.glyph_class_def_offset().resolve(data)
102     }
103 
104     /// Offset to attachment point list table, from beginning of GDEF
105     /// header (may be NULL)
attach_list_offset(&self) -> Nullable<Offset16>106     pub fn attach_list_offset(&self) -> Nullable<Offset16> {
107         let range = self.shape.attach_list_offset_byte_range();
108         self.data.read_at(range.start).unwrap()
109     }
110 
111     /// Attempt to resolve [`attach_list_offset`][Self::attach_list_offset].
attach_list(&self) -> Option<Result<AttachList<'a>, ReadError>>112     pub fn attach_list(&self) -> Option<Result<AttachList<'a>, ReadError>> {
113         let data = self.data;
114         self.attach_list_offset().resolve(data)
115     }
116 
117     /// Offset to ligature caret list table, from beginning of GDEF
118     /// header (may be NULL)
lig_caret_list_offset(&self) -> Nullable<Offset16>119     pub fn lig_caret_list_offset(&self) -> Nullable<Offset16> {
120         let range = self.shape.lig_caret_list_offset_byte_range();
121         self.data.read_at(range.start).unwrap()
122     }
123 
124     /// Attempt to resolve [`lig_caret_list_offset`][Self::lig_caret_list_offset].
lig_caret_list(&self) -> Option<Result<LigCaretList<'a>, ReadError>>125     pub fn lig_caret_list(&self) -> Option<Result<LigCaretList<'a>, ReadError>> {
126         let data = self.data;
127         self.lig_caret_list_offset().resolve(data)
128     }
129 
130     /// Offset to class definition table for mark attachment type, from
131     /// beginning of GDEF header (may be NULL)
mark_attach_class_def_offset(&self) -> Nullable<Offset16>132     pub fn mark_attach_class_def_offset(&self) -> Nullable<Offset16> {
133         let range = self.shape.mark_attach_class_def_offset_byte_range();
134         self.data.read_at(range.start).unwrap()
135     }
136 
137     /// Attempt to resolve [`mark_attach_class_def_offset`][Self::mark_attach_class_def_offset].
mark_attach_class_def(&self) -> Option<Result<ClassDef<'a>, ReadError>>138     pub fn mark_attach_class_def(&self) -> Option<Result<ClassDef<'a>, ReadError>> {
139         let data = self.data;
140         self.mark_attach_class_def_offset().resolve(data)
141     }
142 
143     /// Offset to the table of mark glyph set definitions, from
144     /// beginning of GDEF header (may be NULL)
mark_glyph_sets_def_offset(&self) -> Option<Nullable<Offset16>>145     pub fn mark_glyph_sets_def_offset(&self) -> Option<Nullable<Offset16>> {
146         let range = self.shape.mark_glyph_sets_def_offset_byte_range()?;
147         Some(self.data.read_at(range.start).unwrap())
148     }
149 
150     /// Attempt to resolve [`mark_glyph_sets_def_offset`][Self::mark_glyph_sets_def_offset].
mark_glyph_sets_def(&self) -> Option<Result<MarkGlyphSets<'a>, ReadError>>151     pub fn mark_glyph_sets_def(&self) -> Option<Result<MarkGlyphSets<'a>, ReadError>> {
152         let data = self.data;
153         self.mark_glyph_sets_def_offset().map(|x| x.resolve(data))?
154     }
155 
156     /// Offset to the Item Variation Store table, from beginning of
157     /// GDEF header (may be NULL)
item_var_store_offset(&self) -> Option<Nullable<Offset32>>158     pub fn item_var_store_offset(&self) -> Option<Nullable<Offset32>> {
159         let range = self.shape.item_var_store_offset_byte_range()?;
160         Some(self.data.read_at(range.start).unwrap())
161     }
162 
163     /// Attempt to resolve [`item_var_store_offset`][Self::item_var_store_offset].
item_var_store(&self) -> Option<Result<ItemVariationStore<'a>, ReadError>>164     pub fn item_var_store(&self) -> Option<Result<ItemVariationStore<'a>, ReadError>> {
165         let data = self.data;
166         self.item_var_store_offset().map(|x| x.resolve(data))?
167     }
168 }
169 
170 #[cfg(feature = "traversal")]
171 impl<'a> SomeTable<'a> for Gdef<'a> {
type_name(&self) -> &str172     fn type_name(&self) -> &str {
173         "Gdef"
174     }
get_field(&self, idx: usize) -> Option<Field<'a>>175     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
176         let version = self.version();
177         match idx {
178             0usize => Some(Field::new("version", self.version())),
179             1usize => Some(Field::new(
180                 "glyph_class_def_offset",
181                 FieldType::offset(self.glyph_class_def_offset(), self.glyph_class_def()),
182             )),
183             2usize => Some(Field::new(
184                 "attach_list_offset",
185                 FieldType::offset(self.attach_list_offset(), self.attach_list()),
186             )),
187             3usize => Some(Field::new(
188                 "lig_caret_list_offset",
189                 FieldType::offset(self.lig_caret_list_offset(), self.lig_caret_list()),
190             )),
191             4usize => Some(Field::new(
192                 "mark_attach_class_def_offset",
193                 FieldType::offset(
194                     self.mark_attach_class_def_offset(),
195                     self.mark_attach_class_def(),
196                 ),
197             )),
198             5usize if version.compatible((1, 2)) => Some(Field::new(
199                 "mark_glyph_sets_def_offset",
200                 FieldType::offset(
201                     self.mark_glyph_sets_def_offset().unwrap(),
202                     self.mark_glyph_sets_def().unwrap(),
203                 ),
204             )),
205             6usize if version.compatible((1, 3)) => Some(Field::new(
206                 "item_var_store_offset",
207                 FieldType::offset(
208                     self.item_var_store_offset().unwrap(),
209                     self.item_var_store().unwrap(),
210                 ),
211             )),
212             _ => None,
213         }
214     }
215 }
216 
217 #[cfg(feature = "traversal")]
218 impl<'a> std::fmt::Debug for Gdef<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result219     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
220         (self as &dyn SomeTable<'a>).fmt(f)
221     }
222 }
223 
224 /// Used in the [Glyph Class Definition Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#glyph-class-definition-table)
225 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
226 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
227 #[repr(u16)]
228 #[allow(clippy::manual_non_exhaustive)]
229 pub enum GlyphClassDef {
230     #[default]
231     Base = 1,
232     Ligature = 2,
233     Mark = 3,
234     Component = 4,
235     #[doc(hidden)]
236     /// If font data is malformed we will map unknown values to this variant
237     Unknown,
238 }
239 
240 impl GlyphClassDef {
241     /// Create from a raw scalar.
242     ///
243     /// This will never fail; unknown values will be mapped to the `Unknown` variant
new(raw: u16) -> Self244     pub fn new(raw: u16) -> Self {
245         match raw {
246             1 => Self::Base,
247             2 => Self::Ligature,
248             3 => Self::Mark,
249             4 => Self::Component,
250             _ => Self::Unknown,
251         }
252     }
253 }
254 
255 impl font_types::Scalar for GlyphClassDef {
256     type Raw = <u16 as font_types::Scalar>::Raw;
to_raw(self) -> Self::Raw257     fn to_raw(self) -> Self::Raw {
258         (self as u16).to_raw()
259     }
from_raw(raw: Self::Raw) -> Self260     fn from_raw(raw: Self::Raw) -> Self {
261         let t = <u16>::from_raw(raw);
262         Self::new(t)
263     }
264 }
265 
266 #[cfg(feature = "traversal")]
267 impl<'a> From<GlyphClassDef> for FieldType<'a> {
from(src: GlyphClassDef) -> FieldType<'a>268     fn from(src: GlyphClassDef) -> FieldType<'a> {
269         (src as u16).into()
270     }
271 }
272 
273 /// [Attachment Point List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#attachment-point-list-table)
274 #[derive(Debug, Clone, Copy)]
275 #[doc(hidden)]
276 pub struct AttachListMarker {
277     attach_point_offsets_byte_len: usize,
278 }
279 
280 impl AttachListMarker {
coverage_offset_byte_range(&self) -> Range<usize>281     fn coverage_offset_byte_range(&self) -> Range<usize> {
282         let start = 0;
283         start..start + Offset16::RAW_BYTE_LEN
284     }
glyph_count_byte_range(&self) -> Range<usize>285     fn glyph_count_byte_range(&self) -> Range<usize> {
286         let start = self.coverage_offset_byte_range().end;
287         start..start + u16::RAW_BYTE_LEN
288     }
attach_point_offsets_byte_range(&self) -> Range<usize>289     fn attach_point_offsets_byte_range(&self) -> Range<usize> {
290         let start = self.glyph_count_byte_range().end;
291         start..start + self.attach_point_offsets_byte_len
292     }
293 }
294 
295 impl<'a> FontRead<'a> for AttachList<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>296     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
297         let mut cursor = data.cursor();
298         cursor.advance::<Offset16>();
299         let glyph_count: u16 = cursor.read()?;
300         let attach_point_offsets_byte_len = glyph_count as usize * Offset16::RAW_BYTE_LEN;
301         cursor.advance_by(attach_point_offsets_byte_len);
302         cursor.finish(AttachListMarker {
303             attach_point_offsets_byte_len,
304         })
305     }
306 }
307 
308 /// [Attachment Point List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#attachment-point-list-table)
309 pub type AttachList<'a> = TableRef<'a, AttachListMarker>;
310 
311 impl<'a> AttachList<'a> {
312     /// Offset to Coverage table - from beginning of AttachList table
coverage_offset(&self) -> Offset16313     pub fn coverage_offset(&self) -> Offset16 {
314         let range = self.shape.coverage_offset_byte_range();
315         self.data.read_at(range.start).unwrap()
316     }
317 
318     /// Attempt to resolve [`coverage_offset`][Self::coverage_offset].
coverage(&self) -> Result<CoverageTable<'a>, ReadError>319     pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
320         let data = self.data;
321         self.coverage_offset().resolve(data)
322     }
323 
324     /// Number of glyphs with attachment points
glyph_count(&self) -> u16325     pub fn glyph_count(&self) -> u16 {
326         let range = self.shape.glyph_count_byte_range();
327         self.data.read_at(range.start).unwrap()
328     }
329 
330     /// Array of offsets to AttachPoint tables-from beginning of
331     /// AttachList table-in Coverage Index order
attach_point_offsets(&self) -> &'a [BigEndian<Offset16>]332     pub fn attach_point_offsets(&self) -> &'a [BigEndian<Offset16>] {
333         let range = self.shape.attach_point_offsets_byte_range();
334         self.data.read_array(range).unwrap()
335     }
336 
337     /// A dynamically resolving wrapper for [`attach_point_offsets`][Self::attach_point_offsets].
attach_points(&self) -> ArrayOfOffsets<'a, AttachPoint<'a>, Offset16>338     pub fn attach_points(&self) -> ArrayOfOffsets<'a, AttachPoint<'a>, Offset16> {
339         let data = self.data;
340         let offsets = self.attach_point_offsets();
341         ArrayOfOffsets::new(offsets, data, ())
342     }
343 }
344 
345 #[cfg(feature = "traversal")]
346 impl<'a> SomeTable<'a> for AttachList<'a> {
type_name(&self) -> &str347     fn type_name(&self) -> &str {
348         "AttachList"
349     }
get_field(&self, idx: usize) -> Option<Field<'a>>350     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
351         match idx {
352             0usize => Some(Field::new(
353                 "coverage_offset",
354                 FieldType::offset(self.coverage_offset(), self.coverage()),
355             )),
356             1usize => Some(Field::new("glyph_count", self.glyph_count())),
357             2usize => Some({
358                 let data = self.data;
359                 Field::new(
360                     "attach_point_offsets",
361                     FieldType::array_of_offsets(
362                         better_type_name::<AttachPoint>(),
363                         self.attach_point_offsets(),
364                         move |off| {
365                             let target = off.get().resolve::<AttachPoint>(data);
366                             FieldType::offset(off.get(), target)
367                         },
368                     ),
369                 )
370             }),
371             _ => None,
372         }
373     }
374 }
375 
376 #[cfg(feature = "traversal")]
377 impl<'a> std::fmt::Debug for AttachList<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result378     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
379         (self as &dyn SomeTable<'a>).fmt(f)
380     }
381 }
382 
383 /// Part of [AttachList]
384 #[derive(Debug, Clone, Copy)]
385 #[doc(hidden)]
386 pub struct AttachPointMarker {
387     point_indices_byte_len: usize,
388 }
389 
390 impl AttachPointMarker {
point_count_byte_range(&self) -> Range<usize>391     fn point_count_byte_range(&self) -> Range<usize> {
392         let start = 0;
393         start..start + u16::RAW_BYTE_LEN
394     }
point_indices_byte_range(&self) -> Range<usize>395     fn point_indices_byte_range(&self) -> Range<usize> {
396         let start = self.point_count_byte_range().end;
397         start..start + self.point_indices_byte_len
398     }
399 }
400 
401 impl<'a> FontRead<'a> for AttachPoint<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>402     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
403         let mut cursor = data.cursor();
404         let point_count: u16 = cursor.read()?;
405         let point_indices_byte_len = point_count as usize * u16::RAW_BYTE_LEN;
406         cursor.advance_by(point_indices_byte_len);
407         cursor.finish(AttachPointMarker {
408             point_indices_byte_len,
409         })
410     }
411 }
412 
413 /// Part of [AttachList]
414 pub type AttachPoint<'a> = TableRef<'a, AttachPointMarker>;
415 
416 impl<'a> AttachPoint<'a> {
417     /// Number of attachment points on this glyph
point_count(&self) -> u16418     pub fn point_count(&self) -> u16 {
419         let range = self.shape.point_count_byte_range();
420         self.data.read_at(range.start).unwrap()
421     }
422 
423     /// Array of contour point indices -in increasing numerical order
point_indices(&self) -> &'a [BigEndian<u16>]424     pub fn point_indices(&self) -> &'a [BigEndian<u16>] {
425         let range = self.shape.point_indices_byte_range();
426         self.data.read_array(range).unwrap()
427     }
428 }
429 
430 #[cfg(feature = "traversal")]
431 impl<'a> SomeTable<'a> for AttachPoint<'a> {
type_name(&self) -> &str432     fn type_name(&self) -> &str {
433         "AttachPoint"
434     }
get_field(&self, idx: usize) -> Option<Field<'a>>435     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
436         match idx {
437             0usize => Some(Field::new("point_count", self.point_count())),
438             1usize => Some(Field::new("point_indices", self.point_indices())),
439             _ => None,
440         }
441     }
442 }
443 
444 #[cfg(feature = "traversal")]
445 impl<'a> std::fmt::Debug for AttachPoint<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result446     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
447         (self as &dyn SomeTable<'a>).fmt(f)
448     }
449 }
450 
451 /// [Ligature Caret List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#ligature-caret-list-table)
452 #[derive(Debug, Clone, Copy)]
453 #[doc(hidden)]
454 pub struct LigCaretListMarker {
455     lig_glyph_offsets_byte_len: usize,
456 }
457 
458 impl LigCaretListMarker {
coverage_offset_byte_range(&self) -> Range<usize>459     fn coverage_offset_byte_range(&self) -> Range<usize> {
460         let start = 0;
461         start..start + Offset16::RAW_BYTE_LEN
462     }
lig_glyph_count_byte_range(&self) -> Range<usize>463     fn lig_glyph_count_byte_range(&self) -> Range<usize> {
464         let start = self.coverage_offset_byte_range().end;
465         start..start + u16::RAW_BYTE_LEN
466     }
lig_glyph_offsets_byte_range(&self) -> Range<usize>467     fn lig_glyph_offsets_byte_range(&self) -> Range<usize> {
468         let start = self.lig_glyph_count_byte_range().end;
469         start..start + self.lig_glyph_offsets_byte_len
470     }
471 }
472 
473 impl<'a> FontRead<'a> for LigCaretList<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>474     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
475         let mut cursor = data.cursor();
476         cursor.advance::<Offset16>();
477         let lig_glyph_count: u16 = cursor.read()?;
478         let lig_glyph_offsets_byte_len = lig_glyph_count as usize * Offset16::RAW_BYTE_LEN;
479         cursor.advance_by(lig_glyph_offsets_byte_len);
480         cursor.finish(LigCaretListMarker {
481             lig_glyph_offsets_byte_len,
482         })
483     }
484 }
485 
486 /// [Ligature Caret List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#ligature-caret-list-table)
487 pub type LigCaretList<'a> = TableRef<'a, LigCaretListMarker>;
488 
489 impl<'a> LigCaretList<'a> {
490     /// Offset to Coverage table - from beginning of LigCaretList table
coverage_offset(&self) -> Offset16491     pub fn coverage_offset(&self) -> Offset16 {
492         let range = self.shape.coverage_offset_byte_range();
493         self.data.read_at(range.start).unwrap()
494     }
495 
496     /// Attempt to resolve [`coverage_offset`][Self::coverage_offset].
coverage(&self) -> Result<CoverageTable<'a>, ReadError>497     pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
498         let data = self.data;
499         self.coverage_offset().resolve(data)
500     }
501 
502     /// Number of ligature glyphs
lig_glyph_count(&self) -> u16503     pub fn lig_glyph_count(&self) -> u16 {
504         let range = self.shape.lig_glyph_count_byte_range();
505         self.data.read_at(range.start).unwrap()
506     }
507 
508     /// Array of offsets to LigGlyph tables, from beginning of
509     /// LigCaretList table —in Coverage Index order
lig_glyph_offsets(&self) -> &'a [BigEndian<Offset16>]510     pub fn lig_glyph_offsets(&self) -> &'a [BigEndian<Offset16>] {
511         let range = self.shape.lig_glyph_offsets_byte_range();
512         self.data.read_array(range).unwrap()
513     }
514 
515     /// A dynamically resolving wrapper for [`lig_glyph_offsets`][Self::lig_glyph_offsets].
lig_glyphs(&self) -> ArrayOfOffsets<'a, LigGlyph<'a>, Offset16>516     pub fn lig_glyphs(&self) -> ArrayOfOffsets<'a, LigGlyph<'a>, Offset16> {
517         let data = self.data;
518         let offsets = self.lig_glyph_offsets();
519         ArrayOfOffsets::new(offsets, data, ())
520     }
521 }
522 
523 #[cfg(feature = "traversal")]
524 impl<'a> SomeTable<'a> for LigCaretList<'a> {
type_name(&self) -> &str525     fn type_name(&self) -> &str {
526         "LigCaretList"
527     }
get_field(&self, idx: usize) -> Option<Field<'a>>528     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
529         match idx {
530             0usize => Some(Field::new(
531                 "coverage_offset",
532                 FieldType::offset(self.coverage_offset(), self.coverage()),
533             )),
534             1usize => Some(Field::new("lig_glyph_count", self.lig_glyph_count())),
535             2usize => Some({
536                 let data = self.data;
537                 Field::new(
538                     "lig_glyph_offsets",
539                     FieldType::array_of_offsets(
540                         better_type_name::<LigGlyph>(),
541                         self.lig_glyph_offsets(),
542                         move |off| {
543                             let target = off.get().resolve::<LigGlyph>(data);
544                             FieldType::offset(off.get(), target)
545                         },
546                     ),
547                 )
548             }),
549             _ => None,
550         }
551     }
552 }
553 
554 #[cfg(feature = "traversal")]
555 impl<'a> std::fmt::Debug for LigCaretList<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result556     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
557         (self as &dyn SomeTable<'a>).fmt(f)
558     }
559 }
560 
561 /// [Ligature Glyph Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#ligature-glyph-table)
562 #[derive(Debug, Clone, Copy)]
563 #[doc(hidden)]
564 pub struct LigGlyphMarker {
565     caret_value_offsets_byte_len: usize,
566 }
567 
568 impl LigGlyphMarker {
caret_count_byte_range(&self) -> Range<usize>569     fn caret_count_byte_range(&self) -> Range<usize> {
570         let start = 0;
571         start..start + u16::RAW_BYTE_LEN
572     }
caret_value_offsets_byte_range(&self) -> Range<usize>573     fn caret_value_offsets_byte_range(&self) -> Range<usize> {
574         let start = self.caret_count_byte_range().end;
575         start..start + self.caret_value_offsets_byte_len
576     }
577 }
578 
579 impl<'a> FontRead<'a> for LigGlyph<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>580     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
581         let mut cursor = data.cursor();
582         let caret_count: u16 = cursor.read()?;
583         let caret_value_offsets_byte_len = caret_count as usize * Offset16::RAW_BYTE_LEN;
584         cursor.advance_by(caret_value_offsets_byte_len);
585         cursor.finish(LigGlyphMarker {
586             caret_value_offsets_byte_len,
587         })
588     }
589 }
590 
591 /// [Ligature Glyph Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#ligature-glyph-table)
592 pub type LigGlyph<'a> = TableRef<'a, LigGlyphMarker>;
593 
594 impl<'a> LigGlyph<'a> {
595     /// Number of CaretValue tables for this ligature (components - 1)
caret_count(&self) -> u16596     pub fn caret_count(&self) -> u16 {
597         let range = self.shape.caret_count_byte_range();
598         self.data.read_at(range.start).unwrap()
599     }
600 
601     /// Array of offsets to CaretValue tables, from beginning of
602     /// LigGlyph table — in increasing coordinate order
caret_value_offsets(&self) -> &'a [BigEndian<Offset16>]603     pub fn caret_value_offsets(&self) -> &'a [BigEndian<Offset16>] {
604         let range = self.shape.caret_value_offsets_byte_range();
605         self.data.read_array(range).unwrap()
606     }
607 
608     /// A dynamically resolving wrapper for [`caret_value_offsets`][Self::caret_value_offsets].
caret_values(&self) -> ArrayOfOffsets<'a, CaretValue<'a>, Offset16>609     pub fn caret_values(&self) -> ArrayOfOffsets<'a, CaretValue<'a>, Offset16> {
610         let data = self.data;
611         let offsets = self.caret_value_offsets();
612         ArrayOfOffsets::new(offsets, data, ())
613     }
614 }
615 
616 #[cfg(feature = "traversal")]
617 impl<'a> SomeTable<'a> for LigGlyph<'a> {
type_name(&self) -> &str618     fn type_name(&self) -> &str {
619         "LigGlyph"
620     }
get_field(&self, idx: usize) -> Option<Field<'a>>621     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
622         match idx {
623             0usize => Some(Field::new("caret_count", self.caret_count())),
624             1usize => Some({
625                 let data = self.data;
626                 Field::new(
627                     "caret_value_offsets",
628                     FieldType::array_of_offsets(
629                         better_type_name::<CaretValue>(),
630                         self.caret_value_offsets(),
631                         move |off| {
632                             let target = off.get().resolve::<CaretValue>(data);
633                             FieldType::offset(off.get(), target)
634                         },
635                     ),
636                 )
637             }),
638             _ => None,
639         }
640     }
641 }
642 
643 #[cfg(feature = "traversal")]
644 impl<'a> std::fmt::Debug for LigGlyph<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result645     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
646         (self as &dyn SomeTable<'a>).fmt(f)
647     }
648 }
649 
650 /// [Caret Value Tables](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caret-value-tables)
651 #[derive(Clone)]
652 pub enum CaretValue<'a> {
653     Format1(CaretValueFormat1<'a>),
654     Format2(CaretValueFormat2<'a>),
655     Format3(CaretValueFormat3<'a>),
656 }
657 
658 impl<'a> CaretValue<'a> {
659     /// Format identifier: format = 1
caret_value_format(&self) -> u16660     pub fn caret_value_format(&self) -> u16 {
661         match self {
662             Self::Format1(item) => item.caret_value_format(),
663             Self::Format2(item) => item.caret_value_format(),
664             Self::Format3(item) => item.caret_value_format(),
665         }
666     }
667 }
668 
669 impl<'a> FontRead<'a> for CaretValue<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>670     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
671         let format: u16 = data.read_at(0usize)?;
672         match format {
673             CaretValueFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
674             CaretValueFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
675             CaretValueFormat3Marker::FORMAT => Ok(Self::Format3(FontRead::read(data)?)),
676             other => Err(ReadError::InvalidFormat(other.into())),
677         }
678     }
679 }
680 
681 #[cfg(feature = "traversal")]
682 impl<'a> CaretValue<'a> {
dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>683     fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
684         match self {
685             Self::Format1(table) => table,
686             Self::Format2(table) => table,
687             Self::Format3(table) => table,
688         }
689     }
690 }
691 
692 #[cfg(feature = "traversal")]
693 impl<'a> std::fmt::Debug for CaretValue<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result694     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
695         self.dyn_inner().fmt(f)
696     }
697 }
698 
699 #[cfg(feature = "traversal")]
700 impl<'a> SomeTable<'a> for CaretValue<'a> {
type_name(&self) -> &str701     fn type_name(&self) -> &str {
702         self.dyn_inner().type_name()
703     }
get_field(&self, idx: usize) -> Option<Field<'a>>704     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
705         self.dyn_inner().get_field(idx)
706     }
707 }
708 
709 impl Format<u16> for CaretValueFormat1Marker {
710     const FORMAT: u16 = 1;
711 }
712 
713 /// [CaretValue Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caretvalue-format-1)
714 #[derive(Debug, Clone, Copy)]
715 #[doc(hidden)]
716 pub struct CaretValueFormat1Marker {}
717 
718 impl CaretValueFormat1Marker {
caret_value_format_byte_range(&self) -> Range<usize>719     fn caret_value_format_byte_range(&self) -> Range<usize> {
720         let start = 0;
721         start..start + u16::RAW_BYTE_LEN
722     }
coordinate_byte_range(&self) -> Range<usize>723     fn coordinate_byte_range(&self) -> Range<usize> {
724         let start = self.caret_value_format_byte_range().end;
725         start..start + i16::RAW_BYTE_LEN
726     }
727 }
728 
729 impl<'a> FontRead<'a> for CaretValueFormat1<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>730     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
731         let mut cursor = data.cursor();
732         cursor.advance::<u16>();
733         cursor.advance::<i16>();
734         cursor.finish(CaretValueFormat1Marker {})
735     }
736 }
737 
738 /// [CaretValue Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caretvalue-format-1)
739 pub type CaretValueFormat1<'a> = TableRef<'a, CaretValueFormat1Marker>;
740 
741 impl<'a> CaretValueFormat1<'a> {
742     /// Format identifier: format = 1
caret_value_format(&self) -> u16743     pub fn caret_value_format(&self) -> u16 {
744         let range = self.shape.caret_value_format_byte_range();
745         self.data.read_at(range.start).unwrap()
746     }
747 
748     /// X or Y value, in design units
coordinate(&self) -> i16749     pub fn coordinate(&self) -> i16 {
750         let range = self.shape.coordinate_byte_range();
751         self.data.read_at(range.start).unwrap()
752     }
753 }
754 
755 #[cfg(feature = "traversal")]
756 impl<'a> SomeTable<'a> for CaretValueFormat1<'a> {
type_name(&self) -> &str757     fn type_name(&self) -> &str {
758         "CaretValueFormat1"
759     }
get_field(&self, idx: usize) -> Option<Field<'a>>760     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
761         match idx {
762             0usize => Some(Field::new("caret_value_format", self.caret_value_format())),
763             1usize => Some(Field::new("coordinate", self.coordinate())),
764             _ => None,
765         }
766     }
767 }
768 
769 #[cfg(feature = "traversal")]
770 impl<'a> std::fmt::Debug for CaretValueFormat1<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result771     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
772         (self as &dyn SomeTable<'a>).fmt(f)
773     }
774 }
775 
776 impl Format<u16> for CaretValueFormat2Marker {
777     const FORMAT: u16 = 2;
778 }
779 
780 /// [CaretValue Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caretvalue-format-2)
781 #[derive(Debug, Clone, Copy)]
782 #[doc(hidden)]
783 pub struct CaretValueFormat2Marker {}
784 
785 impl CaretValueFormat2Marker {
caret_value_format_byte_range(&self) -> Range<usize>786     fn caret_value_format_byte_range(&self) -> Range<usize> {
787         let start = 0;
788         start..start + u16::RAW_BYTE_LEN
789     }
caret_value_point_index_byte_range(&self) -> Range<usize>790     fn caret_value_point_index_byte_range(&self) -> Range<usize> {
791         let start = self.caret_value_format_byte_range().end;
792         start..start + u16::RAW_BYTE_LEN
793     }
794 }
795 
796 impl<'a> FontRead<'a> for CaretValueFormat2<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>797     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
798         let mut cursor = data.cursor();
799         cursor.advance::<u16>();
800         cursor.advance::<u16>();
801         cursor.finish(CaretValueFormat2Marker {})
802     }
803 }
804 
805 /// [CaretValue Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caretvalue-format-2)
806 pub type CaretValueFormat2<'a> = TableRef<'a, CaretValueFormat2Marker>;
807 
808 impl<'a> CaretValueFormat2<'a> {
809     /// Format identifier: format = 2
caret_value_format(&self) -> u16810     pub fn caret_value_format(&self) -> u16 {
811         let range = self.shape.caret_value_format_byte_range();
812         self.data.read_at(range.start).unwrap()
813     }
814 
815     /// Contour point index on glyph
caret_value_point_index(&self) -> u16816     pub fn caret_value_point_index(&self) -> u16 {
817         let range = self.shape.caret_value_point_index_byte_range();
818         self.data.read_at(range.start).unwrap()
819     }
820 }
821 
822 #[cfg(feature = "traversal")]
823 impl<'a> SomeTable<'a> for CaretValueFormat2<'a> {
type_name(&self) -> &str824     fn type_name(&self) -> &str {
825         "CaretValueFormat2"
826     }
get_field(&self, idx: usize) -> Option<Field<'a>>827     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
828         match idx {
829             0usize => Some(Field::new("caret_value_format", self.caret_value_format())),
830             1usize => Some(Field::new(
831                 "caret_value_point_index",
832                 self.caret_value_point_index(),
833             )),
834             _ => None,
835         }
836     }
837 }
838 
839 #[cfg(feature = "traversal")]
840 impl<'a> std::fmt::Debug for CaretValueFormat2<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result841     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
842         (self as &dyn SomeTable<'a>).fmt(f)
843     }
844 }
845 
846 impl Format<u16> for CaretValueFormat3Marker {
847     const FORMAT: u16 = 3;
848 }
849 
850 /// [CaretValue Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caretvalue-format-3)
851 #[derive(Debug, Clone, Copy)]
852 #[doc(hidden)]
853 pub struct CaretValueFormat3Marker {}
854 
855 impl CaretValueFormat3Marker {
caret_value_format_byte_range(&self) -> Range<usize>856     fn caret_value_format_byte_range(&self) -> Range<usize> {
857         let start = 0;
858         start..start + u16::RAW_BYTE_LEN
859     }
coordinate_byte_range(&self) -> Range<usize>860     fn coordinate_byte_range(&self) -> Range<usize> {
861         let start = self.caret_value_format_byte_range().end;
862         start..start + i16::RAW_BYTE_LEN
863     }
device_offset_byte_range(&self) -> Range<usize>864     fn device_offset_byte_range(&self) -> Range<usize> {
865         let start = self.coordinate_byte_range().end;
866         start..start + Offset16::RAW_BYTE_LEN
867     }
868 }
869 
870 impl<'a> FontRead<'a> for CaretValueFormat3<'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::<Offset16>();
876         cursor.finish(CaretValueFormat3Marker {})
877     }
878 }
879 
880 /// [CaretValue Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caretvalue-format-3)
881 pub type CaretValueFormat3<'a> = TableRef<'a, CaretValueFormat3Marker>;
882 
883 impl<'a> CaretValueFormat3<'a> {
884     /// Format identifier-format = 3
caret_value_format(&self) -> u16885     pub fn caret_value_format(&self) -> u16 {
886         let range = self.shape.caret_value_format_byte_range();
887         self.data.read_at(range.start).unwrap()
888     }
889 
890     /// X or Y value, in design units
coordinate(&self) -> i16891     pub fn coordinate(&self) -> i16 {
892         let range = self.shape.coordinate_byte_range();
893         self.data.read_at(range.start).unwrap()
894     }
895 
896     /// Offset to Device table (non-variable font) / Variation Index
897     /// table (variable font) for X or Y value-from beginning of
898     /// CaretValue table
device_offset(&self) -> Offset16899     pub fn device_offset(&self) -> Offset16 {
900         let range = self.shape.device_offset_byte_range();
901         self.data.read_at(range.start).unwrap()
902     }
903 
904     /// Attempt to resolve [`device_offset`][Self::device_offset].
device(&self) -> Result<DeviceOrVariationIndex<'a>, ReadError>905     pub fn device(&self) -> Result<DeviceOrVariationIndex<'a>, ReadError> {
906         let data = self.data;
907         self.device_offset().resolve(data)
908     }
909 }
910 
911 #[cfg(feature = "traversal")]
912 impl<'a> SomeTable<'a> for CaretValueFormat3<'a> {
type_name(&self) -> &str913     fn type_name(&self) -> &str {
914         "CaretValueFormat3"
915     }
get_field(&self, idx: usize) -> Option<Field<'a>>916     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
917         match idx {
918             0usize => Some(Field::new("caret_value_format", self.caret_value_format())),
919             1usize => Some(Field::new("coordinate", self.coordinate())),
920             2usize => Some(Field::new(
921                 "device_offset",
922                 FieldType::offset(self.device_offset(), self.device()),
923             )),
924             _ => None,
925         }
926     }
927 }
928 
929 #[cfg(feature = "traversal")]
930 impl<'a> std::fmt::Debug for CaretValueFormat3<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result931     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
932         (self as &dyn SomeTable<'a>).fmt(f)
933     }
934 }
935 
936 impl Format<u16> for MarkGlyphSetsMarker {
937     const FORMAT: u16 = 1;
938 }
939 
940 /// [Mark Glyph Sets Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#mark-glyph-sets-table)
941 #[derive(Debug, Clone, Copy)]
942 #[doc(hidden)]
943 pub struct MarkGlyphSetsMarker {
944     coverage_offsets_byte_len: usize,
945 }
946 
947 impl MarkGlyphSetsMarker {
format_byte_range(&self) -> Range<usize>948     fn format_byte_range(&self) -> Range<usize> {
949         let start = 0;
950         start..start + u16::RAW_BYTE_LEN
951     }
mark_glyph_set_count_byte_range(&self) -> Range<usize>952     fn mark_glyph_set_count_byte_range(&self) -> Range<usize> {
953         let start = self.format_byte_range().end;
954         start..start + u16::RAW_BYTE_LEN
955     }
coverage_offsets_byte_range(&self) -> Range<usize>956     fn coverage_offsets_byte_range(&self) -> Range<usize> {
957         let start = self.mark_glyph_set_count_byte_range().end;
958         start..start + self.coverage_offsets_byte_len
959     }
960 }
961 
962 impl<'a> FontRead<'a> for MarkGlyphSets<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>963     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
964         let mut cursor = data.cursor();
965         cursor.advance::<u16>();
966         let mark_glyph_set_count: u16 = cursor.read()?;
967         let coverage_offsets_byte_len = mark_glyph_set_count as usize * Offset32::RAW_BYTE_LEN;
968         cursor.advance_by(coverage_offsets_byte_len);
969         cursor.finish(MarkGlyphSetsMarker {
970             coverage_offsets_byte_len,
971         })
972     }
973 }
974 
975 /// [Mark Glyph Sets Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#mark-glyph-sets-table)
976 pub type MarkGlyphSets<'a> = TableRef<'a, MarkGlyphSetsMarker>;
977 
978 impl<'a> MarkGlyphSets<'a> {
979     /// Format identifier == 1
format(&self) -> u16980     pub fn format(&self) -> u16 {
981         let range = self.shape.format_byte_range();
982         self.data.read_at(range.start).unwrap()
983     }
984 
985     /// Number of mark glyph sets defined
mark_glyph_set_count(&self) -> u16986     pub fn mark_glyph_set_count(&self) -> u16 {
987         let range = self.shape.mark_glyph_set_count_byte_range();
988         self.data.read_at(range.start).unwrap()
989     }
990 
991     /// Array of offsets to mark glyph set coverage tables, from the
992     /// start of the MarkGlyphSets table.
coverage_offsets(&self) -> &'a [BigEndian<Offset32>]993     pub fn coverage_offsets(&self) -> &'a [BigEndian<Offset32>] {
994         let range = self.shape.coverage_offsets_byte_range();
995         self.data.read_array(range).unwrap()
996     }
997 
998     /// A dynamically resolving wrapper for [`coverage_offsets`][Self::coverage_offsets].
coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset32>999     pub fn coverages(&self) -> ArrayOfOffsets<'a, CoverageTable<'a>, Offset32> {
1000         let data = self.data;
1001         let offsets = self.coverage_offsets();
1002         ArrayOfOffsets::new(offsets, data, ())
1003     }
1004 }
1005 
1006 #[cfg(feature = "traversal")]
1007 impl<'a> SomeTable<'a> for MarkGlyphSets<'a> {
type_name(&self) -> &str1008     fn type_name(&self) -> &str {
1009         "MarkGlyphSets"
1010     }
get_field(&self, idx: usize) -> Option<Field<'a>>1011     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1012         match idx {
1013             0usize => Some(Field::new("format", self.format())),
1014             1usize => Some(Field::new(
1015                 "mark_glyph_set_count",
1016                 self.mark_glyph_set_count(),
1017             )),
1018             2usize => Some({
1019                 let data = self.data;
1020                 Field::new(
1021                     "coverage_offsets",
1022                     FieldType::array_of_offsets(
1023                         better_type_name::<CoverageTable>(),
1024                         self.coverage_offsets(),
1025                         move |off| {
1026                             let target = off.get().resolve::<CoverageTable>(data);
1027                             FieldType::offset(off.get(), target)
1028                         },
1029                     ),
1030                 )
1031             }),
1032             _ => None,
1033         }
1034     }
1035 }
1036 
1037 #[cfg(feature = "traversal")]
1038 impl<'a> std::fmt::Debug for MarkGlyphSets<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1039     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1040         (self as &dyn SomeTable<'a>).fmt(f)
1041     }
1042 }
1043