Coverage Report

Created: 2026-10-28 07:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fontations/write-fonts/generated/generated_cmap.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
pub use read_fonts::tables::cmap::PlatformId;
9
10
/// [cmap](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#overview)
11
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
12
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13
pub struct Cmap {
14
    pub encoding_records: Vec<EncodingRecord>,
15
}
16
17
impl Cmap {
18
    /// Construct a new `Cmap`
19
0
    pub fn new(encoding_records: Vec<EncodingRecord>) -> Self {
20
0
        Self { encoding_records }
21
0
    }
22
}
23
24
impl FontWrite for Cmap {
25
    #[allow(clippy::unnecessary_cast)]
26
0
    fn write_into(&self, writer: &mut TableWriter) {
27
0
        (0 as u16).write_into(writer);
28
0
        (u16::try_from(array_len(&self.encoding_records)).unwrap()).write_into(writer);
29
0
        self.encoding_records.write_into(writer);
30
0
    }
31
0
    fn table_type(&self) -> TableType {
32
0
        TableType::TopLevel(Cmap::TAG)
33
0
    }
34
}
35
36
impl Validate for Cmap {
37
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
38
0
        ctx.in_table("Cmap", |ctx| {
39
0
            ctx.in_field("encoding_records", |ctx| {
40
0
                if self.encoding_records.len() > to_usize(u16::MAX) {
41
0
                    ctx.report("array exceeds max length");
42
0
                }
43
0
                self.encoding_records.validate_impl(ctx);
44
0
            });
45
0
        })
46
0
    }
47
}
48
49
impl TopLevelTable for Cmap {
50
    const TAG: Tag = Tag::new(b"cmap");
51
}
52
53
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap<'a>> for Cmap {
54
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap<'a>, _: FontData) -> Self {
55
0
        let offset_data = obj.offset_data();
56
0
        Cmap {
57
0
            encoding_records: obj.encoding_records().to_owned_obj(offset_data),
58
0
        }
59
0
    }
60
}
61
62
#[allow(clippy::needless_lifetimes)]
63
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap<'a>> for Cmap {}
64
65
impl ReadArgs for Cmap {
66
    type Args = ();
67
}
68
69
impl<'a> FontRead<'a> for Cmap {
70
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
71
0
        <read_fonts::tables::cmap::Cmap as FontRead>::read(data).map(|x| x.to_owned_table())
72
0
    }
73
}
74
75
/// Delta map table (ISO/IEC 14496-22:2026, 5.6.15).
76
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
77
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
78
pub struct Dmap {
79
    pub encoding_records: Vec<EncodingRecord>,
80
}
81
82
impl Dmap {
83
    /// Construct a new `Dmap`
84
0
    pub fn new(encoding_records: Vec<EncodingRecord>) -> Self {
85
0
        Self { encoding_records }
86
0
    }
87
}
88
89
impl FontWrite for Dmap {
90
    #[allow(clippy::unnecessary_cast)]
91
0
    fn write_into(&self, writer: &mut TableWriter) {
92
0
        (0 as u16).write_into(writer);
93
0
        (u16::try_from(array_len(&self.encoding_records)).unwrap()).write_into(writer);
94
0
        self.encoding_records.write_into(writer);
95
0
    }
96
0
    fn table_type(&self) -> TableType {
97
0
        TableType::TopLevel(Dmap::TAG)
98
0
    }
99
}
100
101
impl Validate for Dmap {
102
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
103
0
        ctx.in_table("Dmap", |ctx| {
104
0
            ctx.in_field("encoding_records", |ctx| {
105
0
                if self.encoding_records.len() > to_usize(u16::MAX) {
106
0
                    ctx.report("array exceeds max length");
107
0
                }
108
0
                self.encoding_records.validate_impl(ctx);
109
0
            });
110
0
        })
111
0
    }
112
}
113
114
impl TopLevelTable for Dmap {
115
    const TAG: Tag = Tag::new(b"DMAP");
116
}
117
118
impl<'a> FromObjRef<read_fonts::tables::cmap::Dmap<'a>> for Dmap {
119
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::Dmap<'a>, _: FontData) -> Self {
120
0
        let offset_data = obj.offset_data();
121
0
        Dmap {
122
0
            encoding_records: obj.encoding_records().to_owned_obj(offset_data),
123
0
        }
124
0
    }
125
}
126
127
#[allow(clippy::needless_lifetimes)]
128
impl<'a> FromTableRef<read_fonts::tables::cmap::Dmap<'a>> for Dmap {}
129
130
impl ReadArgs for Dmap {
131
    type Args = ();
132
}
133
134
impl<'a> FontRead<'a> for Dmap {
135
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
136
0
        <read_fonts::tables::cmap::Dmap as FontRead>::read(data).map(|x| x.to_owned_table())
137
0
    }
138
}
139
140
/// [Encoding Record](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#encoding-records-and-encodings)
141
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
142
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
143
pub struct EncodingRecord {
144
    /// Platform ID.
145
    pub platform_id: PlatformId,
146
    /// Platform-specific encoding ID.
147
    pub encoding_id: u16,
148
    /// Byte offset from beginning of the [`Cmap`] or [`Dmap`] table to the
149
    /// subtable for this encoding.
150
    pub subtable: OffsetMarker<CmapSubtable, WIDTH_32>,
151
}
152
153
impl EncodingRecord {
154
    /// Construct a new `EncodingRecord`
155
0
    pub fn new(platform_id: PlatformId, encoding_id: u16, subtable: CmapSubtable) -> Self {
156
0
        Self {
157
0
            platform_id,
158
0
            encoding_id,
159
0
            subtable: subtable.into(),
160
0
        }
161
0
    }
162
}
163
164
impl FontWrite for EncodingRecord {
165
0
    fn write_into(&self, writer: &mut TableWriter) {
166
0
        self.platform_id.write_into(writer);
167
0
        self.encoding_id.write_into(writer);
168
0
        self.subtable.write_into(writer);
169
0
    }
170
0
    fn table_type(&self) -> TableType {
171
0
        TableType::Named("EncodingRecord")
172
0
    }
173
}
174
175
impl Validate for EncodingRecord {
176
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
177
0
        ctx.in_table("EncodingRecord", |ctx| {
178
0
            ctx.in_field("subtable", |ctx| {
179
0
                self.subtable.validate_impl(ctx);
180
0
            });
181
0
        })
182
0
    }
183
}
184
185
impl FromObjRef<read_fonts::tables::cmap::EncodingRecord> for EncodingRecord {
186
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::EncodingRecord, offset_data: FontData) -> Self {
187
0
        EncodingRecord {
188
0
            platform_id: obj.platform_id(),
189
0
            encoding_id: obj.encoding_id(),
190
0
            subtable: obj.subtable(offset_data).to_owned_table(),
191
0
        }
192
0
    }
193
}
194
195
impl FontWrite for PlatformId {
196
0
    fn write_into(&self, writer: &mut TableWriter) {
197
0
        let val = *self as u16;
198
0
        writer.write_slice(&val.to_be_bytes())
199
0
    }
200
}
201
202
/// The different cmap subtable formats.
203
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
204
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
205
pub enum CmapSubtable {
206
    Format0(Cmap0),
207
    Format2(Cmap2),
208
    Format4(Cmap4),
209
    Format6(Cmap6),
210
    Format8(Cmap8),
211
    Format10(Cmap10),
212
    Format12(Cmap12),
213
    Format13(Cmap13),
214
    Format14(Cmap14),
215
    Format15(Cmap15),
216
}
217
218
impl CmapSubtable {
219
    /// Construct a new `Cmap0` subtable
220
0
    pub fn format_0(language: u16, glyph_id_array: Vec<u8>) -> Self {
221
0
        Self::Format0(Cmap0::new(language, glyph_id_array))
222
0
    }
223
224
    /// Construct a new `Cmap2` subtable
225
0
    pub fn format_2(length: u16, language: u16, sub_header_keys: Vec<u16>) -> Self {
226
0
        Self::Format2(Cmap2::new(length, language, sub_header_keys))
227
0
    }
228
229
    /// Construct a new `Cmap4` subtable
230
0
    pub fn format_4(
231
0
        language: u16,
232
0
        end_code: Vec<u16>,
233
0
        start_code: Vec<u16>,
234
0
        id_delta: Vec<i16>,
235
0
        id_range_offsets: Vec<u16>,
236
0
        glyph_id_array: Vec<u16>,
237
0
    ) -> Self {
238
0
        Self::Format4(Cmap4::new(
239
0
            language,
240
0
            end_code,
241
0
            start_code,
242
0
            id_delta,
243
0
            id_range_offsets,
244
0
            glyph_id_array,
245
0
        ))
246
0
    }
247
248
    /// Construct a new `Cmap6` subtable
249
0
    pub fn format_6(
250
0
        length: u16,
251
0
        language: u16,
252
0
        first_code: u16,
253
0
        entry_count: u16,
254
0
        glyph_id_array: Vec<u16>,
255
0
    ) -> Self {
256
0
        Self::Format6(Cmap6::new(
257
0
            length,
258
0
            language,
259
0
            first_code,
260
0
            entry_count,
261
0
            glyph_id_array,
262
0
        ))
263
0
    }
264
265
    /// Construct a new `Cmap8` subtable
266
0
    pub fn format_8(
267
0
        length: u32,
268
0
        language: u32,
269
0
        is32: Vec<u8>,
270
0
        num_groups: u32,
271
0
        groups: Vec<SequentialMapGroup>,
272
0
    ) -> Self {
273
0
        Self::Format8(Cmap8::new(length, language, is32, num_groups, groups))
274
0
    }
275
276
    /// Construct a new `Cmap10` subtable
277
0
    pub fn format_10(
278
0
        length: u32,
279
0
        language: u32,
280
0
        start_char_code: u32,
281
0
        glyph_id_array: Vec<u16>,
282
0
    ) -> Self {
283
0
        Self::Format10(Cmap10::new(
284
0
            length,
285
0
            language,
286
0
            start_char_code,
287
0
            glyph_id_array,
288
0
        ))
289
0
    }
290
291
    /// Construct a new `Cmap12` subtable
292
0
    pub fn format_12(language: u32, groups: Vec<SequentialMapGroup>) -> Self {
293
0
        Self::Format12(Cmap12::new(language, groups))
294
0
    }
295
296
    /// Construct a new `Cmap13` subtable
297
0
    pub fn format_13(
298
0
        length: u32,
299
0
        language: u32,
300
0
        num_groups: u32,
301
0
        groups: Vec<ConstantMapGroup>,
302
0
    ) -> Self {
303
0
        Self::Format13(Cmap13::new(length, language, num_groups, groups))
304
0
    }
305
306
    /// Construct a new `Cmap14` subtable
307
0
    pub fn format_14(var_selector: Vec<VariationSelector>) -> Self {
308
0
        Self::Format14(Cmap14::new(var_selector))
309
0
    }
310
311
    /// Construct a new `Cmap15` subtable
312
0
    pub fn format_15(var_selector: Vec<VariationSelector15>) -> Self {
313
0
        Self::Format15(Cmap15::new(var_selector))
314
0
    }
315
}
316
317
impl Default for CmapSubtable {
318
0
    fn default() -> Self {
319
0
        Self::Format0(Default::default())
320
0
    }
321
}
322
323
impl FontWrite for CmapSubtable {
324
0
    fn write_into(&self, writer: &mut TableWriter) {
325
0
        match self {
326
0
            Self::Format0(item) => item.write_into(writer),
327
0
            Self::Format2(item) => item.write_into(writer),
328
0
            Self::Format4(item) => item.write_into(writer),
329
0
            Self::Format6(item) => item.write_into(writer),
330
0
            Self::Format8(item) => item.write_into(writer),
331
0
            Self::Format10(item) => item.write_into(writer),
332
0
            Self::Format12(item) => item.write_into(writer),
333
0
            Self::Format13(item) => item.write_into(writer),
334
0
            Self::Format14(item) => item.write_into(writer),
335
0
            Self::Format15(item) => item.write_into(writer),
336
        }
337
0
    }
338
0
    fn table_type(&self) -> TableType {
339
0
        match self {
340
0
            Self::Format0(item) => item.table_type(),
341
0
            Self::Format2(item) => item.table_type(),
342
0
            Self::Format4(item) => item.table_type(),
343
0
            Self::Format6(item) => item.table_type(),
344
0
            Self::Format8(item) => item.table_type(),
345
0
            Self::Format10(item) => item.table_type(),
346
0
            Self::Format12(item) => item.table_type(),
347
0
            Self::Format13(item) => item.table_type(),
348
0
            Self::Format14(item) => item.table_type(),
349
0
            Self::Format15(item) => item.table_type(),
350
        }
351
0
    }
352
}
353
354
impl Validate for CmapSubtable {
355
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
356
0
        match self {
357
0
            Self::Format0(item) => item.validate_impl(ctx),
358
0
            Self::Format2(item) => item.validate_impl(ctx),
359
0
            Self::Format4(item) => item.validate_impl(ctx),
360
0
            Self::Format6(item) => item.validate_impl(ctx),
361
0
            Self::Format8(item) => item.validate_impl(ctx),
362
0
            Self::Format10(item) => item.validate_impl(ctx),
363
0
            Self::Format12(item) => item.validate_impl(ctx),
364
0
            Self::Format13(item) => item.validate_impl(ctx),
365
0
            Self::Format14(item) => item.validate_impl(ctx),
366
0
            Self::Format15(item) => item.validate_impl(ctx),
367
        }
368
0
    }
369
}
370
371
impl FromObjRef<read_fonts::tables::cmap::CmapSubtable<'_>> for CmapSubtable {
372
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::CmapSubtable, _: FontData) -> Self {
373
        use read_fonts::tables::cmap::CmapSubtable as ObjRefType;
374
0
        match obj {
375
0
            ObjRefType::Format0(item) => CmapSubtable::Format0(item.to_owned_table()),
376
0
            ObjRefType::Format2(item) => CmapSubtable::Format2(item.to_owned_table()),
377
0
            ObjRefType::Format4(item) => CmapSubtable::Format4(item.to_owned_table()),
378
0
            ObjRefType::Format6(item) => CmapSubtable::Format6(item.to_owned_table()),
379
0
            ObjRefType::Format8(item) => CmapSubtable::Format8(item.to_owned_table()),
380
0
            ObjRefType::Format10(item) => CmapSubtable::Format10(item.to_owned_table()),
381
0
            ObjRefType::Format12(item) => CmapSubtable::Format12(item.to_owned_table()),
382
0
            ObjRefType::Format13(item) => CmapSubtable::Format13(item.to_owned_table()),
383
0
            ObjRefType::Format14(item) => CmapSubtable::Format14(item.to_owned_table()),
384
0
            ObjRefType::Format15(item) => CmapSubtable::Format15(item.to_owned_table()),
385
        }
386
0
    }
387
}
388
389
impl FromTableRef<read_fonts::tables::cmap::CmapSubtable<'_>> for CmapSubtable {}
390
391
impl ReadArgs for CmapSubtable {
392
    type Args = ();
393
}
394
395
impl<'a> FontRead<'a> for CmapSubtable {
396
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
397
0
        <read_fonts::tables::cmap::CmapSubtable as FontRead>::read(data).map(|x| x.to_owned_table())
398
0
    }
399
}
400
401
impl From<Cmap0> for CmapSubtable {
402
0
    fn from(src: Cmap0) -> CmapSubtable {
403
0
        CmapSubtable::Format0(src)
404
0
    }
405
}
406
407
impl From<Cmap2> for CmapSubtable {
408
0
    fn from(src: Cmap2) -> CmapSubtable {
409
0
        CmapSubtable::Format2(src)
410
0
    }
411
}
412
413
impl From<Cmap4> for CmapSubtable {
414
0
    fn from(src: Cmap4) -> CmapSubtable {
415
0
        CmapSubtable::Format4(src)
416
0
    }
417
}
418
419
impl From<Cmap6> for CmapSubtable {
420
0
    fn from(src: Cmap6) -> CmapSubtable {
421
0
        CmapSubtable::Format6(src)
422
0
    }
423
}
424
425
impl From<Cmap8> for CmapSubtable {
426
0
    fn from(src: Cmap8) -> CmapSubtable {
427
0
        CmapSubtable::Format8(src)
428
0
    }
429
}
430
431
impl From<Cmap10> for CmapSubtable {
432
0
    fn from(src: Cmap10) -> CmapSubtable {
433
0
        CmapSubtable::Format10(src)
434
0
    }
435
}
436
437
impl From<Cmap12> for CmapSubtable {
438
0
    fn from(src: Cmap12) -> CmapSubtable {
439
0
        CmapSubtable::Format12(src)
440
0
    }
441
}
442
443
impl From<Cmap13> for CmapSubtable {
444
0
    fn from(src: Cmap13) -> CmapSubtable {
445
0
        CmapSubtable::Format13(src)
446
0
    }
447
}
448
449
impl From<Cmap14> for CmapSubtable {
450
0
    fn from(src: Cmap14) -> CmapSubtable {
451
0
        CmapSubtable::Format14(src)
452
0
    }
453
}
454
455
impl From<Cmap15> for CmapSubtable {
456
0
    fn from(src: Cmap15) -> CmapSubtable {
457
0
        CmapSubtable::Format15(src)
458
0
    }
459
}
460
461
/// [cmap Format 0](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-0-byte-encoding-table): Byte encoding table
462
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
463
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
464
pub struct Cmap0 {
465
    /// For requirements on use of the language field, see “Use of
466
    /// the language field in 'cmap' subtables” in this document.
467
    pub language: u16,
468
    /// An array that maps character codes to glyph index values.
469
    pub glyph_id_array: Vec<u8>,
470
}
471
472
impl Cmap0 {
473
    /// Construct a new `Cmap0`
474
0
    pub fn new(language: u16, glyph_id_array: Vec<u8>) -> Self {
475
0
        Self {
476
0
            language,
477
0
            glyph_id_array,
478
0
        }
479
0
    }
480
}
481
482
impl FontWrite for Cmap0 {
483
    #[allow(clippy::unnecessary_cast)]
484
0
    fn write_into(&self, writer: &mut TableWriter) {
485
0
        (0 as u16).write_into(writer);
486
0
        (256 + 6 as u16).write_into(writer);
487
0
        self.language.write_into(writer);
488
0
        self.glyph_id_array.write_into(writer);
489
0
    }
490
0
    fn table_type(&self) -> TableType {
491
0
        TableType::Named("Cmap0")
492
0
    }
493
}
494
495
impl Validate for Cmap0 {
496
0
    fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
497
}
498
499
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap0<'a>> for Cmap0 {
500
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap0<'a>, _: FontData) -> Self {
501
0
        let offset_data = obj.offset_data();
502
0
        Cmap0 {
503
0
            language: obj.language(),
504
0
            glyph_id_array: obj.glyph_id_array().to_owned_obj(offset_data),
505
0
        }
506
0
    }
507
}
508
509
#[allow(clippy::needless_lifetimes)]
510
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap0<'a>> for Cmap0 {}
511
512
impl ReadArgs for Cmap0 {
513
    type Args = ();
514
}
515
516
impl<'a> FontRead<'a> for Cmap0 {
517
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
518
0
        <read_fonts::tables::cmap::Cmap0 as FontRead>::read(data).map(|x| x.to_owned_table())
519
0
    }
520
}
521
522
/// [cmap Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-2-high-byte-mapping-through-table): High-byte mapping through table
523
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
524
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
525
pub struct Cmap2 {
526
    /// This is the length in bytes of the subtable.
527
    pub length: u16,
528
    /// For requirements on use of the language field, see “Use of
529
    /// the language field in 'cmap' subtables” in this document.
530
    pub language: u16,
531
    /// Array that maps high bytes to subHeaders: value is subHeader
532
    /// index × 8.
533
    pub sub_header_keys: Vec<u16>,
534
}
535
536
impl Cmap2 {
537
    /// Construct a new `Cmap2`
538
0
    pub fn new(length: u16, language: u16, sub_header_keys: Vec<u16>) -> Self {
539
0
        Self {
540
0
            length,
541
0
            language,
542
0
            sub_header_keys,
543
0
        }
544
0
    }
545
}
546
547
impl FontWrite for Cmap2 {
548
    #[allow(clippy::unnecessary_cast)]
549
0
    fn write_into(&self, writer: &mut TableWriter) {
550
0
        (2 as u16).write_into(writer);
551
0
        self.length.write_into(writer);
552
0
        self.language.write_into(writer);
553
0
        self.sub_header_keys.write_into(writer);
554
0
    }
555
0
    fn table_type(&self) -> TableType {
556
0
        TableType::Named("Cmap2")
557
0
    }
558
}
559
560
impl Validate for Cmap2 {
561
0
    fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
562
}
563
564
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap2<'a>> for Cmap2 {
565
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap2<'a>, _: FontData) -> Self {
566
0
        let offset_data = obj.offset_data();
567
0
        Cmap2 {
568
0
            length: obj.length(),
569
0
            language: obj.language(),
570
0
            sub_header_keys: obj.sub_header_keys().to_owned_obj(offset_data),
571
0
        }
572
0
    }
573
}
574
575
#[allow(clippy::needless_lifetimes)]
576
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap2<'a>> for Cmap2 {}
577
578
impl ReadArgs for Cmap2 {
579
    type Args = ();
580
}
581
582
impl<'a> FontRead<'a> for Cmap2 {
583
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
584
0
        <read_fonts::tables::cmap::Cmap2 as FontRead>::read(data).map(|x| x.to_owned_table())
585
0
    }
586
}
587
588
/// Part of [Cmap2]
589
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
590
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
591
pub struct SubHeader {
592
    /// First valid low byte for this SubHeader.
593
    pub first_code: u16,
594
    /// Number of valid low bytes for this SubHeader.
595
    pub entry_count: u16,
596
    /// See text below.
597
    pub id_delta: i16,
598
    /// See text below.
599
    pub id_range_offset: u16,
600
}
601
602
impl SubHeader {
603
    /// Construct a new `SubHeader`
604
0
    pub fn new(first_code: u16, entry_count: u16, id_delta: i16, id_range_offset: u16) -> Self {
605
0
        Self {
606
0
            first_code,
607
0
            entry_count,
608
0
            id_delta,
609
0
            id_range_offset,
610
0
        }
611
0
    }
612
}
613
614
impl FontWrite for SubHeader {
615
0
    fn write_into(&self, writer: &mut TableWriter) {
616
0
        self.first_code.write_into(writer);
617
0
        self.entry_count.write_into(writer);
618
0
        self.id_delta.write_into(writer);
619
0
        self.id_range_offset.write_into(writer);
620
0
    }
621
0
    fn table_type(&self) -> TableType {
622
0
        TableType::Named("SubHeader")
623
0
    }
624
}
625
626
impl Validate for SubHeader {
627
0
    fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
628
}
629
630
impl FromObjRef<read_fonts::tables::cmap::SubHeader> for SubHeader {
631
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::SubHeader, _: FontData) -> Self {
632
0
        SubHeader {
633
0
            first_code: obj.first_code(),
634
0
            entry_count: obj.entry_count(),
635
0
            id_delta: obj.id_delta(),
636
0
            id_range_offset: obj.id_range_offset(),
637
0
        }
638
0
    }
639
}
640
641
/// [cmap Format 4](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-4-segment-mapping-to-delta-values): Segment mapping to delta values
642
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
643
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
644
pub struct Cmap4 {
645
    /// For requirements on use of the language field, see “Use of
646
    /// the language field in 'cmap' subtables” in this document.
647
    pub language: u16,
648
    /// End characterCode for each segment, last=0xFFFF.
649
    pub end_code: Vec<u16>,
650
    /// Start character code for each segment.
651
    pub start_code: Vec<u16>,
652
    /// Delta for all character codes in segment.
653
    pub id_delta: Vec<i16>,
654
    /// Offsets into glyphIdArray or 0
655
    pub id_range_offsets: Vec<u16>,
656
    /// Glyph index array (arbitrary length)
657
    pub glyph_id_array: Vec<u16>,
658
}
659
660
impl Cmap4 {
661
    /// Construct a new `Cmap4`
662
0
    pub fn new(
663
0
        language: u16,
664
0
        end_code: Vec<u16>,
665
0
        start_code: Vec<u16>,
666
0
        id_delta: Vec<i16>,
667
0
        id_range_offsets: Vec<u16>,
668
0
        glyph_id_array: Vec<u16>,
669
0
    ) -> Self {
670
0
        Self {
671
0
            language,
672
0
            end_code,
673
0
            start_code,
674
0
            id_delta,
675
0
            id_range_offsets,
676
0
            glyph_id_array,
677
0
        }
678
0
    }
679
}
680
681
impl FontWrite for Cmap4 {
682
    #[allow(clippy::unnecessary_cast)]
683
0
    fn write_into(&self, writer: &mut TableWriter) {
684
0
        (4 as u16).write_into(writer);
685
0
        (self.compute_length() as u16).write_into(writer);
686
0
        self.language.write_into(writer);
687
0
        (u16::try_from(2 * array_len(&self.end_code)).unwrap()).write_into(writer);
688
0
        (self.compute_search_range() as u16).write_into(writer);
689
0
        (self.compute_entry_selector() as u16).write_into(writer);
690
0
        (self.compute_range_shift() as u16).write_into(writer);
691
0
        self.end_code.write_into(writer);
692
0
        (0 as u16).write_into(writer);
693
0
        self.start_code.write_into(writer);
694
0
        self.id_delta.write_into(writer);
695
0
        self.id_range_offsets.write_into(writer);
696
0
        self.glyph_id_array.write_into(writer);
697
0
    }
698
0
    fn table_type(&self) -> TableType {
699
0
        TableType::Named("Cmap4")
700
0
    }
701
}
702
703
impl Validate for Cmap4 {
704
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
705
0
        ctx.in_table("Cmap4", |ctx| {
706
0
            self.check_length(ctx);
707
0
        })
708
0
    }
709
}
710
711
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap4<'a>> for Cmap4 {
712
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap4<'a>, _: FontData) -> Self {
713
0
        let offset_data = obj.offset_data();
714
0
        Cmap4 {
715
0
            language: obj.language(),
716
0
            end_code: obj.end_code().to_owned_obj(offset_data),
717
0
            start_code: obj.start_code().to_owned_obj(offset_data),
718
0
            id_delta: obj.id_delta().to_owned_obj(offset_data),
719
0
            id_range_offsets: obj.id_range_offsets().to_owned_obj(offset_data),
720
0
            glyph_id_array: obj.glyph_id_array().to_owned_obj(offset_data),
721
0
        }
722
0
    }
723
}
724
725
#[allow(clippy::needless_lifetimes)]
726
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap4<'a>> for Cmap4 {}
727
728
impl ReadArgs for Cmap4 {
729
    type Args = ();
730
}
731
732
impl<'a> FontRead<'a> for Cmap4 {
733
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
734
0
        <read_fonts::tables::cmap::Cmap4 as FontRead>::read(data).map(|x| x.to_owned_table())
735
0
    }
736
}
737
738
/// [cmap Format 6](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-6-trimmed-table-mapping): Trimmed table mapping
739
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
740
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
741
pub struct Cmap6 {
742
    /// This is the length in bytes of the subtable.
743
    pub length: u16,
744
    /// For requirements on use of the language field, see “Use of
745
    /// the language field in 'cmap' subtables” in this document.
746
    pub language: u16,
747
    /// First character code of subrange.
748
    pub first_code: u16,
749
    /// Number of character codes in subrange.
750
    pub entry_count: u16,
751
    /// Array of glyph index values for character codes in the range.
752
    pub glyph_id_array: Vec<u16>,
753
}
754
755
impl Cmap6 {
756
    /// Construct a new `Cmap6`
757
0
    pub fn new(
758
0
        length: u16,
759
0
        language: u16,
760
0
        first_code: u16,
761
0
        entry_count: u16,
762
0
        glyph_id_array: Vec<u16>,
763
0
    ) -> Self {
764
0
        Self {
765
0
            length,
766
0
            language,
767
0
            first_code,
768
0
            entry_count,
769
0
            glyph_id_array,
770
0
        }
771
0
    }
772
}
773
774
impl FontWrite for Cmap6 {
775
    #[allow(clippy::unnecessary_cast)]
776
0
    fn write_into(&self, writer: &mut TableWriter) {
777
0
        (6 as u16).write_into(writer);
778
0
        self.length.write_into(writer);
779
0
        self.language.write_into(writer);
780
0
        self.first_code.write_into(writer);
781
0
        self.entry_count.write_into(writer);
782
0
        self.glyph_id_array.write_into(writer);
783
0
    }
784
0
    fn table_type(&self) -> TableType {
785
0
        TableType::Named("Cmap6")
786
0
    }
787
}
788
789
impl Validate for Cmap6 {
790
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
791
0
        ctx.in_table("Cmap6", |ctx| {
792
0
            ctx.in_field("glyph_id_array", |ctx| {
793
0
                if self.glyph_id_array.len() > to_usize(u16::MAX) {
794
0
                    ctx.report("array exceeds max length");
795
0
                }
796
0
            });
797
0
        })
798
0
    }
799
}
800
801
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap6<'a>> for Cmap6 {
802
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap6<'a>, _: FontData) -> Self {
803
0
        let offset_data = obj.offset_data();
804
0
        Cmap6 {
805
0
            length: obj.length(),
806
0
            language: obj.language(),
807
0
            first_code: obj.first_code(),
808
0
            entry_count: obj.entry_count(),
809
0
            glyph_id_array: obj.glyph_id_array().to_owned_obj(offset_data),
810
0
        }
811
0
    }
812
}
813
814
#[allow(clippy::needless_lifetimes)]
815
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap6<'a>> for Cmap6 {}
816
817
impl ReadArgs for Cmap6 {
818
    type Args = ();
819
}
820
821
impl<'a> FontRead<'a> for Cmap6 {
822
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
823
0
        <read_fonts::tables::cmap::Cmap6 as FontRead>::read(data).map(|x| x.to_owned_table())
824
0
    }
825
}
826
827
/// [cmap Format 8](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-8-mixed-16-bit-and-32-bit-coverage): mixed 16-bit and 32-bit coverage
828
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
829
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
830
pub struct Cmap8 {
831
    /// Byte length of this subtable (including the header)
832
    pub length: u32,
833
    /// For requirements on use of the language field, see “Use of
834
    /// the language field in 'cmap' subtables” in this document.
835
    pub language: u32,
836
    /// Tightly packed array of bits (8K bytes total) indicating
837
    /// whether the particular 16-bit (index) value is the start of a
838
    /// 32-bit character code
839
    pub is32: Vec<u8>,
840
    /// Number of groupings which follow
841
    pub num_groups: u32,
842
    /// Array of SequentialMapGroup records.
843
    pub groups: Vec<SequentialMapGroup>,
844
}
845
846
impl Cmap8 {
847
    /// Construct a new `Cmap8`
848
0
    pub fn new(
849
0
        length: u32,
850
0
        language: u32,
851
0
        is32: Vec<u8>,
852
0
        num_groups: u32,
853
0
        groups: Vec<SequentialMapGroup>,
854
0
    ) -> Self {
855
0
        Self {
856
0
            length,
857
0
            language,
858
0
            is32,
859
0
            num_groups,
860
0
            groups,
861
0
        }
862
0
    }
863
}
864
865
impl FontWrite for Cmap8 {
866
    #[allow(clippy::unnecessary_cast)]
867
0
    fn write_into(&self, writer: &mut TableWriter) {
868
0
        (8 as u16).write_into(writer);
869
0
        (0 as u16).write_into(writer);
870
0
        self.length.write_into(writer);
871
0
        self.language.write_into(writer);
872
0
        self.is32.write_into(writer);
873
0
        self.num_groups.write_into(writer);
874
0
        self.groups.write_into(writer);
875
0
    }
876
0
    fn table_type(&self) -> TableType {
877
0
        TableType::Named("Cmap8")
878
0
    }
879
}
880
881
impl Validate for Cmap8 {
882
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
883
0
        ctx.in_table("Cmap8", |ctx| {
884
0
            ctx.in_field("groups", |ctx| {
885
0
                if self.groups.len() > to_usize(u32::MAX) {
886
0
                    ctx.report("array exceeds max length");
887
0
                }
888
0
                self.groups.validate_impl(ctx);
889
0
            });
890
0
        })
891
0
    }
892
}
893
894
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap8<'a>> for Cmap8 {
895
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap8<'a>, _: FontData) -> Self {
896
0
        let offset_data = obj.offset_data();
897
0
        Cmap8 {
898
0
            length: obj.length(),
899
0
            language: obj.language(),
900
0
            is32: obj.is32().to_owned_obj(offset_data),
901
0
            num_groups: obj.num_groups(),
902
0
            groups: obj.groups().to_owned_obj(offset_data),
903
0
        }
904
0
    }
905
}
906
907
#[allow(clippy::needless_lifetimes)]
908
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap8<'a>> for Cmap8 {}
909
910
impl ReadArgs for Cmap8 {
911
    type Args = ();
912
}
913
914
impl<'a> FontRead<'a> for Cmap8 {
915
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
916
0
        <read_fonts::tables::cmap::Cmap8 as FontRead>::read(data).map(|x| x.to_owned_table())
917
0
    }
918
}
919
920
/// Used in [Cmap8] and [Cmap12]
921
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
922
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
923
pub struct SequentialMapGroup {
924
    /// First character code in this group; note that if this group is
925
    /// for one or more 16-bit character codes (which is determined
926
    /// from the is32 array), this 32-bit value will have the high
927
    /// 16-bits set to zero
928
    pub start_char_code: u32,
929
    /// Last character code in this group; same condition as listed
930
    /// above for the startCharCode
931
    pub end_char_code: u32,
932
    /// Glyph index corresponding to the starting character code
933
    pub start_glyph_id: u32,
934
}
935
936
impl SequentialMapGroup {
937
    /// Construct a new `SequentialMapGroup`
938
0
    pub fn new(start_char_code: u32, end_char_code: u32, start_glyph_id: u32) -> Self {
939
0
        Self {
940
0
            start_char_code,
941
0
            end_char_code,
942
0
            start_glyph_id,
943
0
        }
944
0
    }
945
}
946
947
impl FontWrite for SequentialMapGroup {
948
0
    fn write_into(&self, writer: &mut TableWriter) {
949
0
        self.start_char_code.write_into(writer);
950
0
        self.end_char_code.write_into(writer);
951
0
        self.start_glyph_id.write_into(writer);
952
0
    }
953
0
    fn table_type(&self) -> TableType {
954
0
        TableType::Named("SequentialMapGroup")
955
0
    }
956
}
957
958
impl Validate for SequentialMapGroup {
959
0
    fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
960
}
961
962
impl FromObjRef<read_fonts::tables::cmap::SequentialMapGroup> for SequentialMapGroup {
963
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::SequentialMapGroup, _: FontData) -> Self {
964
0
        SequentialMapGroup {
965
0
            start_char_code: obj.start_char_code(),
966
0
            end_char_code: obj.end_char_code(),
967
0
            start_glyph_id: obj.start_glyph_id(),
968
0
        }
969
0
    }
970
}
971
972
/// [cmap Format 10](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-10-trimmed-array): Tr
973
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
974
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
975
pub struct Cmap10 {
976
    /// Byte length of this subtable (including the header)
977
    pub length: u32,
978
    /// For requirements on use of the language field, see “Use of
979
    /// the language field in 'cmap' subtables” in this document.
980
    pub language: u32,
981
    /// First character code covered
982
    pub start_char_code: u32,
983
    /// Array of glyph indices for the character codes covered
984
    pub glyph_id_array: Vec<u16>,
985
}
986
987
impl Cmap10 {
988
    /// Construct a new `Cmap10`
989
0
    pub fn new(length: u32, language: u32, start_char_code: u32, glyph_id_array: Vec<u16>) -> Self {
990
0
        Self {
991
0
            length,
992
0
            language,
993
0
            start_char_code,
994
0
            glyph_id_array,
995
0
        }
996
0
    }
997
}
998
999
impl FontWrite for Cmap10 {
1000
    #[allow(clippy::unnecessary_cast)]
1001
0
    fn write_into(&self, writer: &mut TableWriter) {
1002
0
        (10 as u16).write_into(writer);
1003
0
        (0 as u16).write_into(writer);
1004
0
        self.length.write_into(writer);
1005
0
        self.language.write_into(writer);
1006
0
        self.start_char_code.write_into(writer);
1007
0
        (u32::try_from(array_len(&self.glyph_id_array)).unwrap()).write_into(writer);
1008
0
        self.glyph_id_array.write_into(writer);
1009
0
    }
1010
0
    fn table_type(&self) -> TableType {
1011
0
        TableType::Named("Cmap10")
1012
0
    }
1013
}
1014
1015
impl Validate for Cmap10 {
1016
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
1017
0
        ctx.in_table("Cmap10", |ctx| {
1018
0
            ctx.in_field("glyph_id_array", |ctx| {
1019
0
                if self.glyph_id_array.len() > to_usize(u32::MAX) {
1020
0
                    ctx.report("array exceeds max length");
1021
0
                }
1022
0
            });
1023
0
        })
1024
0
    }
1025
}
1026
1027
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap10<'a>> for Cmap10 {
1028
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap10<'a>, _: FontData) -> Self {
1029
0
        let offset_data = obj.offset_data();
1030
0
        Cmap10 {
1031
0
            length: obj.length(),
1032
0
            language: obj.language(),
1033
0
            start_char_code: obj.start_char_code(),
1034
0
            glyph_id_array: obj.glyph_id_array().to_owned_obj(offset_data),
1035
0
        }
1036
0
    }
1037
}
1038
1039
#[allow(clippy::needless_lifetimes)]
1040
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap10<'a>> for Cmap10 {}
1041
1042
impl ReadArgs for Cmap10 {
1043
    type Args = ();
1044
}
1045
1046
impl<'a> FontRead<'a> for Cmap10 {
1047
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1048
0
        <read_fonts::tables::cmap::Cmap10 as FontRead>::read(data).map(|x| x.to_owned_table())
1049
0
    }
1050
}
1051
1052
/// [cmap Format 12](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-12-segmented-coverage): Segmented coverage
1053
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1054
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1055
pub struct Cmap12 {
1056
    /// For requirements on use of the language field, see “Use of
1057
    /// the language field in 'cmap' subtables” in this document.
1058
    pub language: u32,
1059
    /// Array of SequentialMapGroup records.
1060
    pub groups: Vec<SequentialMapGroup>,
1061
}
1062
1063
impl Cmap12 {
1064
    /// Construct a new `Cmap12`
1065
0
    pub fn new(language: u32, groups: Vec<SequentialMapGroup>) -> Self {
1066
0
        Self { language, groups }
1067
0
    }
1068
}
1069
1070
impl FontWrite for Cmap12 {
1071
    #[allow(clippy::unnecessary_cast)]
1072
0
    fn write_into(&self, writer: &mut TableWriter) {
1073
0
        (12 as u16).write_into(writer);
1074
0
        (0 as u16).write_into(writer);
1075
0
        (self.compute_length() as u32).write_into(writer);
1076
0
        self.language.write_into(writer);
1077
0
        (u32::try_from(array_len(&self.groups)).unwrap()).write_into(writer);
1078
0
        self.groups.write_into(writer);
1079
0
    }
1080
0
    fn table_type(&self) -> TableType {
1081
0
        TableType::Named("Cmap12")
1082
0
    }
1083
}
1084
1085
impl Validate for Cmap12 {
1086
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
1087
0
        ctx.in_table("Cmap12", |ctx| {
1088
0
            ctx.in_field("groups", |ctx| {
1089
0
                if self.groups.len() > to_usize(u32::MAX) {
1090
0
                    ctx.report("array exceeds max length");
1091
0
                }
1092
0
                self.groups.validate_impl(ctx);
1093
0
            });
1094
0
        })
1095
0
    }
1096
}
1097
1098
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap12<'a>> for Cmap12 {
1099
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap12<'a>, _: FontData) -> Self {
1100
0
        let offset_data = obj.offset_data();
1101
0
        Cmap12 {
1102
0
            language: obj.language(),
1103
0
            groups: obj.groups().to_owned_obj(offset_data),
1104
0
        }
1105
0
    }
1106
}
1107
1108
#[allow(clippy::needless_lifetimes)]
1109
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap12<'a>> for Cmap12 {}
1110
1111
impl ReadArgs for Cmap12 {
1112
    type Args = ();
1113
}
1114
1115
impl<'a> FontRead<'a> for Cmap12 {
1116
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1117
0
        <read_fonts::tables::cmap::Cmap12 as FontRead>::read(data).map(|x| x.to_owned_table())
1118
0
    }
1119
}
1120
1121
/// [cmap Format 13](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-13-many-to-one-range-mappings): Many-to-one range mappings
1122
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1123
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1124
pub struct Cmap13 {
1125
    /// Byte length of this subtable (including the header)
1126
    pub length: u32,
1127
    /// For requirements on use of the language field, see “Use of
1128
    /// the language field in 'cmap' subtables” in this document.
1129
    pub language: u32,
1130
    /// Number of groupings which follow
1131
    pub num_groups: u32,
1132
    /// Array of ConstantMapGroup records.
1133
    pub groups: Vec<ConstantMapGroup>,
1134
}
1135
1136
impl Cmap13 {
1137
    /// Construct a new `Cmap13`
1138
0
    pub fn new(length: u32, language: u32, num_groups: u32, groups: Vec<ConstantMapGroup>) -> Self {
1139
0
        Self {
1140
0
            length,
1141
0
            language,
1142
0
            num_groups,
1143
0
            groups,
1144
0
        }
1145
0
    }
1146
}
1147
1148
impl FontWrite for Cmap13 {
1149
    #[allow(clippy::unnecessary_cast)]
1150
0
    fn write_into(&self, writer: &mut TableWriter) {
1151
0
        (13 as u16).write_into(writer);
1152
0
        (0 as u16).write_into(writer);
1153
0
        self.length.write_into(writer);
1154
0
        self.language.write_into(writer);
1155
0
        self.num_groups.write_into(writer);
1156
0
        self.groups.write_into(writer);
1157
0
    }
1158
0
    fn table_type(&self) -> TableType {
1159
0
        TableType::Named("Cmap13")
1160
0
    }
1161
}
1162
1163
impl Validate for Cmap13 {
1164
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
1165
0
        ctx.in_table("Cmap13", |ctx| {
1166
0
            ctx.in_field("groups", |ctx| {
1167
0
                if self.groups.len() > to_usize(u32::MAX) {
1168
0
                    ctx.report("array exceeds max length");
1169
0
                }
1170
0
                self.groups.validate_impl(ctx);
1171
0
            });
1172
0
        })
1173
0
    }
1174
}
1175
1176
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap13<'a>> for Cmap13 {
1177
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap13<'a>, _: FontData) -> Self {
1178
0
        let offset_data = obj.offset_data();
1179
0
        Cmap13 {
1180
0
            length: obj.length(),
1181
0
            language: obj.language(),
1182
0
            num_groups: obj.num_groups(),
1183
0
            groups: obj.groups().to_owned_obj(offset_data),
1184
0
        }
1185
0
    }
1186
}
1187
1188
#[allow(clippy::needless_lifetimes)]
1189
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap13<'a>> for Cmap13 {}
1190
1191
impl ReadArgs for Cmap13 {
1192
    type Args = ();
1193
}
1194
1195
impl<'a> FontRead<'a> for Cmap13 {
1196
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1197
0
        <read_fonts::tables::cmap::Cmap13 as FontRead>::read(data).map(|x| x.to_owned_table())
1198
0
    }
1199
}
1200
1201
/// Part of [Cmap13]
1202
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1203
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1204
pub struct ConstantMapGroup {
1205
    /// First character code in this group
1206
    pub start_char_code: u32,
1207
    /// Last character code in this group
1208
    pub end_char_code: u32,
1209
    /// Glyph index to be used for all the characters in the group’s
1210
    /// range.
1211
    pub glyph_id: u32,
1212
}
1213
1214
impl ConstantMapGroup {
1215
    /// Construct a new `ConstantMapGroup`
1216
0
    pub fn new(start_char_code: u32, end_char_code: u32, glyph_id: u32) -> Self {
1217
0
        Self {
1218
0
            start_char_code,
1219
0
            end_char_code,
1220
0
            glyph_id,
1221
0
        }
1222
0
    }
1223
}
1224
1225
impl FontWrite for ConstantMapGroup {
1226
0
    fn write_into(&self, writer: &mut TableWriter) {
1227
0
        self.start_char_code.write_into(writer);
1228
0
        self.end_char_code.write_into(writer);
1229
0
        self.glyph_id.write_into(writer);
1230
0
    }
1231
0
    fn table_type(&self) -> TableType {
1232
0
        TableType::Named("ConstantMapGroup")
1233
0
    }
1234
}
1235
1236
impl Validate for ConstantMapGroup {
1237
0
    fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
1238
}
1239
1240
impl FromObjRef<read_fonts::tables::cmap::ConstantMapGroup> for ConstantMapGroup {
1241
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::ConstantMapGroup, _: FontData) -> Self {
1242
0
        ConstantMapGroup {
1243
0
            start_char_code: obj.start_char_code(),
1244
0
            end_char_code: obj.end_char_code(),
1245
0
            glyph_id: obj.glyph_id(),
1246
0
        }
1247
0
    }
1248
}
1249
1250
/// [cmap Format 14](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-14-unicode-variation-sequences): Unicode Variation Sequences
1251
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1252
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1253
pub struct Cmap14 {
1254
    /// Array of VariationSelector records.
1255
    pub var_selector: Vec<VariationSelector>,
1256
}
1257
1258
impl Cmap14 {
1259
    /// Construct a new `Cmap14`
1260
0
    pub fn new(var_selector: Vec<VariationSelector>) -> Self {
1261
0
        Self { var_selector }
1262
0
    }
1263
}
1264
1265
impl Validate for Cmap14 {
1266
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
1267
0
        ctx.in_table("Cmap14", |ctx| {
1268
0
            ctx.in_field("var_selector", |ctx| {
1269
0
                if self.var_selector.len() > to_usize(u32::MAX) {
1270
0
                    ctx.report("array exceeds max length");
1271
0
                }
1272
0
                self.var_selector.validate_impl(ctx);
1273
0
            });
1274
0
        })
1275
0
    }
1276
}
1277
1278
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap14<'a>> for Cmap14 {
1279
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap14<'a>, _: FontData) -> Self {
1280
0
        let offset_data = obj.offset_data();
1281
0
        Cmap14 {
1282
0
            var_selector: obj.var_selector().to_owned_obj(offset_data),
1283
0
        }
1284
0
    }
1285
}
1286
1287
#[allow(clippy::needless_lifetimes)]
1288
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap14<'a>> for Cmap14 {}
1289
1290
impl ReadArgs for Cmap14 {
1291
    type Args = ();
1292
}
1293
1294
impl<'a> FontRead<'a> for Cmap14 {
1295
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1296
0
        <read_fonts::tables::cmap::Cmap14 as FontRead>::read(data).map(|x| x.to_owned_table())
1297
0
    }
1298
}
1299
1300
/// Extended glyph repertoire UVS mapping (ISO/IEC 14496-22:2026, 5.1.2.5.11).
1301
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1302
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1303
pub struct Cmap15 {
1304
    pub var_selector: Vec<VariationSelector15>,
1305
}
1306
1307
impl Cmap15 {
1308
    /// Construct a new `Cmap15`
1309
0
    pub fn new(var_selector: Vec<VariationSelector15>) -> Self {
1310
0
        Self { var_selector }
1311
0
    }
1312
}
1313
1314
impl Validate for Cmap15 {
1315
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
1316
0
        ctx.in_table("Cmap15", |ctx| {
1317
0
            ctx.in_field("var_selector", |ctx| {
1318
0
                if self.var_selector.len() > to_usize(u32::MAX) {
1319
0
                    ctx.report("array exceeds max length");
1320
0
                }
1321
0
                self.var_selector.validate_impl(ctx);
1322
0
            });
1323
0
        })
1324
0
    }
1325
}
1326
1327
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap15<'a>> for Cmap15 {
1328
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap15<'a>, _: FontData) -> Self {
1329
0
        let offset_data = obj.offset_data();
1330
0
        Cmap15 {
1331
0
            var_selector: obj.var_selector().to_owned_obj(offset_data),
1332
0
        }
1333
0
    }
1334
}
1335
1336
#[allow(clippy::needless_lifetimes)]
1337
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap15<'a>> for Cmap15 {}
1338
1339
impl ReadArgs for Cmap15 {
1340
    type Args = ();
1341
}
1342
1343
impl<'a> FontRead<'a> for Cmap15 {
1344
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1345
0
        <read_fonts::tables::cmap::Cmap15 as FontRead>::read(data).map(|x| x.to_owned_table())
1346
0
    }
1347
}
1348
1349
/// Part of [Cmap15].
1350
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1351
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1352
pub struct VariationSelector15 {
1353
    pub var_selector: Uint24,
1354
    pub default_uvs: NullableOffsetMarker<DefaultUvs, WIDTH_32>,
1355
    pub non_default_uvs: NullableOffsetMarker<NonDefaultUvs24, WIDTH_32>,
1356
}
1357
1358
impl VariationSelector15 {
1359
    /// Construct a new `VariationSelector15`
1360
0
    pub fn new(
1361
0
        var_selector: Uint24,
1362
0
        default_uvs: Option<DefaultUvs>,
1363
0
        non_default_uvs: Option<NonDefaultUvs24>,
1364
0
    ) -> Self {
1365
0
        Self {
1366
0
            var_selector,
1367
0
            default_uvs: default_uvs.into(),
1368
0
            non_default_uvs: non_default_uvs.into(),
1369
0
        }
1370
0
    }
1371
}
1372
1373
impl FontWrite for VariationSelector15 {
1374
0
    fn write_into(&self, writer: &mut TableWriter) {
1375
0
        self.var_selector.write_into(writer);
1376
0
        self.default_uvs.write_into(writer);
1377
0
        self.non_default_uvs.write_into(writer);
1378
0
    }
1379
0
    fn table_type(&self) -> TableType {
1380
0
        TableType::Named("VariationSelector15")
1381
0
    }
1382
}
1383
1384
impl Validate for VariationSelector15 {
1385
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
1386
0
        ctx.in_table("VariationSelector15", |ctx| {
1387
0
            ctx.in_field("default_uvs", |ctx| {
1388
0
                self.default_uvs.validate_impl(ctx);
1389
0
            });
1390
0
            ctx.in_field("non_default_uvs", |ctx| {
1391
0
                self.non_default_uvs.validate_impl(ctx);
1392
0
            });
1393
0
        })
1394
0
    }
1395
}
1396
1397
impl FromObjRef<read_fonts::tables::cmap::VariationSelector15> for VariationSelector15 {
1398
0
    fn from_obj_ref(
1399
0
        obj: &read_fonts::tables::cmap::VariationSelector15,
1400
0
        offset_data: FontData,
1401
0
    ) -> Self {
1402
0
        VariationSelector15 {
1403
0
            var_selector: obj.var_selector(),
1404
0
            default_uvs: obj.default_uvs(offset_data).to_owned_table(),
1405
0
            non_default_uvs: obj.non_default_uvs(offset_data).to_owned_table(),
1406
0
        }
1407
0
    }
1408
}
1409
1410
/// Part of [Cmap14]
1411
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1412
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1413
pub struct VariationSelector {
1414
    /// Variation selector
1415
    pub var_selector: Uint24,
1416
    /// Offset from the start of the [`Cmap14`] subtable to Default UVS
1417
    /// Table. May be NULL.
1418
    pub default_uvs: NullableOffsetMarker<DefaultUvs, WIDTH_32>,
1419
    /// Offset from the start of the [`Cmap14`] subtable to Non-Default
1420
    /// UVS Table. May be NULL.
1421
    pub non_default_uvs: NullableOffsetMarker<NonDefaultUvs, WIDTH_32>,
1422
}
1423
1424
impl VariationSelector {
1425
    /// Construct a new `VariationSelector`
1426
0
    pub fn new(
1427
0
        var_selector: Uint24,
1428
0
        default_uvs: Option<DefaultUvs>,
1429
0
        non_default_uvs: Option<NonDefaultUvs>,
1430
0
    ) -> Self {
1431
0
        Self {
1432
0
            var_selector,
1433
0
            default_uvs: default_uvs.into(),
1434
0
            non_default_uvs: non_default_uvs.into(),
1435
0
        }
1436
0
    }
1437
}
1438
1439
impl FontWrite for VariationSelector {
1440
0
    fn write_into(&self, writer: &mut TableWriter) {
1441
0
        self.var_selector.write_into(writer);
1442
0
        self.default_uvs.write_into(writer);
1443
0
        self.non_default_uvs.write_into(writer);
1444
0
    }
1445
0
    fn table_type(&self) -> TableType {
1446
0
        TableType::Named("VariationSelector")
1447
0
    }
1448
}
1449
1450
impl Validate for VariationSelector {
1451
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
1452
0
        ctx.in_table("VariationSelector", |ctx| {
1453
0
            ctx.in_field("default_uvs", |ctx| {
1454
0
                self.default_uvs.validate_impl(ctx);
1455
0
            });
1456
0
            ctx.in_field("non_default_uvs", |ctx| {
1457
0
                self.non_default_uvs.validate_impl(ctx);
1458
0
            });
1459
0
        })
1460
0
    }
1461
}
1462
1463
impl FromObjRef<read_fonts::tables::cmap::VariationSelector> for VariationSelector {
1464
0
    fn from_obj_ref(
1465
0
        obj: &read_fonts::tables::cmap::VariationSelector,
1466
0
        offset_data: FontData,
1467
0
    ) -> Self {
1468
0
        VariationSelector {
1469
0
            var_selector: obj.var_selector(),
1470
0
            default_uvs: obj.default_uvs(offset_data).to_owned_table(),
1471
0
            non_default_uvs: obj.non_default_uvs(offset_data).to_owned_table(),
1472
0
        }
1473
0
    }
1474
}
1475
1476
/// [Default UVS table](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#default-uvs-table)
1477
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1478
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1479
pub struct DefaultUvs {
1480
    /// Number of Unicode character ranges.
1481
    pub num_unicode_value_ranges: u32,
1482
    /// Array of UnicodeRange records.
1483
    pub ranges: Vec<UnicodeRange>,
1484
}
1485
1486
impl DefaultUvs {
1487
    /// Construct a new `DefaultUvs`
1488
0
    pub fn new(num_unicode_value_ranges: u32, ranges: Vec<UnicodeRange>) -> Self {
1489
0
        Self {
1490
0
            num_unicode_value_ranges,
1491
0
            ranges,
1492
0
        }
1493
0
    }
1494
}
1495
1496
impl FontWrite for DefaultUvs {
1497
0
    fn write_into(&self, writer: &mut TableWriter) {
1498
0
        self.num_unicode_value_ranges.write_into(writer);
1499
0
        self.ranges.write_into(writer);
1500
0
    }
1501
0
    fn table_type(&self) -> TableType {
1502
0
        TableType::Named("DefaultUvs")
1503
0
    }
1504
}
1505
1506
impl Validate for DefaultUvs {
1507
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
1508
0
        ctx.in_table("DefaultUvs", |ctx| {
1509
0
            ctx.in_field("ranges", |ctx| {
1510
0
                if self.ranges.len() > to_usize(u32::MAX) {
1511
0
                    ctx.report("array exceeds max length");
1512
0
                }
1513
0
                self.ranges.validate_impl(ctx);
1514
0
            });
1515
0
        })
1516
0
    }
1517
}
1518
1519
impl<'a> FromObjRef<read_fonts::tables::cmap::DefaultUvs<'a>> for DefaultUvs {
1520
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::DefaultUvs<'a>, _: FontData) -> Self {
1521
0
        let offset_data = obj.offset_data();
1522
0
        DefaultUvs {
1523
0
            num_unicode_value_ranges: obj.num_unicode_value_ranges(),
1524
0
            ranges: obj.ranges().to_owned_obj(offset_data),
1525
0
        }
1526
0
    }
1527
}
1528
1529
#[allow(clippy::needless_lifetimes)]
1530
impl<'a> FromTableRef<read_fonts::tables::cmap::DefaultUvs<'a>> for DefaultUvs {}
1531
1532
impl ReadArgs for DefaultUvs {
1533
    type Args = ();
1534
}
1535
1536
impl<'a> FontRead<'a> for DefaultUvs {
1537
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1538
0
        <read_fonts::tables::cmap::DefaultUvs as FontRead>::read(data).map(|x| x.to_owned_table())
1539
0
    }
1540
}
1541
1542
/// [Non-Default UVS table](https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#non-default-uvs-table)
1543
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1544
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1545
pub struct NonDefaultUvs {
1546
    pub num_uvs_mappings: u32,
1547
    pub uvs_mapping: Vec<UvsMapping>,
1548
}
1549
1550
impl NonDefaultUvs {
1551
    /// Construct a new `NonDefaultUvs`
1552
0
    pub fn new(num_uvs_mappings: u32, uvs_mapping: Vec<UvsMapping>) -> Self {
1553
0
        Self {
1554
0
            num_uvs_mappings,
1555
0
            uvs_mapping,
1556
0
        }
1557
0
    }
1558
}
1559
1560
impl FontWrite for NonDefaultUvs {
1561
0
    fn write_into(&self, writer: &mut TableWriter) {
1562
0
        self.num_uvs_mappings.write_into(writer);
1563
0
        self.uvs_mapping.write_into(writer);
1564
0
    }
1565
0
    fn table_type(&self) -> TableType {
1566
0
        TableType::Named("NonDefaultUvs")
1567
0
    }
1568
}
1569
1570
impl Validate for NonDefaultUvs {
1571
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
1572
0
        ctx.in_table("NonDefaultUvs", |ctx| {
1573
0
            ctx.in_field("uvs_mapping", |ctx| {
1574
0
                if self.uvs_mapping.len() > to_usize(u32::MAX) {
1575
0
                    ctx.report("array exceeds max length");
1576
0
                }
1577
0
                self.uvs_mapping.validate_impl(ctx);
1578
0
            });
1579
0
        })
1580
0
    }
1581
}
1582
1583
impl<'a> FromObjRef<read_fonts::tables::cmap::NonDefaultUvs<'a>> for NonDefaultUvs {
1584
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::NonDefaultUvs<'a>, _: FontData) -> Self {
1585
0
        let offset_data = obj.offset_data();
1586
0
        NonDefaultUvs {
1587
0
            num_uvs_mappings: obj.num_uvs_mappings(),
1588
0
            uvs_mapping: obj.uvs_mapping().to_owned_obj(offset_data),
1589
0
        }
1590
0
    }
1591
}
1592
1593
#[allow(clippy::needless_lifetimes)]
1594
impl<'a> FromTableRef<read_fonts::tables::cmap::NonDefaultUvs<'a>> for NonDefaultUvs {}
1595
1596
impl ReadArgs for NonDefaultUvs {
1597
    type Args = ();
1598
}
1599
1600
impl<'a> FontRead<'a> for NonDefaultUvs {
1601
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1602
0
        <read_fonts::tables::cmap::NonDefaultUvs as FontRead>::read(data)
1603
0
            .map(|x| x.to_owned_table())
1604
0
    }
1605
}
1606
1607
/// Non-default UVS mappings with 24-bit glyph IDs, used by [Cmap15].
1608
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1609
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1610
pub struct NonDefaultUvs24 {
1611
    pub uvs_mapping: Vec<UvsMapping24>,
1612
}
1613
1614
impl NonDefaultUvs24 {
1615
    /// Construct a new `NonDefaultUvs24`
1616
0
    pub fn new(uvs_mapping: Vec<UvsMapping24>) -> Self {
1617
0
        Self { uvs_mapping }
1618
0
    }
1619
}
1620
1621
impl FontWrite for NonDefaultUvs24 {
1622
    #[allow(clippy::unnecessary_cast)]
1623
0
    fn write_into(&self, writer: &mut TableWriter) {
1624
0
        (u32::try_from(array_len(&self.uvs_mapping)).unwrap()).write_into(writer);
1625
0
        self.uvs_mapping.write_into(writer);
1626
0
    }
1627
0
    fn table_type(&self) -> TableType {
1628
0
        TableType::Named("NonDefaultUvs24")
1629
0
    }
1630
}
1631
1632
impl Validate for NonDefaultUvs24 {
1633
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
1634
0
        ctx.in_table("NonDefaultUvs24", |ctx| {
1635
0
            ctx.in_field("uvs_mapping", |ctx| {
1636
0
                if self.uvs_mapping.len() > to_usize(u32::MAX) {
1637
0
                    ctx.report("array exceeds max length");
1638
0
                }
1639
0
                self.uvs_mapping.validate_impl(ctx);
1640
0
            });
1641
0
        })
1642
0
    }
1643
}
1644
1645
impl<'a> FromObjRef<read_fonts::tables::cmap::NonDefaultUvs24<'a>> for NonDefaultUvs24 {
1646
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::NonDefaultUvs24<'a>, _: FontData) -> Self {
1647
0
        let offset_data = obj.offset_data();
1648
0
        NonDefaultUvs24 {
1649
0
            uvs_mapping: obj.uvs_mapping().to_owned_obj(offset_data),
1650
0
        }
1651
0
    }
1652
}
1653
1654
#[allow(clippy::needless_lifetimes)]
1655
impl<'a> FromTableRef<read_fonts::tables::cmap::NonDefaultUvs24<'a>> for NonDefaultUvs24 {}
1656
1657
impl ReadArgs for NonDefaultUvs24 {
1658
    type Args = ();
1659
}
1660
1661
impl<'a> FontRead<'a> for NonDefaultUvs24 {
1662
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1663
0
        <read_fonts::tables::cmap::NonDefaultUvs24 as FontRead>::read(data)
1664
0
            .map(|x| x.to_owned_table())
1665
0
    }
1666
}
1667
1668
/// UVSMapping24 record (ISO/IEC 14496-22:2026, 5.1.2.5.11).
1669
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1670
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1671
pub struct UvsMapping24 {
1672
    pub unicode_value: Uint24,
1673
    pub glyph_id: Uint24,
1674
}
1675
1676
impl UvsMapping24 {
1677
    /// Construct a new `UvsMapping24`
1678
0
    pub fn new(unicode_value: Uint24, glyph_id: Uint24) -> Self {
1679
0
        Self {
1680
0
            unicode_value,
1681
0
            glyph_id,
1682
0
        }
1683
0
    }
1684
}
1685
1686
impl FontWrite for UvsMapping24 {
1687
0
    fn write_into(&self, writer: &mut TableWriter) {
1688
0
        self.unicode_value.write_into(writer);
1689
0
        self.glyph_id.write_into(writer);
1690
0
    }
1691
0
    fn table_type(&self) -> TableType {
1692
0
        TableType::Named("UvsMapping24")
1693
0
    }
1694
}
1695
1696
impl Validate for UvsMapping24 {
1697
0
    fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
1698
}
1699
1700
impl FromObjRef<read_fonts::tables::cmap::UvsMapping24> for UvsMapping24 {
1701
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::UvsMapping24, _: FontData) -> Self {
1702
0
        UvsMapping24 {
1703
0
            unicode_value: obj.unicode_value(),
1704
0
            glyph_id: obj.glyph_id(),
1705
0
        }
1706
0
    }
1707
}
1708
1709
/// Part of [Cmap14]
1710
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1711
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1712
pub struct UvsMapping {
1713
    /// Base Unicode value of the UVS
1714
    pub unicode_value: Uint24,
1715
    /// Glyph ID of the UVS
1716
    pub glyph_id: u16,
1717
}
1718
1719
impl UvsMapping {
1720
    /// Construct a new `UvsMapping`
1721
0
    pub fn new(unicode_value: Uint24, glyph_id: u16) -> Self {
1722
0
        Self {
1723
0
            unicode_value,
1724
0
            glyph_id,
1725
0
        }
1726
0
    }
1727
}
1728
1729
impl FontWrite for UvsMapping {
1730
0
    fn write_into(&self, writer: &mut TableWriter) {
1731
0
        self.unicode_value.write_into(writer);
1732
0
        self.glyph_id.write_into(writer);
1733
0
    }
1734
0
    fn table_type(&self) -> TableType {
1735
0
        TableType::Named("UvsMapping")
1736
0
    }
1737
}
1738
1739
impl Validate for UvsMapping {
1740
0
    fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
1741
}
1742
1743
impl FromObjRef<read_fonts::tables::cmap::UvsMapping> for UvsMapping {
1744
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::UvsMapping, _: FontData) -> Self {
1745
0
        UvsMapping {
1746
0
            unicode_value: obj.unicode_value(),
1747
0
            glyph_id: obj.glyph_id(),
1748
0
        }
1749
0
    }
1750
}
1751
1752
/// Part of [Cmap14]
1753
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1754
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1755
pub struct UnicodeRange {
1756
    /// First value in this range
1757
    pub start_unicode_value: Uint24,
1758
    /// Number of additional values in this range
1759
    pub additional_count: u8,
1760
}
1761
1762
impl UnicodeRange {
1763
    /// Construct a new `UnicodeRange`
1764
0
    pub fn new(start_unicode_value: Uint24, additional_count: u8) -> Self {
1765
0
        Self {
1766
0
            start_unicode_value,
1767
0
            additional_count,
1768
0
        }
1769
0
    }
1770
}
1771
1772
impl FontWrite for UnicodeRange {
1773
0
    fn write_into(&self, writer: &mut TableWriter) {
1774
0
        self.start_unicode_value.write_into(writer);
1775
0
        self.additional_count.write_into(writer);
1776
0
    }
1777
0
    fn table_type(&self) -> TableType {
1778
0
        TableType::Named("UnicodeRange")
1779
0
    }
1780
}
1781
1782
impl Validate for UnicodeRange {
1783
0
    fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
1784
}
1785
1786
impl FromObjRef<read_fonts::tables::cmap::UnicodeRange> for UnicodeRange {
1787
0
    fn from_obj_ref(obj: &read_fonts::tables::cmap::UnicodeRange, _: FontData) -> Self {
1788
0
        UnicodeRange {
1789
0
            start_unicode_value: obj.start_unicode_value(),
1790
0
            additional_count: obj.additional_count(),
1791
0
        }
1792
0
    }
1793
}