write_fonts/generated/
generated_gdef.rs

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)]
6use crate::codegen_prelude::*;
7
8pub use read_fonts::tables::gdef::GlyphClassDef;
9
10/// [GDEF](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#gdef-header) 1.0
11#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct Gdef {
14    /// Offset to class definition table for glyph type, from beginning
15    /// of GDEF header (may be NULL)
16    pub glyph_class_def: NullableOffsetMarker<ClassDef>,
17    /// Offset to attachment point list table, from beginning of GDEF
18    /// header (may be NULL)
19    pub attach_list: NullableOffsetMarker<AttachList>,
20    /// Offset to ligature caret list table, from beginning of GDEF
21    /// header (may be NULL)
22    pub lig_caret_list: NullableOffsetMarker<LigCaretList>,
23    /// Offset to class definition table for mark attachment type, from
24    /// beginning of GDEF header (may be NULL)
25    pub mark_attach_class_def: NullableOffsetMarker<ClassDef>,
26    /// Offset to the table of mark glyph set definitions, from
27    /// beginning of GDEF header (may be NULL)
28    pub mark_glyph_sets_def: NullableOffsetMarker<MarkGlyphSets>,
29    /// Offset to the Item Variation Store table, from beginning of
30    /// GDEF header (may be NULL)
31    pub item_var_store: NullableOffsetMarker<ItemVariationStore, WIDTH_32>,
32}
33
34impl Gdef {
35    /// Construct a new `Gdef`
36    pub fn new(
37        glyph_class_def: Option<ClassDef>,
38        attach_list: Option<AttachList>,
39        lig_caret_list: Option<LigCaretList>,
40        mark_attach_class_def: Option<ClassDef>,
41    ) -> Self {
42        Self {
43            glyph_class_def: glyph_class_def.into(),
44            attach_list: attach_list.into(),
45            lig_caret_list: lig_caret_list.into(),
46            mark_attach_class_def: mark_attach_class_def.into(),
47            ..Default::default()
48        }
49    }
50}
51
52impl FontWrite for Gdef {
53    #[allow(clippy::unnecessary_cast)]
54    fn write_into(&self, writer: &mut TableWriter) {
55        let version = self.compute_version() as MajorMinor;
56        version.write_into(writer);
57        self.glyph_class_def.write_into(writer);
58        self.attach_list.write_into(writer);
59        self.lig_caret_list.write_into(writer);
60        self.mark_attach_class_def.write_into(writer);
61        version
62            .compatible((1u16, 2u16))
63            .then(|| self.mark_glyph_sets_def.write_into(writer));
64        version
65            .compatible((1u16, 3u16))
66            .then(|| self.item_var_store.write_into(writer));
67    }
68    fn table_type(&self) -> TableType {
69        TableType::TopLevel(Gdef::TAG)
70    }
71}
72
73impl Validate for Gdef {
74    fn validate_impl(&self, ctx: &mut ValidationCtx) {
75        ctx.in_table("Gdef", |ctx| {
76            ctx.in_field("glyph_class_def", |ctx| {
77                self.glyph_class_def.validate_impl(ctx);
78            });
79            ctx.in_field("attach_list", |ctx| {
80                self.attach_list.validate_impl(ctx);
81            });
82            ctx.in_field("lig_caret_list", |ctx| {
83                self.lig_caret_list.validate_impl(ctx);
84            });
85            ctx.in_field("mark_attach_class_def", |ctx| {
86                self.mark_attach_class_def.validate_impl(ctx);
87            });
88            ctx.in_field("mark_glyph_sets_def", |ctx| {
89                self.mark_glyph_sets_def.validate_impl(ctx);
90            });
91            ctx.in_field("item_var_store", |ctx| {
92                self.item_var_store.validate_impl(ctx);
93            });
94        })
95    }
96}
97
98impl TopLevelTable for Gdef {
99    const TAG: Tag = Tag::new(b"GDEF");
100}
101
102impl<'a> FromObjRef<read_fonts::tables::gdef::Gdef<'a>> for Gdef {
103    fn from_obj_ref(obj: &read_fonts::tables::gdef::Gdef<'a>, _: FontData) -> Self {
104        Gdef {
105            glyph_class_def: obj.glyph_class_def().to_owned_table(),
106            attach_list: obj.attach_list().to_owned_table(),
107            lig_caret_list: obj.lig_caret_list().to_owned_table(),
108            mark_attach_class_def: obj.mark_attach_class_def().to_owned_table(),
109            mark_glyph_sets_def: obj.mark_glyph_sets_def().to_owned_table(),
110            item_var_store: obj.item_var_store().to_owned_table(),
111        }
112    }
113}
114
115#[allow(clippy::needless_lifetimes)]
116impl<'a> FromTableRef<read_fonts::tables::gdef::Gdef<'a>> for Gdef {}
117
118impl<'a> FontRead<'a> for Gdef {
119    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
120        <read_fonts::tables::gdef::Gdef as FontRead>::read(data).map(|x| x.to_owned_table())
121    }
122}
123
124impl FontWrite for GlyphClassDef {
125    fn write_into(&self, writer: &mut TableWriter) {
126        let val = *self as u16;
127        writer.write_slice(&val.to_be_bytes())
128    }
129}
130
131/// [Attachment Point List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#attachment-point-list-table)
132#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
133#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
134pub struct AttachList {
135    /// Offset to Coverage table - from beginning of AttachList table
136    pub coverage: OffsetMarker<CoverageTable>,
137    /// Array of offsets to AttachPoint tables-from beginning of
138    /// AttachList table-in Coverage Index order
139    pub attach_points: Vec<OffsetMarker<AttachPoint>>,
140}
141
142impl AttachList {
143    /// Construct a new `AttachList`
144    pub fn new(coverage: CoverageTable, attach_points: Vec<AttachPoint>) -> Self {
145        Self {
146            coverage: coverage.into(),
147            attach_points: attach_points.into_iter().map(Into::into).collect(),
148        }
149    }
150}
151
152impl FontWrite for AttachList {
153    #[allow(clippy::unnecessary_cast)]
154    fn write_into(&self, writer: &mut TableWriter) {
155        self.coverage.write_into(writer);
156        (u16::try_from(array_len(&self.attach_points)).unwrap()).write_into(writer);
157        self.attach_points.write_into(writer);
158    }
159    fn table_type(&self) -> TableType {
160        TableType::Named("AttachList")
161    }
162}
163
164impl Validate for AttachList {
165    fn validate_impl(&self, ctx: &mut ValidationCtx) {
166        ctx.in_table("AttachList", |ctx| {
167            ctx.in_field("coverage", |ctx| {
168                self.coverage.validate_impl(ctx);
169            });
170            ctx.in_field("attach_points", |ctx| {
171                if self.attach_points.len() > (u16::MAX as usize) {
172                    ctx.report("array exceeds max length");
173                }
174                self.attach_points.validate_impl(ctx);
175            });
176        })
177    }
178}
179
180impl<'a> FromObjRef<read_fonts::tables::gdef::AttachList<'a>> for AttachList {
181    fn from_obj_ref(obj: &read_fonts::tables::gdef::AttachList<'a>, _: FontData) -> Self {
182        AttachList {
183            coverage: obj.coverage().to_owned_table(),
184            attach_points: obj.attach_points().to_owned_table(),
185        }
186    }
187}
188
189#[allow(clippy::needless_lifetimes)]
190impl<'a> FromTableRef<read_fonts::tables::gdef::AttachList<'a>> for AttachList {}
191
192impl<'a> FontRead<'a> for AttachList {
193    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
194        <read_fonts::tables::gdef::AttachList as FontRead>::read(data).map(|x| x.to_owned_table())
195    }
196}
197
198/// Part of [AttachList]
199#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
200#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
201pub struct AttachPoint {
202    /// Array of contour point indices -in increasing numerical order
203    pub point_indices: Vec<u16>,
204}
205
206impl AttachPoint {
207    /// Construct a new `AttachPoint`
208    pub fn new(point_indices: Vec<u16>) -> Self {
209        Self { point_indices }
210    }
211}
212
213impl FontWrite for AttachPoint {
214    #[allow(clippy::unnecessary_cast)]
215    fn write_into(&self, writer: &mut TableWriter) {
216        (u16::try_from(array_len(&self.point_indices)).unwrap()).write_into(writer);
217        self.point_indices.write_into(writer);
218    }
219    fn table_type(&self) -> TableType {
220        TableType::Named("AttachPoint")
221    }
222}
223
224impl Validate for AttachPoint {
225    fn validate_impl(&self, ctx: &mut ValidationCtx) {
226        ctx.in_table("AttachPoint", |ctx| {
227            ctx.in_field("point_indices", |ctx| {
228                if self.point_indices.len() > (u16::MAX as usize) {
229                    ctx.report("array exceeds max length");
230                }
231            });
232        })
233    }
234}
235
236impl<'a> FromObjRef<read_fonts::tables::gdef::AttachPoint<'a>> for AttachPoint {
237    fn from_obj_ref(obj: &read_fonts::tables::gdef::AttachPoint<'a>, _: FontData) -> Self {
238        let offset_data = obj.offset_data();
239        AttachPoint {
240            point_indices: obj.point_indices().to_owned_obj(offset_data),
241        }
242    }
243}
244
245#[allow(clippy::needless_lifetimes)]
246impl<'a> FromTableRef<read_fonts::tables::gdef::AttachPoint<'a>> for AttachPoint {}
247
248impl<'a> FontRead<'a> for AttachPoint {
249    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
250        <read_fonts::tables::gdef::AttachPoint as FontRead>::read(data).map(|x| x.to_owned_table())
251    }
252}
253
254/// [Ligature Caret List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#ligature-caret-list-table)
255#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
256#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
257pub struct LigCaretList {
258    /// Offset to Coverage table - from beginning of LigCaretList table
259    pub coverage: OffsetMarker<CoverageTable>,
260    /// Array of offsets to LigGlyph tables, from beginning of
261    /// LigCaretList table —in Coverage Index order
262    pub lig_glyphs: Vec<OffsetMarker<LigGlyph>>,
263}
264
265impl LigCaretList {
266    /// Construct a new `LigCaretList`
267    pub fn new(coverage: CoverageTable, lig_glyphs: Vec<LigGlyph>) -> Self {
268        Self {
269            coverage: coverage.into(),
270            lig_glyphs: lig_glyphs.into_iter().map(Into::into).collect(),
271        }
272    }
273}
274
275impl FontWrite for LigCaretList {
276    #[allow(clippy::unnecessary_cast)]
277    fn write_into(&self, writer: &mut TableWriter) {
278        self.coverage.write_into(writer);
279        (u16::try_from(array_len(&self.lig_glyphs)).unwrap()).write_into(writer);
280        self.lig_glyphs.write_into(writer);
281    }
282    fn table_type(&self) -> TableType {
283        TableType::Named("LigCaretList")
284    }
285}
286
287impl Validate for LigCaretList {
288    fn validate_impl(&self, ctx: &mut ValidationCtx) {
289        ctx.in_table("LigCaretList", |ctx| {
290            ctx.in_field("coverage", |ctx| {
291                self.coverage.validate_impl(ctx);
292            });
293            ctx.in_field("lig_glyphs", |ctx| {
294                if self.lig_glyphs.len() > (u16::MAX as usize) {
295                    ctx.report("array exceeds max length");
296                }
297                self.lig_glyphs.validate_impl(ctx);
298            });
299        })
300    }
301}
302
303impl<'a> FromObjRef<read_fonts::tables::gdef::LigCaretList<'a>> for LigCaretList {
304    fn from_obj_ref(obj: &read_fonts::tables::gdef::LigCaretList<'a>, _: FontData) -> Self {
305        LigCaretList {
306            coverage: obj.coverage().to_owned_table(),
307            lig_glyphs: obj.lig_glyphs().to_owned_table(),
308        }
309    }
310}
311
312#[allow(clippy::needless_lifetimes)]
313impl<'a> FromTableRef<read_fonts::tables::gdef::LigCaretList<'a>> for LigCaretList {}
314
315impl<'a> FontRead<'a> for LigCaretList {
316    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
317        <read_fonts::tables::gdef::LigCaretList as FontRead>::read(data).map(|x| x.to_owned_table())
318    }
319}
320
321/// [Ligature Glyph Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#ligature-glyph-table)
322#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
323#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
324pub struct LigGlyph {
325    /// Array of offsets to CaretValue tables, from beginning of
326    /// LigGlyph table — in increasing coordinate order
327    pub caret_values: Vec<OffsetMarker<CaretValue>>,
328}
329
330impl LigGlyph {
331    /// Construct a new `LigGlyph`
332    pub fn new(caret_values: Vec<CaretValue>) -> Self {
333        Self {
334            caret_values: caret_values.into_iter().map(Into::into).collect(),
335        }
336    }
337}
338
339impl FontWrite for LigGlyph {
340    #[allow(clippy::unnecessary_cast)]
341    fn write_into(&self, writer: &mut TableWriter) {
342        (u16::try_from(array_len(&self.caret_values)).unwrap()).write_into(writer);
343        self.caret_values.write_into(writer);
344    }
345    fn table_type(&self) -> TableType {
346        TableType::Named("LigGlyph")
347    }
348}
349
350impl Validate for LigGlyph {
351    fn validate_impl(&self, ctx: &mut ValidationCtx) {
352        ctx.in_table("LigGlyph", |ctx| {
353            ctx.in_field("caret_values", |ctx| {
354                if self.caret_values.len() > (u16::MAX as usize) {
355                    ctx.report("array exceeds max length");
356                }
357                self.caret_values.validate_impl(ctx);
358            });
359        })
360    }
361}
362
363impl<'a> FromObjRef<read_fonts::tables::gdef::LigGlyph<'a>> for LigGlyph {
364    fn from_obj_ref(obj: &read_fonts::tables::gdef::LigGlyph<'a>, _: FontData) -> Self {
365        LigGlyph {
366            caret_values: obj.caret_values().to_owned_table(),
367        }
368    }
369}
370
371#[allow(clippy::needless_lifetimes)]
372impl<'a> FromTableRef<read_fonts::tables::gdef::LigGlyph<'a>> for LigGlyph {}
373
374impl<'a> FontRead<'a> for LigGlyph {
375    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
376        <read_fonts::tables::gdef::LigGlyph as FontRead>::read(data).map(|x| x.to_owned_table())
377    }
378}
379
380/// [Caret Value Tables](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caret-value-tables)
381#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
382#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
383pub enum CaretValue {
384    Format1(CaretValueFormat1),
385    Format2(CaretValueFormat2),
386    Format3(CaretValueFormat3),
387}
388
389impl CaretValue {
390    /// Construct a new `CaretValueFormat1` subtable
391    pub fn format_1(coordinate: i16) -> Self {
392        Self::Format1(CaretValueFormat1::new(coordinate))
393    }
394
395    /// Construct a new `CaretValueFormat2` subtable
396    pub fn format_2(caret_value_point_index: u16) -> Self {
397        Self::Format2(CaretValueFormat2::new(caret_value_point_index))
398    }
399
400    /// Construct a new `CaretValueFormat3` subtable
401    pub fn format_3(coordinate: i16, device: DeviceOrVariationIndex) -> Self {
402        Self::Format3(CaretValueFormat3::new(coordinate, device))
403    }
404}
405
406impl Default for CaretValue {
407    fn default() -> Self {
408        Self::Format1(Default::default())
409    }
410}
411
412impl FontWrite for CaretValue {
413    fn write_into(&self, writer: &mut TableWriter) {
414        match self {
415            Self::Format1(item) => item.write_into(writer),
416            Self::Format2(item) => item.write_into(writer),
417            Self::Format3(item) => item.write_into(writer),
418        }
419    }
420    fn table_type(&self) -> TableType {
421        match self {
422            Self::Format1(item) => item.table_type(),
423            Self::Format2(item) => item.table_type(),
424            Self::Format3(item) => item.table_type(),
425        }
426    }
427}
428
429impl Validate for CaretValue {
430    fn validate_impl(&self, ctx: &mut ValidationCtx) {
431        match self {
432            Self::Format1(item) => item.validate_impl(ctx),
433            Self::Format2(item) => item.validate_impl(ctx),
434            Self::Format3(item) => item.validate_impl(ctx),
435        }
436    }
437}
438
439impl FromObjRef<read_fonts::tables::gdef::CaretValue<'_>> for CaretValue {
440    fn from_obj_ref(obj: &read_fonts::tables::gdef::CaretValue, _: FontData) -> Self {
441        use read_fonts::tables::gdef::CaretValue as ObjRefType;
442        match obj {
443            ObjRefType::Format1(item) => CaretValue::Format1(item.to_owned_table()),
444            ObjRefType::Format2(item) => CaretValue::Format2(item.to_owned_table()),
445            ObjRefType::Format3(item) => CaretValue::Format3(item.to_owned_table()),
446        }
447    }
448}
449
450impl FromTableRef<read_fonts::tables::gdef::CaretValue<'_>> for CaretValue {}
451
452impl<'a> FontRead<'a> for CaretValue {
453    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
454        <read_fonts::tables::gdef::CaretValue as FontRead>::read(data).map(|x| x.to_owned_table())
455    }
456}
457
458impl From<CaretValueFormat1> for CaretValue {
459    fn from(src: CaretValueFormat1) -> CaretValue {
460        CaretValue::Format1(src)
461    }
462}
463
464impl From<CaretValueFormat2> for CaretValue {
465    fn from(src: CaretValueFormat2) -> CaretValue {
466        CaretValue::Format2(src)
467    }
468}
469
470impl From<CaretValueFormat3> for CaretValue {
471    fn from(src: CaretValueFormat3) -> CaretValue {
472        CaretValue::Format3(src)
473    }
474}
475
476/// [CaretValue Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caretvalue-format-1)
477#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
478#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
479pub struct CaretValueFormat1 {
480    /// X or Y value, in design units
481    pub coordinate: i16,
482}
483
484impl CaretValueFormat1 {
485    /// Construct a new `CaretValueFormat1`
486    pub fn new(coordinate: i16) -> Self {
487        Self { coordinate }
488    }
489}
490
491impl FontWrite for CaretValueFormat1 {
492    #[allow(clippy::unnecessary_cast)]
493    fn write_into(&self, writer: &mut TableWriter) {
494        (1 as u16).write_into(writer);
495        self.coordinate.write_into(writer);
496    }
497    fn table_type(&self) -> TableType {
498        TableType::Named("CaretValueFormat1")
499    }
500}
501
502impl Validate for CaretValueFormat1 {
503    fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
504}
505
506impl<'a> FromObjRef<read_fonts::tables::gdef::CaretValueFormat1<'a>> for CaretValueFormat1 {
507    fn from_obj_ref(obj: &read_fonts::tables::gdef::CaretValueFormat1<'a>, _: FontData) -> Self {
508        CaretValueFormat1 {
509            coordinate: obj.coordinate(),
510        }
511    }
512}
513
514#[allow(clippy::needless_lifetimes)]
515impl<'a> FromTableRef<read_fonts::tables::gdef::CaretValueFormat1<'a>> for CaretValueFormat1 {}
516
517impl<'a> FontRead<'a> for CaretValueFormat1 {
518    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
519        <read_fonts::tables::gdef::CaretValueFormat1 as FontRead>::read(data)
520            .map(|x| x.to_owned_table())
521    }
522}
523
524/// [CaretValue Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caretvalue-format-2)
525#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
526#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
527pub struct CaretValueFormat2 {
528    /// Contour point index on glyph
529    pub caret_value_point_index: u16,
530}
531
532impl CaretValueFormat2 {
533    /// Construct a new `CaretValueFormat2`
534    pub fn new(caret_value_point_index: u16) -> Self {
535        Self {
536            caret_value_point_index,
537        }
538    }
539}
540
541impl FontWrite for CaretValueFormat2 {
542    #[allow(clippy::unnecessary_cast)]
543    fn write_into(&self, writer: &mut TableWriter) {
544        (2 as u16).write_into(writer);
545        self.caret_value_point_index.write_into(writer);
546    }
547    fn table_type(&self) -> TableType {
548        TableType::Named("CaretValueFormat2")
549    }
550}
551
552impl Validate for CaretValueFormat2 {
553    fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
554}
555
556impl<'a> FromObjRef<read_fonts::tables::gdef::CaretValueFormat2<'a>> for CaretValueFormat2 {
557    fn from_obj_ref(obj: &read_fonts::tables::gdef::CaretValueFormat2<'a>, _: FontData) -> Self {
558        CaretValueFormat2 {
559            caret_value_point_index: obj.caret_value_point_index(),
560        }
561    }
562}
563
564#[allow(clippy::needless_lifetimes)]
565impl<'a> FromTableRef<read_fonts::tables::gdef::CaretValueFormat2<'a>> for CaretValueFormat2 {}
566
567impl<'a> FontRead<'a> for CaretValueFormat2 {
568    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
569        <read_fonts::tables::gdef::CaretValueFormat2 as FontRead>::read(data)
570            .map(|x| x.to_owned_table())
571    }
572}
573
574/// [CaretValue Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#caretvalue-format-3)
575#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
576#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
577pub struct CaretValueFormat3 {
578    /// X or Y value, in design units
579    pub coordinate: i16,
580    /// Offset to Device table (non-variable font) / Variation Index
581    /// table (variable font) for X or Y value-from beginning of
582    /// CaretValue table
583    pub device: OffsetMarker<DeviceOrVariationIndex>,
584}
585
586impl CaretValueFormat3 {
587    /// Construct a new `CaretValueFormat3`
588    pub fn new(coordinate: i16, device: DeviceOrVariationIndex) -> Self {
589        Self {
590            coordinate,
591            device: device.into(),
592        }
593    }
594}
595
596impl FontWrite for CaretValueFormat3 {
597    #[allow(clippy::unnecessary_cast)]
598    fn write_into(&self, writer: &mut TableWriter) {
599        (3 as u16).write_into(writer);
600        self.coordinate.write_into(writer);
601        self.device.write_into(writer);
602    }
603    fn table_type(&self) -> TableType {
604        TableType::Named("CaretValueFormat3")
605    }
606}
607
608impl Validate for CaretValueFormat3 {
609    fn validate_impl(&self, ctx: &mut ValidationCtx) {
610        ctx.in_table("CaretValueFormat3", |ctx| {
611            ctx.in_field("device", |ctx| {
612                self.device.validate_impl(ctx);
613            });
614        })
615    }
616}
617
618impl<'a> FromObjRef<read_fonts::tables::gdef::CaretValueFormat3<'a>> for CaretValueFormat3 {
619    fn from_obj_ref(obj: &read_fonts::tables::gdef::CaretValueFormat3<'a>, _: FontData) -> Self {
620        CaretValueFormat3 {
621            coordinate: obj.coordinate(),
622            device: obj.device().to_owned_table(),
623        }
624    }
625}
626
627#[allow(clippy::needless_lifetimes)]
628impl<'a> FromTableRef<read_fonts::tables::gdef::CaretValueFormat3<'a>> for CaretValueFormat3 {}
629
630impl<'a> FontRead<'a> for CaretValueFormat3 {
631    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
632        <read_fonts::tables::gdef::CaretValueFormat3 as FontRead>::read(data)
633            .map(|x| x.to_owned_table())
634    }
635}
636
637/// [Mark Glyph Sets Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#mark-glyph-sets-table)
638#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
639#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
640pub struct MarkGlyphSets {
641    /// Array of offsets to mark glyph set coverage tables, from the
642    /// start of the MarkGlyphSets table.
643    pub coverages: Vec<OffsetMarker<CoverageTable, WIDTH_32>>,
644}
645
646impl MarkGlyphSets {
647    /// Construct a new `MarkGlyphSets`
648    pub fn new(coverages: Vec<CoverageTable>) -> Self {
649        Self {
650            coverages: coverages.into_iter().map(Into::into).collect(),
651        }
652    }
653}
654
655impl FontWrite for MarkGlyphSets {
656    #[allow(clippy::unnecessary_cast)]
657    fn write_into(&self, writer: &mut TableWriter) {
658        (1 as u16).write_into(writer);
659        (u16::try_from(array_len(&self.coverages)).unwrap()).write_into(writer);
660        self.coverages.write_into(writer);
661    }
662    fn table_type(&self) -> TableType {
663        TableType::Named("MarkGlyphSets")
664    }
665}
666
667impl Validate for MarkGlyphSets {
668    fn validate_impl(&self, ctx: &mut ValidationCtx) {
669        ctx.in_table("MarkGlyphSets", |ctx| {
670            ctx.in_field("coverages", |ctx| {
671                if self.coverages.len() > (u16::MAX as usize) {
672                    ctx.report("array exceeds max length");
673                }
674                self.coverages.validate_impl(ctx);
675            });
676        })
677    }
678}
679
680impl<'a> FromObjRef<read_fonts::tables::gdef::MarkGlyphSets<'a>> for MarkGlyphSets {
681    fn from_obj_ref(obj: &read_fonts::tables::gdef::MarkGlyphSets<'a>, _: FontData) -> Self {
682        MarkGlyphSets {
683            coverages: obj.coverages().to_owned_table(),
684        }
685    }
686}
687
688#[allow(clippy::needless_lifetimes)]
689impl<'a> FromTableRef<read_fonts::tables::gdef::MarkGlyphSets<'a>> for MarkGlyphSets {}
690
691impl<'a> FontRead<'a> for MarkGlyphSets {
692    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
693        <read_fonts::tables::gdef::MarkGlyphSets as FontRead>::read(data)
694            .map(|x| x.to_owned_table())
695    }
696}