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