1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8impl<'a> MinByteRange<'a> for Varc<'a> {
9 fn min_byte_range(&self) -> Range<usize> {
10 0..self.var_composite_glyphs_offset_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 Varc<'_> {
19 const TAG: Tag = Tag::new(b"VARC");
21}
22
23impl ReadArgs for Varc<'_> {
24 type Args = ();
25}
26
27impl<'a> FontRead<'a> for Varc<'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)]
41pub struct Varc<'a> {
42 data: FontData<'a>,
43}
44
45#[allow(clippy::needless_lifetimes)]
46impl<'a> Varc<'a> {
47 pub const MIN_SIZE: usize = (MajorMinor::RAW_BYTE_LEN
48 + Offset32::RAW_BYTE_LEN
49 + Offset32::RAW_BYTE_LEN
50 + Offset32::RAW_BYTE_LEN
51 + Offset32::RAW_BYTE_LEN
52 + Offset32::RAW_BYTE_LEN);
53 basic_table_impls!(impl_the_methods);
54
55 pub fn version(&self) -> MajorMinor {
57 let range = self.version_byte_range();
58 self.data.read_at(range.start).ok().unwrap()
59 }
60
61 pub fn coverage_offset(&self) -> Offset32 {
62 let range = self.coverage_offset_byte_range();
63 self.data.read_at(range.start).ok().unwrap()
64 }
65
66 pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
68 let data = self.data;
69 self.coverage_offset().resolve(data)
70 }
71
72 pub fn multi_var_store_offset(&self) -> Nullable<Offset32> {
73 let range = self.multi_var_store_offset_byte_range();
74 self.data.read_at(range.start).ok().unwrap()
75 }
76
77 pub fn multi_var_store(&self) -> Option<Result<MultiItemVariationStore<'a>, ReadError>> {
79 let data = self.data;
80 self.multi_var_store_offset().resolve(data)
81 }
82
83 pub fn condition_list_offset(&self) -> Nullable<Offset32> {
84 let range = self.condition_list_offset_byte_range();
85 self.data.read_at(range.start).ok().unwrap()
86 }
87
88 pub fn condition_list(&self) -> Option<Result<ConditionList<'a>, ReadError>> {
90 let data = self.data;
91 self.condition_list_offset().resolve(data)
92 }
93
94 pub fn axis_indices_list_offset(&self) -> Nullable<Offset32> {
95 let range = self.axis_indices_list_offset_byte_range();
96 self.data.read_at(range.start).ok().unwrap()
97 }
98
99 pub fn axis_indices_list(&self) -> Option<Result<Index2<'a>, ReadError>> {
101 let data = self.data;
102 self.axis_indices_list_offset().resolve(data)
103 }
104
105 pub fn var_composite_glyphs_offset(&self) -> Offset32 {
106 let range = self.var_composite_glyphs_offset_byte_range();
107 self.data.read_at(range.start).ok().unwrap()
108 }
109
110 pub fn var_composite_glyphs(&self) -> Result<Index2<'a>, ReadError> {
112 let data = self.data;
113 self.var_composite_glyphs_offset().resolve(data)
114 }
115
116 pub fn version_byte_range(&self) -> Range<usize> {
117 let start = 0;
118 let end = start + MajorMinor::RAW_BYTE_LEN;
119 start..end
120 }
121
122 pub fn coverage_offset_byte_range(&self) -> Range<usize> {
123 let start = self.version_byte_range().end;
124 let end = start + Offset32::RAW_BYTE_LEN;
125 start..end
126 }
127
128 pub fn multi_var_store_offset_byte_range(&self) -> Range<usize> {
129 let start = self.coverage_offset_byte_range().end;
130 let end = start + Offset32::RAW_BYTE_LEN;
131 start..end
132 }
133
134 pub fn condition_list_offset_byte_range(&self) -> Range<usize> {
135 let start = self.multi_var_store_offset_byte_range().end;
136 let end = start + Offset32::RAW_BYTE_LEN;
137 start..end
138 }
139
140 pub fn axis_indices_list_offset_byte_range(&self) -> Range<usize> {
141 let start = self.condition_list_offset_byte_range().end;
142 let end = start + Offset32::RAW_BYTE_LEN;
143 start..end
144 }
145
146 pub fn var_composite_glyphs_offset_byte_range(&self) -> Range<usize> {
147 let start = self.axis_indices_list_offset_byte_range().end;
148 let end = start + Offset32::RAW_BYTE_LEN;
149 start..end
150 }
151}
152
153const _: () = assert!(FontData::default_data_long_enough(Varc::MIN_SIZE));
154
155impl Default for Varc<'_> {
156 fn default() -> Self {
157 Self {
158 data: FontData::default_table_data(),
159 }
160 }
161}
162
163impl Format<u16> for MultiItemVariationStore<'_> {
164 const FORMAT: u16 = 1;
165}
166
167impl<'a> MinByteRange<'a> for MultiItemVariationStore<'a> {
168 fn min_byte_range(&self) -> Range<usize> {
169 0..self.variation_data_offsets_byte_range().end
170 }
171 fn min_table_bytes(&self) -> &'a [u8] {
172 let range = self.min_byte_range();
173 self.data.as_bytes().get(range).unwrap_or_default()
174 }
175}
176
177impl ReadArgs for MultiItemVariationStore<'_> {
178 type Args = ();
179}
180
181impl<'a> FontRead<'a> for MultiItemVariationStore<'a> {
182 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
183 #[allow(clippy::absurd_extreme_comparisons)]
184 if data.len() < Self::MIN_SIZE {
185 return Err(ReadError::OutOfBounds);
186 }
187 Ok(Self { data })
188 }
189}
190
191#[derive(Clone)]
194pub struct MultiItemVariationStore<'a> {
195 data: FontData<'a>,
196}
197
198#[allow(clippy::needless_lifetimes)]
199impl<'a> MultiItemVariationStore<'a> {
200 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
201 basic_table_impls!(impl_the_methods);
202
203 pub fn format(&self) -> u16 {
204 let range = self.format_byte_range();
205 self.data.read_at(range.start).ok().unwrap()
206 }
207
208 pub fn region_list_offset(&self) -> Offset32 {
209 let range = self.region_list_offset_byte_range();
210 self.data.read_at(range.start).ok().unwrap()
211 }
212
213 pub fn region_list(&self) -> Result<SparseVariationRegionList<'a>, ReadError> {
215 let data = self.data;
216 self.region_list_offset().resolve(data)
217 }
218
219 pub fn variation_data_count(&self) -> u16 {
220 let range = self.variation_data_count_byte_range();
221 self.data.read_at(range.start).ok().unwrap()
222 }
223
224 pub fn variation_data_offsets(&self) -> &'a [BigEndian<Offset32>] {
225 let range = self.variation_data_offsets_byte_range();
226 self.data.read_array(range).ok().unwrap_or_default()
227 }
228
229 pub fn variation_data(&self) -> ArrayOfOffsets<'a, MultiItemVariationData<'a>, Offset32> {
231 let data = self.data;
232 let offsets = self.variation_data_offsets();
233 ArrayOfOffsets::new(offsets, data, ())
234 }
235
236 pub fn format_byte_range(&self) -> Range<usize> {
237 let start = 0;
238 let end = start + u16::RAW_BYTE_LEN;
239 start..end
240 }
241
242 pub fn region_list_offset_byte_range(&self) -> Range<usize> {
243 let start = self.format_byte_range().end;
244 let end = start + Offset32::RAW_BYTE_LEN;
245 start..end
246 }
247
248 pub fn variation_data_count_byte_range(&self) -> Range<usize> {
249 let start = self.region_list_offset_byte_range().end;
250 let end = start + u16::RAW_BYTE_LEN;
251 start..end
252 }
253
254 pub fn variation_data_offsets_byte_range(&self) -> Range<usize> {
255 let variation_data_count = self.variation_data_count();
256 let start = self.variation_data_count_byte_range().end;
257 let end = start
258 + (transforms::to_usize(variation_data_count)).saturating_mul(Offset32::RAW_BYTE_LEN);
259 start..end
260 }
261}
262
263const _: () = assert!(FontData::default_data_long_enough(
264 MultiItemVariationStore::MIN_SIZE
265));
266
267impl Default for MultiItemVariationStore<'_> {
268 fn default() -> Self {
269 Self {
270 data: FontData::default_format_1_u16_table_data(),
271 }
272 }
273}
274
275impl<'a> MinByteRange<'a> for SparseVariationRegionList<'a> {
276 fn min_byte_range(&self) -> Range<usize> {
277 0..self.region_offsets_byte_range().end
278 }
279 fn min_table_bytes(&self) -> &'a [u8] {
280 let range = self.min_byte_range();
281 self.data.as_bytes().get(range).unwrap_or_default()
282 }
283}
284
285impl ReadArgs for SparseVariationRegionList<'_> {
286 type Args = ();
287}
288
289impl<'a> FontRead<'a> for SparseVariationRegionList<'a> {
290 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
291 #[allow(clippy::absurd_extreme_comparisons)]
292 if data.len() < Self::MIN_SIZE {
293 return Err(ReadError::OutOfBounds);
294 }
295 Ok(Self { data })
296 }
297}
298
299#[derive(Clone)]
300pub struct SparseVariationRegionList<'a> {
301 data: FontData<'a>,
302}
303
304#[allow(clippy::needless_lifetimes)]
305impl<'a> SparseVariationRegionList<'a> {
306 pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
307 basic_table_impls!(impl_the_methods);
308
309 pub fn region_count(&self) -> u16 {
310 let range = self.region_count_byte_range();
311 self.data.read_at(range.start).ok().unwrap()
312 }
313
314 pub fn region_offsets(&self) -> &'a [BigEndian<Offset32>] {
315 let range = self.region_offsets_byte_range();
316 self.data.read_array(range).ok().unwrap_or_default()
317 }
318
319 pub fn regions(&self) -> ArrayOfOffsets<'a, SparseVariationRegion<'a>, Offset32> {
321 let data = self.data;
322 let offsets = self.region_offsets();
323 ArrayOfOffsets::new(offsets, data, ())
324 }
325
326 pub fn region_count_byte_range(&self) -> Range<usize> {
327 let start = 0;
328 let end = start + u16::RAW_BYTE_LEN;
329 start..end
330 }
331
332 pub fn region_offsets_byte_range(&self) -> Range<usize> {
333 let region_count = self.region_count();
334 let start = self.region_count_byte_range().end;
335 let end =
336 start + (transforms::to_usize(region_count)).saturating_mul(Offset32::RAW_BYTE_LEN);
337 start..end
338 }
339}
340
341const _: () = assert!(FontData::default_data_long_enough(
342 SparseVariationRegionList::MIN_SIZE
343));
344
345impl Default for SparseVariationRegionList<'_> {
346 fn default() -> Self {
347 Self {
348 data: FontData::default_table_data(),
349 }
350 }
351}
352
353impl<'a> MinByteRange<'a> for SparseVariationRegion<'a> {
354 fn min_byte_range(&self) -> Range<usize> {
355 0..self.region_axes_byte_range().end
356 }
357 fn min_table_bytes(&self) -> &'a [u8] {
358 let range = self.min_byte_range();
359 self.data.as_bytes().get(range).unwrap_or_default()
360 }
361}
362
363impl ReadArgs for SparseVariationRegion<'_> {
364 type Args = ();
365}
366
367impl<'a> FontRead<'a> for SparseVariationRegion<'a> {
368 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
369 #[allow(clippy::absurd_extreme_comparisons)]
370 if data.len() < Self::MIN_SIZE {
371 return Err(ReadError::OutOfBounds);
372 }
373 Ok(Self { data })
374 }
375}
376
377#[derive(Clone)]
378pub struct SparseVariationRegion<'a> {
379 data: FontData<'a>,
380}
381
382#[allow(clippy::needless_lifetimes)]
383impl<'a> SparseVariationRegion<'a> {
384 pub const MIN_SIZE: usize = u16::RAW_BYTE_LEN;
385 basic_table_impls!(impl_the_methods);
386
387 pub fn region_axis_count(&self) -> u16 {
388 let range = self.region_axis_count_byte_range();
389 self.data.read_at(range.start).ok().unwrap()
390 }
391
392 pub fn region_axes(&self) -> &'a [SparseRegionAxisCoordinates] {
393 let range = self.region_axes_byte_range();
394 self.data.read_array(range).ok().unwrap_or_default()
395 }
396
397 pub fn region_axis_count_byte_range(&self) -> Range<usize> {
398 let start = 0;
399 let end = start + u16::RAW_BYTE_LEN;
400 start..end
401 }
402
403 pub fn region_axes_byte_range(&self) -> Range<usize> {
404 let region_axis_count = self.region_axis_count();
405 let start = self.region_axis_count_byte_range().end;
406 let end = start
407 + (transforms::to_usize(region_axis_count))
408 .saturating_mul(SparseRegionAxisCoordinates::RAW_BYTE_LEN);
409 start..end
410 }
411}
412
413const _: () = assert!(FontData::default_data_long_enough(
414 SparseVariationRegion::MIN_SIZE
415));
416
417impl Default for SparseVariationRegion<'_> {
418 fn default() -> Self {
419 Self {
420 data: FontData::default_table_data(),
421 }
422 }
423}
424
425#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
426#[repr(C)]
427#[repr(packed)]
428pub struct SparseRegionAxisCoordinates {
429 pub axis_index: BigEndian<u16>,
430 pub start: BigEndian<F2Dot14>,
431 pub peak: BigEndian<F2Dot14>,
432 pub end: BigEndian<F2Dot14>,
433}
434
435impl SparseRegionAxisCoordinates {
436 pub fn axis_index(&self) -> u16 {
437 self.axis_index.get()
438 }
439
440 pub fn start(&self) -> F2Dot14 {
441 self.start.get()
442 }
443
444 pub fn peak(&self) -> F2Dot14 {
445 self.peak.get()
446 }
447
448 pub fn end(&self) -> F2Dot14 {
449 self.end.get()
450 }
451}
452
453impl FixedSize for SparseRegionAxisCoordinates {
454 const RAW_BYTE_LEN: usize =
455 u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN;
456}
457
458impl Format<u8> for MultiItemVariationData<'_> {
459 const FORMAT: u8 = 1;
460}
461
462impl<'a> MinByteRange<'a> for MultiItemVariationData<'a> {
463 fn min_byte_range(&self) -> Range<usize> {
464 0..self.raw_delta_sets_byte_range().end
465 }
466 fn min_table_bytes(&self) -> &'a [u8] {
467 let range = self.min_byte_range();
468 self.data.as_bytes().get(range).unwrap_or_default()
469 }
470}
471
472impl ReadArgs for MultiItemVariationData<'_> {
473 type Args = ();
474}
475
476impl<'a> FontRead<'a> for MultiItemVariationData<'a> {
477 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
478 #[allow(clippy::absurd_extreme_comparisons)]
479 if data.len() < Self::MIN_SIZE {
480 return Err(ReadError::OutOfBounds);
481 }
482 Ok(Self { data })
483 }
484}
485
486#[derive(Clone)]
487pub struct MultiItemVariationData<'a> {
488 data: FontData<'a>,
489}
490
491#[allow(clippy::needless_lifetimes)]
492impl<'a> MultiItemVariationData<'a> {
493 pub const MIN_SIZE: usize = (u8::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
494 basic_table_impls!(impl_the_methods);
495
496 pub fn format(&self) -> u8 {
497 let range = self.format_byte_range();
498 self.data.read_at(range.start).ok().unwrap()
499 }
500
501 pub fn region_index_count(&self) -> u16 {
502 let range = self.region_index_count_byte_range();
503 self.data.read_at(range.start).ok().unwrap()
504 }
505
506 pub fn region_indices(&self) -> &'a [BigEndian<u16>] {
507 let range = self.region_indices_byte_range();
508 self.data.read_array(range).ok().unwrap_or_default()
509 }
510
511 pub fn raw_delta_sets(&self) -> &'a [u8] {
512 let range = self.raw_delta_sets_byte_range();
513 self.data.read_array(range).ok().unwrap_or_default()
514 }
515
516 pub fn format_byte_range(&self) -> Range<usize> {
517 let start = 0;
518 let end = start + u8::RAW_BYTE_LEN;
519 start..end
520 }
521
522 pub fn region_index_count_byte_range(&self) -> Range<usize> {
523 let start = self.format_byte_range().end;
524 let end = start + u16::RAW_BYTE_LEN;
525 start..end
526 }
527
528 pub fn region_indices_byte_range(&self) -> Range<usize> {
529 let region_index_count = self.region_index_count();
530 let start = self.region_index_count_byte_range().end;
531 let end =
532 start + (transforms::to_usize(region_index_count)).saturating_mul(u16::RAW_BYTE_LEN);
533 start..end
534 }
535
536 pub fn raw_delta_sets_byte_range(&self) -> Range<usize> {
537 let start = self.region_indices_byte_range().end;
538 let end =
539 start + self.data.len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
540 start..end
541 }
542}
543
544const _: () = assert!(FontData::default_data_long_enough(
545 MultiItemVariationData::MIN_SIZE
546));
547
548impl Default for MultiItemVariationData<'_> {
549 fn default() -> Self {
550 Self {
551 data: FontData::default_format_1_u8_table_data(),
552 }
553 }
554}
555
556impl<'a> MinByteRange<'a> for ConditionList<'a> {
557 fn min_byte_range(&self) -> Range<usize> {
558 0..self.condition_offsets_byte_range().end
559 }
560 fn min_table_bytes(&self) -> &'a [u8] {
561 let range = self.min_byte_range();
562 self.data.as_bytes().get(range).unwrap_or_default()
563 }
564}
565
566impl ReadArgs for ConditionList<'_> {
567 type Args = ();
568}
569
570impl<'a> FontRead<'a> for ConditionList<'a> {
571 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
572 #[allow(clippy::absurd_extreme_comparisons)]
573 if data.len() < Self::MIN_SIZE {
574 return Err(ReadError::OutOfBounds);
575 }
576 Ok(Self { data })
577 }
578}
579
580#[derive(Clone)]
581pub struct ConditionList<'a> {
582 data: FontData<'a>,
583}
584
585#[allow(clippy::needless_lifetimes)]
586impl<'a> ConditionList<'a> {
587 pub const MIN_SIZE: usize = u32::RAW_BYTE_LEN;
588 basic_table_impls!(impl_the_methods);
589
590 pub fn condition_count(&self) -> u32 {
591 let range = self.condition_count_byte_range();
592 self.data.read_at(range.start).ok().unwrap()
593 }
594
595 pub fn condition_offsets(&self) -> &'a [BigEndian<Offset32>] {
596 let range = self.condition_offsets_byte_range();
597 self.data.read_array(range).ok().unwrap_or_default()
598 }
599
600 pub fn conditions(&self) -> ArrayOfOffsets<'a, Condition<'a>, Offset32> {
602 let data = self.data;
603 let offsets = self.condition_offsets();
604 ArrayOfOffsets::new(offsets, data, ())
605 }
606
607 pub fn condition_count_byte_range(&self) -> Range<usize> {
608 let start = 0;
609 let end = start + u32::RAW_BYTE_LEN;
610 start..end
611 }
612
613 pub fn condition_offsets_byte_range(&self) -> Range<usize> {
614 let condition_count = self.condition_count();
615 let start = self.condition_count_byte_range().end;
616 let end =
617 start + (transforms::to_usize(condition_count)).saturating_mul(Offset32::RAW_BYTE_LEN);
618 start..end
619 }
620}
621
622const _: () = assert!(FontData::default_data_long_enough(ConditionList::MIN_SIZE));
623
624impl Default for ConditionList<'_> {
625 fn default() -> Self {
626 Self {
627 data: FontData::default_table_data(),
628 }
629 }
630}
631
632#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
636#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
637#[repr(transparent)]
638pub struct VarcFlags {
639 bits: u32,
640}
641
642impl VarcFlags {
643 pub const RESET_UNSPECIFIED_AXES: Self = Self {
644 bits: 0b0000_0000_0000_0001,
645 };
646
647 pub const HAVE_AXES: Self = Self {
648 bits: 0b0000_0000_0000_0010,
649 };
650
651 pub const AXIS_VALUES_HAVE_VARIATION: Self = Self {
652 bits: 0b0000_0000_0000_0100,
653 };
654
655 pub const TRANSFORM_HAS_VARIATION: Self = Self {
656 bits: 0b0000_0000_0000_1000,
657 };
658
659 pub const HAVE_TRANSLATE_X: Self = Self {
660 bits: 0b0000_0000_0001_0000,
661 };
662
663 pub const HAVE_TRANSLATE_Y: Self = Self {
664 bits: 0b0000_0000_0010_0000,
665 };
666
667 pub const HAVE_ROTATION: Self = Self {
668 bits: 0b0000_0000_0100_0000,
669 };
670
671 pub const HAVE_CONDITION: Self = Self {
672 bits: 0b0000_0000_1000_0000,
673 };
674
675 pub const HAVE_SCALE_X: Self = Self {
676 bits: 0b0000_0001_0000_0000,
677 };
678
679 pub const HAVE_SCALE_Y: Self = Self {
680 bits: 0b0000_0010_0000_0000,
681 };
682
683 pub const HAVE_TCENTER_X: Self = Self {
684 bits: 0b0000_0100_0000_0000,
685 };
686
687 pub const HAVE_TCENTER_Y: Self = Self {
688 bits: 0b0000_1000_0000_0000,
689 };
690
691 pub const GID_IS_24BIT: Self = Self {
692 bits: 0b0001_0000_0000_0000,
693 };
694
695 pub const HAVE_SKEW_X: Self = Self {
696 bits: 0b0010_0000_0000_0000,
697 };
698
699 pub const HAVE_SKEW_Y: Self = Self {
700 bits: 0b0100_0000_0000_0000,
701 };
702
703 pub const RESERVED_MASK: Self = Self { bits: 0xFFFF8000 };
704}
705
706impl VarcFlags {
707 #[inline]
709 pub const fn empty() -> Self {
710 Self { bits: 0 }
711 }
712
713 #[inline]
715 pub const fn all() -> Self {
716 Self {
717 bits: Self::RESET_UNSPECIFIED_AXES.bits
718 | Self::HAVE_AXES.bits
719 | Self::AXIS_VALUES_HAVE_VARIATION.bits
720 | Self::TRANSFORM_HAS_VARIATION.bits
721 | Self::HAVE_TRANSLATE_X.bits
722 | Self::HAVE_TRANSLATE_Y.bits
723 | Self::HAVE_ROTATION.bits
724 | Self::HAVE_CONDITION.bits
725 | Self::HAVE_SCALE_X.bits
726 | Self::HAVE_SCALE_Y.bits
727 | Self::HAVE_TCENTER_X.bits
728 | Self::HAVE_TCENTER_Y.bits
729 | Self::GID_IS_24BIT.bits
730 | Self::HAVE_SKEW_X.bits
731 | Self::HAVE_SKEW_Y.bits
732 | Self::RESERVED_MASK.bits,
733 }
734 }
735
736 #[inline]
738 pub const fn bits(&self) -> u32 {
739 self.bits
740 }
741
742 #[inline]
745 pub const fn from_bits(bits: u32) -> Option<Self> {
746 if (bits & !Self::all().bits()) == 0 {
747 Some(Self { bits })
748 } else {
749 None
750 }
751 }
752
753 #[inline]
756 pub const fn from_bits_truncate(bits: u32) -> Self {
757 Self {
758 bits: bits & Self::all().bits,
759 }
760 }
761
762 #[inline]
764 pub const fn is_empty(&self) -> bool {
765 self.bits() == Self::empty().bits()
766 }
767
768 #[inline]
770 pub const fn intersects(&self, other: Self) -> bool {
771 !(Self {
772 bits: self.bits & other.bits,
773 })
774 .is_empty()
775 }
776
777 #[inline]
779 pub const fn contains(&self, other: Self) -> bool {
780 (self.bits & other.bits) == other.bits
781 }
782
783 #[inline]
785 pub fn insert(&mut self, other: Self) {
786 self.bits |= other.bits;
787 }
788
789 #[inline]
791 pub fn remove(&mut self, other: Self) {
792 self.bits &= !other.bits;
793 }
794
795 #[inline]
797 pub fn toggle(&mut self, other: Self) {
798 self.bits ^= other.bits;
799 }
800
801 #[inline]
812 #[must_use]
813 pub const fn intersection(self, other: Self) -> Self {
814 Self {
815 bits: self.bits & other.bits,
816 }
817 }
818
819 #[inline]
830 #[must_use]
831 pub const fn union(self, other: Self) -> Self {
832 Self {
833 bits: self.bits | other.bits,
834 }
835 }
836
837 #[inline]
850 #[must_use]
851 pub const fn difference(self, other: Self) -> Self {
852 Self {
853 bits: self.bits & !other.bits,
854 }
855 }
856}
857
858impl std::ops::BitOr for VarcFlags {
859 type Output = Self;
860
861 #[inline]
863 fn bitor(self, other: VarcFlags) -> Self {
864 Self {
865 bits: self.bits | other.bits,
866 }
867 }
868}
869
870impl std::ops::BitOrAssign for VarcFlags {
871 #[inline]
873 fn bitor_assign(&mut self, other: Self) {
874 self.bits |= other.bits;
875 }
876}
877
878impl std::ops::BitXor for VarcFlags {
879 type Output = Self;
880
881 #[inline]
883 fn bitxor(self, other: Self) -> Self {
884 Self {
885 bits: self.bits ^ other.bits,
886 }
887 }
888}
889
890impl std::ops::BitXorAssign for VarcFlags {
891 #[inline]
893 fn bitxor_assign(&mut self, other: Self) {
894 self.bits ^= other.bits;
895 }
896}
897
898impl std::ops::BitAnd for VarcFlags {
899 type Output = Self;
900
901 #[inline]
903 fn bitand(self, other: Self) -> Self {
904 Self {
905 bits: self.bits & other.bits,
906 }
907 }
908}
909
910impl std::ops::BitAndAssign for VarcFlags {
911 #[inline]
913 fn bitand_assign(&mut self, other: Self) {
914 self.bits &= other.bits;
915 }
916}
917
918impl std::ops::Sub for VarcFlags {
919 type Output = Self;
920
921 #[inline]
923 fn sub(self, other: Self) -> Self {
924 Self {
925 bits: self.bits & !other.bits,
926 }
927 }
928}
929
930impl std::ops::SubAssign for VarcFlags {
931 #[inline]
933 fn sub_assign(&mut self, other: Self) {
934 self.bits &= !other.bits;
935 }
936}
937
938impl std::ops::Not for VarcFlags {
939 type Output = Self;
940
941 #[inline]
943 fn not(self) -> Self {
944 Self { bits: !self.bits } & Self::all()
945 }
946}
947
948impl std::fmt::Debug for VarcFlags {
949 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
950 let members: &[(&str, Self)] = &[
951 ("RESET_UNSPECIFIED_AXES", Self::RESET_UNSPECIFIED_AXES),
952 ("HAVE_AXES", Self::HAVE_AXES),
953 (
954 "AXIS_VALUES_HAVE_VARIATION",
955 Self::AXIS_VALUES_HAVE_VARIATION,
956 ),
957 ("TRANSFORM_HAS_VARIATION", Self::TRANSFORM_HAS_VARIATION),
958 ("HAVE_TRANSLATE_X", Self::HAVE_TRANSLATE_X),
959 ("HAVE_TRANSLATE_Y", Self::HAVE_TRANSLATE_Y),
960 ("HAVE_ROTATION", Self::HAVE_ROTATION),
961 ("HAVE_CONDITION", Self::HAVE_CONDITION),
962 ("HAVE_SCALE_X", Self::HAVE_SCALE_X),
963 ("HAVE_SCALE_Y", Self::HAVE_SCALE_Y),
964 ("HAVE_TCENTER_X", Self::HAVE_TCENTER_X),
965 ("HAVE_TCENTER_Y", Self::HAVE_TCENTER_Y),
966 ("GID_IS_24BIT", Self::GID_IS_24BIT),
967 ("HAVE_SKEW_X", Self::HAVE_SKEW_X),
968 ("HAVE_SKEW_Y", Self::HAVE_SKEW_Y),
969 ("RESERVED_MASK", Self::RESERVED_MASK),
970 ];
971 let mut first = true;
972 for (name, value) in members {
973 if self.contains(*value) {
974 if !first {
975 f.write_str(" | ")?;
976 }
977 first = false;
978 f.write_str(name)?;
979 }
980 }
981 if first {
982 f.write_str("(empty)")?;
983 }
984 Ok(())
985 }
986}
987
988impl std::fmt::Binary for VarcFlags {
989 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
990 std::fmt::Binary::fmt(&self.bits, f)
991 }
992}
993
994impl std::fmt::Octal for VarcFlags {
995 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
996 std::fmt::Octal::fmt(&self.bits, f)
997 }
998}
999
1000impl std::fmt::LowerHex for VarcFlags {
1001 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1002 std::fmt::LowerHex::fmt(&self.bits, f)
1003 }
1004}
1005
1006impl std::fmt::UpperHex for VarcFlags {
1007 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1008 std::fmt::UpperHex::fmt(&self.bits, f)
1009 }
1010}
1011
1012impl font_types::Scalar for VarcFlags {
1013 type Raw = <u32 as font_types::Scalar>::Raw;
1014 fn to_raw(self) -> Self::Raw {
1015 self.bits().to_raw()
1016 }
1017 fn from_raw(raw: Self::Raw) -> Self {
1018 let t = <u32>::from_raw(raw);
1019 Self::from_bits_truncate(t)
1020 }
1021}