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