Coverage Report

Created: 2026-02-14 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fontations/read-fonts/generated/generated_dsig.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
/// [DSIG (Digital Signature Table)](https://docs.microsoft.com/en-us/typography/opentype/spec/dsig#table-structure) table
9
#[derive(Debug, Clone, Copy)]
10
#[doc(hidden)]
11
pub struct DsigMarker {
12
    signature_records_byte_len: usize,
13
}
14
15
impl DsigMarker {
16
    pub fn version_byte_range(&self) -> Range<usize> {
17
        let start = 0;
18
        start..start + u32::RAW_BYTE_LEN
19
    }
20
21
    pub fn num_signatures_byte_range(&self) -> Range<usize> {
22
        let start = self.version_byte_range().end;
23
        start..start + u16::RAW_BYTE_LEN
24
    }
25
26
    pub fn flags_byte_range(&self) -> Range<usize> {
27
        let start = self.num_signatures_byte_range().end;
28
        start..start + PermissionFlags::RAW_BYTE_LEN
29
    }
30
31
    pub fn signature_records_byte_range(&self) -> Range<usize> {
32
        let start = self.flags_byte_range().end;
33
        start..start + self.signature_records_byte_len
34
    }
35
}
36
37
impl MinByteRange for DsigMarker {
38
    fn min_byte_range(&self) -> Range<usize> {
39
        0..self.signature_records_byte_range().end
40
    }
41
}
42
43
impl TopLevelTable for Dsig<'_> {
44
    /// `DSIG`
45
    const TAG: Tag = Tag::new(b"DSIG");
46
}
47
48
impl<'a> FontRead<'a> for Dsig<'a> {
49
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
50
        let mut cursor = data.cursor();
51
        cursor.advance::<u32>();
52
        let num_signatures: u16 = cursor.read()?;
53
        cursor.advance::<PermissionFlags>();
54
        let signature_records_byte_len = (num_signatures as usize)
55
            .checked_mul(SignatureRecord::RAW_BYTE_LEN)
56
            .ok_or(ReadError::OutOfBounds)?;
57
        cursor.advance_by(signature_records_byte_len);
58
        cursor.finish(DsigMarker {
59
            signature_records_byte_len,
60
        })
61
    }
62
}
63
64
/// [DSIG (Digital Signature Table)](https://docs.microsoft.com/en-us/typography/opentype/spec/dsig#table-structure) table
65
pub type Dsig<'a> = TableRef<'a, DsigMarker>;
66
67
#[allow(clippy::needless_lifetimes)]
68
impl<'a> Dsig<'a> {
69
    /// Version number of the DSIG table (0x00000001)
70
    pub fn version(&self) -> u32 {
71
        let range = self.shape.version_byte_range();
72
        self.data.read_at(range.start).unwrap()
73
    }
74
75
    /// Number of signatures in the table
76
    pub fn num_signatures(&self) -> u16 {
77
        let range = self.shape.num_signatures_byte_range();
78
        self.data.read_at(range.start).unwrap()
79
    }
80
81
    /// Permission flags
82
    pub fn flags(&self) -> PermissionFlags {
83
        let range = self.shape.flags_byte_range();
84
        self.data.read_at(range.start).unwrap()
85
    }
86
87
    /// Array of signature records
88
    pub fn signature_records(&self) -> &'a [SignatureRecord] {
89
        let range = self.shape.signature_records_byte_range();
90
        self.data.read_array(range).unwrap()
91
    }
92
}
93
94
#[cfg(feature = "experimental_traverse")]
95
impl<'a> SomeTable<'a> for Dsig<'a> {
96
    fn type_name(&self) -> &str {
97
        "Dsig"
98
    }
99
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
100
        match idx {
101
            0usize => Some(Field::new("version", self.version())),
102
            1usize => Some(Field::new("num_signatures", self.num_signatures())),
103
            2usize => Some(Field::new("flags", self.flags())),
104
            3usize => Some(Field::new(
105
                "signature_records",
106
                traversal::FieldType::array_of_records(
107
                    stringify!(SignatureRecord),
108
                    self.signature_records(),
109
                    self.offset_data(),
110
                ),
111
            )),
112
            _ => None,
113
        }
114
    }
115
}
116
117
#[cfg(feature = "experimental_traverse")]
118
#[allow(clippy::needless_lifetimes)]
119
impl<'a> std::fmt::Debug for Dsig<'a> {
120
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121
        (self as &dyn SomeTable<'a>).fmt(f)
122
    }
123
}
124
125
/// [Permission flags](https://learn.microsoft.com/en-us/typography/opentype/spec/dsig#table-structure)
126
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
127
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
128
#[repr(transparent)]
129
pub struct PermissionFlags {
130
    bits: u16,
131
}
132
133
impl PermissionFlags {
134
    /// Bit 0: Cannot be resigned
135
    pub const CANNOT_BE_RESIGNED: Self = Self {
136
        bits: 0b0000_0000_0000_0001,
137
    };
138
}
139
140
impl PermissionFlags {
141
    ///  Returns an empty set of flags.
142
    #[inline]
143
    pub const fn empty() -> Self {
144
        Self { bits: 0 }
145
    }
146
147
    /// Returns the set containing all flags.
148
    #[inline]
149
    pub const fn all() -> Self {
150
        Self {
151
            bits: Self::CANNOT_BE_RESIGNED.bits,
152
        }
153
    }
154
155
    /// Returns the raw value of the flags currently stored.
156
    #[inline]
157
0
    pub const fn bits(&self) -> u16 {
158
0
        self.bits
159
0
    }
160
161
    /// Convert from underlying bit representation, unless that
162
    /// representation contains bits that do not correspond to a flag.
163
    #[inline]
164
    pub const fn from_bits(bits: u16) -> Option<Self> {
165
        if (bits & !Self::all().bits()) == 0 {
166
            Some(Self { bits })
167
        } else {
168
            None
169
        }
170
    }
171
172
    /// Convert from underlying bit representation, dropping any bits
173
    /// that do not correspond to flags.
174
    #[inline]
175
    pub const fn from_bits_truncate(bits: u16) -> Self {
176
        Self {
177
            bits: bits & Self::all().bits,
178
        }
179
    }
180
181
    /// Returns `true` if no flags are currently stored.
182
    #[inline]
183
    pub const fn is_empty(&self) -> bool {
184
        self.bits() == Self::empty().bits()
185
    }
186
187
    /// Returns `true` if there are flags common to both `self` and `other`.
188
    #[inline]
189
    pub const fn intersects(&self, other: Self) -> bool {
190
        !(Self {
191
            bits: self.bits & other.bits,
192
        })
193
        .is_empty()
194
    }
195
196
    /// Returns `true` if all of the flags in `other` are contained within `self`.
197
    #[inline]
198
    pub const fn contains(&self, other: Self) -> bool {
199
        (self.bits & other.bits) == other.bits
200
    }
201
202
    /// Inserts the specified flags in-place.
203
    #[inline]
204
    pub fn insert(&mut self, other: Self) {
205
        self.bits |= other.bits;
206
    }
207
208
    /// Removes the specified flags in-place.
209
    #[inline]
210
    pub fn remove(&mut self, other: Self) {
211
        self.bits &= !other.bits;
212
    }
213
214
    /// Toggles the specified flags in-place.
215
    #[inline]
216
    pub fn toggle(&mut self, other: Self) {
217
        self.bits ^= other.bits;
218
    }
219
220
    /// Returns the intersection between the flags in `self` and
221
    /// `other`.
222
    ///
223
    /// Specifically, the returned set contains only the flags which are
224
    /// present in *both* `self` *and* `other`.
225
    ///
226
    /// This is equivalent to using the `&` operator (e.g.
227
    /// [`ops::BitAnd`]), as in `flags & other`.
228
    ///
229
    /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
230
    #[inline]
231
    #[must_use]
232
    pub const fn intersection(self, other: Self) -> Self {
233
        Self {
234
            bits: self.bits & other.bits,
235
        }
236
    }
237
238
    /// Returns the union of between the flags in `self` and `other`.
239
    ///
240
    /// Specifically, the returned set contains all flags which are
241
    /// present in *either* `self` *or* `other`, including any which are
242
    /// present in both.
243
    ///
244
    /// This is equivalent to using the `|` operator (e.g.
245
    /// [`ops::BitOr`]), as in `flags | other`.
246
    ///
247
    /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
248
    #[inline]
249
    #[must_use]
250
    pub const fn union(self, other: Self) -> Self {
251
        Self {
252
            bits: self.bits | other.bits,
253
        }
254
    }
255
256
    /// Returns the difference between the flags in `self` and `other`.
257
    ///
258
    /// Specifically, the returned set contains all flags present in
259
    /// `self`, except for the ones present in `other`.
260
    ///
261
    /// It is also conceptually equivalent to the "bit-clear" operation:
262
    /// `flags & !other` (and this syntax is also supported).
263
    ///
264
    /// This is equivalent to using the `-` operator (e.g.
265
    /// [`ops::Sub`]), as in `flags - other`.
266
    ///
267
    /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
268
    #[inline]
269
    #[must_use]
270
    pub const fn difference(self, other: Self) -> Self {
271
        Self {
272
            bits: self.bits & !other.bits,
273
        }
274
    }
275
}
276
277
impl std::ops::BitOr for PermissionFlags {
278
    type Output = Self;
279
280
    /// Returns the union of the two sets of flags.
281
    #[inline]
282
    fn bitor(self, other: PermissionFlags) -> Self {
283
        Self {
284
            bits: self.bits | other.bits,
285
        }
286
    }
287
}
288
289
impl std::ops::BitOrAssign for PermissionFlags {
290
    /// Adds the set of flags.
291
    #[inline]
292
    fn bitor_assign(&mut self, other: Self) {
293
        self.bits |= other.bits;
294
    }
295
}
296
297
impl std::ops::BitXor for PermissionFlags {
298
    type Output = Self;
299
300
    /// Returns the left flags, but with all the right flags toggled.
301
    #[inline]
302
    fn bitxor(self, other: Self) -> Self {
303
        Self {
304
            bits: self.bits ^ other.bits,
305
        }
306
    }
307
}
308
309
impl std::ops::BitXorAssign for PermissionFlags {
310
    /// Toggles the set of flags.
311
    #[inline]
312
    fn bitxor_assign(&mut self, other: Self) {
313
        self.bits ^= other.bits;
314
    }
315
}
316
317
impl std::ops::BitAnd for PermissionFlags {
318
    type Output = Self;
319
320
    /// Returns the intersection between the two sets of flags.
321
    #[inline]
322
    fn bitand(self, other: Self) -> Self {
323
        Self {
324
            bits: self.bits & other.bits,
325
        }
326
    }
327
}
328
329
impl std::ops::BitAndAssign for PermissionFlags {
330
    /// Disables all flags disabled in the set.
331
    #[inline]
332
    fn bitand_assign(&mut self, other: Self) {
333
        self.bits &= other.bits;
334
    }
335
}
336
337
impl std::ops::Sub for PermissionFlags {
338
    type Output = Self;
339
340
    /// Returns the set difference of the two sets of flags.
341
    #[inline]
342
    fn sub(self, other: Self) -> Self {
343
        Self {
344
            bits: self.bits & !other.bits,
345
        }
346
    }
347
}
348
349
impl std::ops::SubAssign for PermissionFlags {
350
    /// Disables all flags enabled in the set.
351
    #[inline]
352
    fn sub_assign(&mut self, other: Self) {
353
        self.bits &= !other.bits;
354
    }
355
}
356
357
impl std::ops::Not for PermissionFlags {
358
    type Output = Self;
359
360
    /// Returns the complement of this set of flags.
361
    #[inline]
362
    fn not(self) -> Self {
363
        Self { bits: !self.bits } & Self::all()
364
    }
365
}
366
367
impl std::fmt::Debug for PermissionFlags {
368
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
369
        let members: &[(&str, Self)] = &[("CANNOT_BE_RESIGNED", Self::CANNOT_BE_RESIGNED)];
370
        let mut first = true;
371
        for (name, value) in members {
372
            if self.contains(*value) {
373
                if !first {
374
                    f.write_str(" | ")?;
375
                }
376
                first = false;
377
                f.write_str(name)?;
378
            }
379
        }
380
        if first {
381
            f.write_str("(empty)")?;
382
        }
383
        Ok(())
384
    }
385
}
386
387
impl std::fmt::Binary for PermissionFlags {
388
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
389
        std::fmt::Binary::fmt(&self.bits, f)
390
    }
391
}
392
393
impl std::fmt::Octal for PermissionFlags {
394
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
395
        std::fmt::Octal::fmt(&self.bits, f)
396
    }
397
}
398
399
impl std::fmt::LowerHex for PermissionFlags {
400
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
401
        std::fmt::LowerHex::fmt(&self.bits, f)
402
    }
403
}
404
405
impl std::fmt::UpperHex for PermissionFlags {
406
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
407
        std::fmt::UpperHex::fmt(&self.bits, f)
408
    }
409
}
410
411
impl font_types::Scalar for PermissionFlags {
412
    type Raw = <u16 as font_types::Scalar>::Raw;
413
    fn to_raw(self) -> Self::Raw {
414
        self.bits().to_raw()
415
    }
416
    fn from_raw(raw: Self::Raw) -> Self {
417
        let t = <u16>::from_raw(raw);
418
        Self::from_bits_truncate(t)
419
    }
420
}
421
422
#[cfg(feature = "experimental_traverse")]
423
impl<'a> From<PermissionFlags> for FieldType<'a> {
424
    fn from(src: PermissionFlags) -> FieldType<'a> {
425
        src.bits().into()
426
    }
427
}
428
429
/// [Signature Record](https://learn.microsoft.com/en-us/typography/opentype/spec/dsig#table-structure)
430
#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
431
#[repr(C)]
432
#[repr(packed)]
433
pub struct SignatureRecord {
434
    /// Format of the signature
435
    pub format: BigEndian<u32>,
436
    /// Length of signature in bytes
437
    pub length: BigEndian<u32>,
438
    /// Offset to the signature block from the beginning of the table
439
    pub signature_block_offset: BigEndian<Offset32>,
440
}
441
442
impl SignatureRecord {
443
    /// Format of the signature
444
    pub fn format(&self) -> u32 {
445
        self.format.get()
446
    }
447
448
    /// Length of signature in bytes
449
    pub fn length(&self) -> u32 {
450
        self.length.get()
451
    }
452
453
    /// Offset to the signature block from the beginning of the table
454
    pub fn signature_block_offset(&self) -> Offset32 {
455
        self.signature_block_offset.get()
456
    }
457
}
458
459
impl FixedSize for SignatureRecord {
460
    const RAW_BYTE_LEN: usize = u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN;
461
}
462
463
#[cfg(feature = "experimental_traverse")]
464
impl<'a> SomeRecord<'a> for SignatureRecord {
465
    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
466
        RecordResolver {
467
            name: "SignatureRecord",
468
            get_field: Box::new(move |idx, _data| match idx {
469
                0usize => Some(Field::new("format", self.format())),
470
                1usize => Some(Field::new("length", self.length())),
471
                2usize => Some(Field::new(
472
                    "signature_block_offset",
473
                    FieldType::offset(self.signature_block_offset(), self.signature_block(_data)),
474
                )),
475
                _ => None,
476
            }),
477
            data,
478
        }
479
    }
480
}
481
482
/// [Signature Block Format 1](https://learn.microsoft.com/en-us/typography/opentype/spec/dsig#table-structure)
483
#[derive(Debug, Clone, Copy)]
484
#[doc(hidden)]
485
pub struct SignatureBlockFormat1Marker {
486
    signature_byte_len: usize,
487
}
488
489
impl SignatureBlockFormat1Marker {
490
    pub fn _reserved1_byte_range(&self) -> Range<usize> {
491
        let start = 0;
492
        start..start + u16::RAW_BYTE_LEN
493
    }
494
495
    pub fn _reserved2_byte_range(&self) -> Range<usize> {
496
        let start = self._reserved1_byte_range().end;
497
        start..start + u16::RAW_BYTE_LEN
498
    }
499
500
    pub fn signature_length_byte_range(&self) -> Range<usize> {
501
        let start = self._reserved2_byte_range().end;
502
        start..start + u32::RAW_BYTE_LEN
503
    }
504
505
    pub fn signature_byte_range(&self) -> Range<usize> {
506
        let start = self.signature_length_byte_range().end;
507
        start..start + self.signature_byte_len
508
    }
509
}
510
511
impl MinByteRange for SignatureBlockFormat1Marker {
512
    fn min_byte_range(&self) -> Range<usize> {
513
        0..self.signature_byte_range().end
514
    }
515
}
516
517
impl<'a> FontRead<'a> for SignatureBlockFormat1<'a> {
518
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
519
        let mut cursor = data.cursor();
520
        cursor.advance::<u16>();
521
        cursor.advance::<u16>();
522
        let signature_length: u32 = cursor.read()?;
523
        let signature_byte_len = (signature_length as usize)
524
            .checked_mul(u8::RAW_BYTE_LEN)
525
            .ok_or(ReadError::OutOfBounds)?;
526
        cursor.advance_by(signature_byte_len);
527
        cursor.finish(SignatureBlockFormat1Marker { signature_byte_len })
528
    }
529
}
530
531
/// [Signature Block Format 1](https://learn.microsoft.com/en-us/typography/opentype/spec/dsig#table-structure)
532
pub type SignatureBlockFormat1<'a> = TableRef<'a, SignatureBlockFormat1Marker>;
533
534
#[allow(clippy::needless_lifetimes)]
535
impl<'a> SignatureBlockFormat1<'a> {
536
    /// Length (in bytes) of the PKCS#7 packet in the signature field.
537
    pub fn signature_length(&self) -> u32 {
538
        let range = self.shape.signature_length_byte_range();
539
        self.data.read_at(range.start).unwrap()
540
    }
541
542
    /// PKCS#7 packet
543
    pub fn signature(&self) -> &'a [u8] {
544
        let range = self.shape.signature_byte_range();
545
        self.data.read_array(range).unwrap()
546
    }
547
}
548
549
#[cfg(feature = "experimental_traverse")]
550
impl<'a> SomeTable<'a> for SignatureBlockFormat1<'a> {
551
    fn type_name(&self) -> &str {
552
        "SignatureBlockFormat1"
553
    }
554
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
555
        match idx {
556
            0usize => Some(Field::new("signature_length", self.signature_length())),
557
            1usize => Some(Field::new("signature", self.signature())),
558
            _ => None,
559
        }
560
    }
561
}
562
563
#[cfg(feature = "experimental_traverse")]
564
#[allow(clippy::needless_lifetimes)]
565
impl<'a> std::fmt::Debug for SignatureBlockFormat1<'a> {
566
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
567
        (self as &dyn SomeTable<'a>).fmt(f)
568
    }
569
}