1#[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 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#[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 pub fn version(&self) -> u32 {
51 let range = self.version_byte_range();
52 self.data.read_at(range.start).ok().unwrap()
53 }
54
55 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 pub fn flags(&self) -> PermissionFlags {
63 let range = self.flags_byte_range();
64 self.data.read_at(range.start).ok().unwrap()
65 }
66
67 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#[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 pub const CANNOT_BE_RESIGNED: Self = Self {
152 bits: 0b0000_0000_0000_0001,
153 };
154}
155
156impl PermissionFlags {
157 #[inline]
159 pub const fn empty() -> Self {
160 Self { bits: 0 }
161 }
162
163 #[inline]
165 pub const fn all() -> Self {
166 Self {
167 bits: Self::CANNOT_BE_RESIGNED.bits,
168 }
169 }
170
171 #[inline]
173 pub const fn bits(&self) -> u16 {
174 self.bits
175 }
176
177 #[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 #[inline]
191 pub const fn from_bits_truncate(bits: u16) -> Self {
192 Self {
193 bits: bits & Self::all().bits,
194 }
195 }
196
197 #[inline]
199 pub const fn is_empty(&self) -> bool {
200 self.bits() == Self::empty().bits()
201 }
202
203 #[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 #[inline]
214 pub const fn contains(&self, other: Self) -> bool {
215 (self.bits & other.bits) == other.bits
216 }
217
218 #[inline]
220 pub fn insert(&mut self, other: Self) {
221 self.bits |= other.bits;
222 }
223
224 #[inline]
226 pub fn remove(&mut self, other: Self) {
227 self.bits &= !other.bits;
228 }
229
230 #[inline]
232 pub fn toggle(&mut self, other: Self) {
233 self.bits ^= other.bits;
234 }
235
236 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
447#[repr(C)]
448#[repr(packed)]
449pub struct SignatureRecord {
450 pub format: BigEndian<u32>,
452 pub length: BigEndian<u32>,
454 pub signature_block_offset: BigEndian<Offset32>,
456}
457
458impl SignatureRecord {
459 pub fn format(&self) -> u32 {
461 self.format.get()
462 }
463
464 pub fn length(&self) -> u32 {
466 self.length.get()
467 }
468
469 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#[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 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 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}