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<'a> FontRead<'a> for Dsig<'a> {
24 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
25 #[allow(clippy::absurd_extreme_comparisons)]
26 if data.len() < Self::MIN_SIZE {
27 return Err(ReadError::OutOfBounds);
28 }
29 Ok(Self { data })
30 }
31}
32
33#[derive(Clone)]
35pub struct Dsig<'a> {
36 data: FontData<'a>,
37}
38
39#[allow(clippy::needless_lifetimes)]
40impl<'a> Dsig<'a> {
41 pub const MIN_SIZE: usize =
42 (u32::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + PermissionFlags::RAW_BYTE_LEN);
43 basic_table_impls!(impl_the_methods);
44
45 pub fn version(&self) -> u32 {
47 let range = self.version_byte_range();
48 self.data.read_at(range.start).ok().unwrap()
49 }
50
51 pub fn num_signatures(&self) -> u16 {
53 let range = self.num_signatures_byte_range();
54 self.data.read_at(range.start).ok().unwrap()
55 }
56
57 pub fn flags(&self) -> PermissionFlags {
59 let range = self.flags_byte_range();
60 self.data.read_at(range.start).ok().unwrap()
61 }
62
63 pub fn signature_records(&self) -> &'a [SignatureRecord] {
65 let range = self.signature_records_byte_range();
66 self.data.read_array(range).ok().unwrap_or_default()
67 }
68
69 pub fn version_byte_range(&self) -> Range<usize> {
70 let start = 0;
71 start..start + u32::RAW_BYTE_LEN
72 }
73
74 pub fn num_signatures_byte_range(&self) -> Range<usize> {
75 let start = self.version_byte_range().end;
76 start..start + u16::RAW_BYTE_LEN
77 }
78
79 pub fn flags_byte_range(&self) -> Range<usize> {
80 let start = self.num_signatures_byte_range().end;
81 start..start + PermissionFlags::RAW_BYTE_LEN
82 }
83
84 pub fn signature_records_byte_range(&self) -> Range<usize> {
85 let num_signatures = self.num_signatures();
86 let start = self.flags_byte_range().end;
87 start
88 ..start
89 + (transforms::to_usize(num_signatures))
90 .saturating_mul(SignatureRecord::RAW_BYTE_LEN)
91 }
92}
93
94const _: () = assert!(FontData::default_data_long_enough(Dsig::MIN_SIZE));
95
96impl Default for Dsig<'_> {
97 fn default() -> Self {
98 Self {
99 data: FontData::default_table_data(),
100 }
101 }
102}
103
104#[cfg(feature = "experimental_traverse")]
105impl<'a> SomeTable<'a> for Dsig<'a> {
106 fn type_name(&self) -> &str {
107 "Dsig"
108 }
109 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
110 match idx {
111 0usize => Some(Field::new("version", self.version())),
112 1usize => Some(Field::new("num_signatures", self.num_signatures())),
113 2usize => Some(Field::new("flags", self.flags())),
114 3usize => Some(Field::new(
115 "signature_records",
116 traversal::FieldType::array_of_records(
117 stringify!(SignatureRecord),
118 self.signature_records(),
119 self.offset_data(),
120 ),
121 )),
122 _ => None,
123 }
124 }
125}
126
127#[cfg(feature = "experimental_traverse")]
128#[allow(clippy::needless_lifetimes)]
129impl<'a> std::fmt::Debug for Dsig<'a> {
130 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
131 (self as &dyn SomeTable<'a>).fmt(f)
132 }
133}
134
135#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
137#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
138#[repr(transparent)]
139pub struct PermissionFlags {
140 bits: u16,
141}
142
143impl PermissionFlags {
144 pub const CANNOT_BE_RESIGNED: Self = Self {
146 bits: 0b0000_0000_0000_0001,
147 };
148}
149
150impl PermissionFlags {
151 #[inline]
153 pub const fn empty() -> Self {
154 Self { bits: 0 }
155 }
156
157 #[inline]
159 pub const fn all() -> Self {
160 Self {
161 bits: Self::CANNOT_BE_RESIGNED.bits,
162 }
163 }
164
165 #[inline]
167 pub const fn bits(&self) -> u16 {
168 self.bits
169 }
170
171 #[inline]
174 pub const fn from_bits(bits: u16) -> Option<Self> {
175 if (bits & !Self::all().bits()) == 0 {
176 Some(Self { bits })
177 } else {
178 None
179 }
180 }
181
182 #[inline]
185 pub const fn from_bits_truncate(bits: u16) -> Self {
186 Self {
187 bits: bits & Self::all().bits,
188 }
189 }
190
191 #[inline]
193 pub const fn is_empty(&self) -> bool {
194 self.bits() == Self::empty().bits()
195 }
196
197 #[inline]
199 pub const fn intersects(&self, other: Self) -> bool {
200 !(Self {
201 bits: self.bits & other.bits,
202 })
203 .is_empty()
204 }
205
206 #[inline]
208 pub const fn contains(&self, other: Self) -> bool {
209 (self.bits & other.bits) == other.bits
210 }
211
212 #[inline]
214 pub fn insert(&mut self, other: Self) {
215 self.bits |= other.bits;
216 }
217
218 #[inline]
220 pub fn remove(&mut self, other: Self) {
221 self.bits &= !other.bits;
222 }
223
224 #[inline]
226 pub fn toggle(&mut self, other: Self) {
227 self.bits ^= other.bits;
228 }
229
230 #[inline]
241 #[must_use]
242 pub const fn intersection(self, other: Self) -> Self {
243 Self {
244 bits: self.bits & other.bits,
245 }
246 }
247
248 #[inline]
259 #[must_use]
260 pub const fn union(self, other: Self) -> Self {
261 Self {
262 bits: self.bits | other.bits,
263 }
264 }
265
266 #[inline]
279 #[must_use]
280 pub const fn difference(self, other: Self) -> Self {
281 Self {
282 bits: self.bits & !other.bits,
283 }
284 }
285}
286
287impl std::ops::BitOr for PermissionFlags {
288 type Output = Self;
289
290 #[inline]
292 fn bitor(self, other: PermissionFlags) -> Self {
293 Self {
294 bits: self.bits | other.bits,
295 }
296 }
297}
298
299impl std::ops::BitOrAssign for PermissionFlags {
300 #[inline]
302 fn bitor_assign(&mut self, other: Self) {
303 self.bits |= other.bits;
304 }
305}
306
307impl std::ops::BitXor for PermissionFlags {
308 type Output = Self;
309
310 #[inline]
312 fn bitxor(self, other: Self) -> Self {
313 Self {
314 bits: self.bits ^ other.bits,
315 }
316 }
317}
318
319impl std::ops::BitXorAssign for PermissionFlags {
320 #[inline]
322 fn bitxor_assign(&mut self, other: Self) {
323 self.bits ^= other.bits;
324 }
325}
326
327impl std::ops::BitAnd for PermissionFlags {
328 type Output = Self;
329
330 #[inline]
332 fn bitand(self, other: Self) -> Self {
333 Self {
334 bits: self.bits & other.bits,
335 }
336 }
337}
338
339impl std::ops::BitAndAssign for PermissionFlags {
340 #[inline]
342 fn bitand_assign(&mut self, other: Self) {
343 self.bits &= other.bits;
344 }
345}
346
347impl std::ops::Sub for PermissionFlags {
348 type Output = Self;
349
350 #[inline]
352 fn sub(self, other: Self) -> Self {
353 Self {
354 bits: self.bits & !other.bits,
355 }
356 }
357}
358
359impl std::ops::SubAssign for PermissionFlags {
360 #[inline]
362 fn sub_assign(&mut self, other: Self) {
363 self.bits &= !other.bits;
364 }
365}
366
367impl std::ops::Not for PermissionFlags {
368 type Output = Self;
369
370 #[inline]
372 fn not(self) -> Self {
373 Self { bits: !self.bits } & Self::all()
374 }
375}
376
377impl std::fmt::Debug for PermissionFlags {
378 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
379 let members: &[(&str, Self)] = &[("CANNOT_BE_RESIGNED", Self::CANNOT_BE_RESIGNED)];
380 let mut first = true;
381 for (name, value) in members {
382 if self.contains(*value) {
383 if !first {
384 f.write_str(" | ")?;
385 }
386 first = false;
387 f.write_str(name)?;
388 }
389 }
390 if first {
391 f.write_str("(empty)")?;
392 }
393 Ok(())
394 }
395}
396
397impl std::fmt::Binary for PermissionFlags {
398 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
399 std::fmt::Binary::fmt(&self.bits, f)
400 }
401}
402
403impl std::fmt::Octal for PermissionFlags {
404 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
405 std::fmt::Octal::fmt(&self.bits, f)
406 }
407}
408
409impl std::fmt::LowerHex for PermissionFlags {
410 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
411 std::fmt::LowerHex::fmt(&self.bits, f)
412 }
413}
414
415impl std::fmt::UpperHex for PermissionFlags {
416 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
417 std::fmt::UpperHex::fmt(&self.bits, f)
418 }
419}
420
421impl font_types::Scalar for PermissionFlags {
422 type Raw = <u16 as font_types::Scalar>::Raw;
423 fn to_raw(self) -> Self::Raw {
424 self.bits().to_raw()
425 }
426 fn from_raw(raw: Self::Raw) -> Self {
427 let t = <u16>::from_raw(raw);
428 Self::from_bits_truncate(t)
429 }
430}
431
432#[cfg(feature = "experimental_traverse")]
433impl<'a> From<PermissionFlags> for FieldType<'a> {
434 fn from(src: PermissionFlags) -> FieldType<'a> {
435 src.bits().into()
436 }
437}
438
439#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
441#[repr(C)]
442#[repr(packed)]
443pub struct SignatureRecord {
444 pub format: BigEndian<u32>,
446 pub length: BigEndian<u32>,
448 pub signature_block_offset: BigEndian<Offset32>,
450}
451
452impl SignatureRecord {
453 pub fn format(&self) -> u32 {
455 self.format.get()
456 }
457
458 pub fn length(&self) -> u32 {
460 self.length.get()
461 }
462
463 pub fn signature_block_offset(&self) -> Offset32 {
465 self.signature_block_offset.get()
466 }
467}
468
469impl FixedSize for SignatureRecord {
470 const RAW_BYTE_LEN: usize = u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN;
471}
472
473#[cfg(feature = "experimental_traverse")]
474impl<'a> SomeRecord<'a> for SignatureRecord {
475 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
476 RecordResolver {
477 name: "SignatureRecord",
478 get_field: Box::new(move |idx, _data| match idx {
479 0usize => Some(Field::new("format", self.format())),
480 1usize => Some(Field::new("length", self.length())),
481 2usize => Some(Field::new(
482 "signature_block_offset",
483 FieldType::offset(self.signature_block_offset(), self.signature_block(_data)),
484 )),
485 _ => None,
486 }),
487 data,
488 }
489 }
490}
491
492impl<'a> MinByteRange<'a> for SignatureBlockFormat1<'a> {
493 fn min_byte_range(&self) -> Range<usize> {
494 0..self.signature_byte_range().end
495 }
496 fn min_table_bytes(&self) -> &'a [u8] {
497 let range = self.min_byte_range();
498 self.data.as_bytes().get(range).unwrap_or_default()
499 }
500}
501
502impl<'a> FontRead<'a> for SignatureBlockFormat1<'a> {
503 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
504 #[allow(clippy::absurd_extreme_comparisons)]
505 if data.len() < Self::MIN_SIZE {
506 return Err(ReadError::OutOfBounds);
507 }
508 Ok(Self { data })
509 }
510}
511
512#[derive(Clone)]
514pub struct SignatureBlockFormat1<'a> {
515 data: FontData<'a>,
516}
517
518#[allow(clippy::needless_lifetimes)]
519impl<'a> SignatureBlockFormat1<'a> {
520 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
521 basic_table_impls!(impl_the_methods);
522
523 pub fn signature_length(&self) -> u32 {
525 let range = self.signature_length_byte_range();
526 self.data.read_at(range.start).ok().unwrap()
527 }
528
529 pub fn signature(&self) -> &'a [u8] {
531 let range = self.signature_byte_range();
532 self.data.read_array(range).ok().unwrap_or_default()
533 }
534
535 pub fn _reserved1_byte_range(&self) -> Range<usize> {
536 let start = 0;
537 start..start + u16::RAW_BYTE_LEN
538 }
539
540 pub fn _reserved2_byte_range(&self) -> Range<usize> {
541 let start = self._reserved1_byte_range().end;
542 start..start + u16::RAW_BYTE_LEN
543 }
544
545 pub fn signature_length_byte_range(&self) -> Range<usize> {
546 let start = self._reserved2_byte_range().end;
547 start..start + u32::RAW_BYTE_LEN
548 }
549
550 pub fn signature_byte_range(&self) -> Range<usize> {
551 let signature_length = self.signature_length();
552 let start = self.signature_length_byte_range().end;
553 start..start + (transforms::to_usize(signature_length)).saturating_mul(u8::RAW_BYTE_LEN)
554 }
555}
556
557const _: () = assert!(FontData::default_data_long_enough(
558 SignatureBlockFormat1::MIN_SIZE
559));
560
561impl Default for SignatureBlockFormat1<'_> {
562 fn default() -> Self {
563 Self {
564 data: FontData::default_table_data(),
565 }
566 }
567}
568
569#[cfg(feature = "experimental_traverse")]
570impl<'a> SomeTable<'a> for SignatureBlockFormat1<'a> {
571 fn type_name(&self) -> &str {
572 "SignatureBlockFormat1"
573 }
574 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
575 match idx {
576 0usize => Some(Field::new("signature_length", self.signature_length())),
577 1usize => Some(Field::new("signature", self.signature())),
578 _ => None,
579 }
580 }
581}
582
583#[cfg(feature = "experimental_traverse")]
584#[allow(clippy::needless_lifetimes)]
585impl<'a> std::fmt::Debug for SignatureBlockFormat1<'a> {
586 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
587 (self as &dyn SomeTable<'a>).fmt(f)
588 }
589}