Skip to main content

read_fonts/generated/
generated_dsig.rs

1// THIS FILE IS AUTOGENERATED.
2// Any changes to this file will be overwritten.
3// For more information about how codegen works, see font-codegen/README.md
4
5#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8impl<'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
18impl TopLevelTable for Dsig<'_> {
19    /// `DSIG`
20    const TAG: Tag = Tag::new(b"DSIG");
21}
22
23impl ReadArgs for Dsig<'_> {
24    type Args = ();
25}
26
27impl<'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)]
39pub struct Dsig<'a> {
40    data: FontData<'a>,
41}
42
43#[allow(clippy::needless_lifetimes)]
44impl<'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
100const _: () = assert!(FontData::default_data_long_enough(Dsig::MIN_SIZE));
101
102impl Default for Dsig<'_> {
103    fn default() -> Self {
104        Self {
105            data: FontData::default_table_data(),
106        }
107    }
108}
109
110#[cfg(feature = "experimental_traverse")]
111impl<'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)]
135impl<'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)]
145pub struct PermissionFlags {
146    bits: u16,
147}
148
149impl PermissionFlags {
150    /// Bit 0: Cannot be resigned
151    pub const CANNOT_BE_RESIGNED: Self = Self {
152        bits: 0b0000_0000_0000_0001,
153    };
154}
155
156impl 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    pub const fn bits(&self) -> u16 {
174        self.bits
175    }
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
293impl 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
305impl 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
313impl 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
325impl 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
333impl 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
345impl 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
353impl 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
365impl 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
373impl 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
383impl 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
403impl 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
409impl 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
415impl 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
421impl 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
427impl 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")]
439impl<'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)]
449pub 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
458impl 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
475impl 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")]
480impl<'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
498impl<'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
508impl ReadArgs for SignatureBlockFormat1<'_> {
509    type Args = ();
510}
511
512impl<'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)]
524pub struct SignatureBlockFormat1<'a> {
525    data: FontData<'a>,
526}
527
528#[allow(clippy::needless_lifetimes)]
529impl<'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
571const _: () = assert!(FontData::default_data_long_enough(
572    SignatureBlockFormat1::MIN_SIZE
573));
574
575impl Default for SignatureBlockFormat1<'_> {
576    fn default() -> Self {
577        Self {
578            data: FontData::default_table_data(),
579        }
580    }
581}
582
583#[cfg(feature = "experimental_traverse")]
584impl<'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)]
599impl<'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}