Coverage Report

Created: 2026-09-14 08:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fontations/write-fonts/generated/generated_base.rs
Line
Count
Source
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
/// The [BASE](https://learn.microsoft.com/en-us/typography/opentype/spec/base) (Baseline) table
9
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
10
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11
pub struct Base {
12
    /// Offset to horizontal Axis table, from beginning of BASE table (may be NULL)
13
    pub horiz_axis: NullableOffsetMarker<Axis>,
14
    /// Offset to vertical Axis table, from beginning of BASE table (may be NULL)
15
    pub vert_axis: NullableOffsetMarker<Axis>,
16
    /// Offset to Item Variation Store table, from beginning of BASE table (may be null)
17
    pub item_var_store: NullableOffsetMarker<ItemVariationStore, WIDTH_32>,
18
}
19
20
impl Base {
21
    /// Construct a new `Base`
22
0
    pub fn new(horiz_axis: Option<Axis>, vert_axis: Option<Axis>) -> Self {
23
0
        Self {
24
0
            horiz_axis: horiz_axis.into(),
25
0
            vert_axis: vert_axis.into(),
26
0
            ..Default::default()
27
0
        }
28
0
    }
29
}
30
31
impl FontWrite for Base {
32
    #[allow(clippy::unnecessary_cast)]
33
0
    fn write_into(&self, writer: &mut TableWriter) {
34
0
        let version = self.compute_version() as MajorMinor;
35
0
        version.write_into(writer);
36
0
        self.horiz_axis.write_into(writer);
37
0
        self.vert_axis.write_into(writer);
38
0
        version
39
0
            .compatible((1u16, 1u16))
40
0
            .then(|| self.item_var_store.write_into(writer));
41
0
    }
42
0
    fn table_type(&self) -> TableType {
43
0
        TableType::TopLevel(Base::TAG)
44
0
    }
45
}
46
47
impl Validate for Base {
48
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
49
0
        ctx.in_table("Base", |ctx| {
50
0
            ctx.in_field("horiz_axis", |ctx| {
51
0
                self.horiz_axis.validate_impl(ctx);
52
0
            });
53
0
            ctx.in_field("vert_axis", |ctx| {
54
0
                self.vert_axis.validate_impl(ctx);
55
0
            });
56
0
            ctx.in_field("item_var_store", |ctx| {
57
0
                self.item_var_store.validate_impl(ctx);
58
0
            });
59
0
        })
60
0
    }
61
}
62
63
impl TopLevelTable for Base {
64
    const TAG: Tag = Tag::new(b"BASE");
65
}
66
67
impl<'a> FromObjRef<read_fonts::tables::base::Base<'a>> for Base {
68
0
    fn from_obj_ref(obj: &read_fonts::tables::base::Base<'a>, _: FontData) -> Self {
69
0
        Base {
70
0
            horiz_axis: obj.horiz_axis().to_owned_table(),
71
0
            vert_axis: obj.vert_axis().to_owned_table(),
72
0
            item_var_store: obj.item_var_store().to_owned_table(),
73
0
        }
74
0
    }
75
}
76
77
#[allow(clippy::needless_lifetimes)]
78
impl<'a> FromTableRef<read_fonts::tables::base::Base<'a>> for Base {}
79
80
impl ReadArgs for Base {
81
    type Args = ();
82
}
83
84
impl<'a> FontRead<'a> for Base {
85
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
86
0
        <read_fonts::tables::base::Base as FontRead>::read(data).map(|x| x.to_owned_table())
87
0
    }
88
}
89
90
/// [Axis Table](https://learn.microsoft.com/en-us/typography/opentype/spec/base#axis-tables-horizaxis-and-vertaxis)
91
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
92
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
93
pub struct Axis {
94
    /// Offset to BaseTagList table, from beginning of Axis table (may
95
    /// be NULL)
96
    pub base_tag_list: NullableOffsetMarker<BaseTagList>,
97
    /// Offset to BaseScriptList table, from beginning of Axis table
98
    pub base_script_list: OffsetMarker<BaseScriptList>,
99
}
100
101
impl Axis {
102
    /// Construct a new `Axis`
103
0
    pub fn new(base_tag_list: Option<BaseTagList>, base_script_list: BaseScriptList) -> Self {
104
0
        Self {
105
0
            base_tag_list: base_tag_list.into(),
106
0
            base_script_list: base_script_list.into(),
107
0
        }
108
0
    }
109
}
110
111
impl FontWrite for Axis {
112
0
    fn write_into(&self, writer: &mut TableWriter) {
113
0
        self.base_tag_list.write_into(writer);
114
0
        self.base_script_list.write_into(writer);
115
0
    }
116
0
    fn table_type(&self) -> TableType {
117
0
        TableType::Named("Axis")
118
0
    }
119
}
120
121
impl Validate for Axis {
122
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
123
0
        ctx.in_table("Axis", |ctx| {
124
0
            ctx.in_field("base_tag_list", |ctx| {
125
0
                self.base_tag_list.validate_impl(ctx);
126
0
            });
127
0
            ctx.in_field("base_script_list", |ctx| {
128
0
                self.base_script_list.validate_impl(ctx);
129
0
            });
130
0
        })
131
0
    }
132
}
133
134
impl<'a> FromObjRef<read_fonts::tables::base::Axis<'a>> for Axis {
135
0
    fn from_obj_ref(obj: &read_fonts::tables::base::Axis<'a>, _: FontData) -> Self {
136
0
        Axis {
137
0
            base_tag_list: obj.base_tag_list().to_owned_table(),
138
0
            base_script_list: obj.base_script_list().to_owned_table(),
139
0
        }
140
0
    }
141
}
142
143
#[allow(clippy::needless_lifetimes)]
144
impl<'a> FromTableRef<read_fonts::tables::base::Axis<'a>> for Axis {}
145
146
impl ReadArgs for Axis {
147
    type Args = ();
148
}
149
150
impl<'a> FontRead<'a> for Axis {
151
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
152
0
        <read_fonts::tables::base::Axis as FontRead>::read(data).map(|x| x.to_owned_table())
153
0
    }
154
}
155
156
/// [BaseTagList Table](https://learn.microsoft.com/en-us/typography/opentype/spec/base#basetaglist-table)
157
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
158
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
159
pub struct BaseTagList {
160
    /// Array of 4-byte baseline identification tags — must be in
161
    /// alphabetical order
162
    pub baseline_tags: Vec<Tag>,
163
}
164
165
impl BaseTagList {
166
    /// Construct a new `BaseTagList`
167
0
    pub fn new(baseline_tags: Vec<Tag>) -> Self {
168
0
        Self { baseline_tags }
169
0
    }
170
}
171
172
impl FontWrite for BaseTagList {
173
    #[allow(clippy::unnecessary_cast)]
174
0
    fn write_into(&self, writer: &mut TableWriter) {
175
0
        (u16::try_from(array_len(&self.baseline_tags)).unwrap()).write_into(writer);
176
0
        self.baseline_tags.write_into(writer);
177
0
    }
178
0
    fn table_type(&self) -> TableType {
179
0
        TableType::Named("BaseTagList")
180
0
    }
181
}
182
183
impl Validate for BaseTagList {
184
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
185
0
        ctx.in_table("BaseTagList", |ctx| {
186
0
            ctx.in_field("baseline_tags", |ctx| {
187
0
                if self.baseline_tags.len() > to_usize(u16::MAX) {
188
0
                    ctx.report("array exceeds max length");
189
0
                }
190
0
            });
191
0
        })
192
0
    }
193
}
194
195
impl<'a> FromObjRef<read_fonts::tables::base::BaseTagList<'a>> for BaseTagList {
196
0
    fn from_obj_ref(obj: &read_fonts::tables::base::BaseTagList<'a>, _: FontData) -> Self {
197
0
        let offset_data = obj.offset_data();
198
0
        BaseTagList {
199
0
            baseline_tags: obj.baseline_tags().to_owned_obj(offset_data),
200
0
        }
201
0
    }
202
}
203
204
#[allow(clippy::needless_lifetimes)]
205
impl<'a> FromTableRef<read_fonts::tables::base::BaseTagList<'a>> for BaseTagList {}
206
207
impl ReadArgs for BaseTagList {
208
    type Args = ();
209
}
210
211
impl<'a> FontRead<'a> for BaseTagList {
212
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
213
0
        <read_fonts::tables::base::BaseTagList as FontRead>::read(data).map(|x| x.to_owned_table())
214
0
    }
215
}
216
217
/// [BaseScriptList Table](https://learn.microsoft.com/en-us/typography/opentype/spec/base#basescriptlist-table)
218
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
219
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
220
pub struct BaseScriptList {
221
    /// Array of BaseScriptRecords, in alphabetical order by
222
    /// baseScriptTag
223
    pub base_script_records: Vec<BaseScriptRecord>,
224
}
225
226
impl BaseScriptList {
227
    /// Construct a new `BaseScriptList`
228
0
    pub fn new(base_script_records: Vec<BaseScriptRecord>) -> Self {
229
0
        Self {
230
0
            base_script_records,
231
0
        }
232
0
    }
233
}
234
235
impl FontWrite for BaseScriptList {
236
    #[allow(clippy::unnecessary_cast)]
237
0
    fn write_into(&self, writer: &mut TableWriter) {
238
0
        (u16::try_from(array_len(&self.base_script_records)).unwrap()).write_into(writer);
239
0
        self.base_script_records.write_into(writer);
240
0
    }
241
0
    fn table_type(&self) -> TableType {
242
0
        TableType::Named("BaseScriptList")
243
0
    }
244
}
245
246
impl Validate for BaseScriptList {
247
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
248
0
        ctx.in_table("BaseScriptList", |ctx| {
249
0
            ctx.in_field("base_script_records", |ctx| {
250
0
                if self.base_script_records.len() > to_usize(u16::MAX) {
251
0
                    ctx.report("array exceeds max length");
252
0
                }
253
0
                self.base_script_records.validate_impl(ctx);
254
0
            });
255
0
        })
256
0
    }
257
}
258
259
impl<'a> FromObjRef<read_fonts::tables::base::BaseScriptList<'a>> for BaseScriptList {
260
0
    fn from_obj_ref(obj: &read_fonts::tables::base::BaseScriptList<'a>, _: FontData) -> Self {
261
0
        let offset_data = obj.offset_data();
262
0
        BaseScriptList {
263
0
            base_script_records: obj.base_script_records().to_owned_obj(offset_data),
264
0
        }
265
0
    }
266
}
267
268
#[allow(clippy::needless_lifetimes)]
269
impl<'a> FromTableRef<read_fonts::tables::base::BaseScriptList<'a>> for BaseScriptList {}
270
271
impl ReadArgs for BaseScriptList {
272
    type Args = ();
273
}
274
275
impl<'a> FontRead<'a> for BaseScriptList {
276
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
277
0
        <read_fonts::tables::base::BaseScriptList as FontRead>::read(data)
278
0
            .map(|x| x.to_owned_table())
279
0
    }
280
}
281
282
/// [BaseScriptRecord](https://learn.microsoft.com/en-us/typography/opentype/spec/base#basescriptrecord)
283
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
284
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
285
pub struct BaseScriptRecord {
286
    /// 4-byte script identification tag
287
    pub base_script_tag: Tag,
288
    /// Offset to BaseScript table, from beginning of BaseScriptList
289
    pub base_script: OffsetMarker<BaseScript>,
290
}
291
292
impl BaseScriptRecord {
293
    /// Construct a new `BaseScriptRecord`
294
0
    pub fn new(base_script_tag: Tag, base_script: BaseScript) -> Self {
295
0
        Self {
296
0
            base_script_tag,
297
0
            base_script: base_script.into(),
298
0
        }
299
0
    }
300
}
301
302
impl FontWrite for BaseScriptRecord {
303
0
    fn write_into(&self, writer: &mut TableWriter) {
304
0
        self.base_script_tag.write_into(writer);
305
0
        self.base_script.write_into(writer);
306
0
    }
307
0
    fn table_type(&self) -> TableType {
308
0
        TableType::Named("BaseScriptRecord")
309
0
    }
310
}
311
312
impl Validate for BaseScriptRecord {
313
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
314
0
        ctx.in_table("BaseScriptRecord", |ctx| {
315
0
            ctx.in_field("base_script", |ctx| {
316
0
                self.base_script.validate_impl(ctx);
317
0
            });
318
0
        })
319
0
    }
320
}
321
322
impl FromObjRef<read_fonts::tables::base::BaseScriptRecord> for BaseScriptRecord {
323
0
    fn from_obj_ref(
324
0
        obj: &read_fonts::tables::base::BaseScriptRecord,
325
0
        offset_data: FontData,
326
0
    ) -> Self {
327
0
        BaseScriptRecord {
328
0
            base_script_tag: obj.base_script_tag(),
329
0
            base_script: obj.base_script(offset_data).to_owned_table(),
330
0
        }
331
0
    }
332
}
333
334
/// [BaseScript Table](https://learn.microsoft.com/en-us/typography/opentype/spec/base#basescript-table)
335
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
336
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
337
pub struct BaseScript {
338
    /// Offset to BaseValues table, from beginning of BaseScript table (may be NULL)
339
    pub base_values: NullableOffsetMarker<BaseValues>,
340
    /// Offset to MinMax table, from beginning of BaseScript table (may be NULL)
341
    pub default_min_max: NullableOffsetMarker<MinMax>,
342
    /// Array of BaseLangSysRecords, in alphabetical order by
343
    /// BaseLangSysTag
344
    pub base_lang_sys_records: Vec<BaseLangSysRecord>,
345
}
346
347
impl BaseScript {
348
    /// Construct a new `BaseScript`
349
0
    pub fn new(
350
0
        base_values: Option<BaseValues>,
351
0
        default_min_max: Option<MinMax>,
352
0
        base_lang_sys_records: Vec<BaseLangSysRecord>,
353
0
    ) -> Self {
354
0
        Self {
355
0
            base_values: base_values.into(),
356
0
            default_min_max: default_min_max.into(),
357
0
            base_lang_sys_records,
358
0
        }
359
0
    }
360
}
361
362
impl FontWrite for BaseScript {
363
    #[allow(clippy::unnecessary_cast)]
364
0
    fn write_into(&self, writer: &mut TableWriter) {
365
0
        self.base_values.write_into(writer);
366
0
        self.default_min_max.write_into(writer);
367
0
        (u16::try_from(array_len(&self.base_lang_sys_records)).unwrap()).write_into(writer);
368
0
        self.base_lang_sys_records.write_into(writer);
369
0
    }
370
0
    fn table_type(&self) -> TableType {
371
0
        TableType::Named("BaseScript")
372
0
    }
373
}
374
375
impl Validate for BaseScript {
376
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
377
0
        ctx.in_table("BaseScript", |ctx| {
378
0
            ctx.in_field("base_values", |ctx| {
379
0
                self.base_values.validate_impl(ctx);
380
0
            });
381
0
            ctx.in_field("default_min_max", |ctx| {
382
0
                self.default_min_max.validate_impl(ctx);
383
0
            });
384
0
            ctx.in_field("base_lang_sys_records", |ctx| {
385
0
                if self.base_lang_sys_records.len() > to_usize(u16::MAX) {
386
0
                    ctx.report("array exceeds max length");
387
0
                }
388
0
                self.base_lang_sys_records.validate_impl(ctx);
389
0
            });
390
0
        })
391
0
    }
392
}
393
394
impl<'a> FromObjRef<read_fonts::tables::base::BaseScript<'a>> for BaseScript {
395
0
    fn from_obj_ref(obj: &read_fonts::tables::base::BaseScript<'a>, _: FontData) -> Self {
396
0
        let offset_data = obj.offset_data();
397
0
        BaseScript {
398
0
            base_values: obj.base_values().to_owned_table(),
399
0
            default_min_max: obj.default_min_max().to_owned_table(),
400
0
            base_lang_sys_records: obj.base_lang_sys_records().to_owned_obj(offset_data),
401
0
        }
402
0
    }
403
}
404
405
#[allow(clippy::needless_lifetimes)]
406
impl<'a> FromTableRef<read_fonts::tables::base::BaseScript<'a>> for BaseScript {}
407
408
impl ReadArgs for BaseScript {
409
    type Args = ();
410
}
411
412
impl<'a> FontRead<'a> for BaseScript {
413
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
414
0
        <read_fonts::tables::base::BaseScript as FontRead>::read(data).map(|x| x.to_owned_table())
415
0
    }
416
}
417
418
/// [BaseLangSysRecord](https://learn.microsoft.com/en-us/typography/opentype/spec/base#baselangsysrecord)
419
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
420
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
421
pub struct BaseLangSysRecord {
422
    /// 4-byte language system identification tag
423
    pub base_lang_sys_tag: Tag,
424
    /// Offset to MinMax table, from beginning of BaseScript table
425
    pub min_max: OffsetMarker<MinMax>,
426
}
427
428
impl BaseLangSysRecord {
429
    /// Construct a new `BaseLangSysRecord`
430
0
    pub fn new(base_lang_sys_tag: Tag, min_max: MinMax) -> Self {
431
0
        Self {
432
0
            base_lang_sys_tag,
433
0
            min_max: min_max.into(),
434
0
        }
435
0
    }
436
}
437
438
impl FontWrite for BaseLangSysRecord {
439
0
    fn write_into(&self, writer: &mut TableWriter) {
440
0
        self.base_lang_sys_tag.write_into(writer);
441
0
        self.min_max.write_into(writer);
442
0
    }
443
0
    fn table_type(&self) -> TableType {
444
0
        TableType::Named("BaseLangSysRecord")
445
0
    }
446
}
447
448
impl Validate for BaseLangSysRecord {
449
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
450
0
        ctx.in_table("BaseLangSysRecord", |ctx| {
451
0
            ctx.in_field("min_max", |ctx| {
452
0
                self.min_max.validate_impl(ctx);
453
0
            });
454
0
        })
455
0
    }
456
}
457
458
impl FromObjRef<read_fonts::tables::base::BaseLangSysRecord> for BaseLangSysRecord {
459
0
    fn from_obj_ref(
460
0
        obj: &read_fonts::tables::base::BaseLangSysRecord,
461
0
        offset_data: FontData,
462
0
    ) -> Self {
463
0
        BaseLangSysRecord {
464
0
            base_lang_sys_tag: obj.base_lang_sys_tag(),
465
0
            min_max: obj.min_max(offset_data).to_owned_table(),
466
0
        }
467
0
    }
468
}
469
470
/// [BaseValues](https://learn.microsoft.com/en-us/typography/opentype/spec/base#basevalues-table) table
471
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
472
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
473
pub struct BaseValues {
474
    /// Index number of default baseline for this script — equals
475
    /// index position of baseline tag in baselineTags array of the
476
    /// BaseTagList
477
    pub default_baseline_index: u16,
478
    /// Array of offsets to BaseCoord tables, from beginning of
479
    /// BaseValues table — order matches baselineTags array in the
480
    /// BaseTagList
481
    pub base_coords: Vec<OffsetMarker<BaseCoord>>,
482
}
483
484
impl BaseValues {
485
    /// Construct a new `BaseValues`
486
0
    pub fn new(default_baseline_index: u16, base_coords: Vec<BaseCoord>) -> Self {
487
0
        Self {
488
0
            default_baseline_index,
489
0
            base_coords: base_coords.into_iter().map(Into::into).collect(),
490
0
        }
491
0
    }
492
}
493
494
impl FontWrite for BaseValues {
495
    #[allow(clippy::unnecessary_cast)]
496
0
    fn write_into(&self, writer: &mut TableWriter) {
497
0
        self.default_baseline_index.write_into(writer);
498
0
        (u16::try_from(array_len(&self.base_coords)).unwrap()).write_into(writer);
499
0
        self.base_coords.write_into(writer);
500
0
    }
501
0
    fn table_type(&self) -> TableType {
502
0
        TableType::Named("BaseValues")
503
0
    }
504
}
505
506
impl Validate for BaseValues {
507
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
508
0
        ctx.in_table("BaseValues", |ctx| {
509
0
            ctx.in_field("base_coords", |ctx| {
510
0
                if self.base_coords.len() > to_usize(u16::MAX) {
511
0
                    ctx.report("array exceeds max length");
512
0
                }
513
0
                self.base_coords.validate_impl(ctx);
514
0
            });
515
0
        })
516
0
    }
517
}
518
519
impl<'a> FromObjRef<read_fonts::tables::base::BaseValues<'a>> for BaseValues {
520
0
    fn from_obj_ref(obj: &read_fonts::tables::base::BaseValues<'a>, _: FontData) -> Self {
521
0
        BaseValues {
522
0
            default_baseline_index: obj.default_baseline_index(),
523
0
            base_coords: obj.base_coords().to_owned_table(),
524
0
        }
525
0
    }
526
}
527
528
#[allow(clippy::needless_lifetimes)]
529
impl<'a> FromTableRef<read_fonts::tables::base::BaseValues<'a>> for BaseValues {}
530
531
impl ReadArgs for BaseValues {
532
    type Args = ();
533
}
534
535
impl<'a> FontRead<'a> for BaseValues {
536
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
537
0
        <read_fonts::tables::base::BaseValues as FontRead>::read(data).map(|x| x.to_owned_table())
538
0
    }
539
}
540
541
/// [MinMax](https://learn.microsoft.com/en-us/typography/opentype/spec/base#minmax-table) table
542
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
543
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
544
pub struct MinMax {
545
    /// Offset to BaseCoord table that defines the minimum extent
546
    /// value, from the beginning of MinMax table (may be NULL)
547
    pub min_coord: NullableOffsetMarker<BaseCoord>,
548
    /// Offset to BaseCoord table that defines maximum extent value,
549
    /// from the beginning of MinMax table (may be NULL)
550
    pub max_coord: NullableOffsetMarker<BaseCoord>,
551
    /// Array of FeatMinMaxRecords, in alphabetical order by
552
    /// featureTableTag
553
    pub feat_min_max_records: Vec<FeatMinMaxRecord>,
554
}
555
556
impl MinMax {
557
    /// Construct a new `MinMax`
558
0
    pub fn new(
559
0
        min_coord: Option<BaseCoord>,
560
0
        max_coord: Option<BaseCoord>,
561
0
        feat_min_max_records: Vec<FeatMinMaxRecord>,
562
0
    ) -> Self {
563
0
        Self {
564
0
            min_coord: min_coord.into(),
565
0
            max_coord: max_coord.into(),
566
0
            feat_min_max_records,
567
0
        }
568
0
    }
569
}
570
571
impl FontWrite for MinMax {
572
    #[allow(clippy::unnecessary_cast)]
573
0
    fn write_into(&self, writer: &mut TableWriter) {
574
0
        self.min_coord.write_into(writer);
575
0
        self.max_coord.write_into(writer);
576
0
        (u16::try_from(array_len(&self.feat_min_max_records)).unwrap()).write_into(writer);
577
0
        self.feat_min_max_records.write_into(writer);
578
0
    }
579
0
    fn table_type(&self) -> TableType {
580
0
        TableType::Named("MinMax")
581
0
    }
582
}
583
584
impl Validate for MinMax {
585
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
586
0
        ctx.in_table("MinMax", |ctx| {
587
0
            ctx.in_field("min_coord", |ctx| {
588
0
                self.min_coord.validate_impl(ctx);
589
0
            });
590
0
            ctx.in_field("max_coord", |ctx| {
591
0
                self.max_coord.validate_impl(ctx);
592
0
            });
593
0
            ctx.in_field("feat_min_max_records", |ctx| {
594
0
                if self.feat_min_max_records.len() > to_usize(u16::MAX) {
595
0
                    ctx.report("array exceeds max length");
596
0
                }
597
0
                self.feat_min_max_records.validate_impl(ctx);
598
0
            });
599
0
        })
600
0
    }
601
}
602
603
impl<'a> FromObjRef<read_fonts::tables::base::MinMax<'a>> for MinMax {
604
0
    fn from_obj_ref(obj: &read_fonts::tables::base::MinMax<'a>, _: FontData) -> Self {
605
0
        let offset_data = obj.offset_data();
606
0
        MinMax {
607
0
            min_coord: obj.min_coord().to_owned_table(),
608
0
            max_coord: obj.max_coord().to_owned_table(),
609
0
            feat_min_max_records: obj.feat_min_max_records().to_owned_obj(offset_data),
610
0
        }
611
0
    }
612
}
613
614
#[allow(clippy::needless_lifetimes)]
615
impl<'a> FromTableRef<read_fonts::tables::base::MinMax<'a>> for MinMax {}
616
617
impl ReadArgs for MinMax {
618
    type Args = ();
619
}
620
621
impl<'a> FontRead<'a> for MinMax {
622
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
623
0
        <read_fonts::tables::base::MinMax as FontRead>::read(data).map(|x| x.to_owned_table())
624
0
    }
625
}
626
627
/// [FeatMinMaxRecord](https://learn.microsoft.com/en-us/typography/opentype/spec/base#baselangsysrecord)
628
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
629
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
630
pub struct FeatMinMaxRecord {
631
    /// 4-byte feature identification tag — must match feature tag in
632
    /// FeatureList
633
    pub feature_table_tag: Tag,
634
    /// Offset to BaseCoord table that defines the minimum extent
635
    /// value, from beginning of MinMax table (may be NULL)
636
    pub min_coord: NullableOffsetMarker<BaseCoord>,
637
    /// Offset to BaseCoord table that defines the maximum extent
638
    /// value, from beginning of MinMax table (may be NULL)
639
    pub max_coord: NullableOffsetMarker<BaseCoord>,
640
}
641
642
impl FeatMinMaxRecord {
643
    /// Construct a new `FeatMinMaxRecord`
644
0
    pub fn new(
645
0
        feature_table_tag: Tag,
646
0
        min_coord: Option<BaseCoord>,
647
0
        max_coord: Option<BaseCoord>,
648
0
    ) -> Self {
649
0
        Self {
650
0
            feature_table_tag,
651
0
            min_coord: min_coord.into(),
652
0
            max_coord: max_coord.into(),
653
0
        }
654
0
    }
655
}
656
657
impl FontWrite for FeatMinMaxRecord {
658
0
    fn write_into(&self, writer: &mut TableWriter) {
659
0
        self.feature_table_tag.write_into(writer);
660
0
        self.min_coord.write_into(writer);
661
0
        self.max_coord.write_into(writer);
662
0
    }
663
0
    fn table_type(&self) -> TableType {
664
0
        TableType::Named("FeatMinMaxRecord")
665
0
    }
666
}
667
668
impl Validate for FeatMinMaxRecord {
669
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
670
0
        ctx.in_table("FeatMinMaxRecord", |ctx| {
671
0
            ctx.in_field("min_coord", |ctx| {
672
0
                self.min_coord.validate_impl(ctx);
673
0
            });
674
0
            ctx.in_field("max_coord", |ctx| {
675
0
                self.max_coord.validate_impl(ctx);
676
0
            });
677
0
        })
678
0
    }
679
}
680
681
impl FromObjRef<read_fonts::tables::base::FeatMinMaxRecord> for FeatMinMaxRecord {
682
0
    fn from_obj_ref(
683
0
        obj: &read_fonts::tables::base::FeatMinMaxRecord,
684
0
        offset_data: FontData,
685
0
    ) -> Self {
686
0
        FeatMinMaxRecord {
687
0
            feature_table_tag: obj.feature_table_tag(),
688
0
            min_coord: obj.min_coord(offset_data).to_owned_table(),
689
0
            max_coord: obj.max_coord(offset_data).to_owned_table(),
690
0
        }
691
0
    }
692
}
693
694
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
695
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
696
pub enum BaseCoord {
697
    Format1(BaseCoordFormat1),
698
    Format2(BaseCoordFormat2),
699
    Format3(BaseCoordFormat3),
700
}
701
702
impl BaseCoord {
703
    /// Construct a new `BaseCoordFormat1` subtable
704
0
    pub fn format_1(coordinate: i16) -> Self {
705
0
        Self::Format1(BaseCoordFormat1::new(coordinate))
706
0
    }
707
708
    /// Construct a new `BaseCoordFormat2` subtable
709
0
    pub fn format_2(coordinate: i16, reference_glyph: u16, base_coord_point: u16) -> Self {
710
0
        Self::Format2(BaseCoordFormat2::new(
711
0
            coordinate,
712
0
            reference_glyph,
713
0
            base_coord_point,
714
0
        ))
715
0
    }
716
717
    /// Construct a new `BaseCoordFormat3` subtable
718
0
    pub fn format_3(coordinate: i16, device: Option<DeviceOrVariationIndex>) -> Self {
719
0
        Self::Format3(BaseCoordFormat3::new(coordinate, device))
720
0
    }
721
}
722
723
impl Default for BaseCoord {
724
0
    fn default() -> Self {
725
0
        Self::Format1(Default::default())
726
0
    }
727
}
728
729
impl FontWrite for BaseCoord {
730
0
    fn write_into(&self, writer: &mut TableWriter) {
731
0
        match self {
732
0
            Self::Format1(item) => item.write_into(writer),
733
0
            Self::Format2(item) => item.write_into(writer),
734
0
            Self::Format3(item) => item.write_into(writer),
735
        }
736
0
    }
737
0
    fn table_type(&self) -> TableType {
738
0
        match self {
739
0
            Self::Format1(item) => item.table_type(),
740
0
            Self::Format2(item) => item.table_type(),
741
0
            Self::Format3(item) => item.table_type(),
742
        }
743
0
    }
744
}
745
746
impl Validate for BaseCoord {
747
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
748
0
        match self {
749
0
            Self::Format1(item) => item.validate_impl(ctx),
750
0
            Self::Format2(item) => item.validate_impl(ctx),
751
0
            Self::Format3(item) => item.validate_impl(ctx),
752
        }
753
0
    }
754
}
755
756
impl FromObjRef<read_fonts::tables::base::BaseCoord<'_>> for BaseCoord {
757
0
    fn from_obj_ref(obj: &read_fonts::tables::base::BaseCoord, _: FontData) -> Self {
758
        use read_fonts::tables::base::BaseCoord as ObjRefType;
759
0
        match obj {
760
0
            ObjRefType::Format1(item) => BaseCoord::Format1(item.to_owned_table()),
761
0
            ObjRefType::Format2(item) => BaseCoord::Format2(item.to_owned_table()),
762
0
            ObjRefType::Format3(item) => BaseCoord::Format3(item.to_owned_table()),
763
        }
764
0
    }
765
}
766
767
impl FromTableRef<read_fonts::tables::base::BaseCoord<'_>> for BaseCoord {}
768
769
impl ReadArgs for BaseCoord {
770
    type Args = ();
771
}
772
773
impl<'a> FontRead<'a> for BaseCoord {
774
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
775
0
        <read_fonts::tables::base::BaseCoord as FontRead>::read(data).map(|x| x.to_owned_table())
776
0
    }
777
}
778
779
impl From<BaseCoordFormat1> for BaseCoord {
780
0
    fn from(src: BaseCoordFormat1) -> BaseCoord {
781
0
        BaseCoord::Format1(src)
782
0
    }
783
}
784
785
impl From<BaseCoordFormat2> for BaseCoord {
786
0
    fn from(src: BaseCoordFormat2) -> BaseCoord {
787
0
        BaseCoord::Format2(src)
788
0
    }
789
}
790
791
impl From<BaseCoordFormat3> for BaseCoord {
792
0
    fn from(src: BaseCoordFormat3) -> BaseCoord {
793
0
        BaseCoord::Format3(src)
794
0
    }
795
}
796
797
/// [BaseCoordFormat1](https://learn.microsoft.com/en-us/typography/opentype/spec/base#basecoord-format-1)
798
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
799
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
800
pub struct BaseCoordFormat1 {
801
    /// X or Y value, in design units
802
    pub coordinate: i16,
803
}
804
805
impl BaseCoordFormat1 {
806
    /// Construct a new `BaseCoordFormat1`
807
0
    pub fn new(coordinate: i16) -> Self {
808
0
        Self { coordinate }
809
0
    }
810
}
811
812
impl FontWrite for BaseCoordFormat1 {
813
    #[allow(clippy::unnecessary_cast)]
814
0
    fn write_into(&self, writer: &mut TableWriter) {
815
0
        (1 as u16).write_into(writer);
816
0
        self.coordinate.write_into(writer);
817
0
    }
818
0
    fn table_type(&self) -> TableType {
819
0
        TableType::Named("BaseCoordFormat1")
820
0
    }
821
}
822
823
impl Validate for BaseCoordFormat1 {
824
0
    fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
825
}
826
827
impl<'a> FromObjRef<read_fonts::tables::base::BaseCoordFormat1<'a>> for BaseCoordFormat1 {
828
0
    fn from_obj_ref(obj: &read_fonts::tables::base::BaseCoordFormat1<'a>, _: FontData) -> Self {
829
0
        BaseCoordFormat1 {
830
0
            coordinate: obj.coordinate(),
831
0
        }
832
0
    }
833
}
834
835
#[allow(clippy::needless_lifetimes)]
836
impl<'a> FromTableRef<read_fonts::tables::base::BaseCoordFormat1<'a>> for BaseCoordFormat1 {}
837
838
impl ReadArgs for BaseCoordFormat1 {
839
    type Args = ();
840
}
841
842
impl<'a> FontRead<'a> for BaseCoordFormat1 {
843
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
844
0
        <read_fonts::tables::base::BaseCoordFormat1 as FontRead>::read(data)
845
0
            .map(|x| x.to_owned_table())
846
0
    }
847
}
848
849
/// [BaseCoordFormat2](https://learn.microsoft.com/en-us/typography/opentype/spec/base#basecoord-format-2)
850
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
851
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
852
pub struct BaseCoordFormat2 {
853
    /// X or Y value, in design units
854
    pub coordinate: i16,
855
    /// Glyph ID of control glyph
856
    pub reference_glyph: u16,
857
    /// Index of contour point on the reference glyph
858
    pub base_coord_point: u16,
859
}
860
861
impl BaseCoordFormat2 {
862
    /// Construct a new `BaseCoordFormat2`
863
0
    pub fn new(coordinate: i16, reference_glyph: u16, base_coord_point: u16) -> Self {
864
0
        Self {
865
0
            coordinate,
866
0
            reference_glyph,
867
0
            base_coord_point,
868
0
        }
869
0
    }
870
}
871
872
impl FontWrite for BaseCoordFormat2 {
873
    #[allow(clippy::unnecessary_cast)]
874
0
    fn write_into(&self, writer: &mut TableWriter) {
875
0
        (2 as u16).write_into(writer);
876
0
        self.coordinate.write_into(writer);
877
0
        self.reference_glyph.write_into(writer);
878
0
        self.base_coord_point.write_into(writer);
879
0
    }
880
0
    fn table_type(&self) -> TableType {
881
0
        TableType::Named("BaseCoordFormat2")
882
0
    }
883
}
884
885
impl Validate for BaseCoordFormat2 {
886
0
    fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
887
}
888
889
impl<'a> FromObjRef<read_fonts::tables::base::BaseCoordFormat2<'a>> for BaseCoordFormat2 {
890
0
    fn from_obj_ref(obj: &read_fonts::tables::base::BaseCoordFormat2<'a>, _: FontData) -> Self {
891
0
        BaseCoordFormat2 {
892
0
            coordinate: obj.coordinate(),
893
0
            reference_glyph: obj.reference_glyph(),
894
0
            base_coord_point: obj.base_coord_point(),
895
0
        }
896
0
    }
897
}
898
899
#[allow(clippy::needless_lifetimes)]
900
impl<'a> FromTableRef<read_fonts::tables::base::BaseCoordFormat2<'a>> for BaseCoordFormat2 {}
901
902
impl ReadArgs for BaseCoordFormat2 {
903
    type Args = ();
904
}
905
906
impl<'a> FontRead<'a> for BaseCoordFormat2 {
907
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
908
0
        <read_fonts::tables::base::BaseCoordFormat2 as FontRead>::read(data)
909
0
            .map(|x| x.to_owned_table())
910
0
    }
911
}
912
913
/// [BaseCoordFormat3](https://learn.microsoft.com/en-us/typography/opentype/spec/base#basecoord-format-3)
914
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
915
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
916
pub struct BaseCoordFormat3 {
917
    /// X or Y value, in design units
918
    pub coordinate: i16,
919
    /// Offset to Device table (non-variable font) / Variation Index
920
    /// table (variable font) for X or Y value, from beginning of
921
    /// BaseCoord table (may be NULL).
922
    pub device: NullableOffsetMarker<DeviceOrVariationIndex>,
923
}
924
925
impl BaseCoordFormat3 {
926
    /// Construct a new `BaseCoordFormat3`
927
0
    pub fn new(coordinate: i16, device: Option<DeviceOrVariationIndex>) -> Self {
928
0
        Self {
929
0
            coordinate,
930
0
            device: device.into(),
931
0
        }
932
0
    }
933
}
934
935
impl FontWrite for BaseCoordFormat3 {
936
    #[allow(clippy::unnecessary_cast)]
937
0
    fn write_into(&self, writer: &mut TableWriter) {
938
0
        (3 as u16).write_into(writer);
939
0
        self.coordinate.write_into(writer);
940
0
        self.device.write_into(writer);
941
0
    }
942
0
    fn table_type(&self) -> TableType {
943
0
        TableType::Named("BaseCoordFormat3")
944
0
    }
945
}
946
947
impl Validate for BaseCoordFormat3 {
948
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
949
0
        ctx.in_table("BaseCoordFormat3", |ctx| {
950
0
            ctx.in_field("device", |ctx| {
951
0
                self.device.validate_impl(ctx);
952
0
            });
953
0
        })
954
0
    }
955
}
956
957
impl<'a> FromObjRef<read_fonts::tables::base::BaseCoordFormat3<'a>> for BaseCoordFormat3 {
958
0
    fn from_obj_ref(obj: &read_fonts::tables::base::BaseCoordFormat3<'a>, _: FontData) -> Self {
959
0
        BaseCoordFormat3 {
960
0
            coordinate: obj.coordinate(),
961
0
            device: obj.device().to_owned_table(),
962
0
        }
963
0
    }
964
}
965
966
#[allow(clippy::needless_lifetimes)]
967
impl<'a> FromTableRef<read_fonts::tables::base::BaseCoordFormat3<'a>> for BaseCoordFormat3 {}
968
969
impl ReadArgs for BaseCoordFormat3 {
970
    type Args = ();
971
}
972
973
impl<'a> FontRead<'a> for BaseCoordFormat3 {
974
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
975
0
        <read_fonts::tables::base::BaseCoordFormat3 as FontRead>::read(data)
976
0
            .map(|x| x.to_owned_table())
977
0
    }
978
}