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