Coverage Report

Created: 2026-07-25 07:50

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