1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8#[derive(Debug, Clone, Copy)]
12#[doc(hidden)]
13pub struct VarcMarker {}
14
15impl VarcMarker {
16 pub fn version_byte_range(&self) -> Range<usize> {
17 let start = 0;
18 start..start + MajorMinor::RAW_BYTE_LEN
19 }
20
21 pub fn coverage_offset_byte_range(&self) -> Range<usize> {
22 let start = self.version_byte_range().end;
23 start..start + Offset32::RAW_BYTE_LEN
24 }
25
26 pub fn multi_var_store_offset_byte_range(&self) -> Range<usize> {
27 let start = self.coverage_offset_byte_range().end;
28 start..start + Offset32::RAW_BYTE_LEN
29 }
30
31 pub fn condition_list_offset_byte_range(&self) -> Range<usize> {
32 let start = self.multi_var_store_offset_byte_range().end;
33 start..start + Offset32::RAW_BYTE_LEN
34 }
35
36 pub fn axis_indices_list_offset_byte_range(&self) -> Range<usize> {
37 let start = self.condition_list_offset_byte_range().end;
38 start..start + Offset32::RAW_BYTE_LEN
39 }
40
41 pub fn var_composite_glyphs_offset_byte_range(&self) -> Range<usize> {
42 let start = self.axis_indices_list_offset_byte_range().end;
43 start..start + Offset32::RAW_BYTE_LEN
44 }
45}
46
47impl MinByteRange for VarcMarker {
48 fn min_byte_range(&self) -> Range<usize> {
49 0..self.var_composite_glyphs_offset_byte_range().end
50 }
51}
52
53impl TopLevelTable for Varc<'_> {
54 const TAG: Tag = Tag::new(b"VARC");
56}
57
58impl<'a> FontRead<'a> for Varc<'a> {
59 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
60 let mut cursor = data.cursor();
61 cursor.advance::<MajorMinor>();
62 cursor.advance::<Offset32>();
63 cursor.advance::<Offset32>();
64 cursor.advance::<Offset32>();
65 cursor.advance::<Offset32>();
66 cursor.advance::<Offset32>();
67 cursor.finish(VarcMarker {})
68 }
69}
70
71pub type Varc<'a> = TableRef<'a, VarcMarker>;
75
76#[allow(clippy::needless_lifetimes)]
77impl<'a> Varc<'a> {
78 pub fn version(&self) -> MajorMinor {
80 let range = self.shape.version_byte_range();
81 self.data.read_at(range.start).unwrap()
82 }
83
84 pub fn coverage_offset(&self) -> Offset32 {
85 let range = self.shape.coverage_offset_byte_range();
86 self.data.read_at(range.start).unwrap()
87 }
88
89 pub fn coverage(&self) -> Result<CoverageTable<'a>, ReadError> {
91 let data = self.data;
92 self.coverage_offset().resolve(data)
93 }
94
95 pub fn multi_var_store_offset(&self) -> Nullable<Offset32> {
96 let range = self.shape.multi_var_store_offset_byte_range();
97 self.data.read_at(range.start).unwrap()
98 }
99
100 pub fn multi_var_store(&self) -> Option<Result<MultiItemVariationStore<'a>, ReadError>> {
102 let data = self.data;
103 self.multi_var_store_offset().resolve(data)
104 }
105
106 pub fn condition_list_offset(&self) -> Nullable<Offset32> {
107 let range = self.shape.condition_list_offset_byte_range();
108 self.data.read_at(range.start).unwrap()
109 }
110
111 pub fn condition_list(&self) -> Option<Result<ConditionList<'a>, ReadError>> {
113 let data = self.data;
114 self.condition_list_offset().resolve(data)
115 }
116
117 pub fn axis_indices_list_offset(&self) -> Nullable<Offset32> {
118 let range = self.shape.axis_indices_list_offset_byte_range();
119 self.data.read_at(range.start).unwrap()
120 }
121
122 pub fn axis_indices_list(&self) -> Option<Result<Index2<'a>, ReadError>> {
124 let data = self.data;
125 self.axis_indices_list_offset().resolve(data)
126 }
127
128 pub fn var_composite_glyphs_offset(&self) -> Offset32 {
129 let range = self.shape.var_composite_glyphs_offset_byte_range();
130 self.data.read_at(range.start).unwrap()
131 }
132
133 pub fn var_composite_glyphs(&self) -> Result<Index2<'a>, ReadError> {
135 let data = self.data;
136 self.var_composite_glyphs_offset().resolve(data)
137 }
138}
139
140#[cfg(feature = "experimental_traverse")]
141impl<'a> SomeTable<'a> for Varc<'a> {
142 fn type_name(&self) -> &str {
143 "Varc"
144 }
145 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
146 match idx {
147 0usize => Some(Field::new("version", self.version())),
148 1usize => Some(Field::new(
149 "coverage_offset",
150 FieldType::offset(self.coverage_offset(), self.coverage()),
151 )),
152 2usize => Some(Field::new(
153 "multi_var_store_offset",
154 FieldType::offset(self.multi_var_store_offset(), self.multi_var_store()),
155 )),
156 3usize => Some(Field::new(
157 "condition_list_offset",
158 FieldType::offset(self.condition_list_offset(), self.condition_list()),
159 )),
160 4usize => Some(Field::new(
161 "axis_indices_list_offset",
162 FieldType::offset(self.axis_indices_list_offset(), self.axis_indices_list()),
163 )),
164 5usize => Some(Field::new(
165 "var_composite_glyphs_offset",
166 FieldType::offset(
167 self.var_composite_glyphs_offset(),
168 self.var_composite_glyphs(),
169 ),
170 )),
171 _ => None,
172 }
173 }
174}
175
176#[cfg(feature = "experimental_traverse")]
177#[allow(clippy::needless_lifetimes)]
178impl<'a> std::fmt::Debug for Varc<'a> {
179 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
180 (self as &dyn SomeTable<'a>).fmt(f)
181 }
182}
183
184impl Format<u16> for MultiItemVariationStoreMarker {
185 const FORMAT: u16 = 1;
186}
187
188#[derive(Debug, Clone, Copy)]
191#[doc(hidden)]
192pub struct MultiItemVariationStoreMarker {
193 variation_data_offsets_byte_len: usize,
194}
195
196impl MultiItemVariationStoreMarker {
197 pub fn format_byte_range(&self) -> Range<usize> {
198 let start = 0;
199 start..start + u16::RAW_BYTE_LEN
200 }
201
202 pub fn region_list_offset_byte_range(&self) -> Range<usize> {
203 let start = self.format_byte_range().end;
204 start..start + Offset32::RAW_BYTE_LEN
205 }
206
207 pub fn variation_data_count_byte_range(&self) -> Range<usize> {
208 let start = self.region_list_offset_byte_range().end;
209 start..start + u16::RAW_BYTE_LEN
210 }
211
212 pub fn variation_data_offsets_byte_range(&self) -> Range<usize> {
213 let start = self.variation_data_count_byte_range().end;
214 start..start + self.variation_data_offsets_byte_len
215 }
216}
217
218impl MinByteRange for MultiItemVariationStoreMarker {
219 fn min_byte_range(&self) -> Range<usize> {
220 0..self.variation_data_offsets_byte_range().end
221 }
222}
223
224impl<'a> FontRead<'a> for MultiItemVariationStore<'a> {
225 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
226 let mut cursor = data.cursor();
227 cursor.advance::<u16>();
228 cursor.advance::<Offset32>();
229 let variation_data_count: u16 = cursor.read()?;
230 let variation_data_offsets_byte_len = (variation_data_count as usize)
231 .checked_mul(Offset32::RAW_BYTE_LEN)
232 .ok_or(ReadError::OutOfBounds)?;
233 cursor.advance_by(variation_data_offsets_byte_len);
234 cursor.finish(MultiItemVariationStoreMarker {
235 variation_data_offsets_byte_len,
236 })
237 }
238}
239
240pub type MultiItemVariationStore<'a> = TableRef<'a, MultiItemVariationStoreMarker>;
243
244#[allow(clippy::needless_lifetimes)]
245impl<'a> MultiItemVariationStore<'a> {
246 pub fn format(&self) -> u16 {
247 let range = self.shape.format_byte_range();
248 self.data.read_at(range.start).unwrap()
249 }
250
251 pub fn region_list_offset(&self) -> Offset32 {
252 let range = self.shape.region_list_offset_byte_range();
253 self.data.read_at(range.start).unwrap()
254 }
255
256 pub fn region_list(&self) -> Result<SparseVariationRegionList<'a>, ReadError> {
258 let data = self.data;
259 self.region_list_offset().resolve(data)
260 }
261
262 pub fn variation_data_count(&self) -> u16 {
263 let range = self.shape.variation_data_count_byte_range();
264 self.data.read_at(range.start).unwrap()
265 }
266
267 pub fn variation_data_offsets(&self) -> &'a [BigEndian<Offset32>] {
268 let range = self.shape.variation_data_offsets_byte_range();
269 self.data.read_array(range).unwrap()
270 }
271
272 pub fn variation_data(&self) -> ArrayOfOffsets<'a, MultiItemVariationData<'a>, Offset32> {
274 let data = self.data;
275 let offsets = self.variation_data_offsets();
276 ArrayOfOffsets::new(offsets, data, ())
277 }
278}
279
280#[cfg(feature = "experimental_traverse")]
281impl<'a> SomeTable<'a> for MultiItemVariationStore<'a> {
282 fn type_name(&self) -> &str {
283 "MultiItemVariationStore"
284 }
285 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
286 match idx {
287 0usize => Some(Field::new("format", self.format())),
288 1usize => Some(Field::new(
289 "region_list_offset",
290 FieldType::offset(self.region_list_offset(), self.region_list()),
291 )),
292 2usize => Some(Field::new(
293 "variation_data_count",
294 self.variation_data_count(),
295 )),
296 3usize => Some({
297 let data = self.data;
298 Field::new(
299 "variation_data_offsets",
300 FieldType::array_of_offsets(
301 better_type_name::<MultiItemVariationData>(),
302 self.variation_data_offsets(),
303 move |off| {
304 let target = off.get().resolve::<MultiItemVariationData>(data);
305 FieldType::offset(off.get(), target)
306 },
307 ),
308 )
309 }),
310 _ => None,
311 }
312 }
313}
314
315#[cfg(feature = "experimental_traverse")]
316#[allow(clippy::needless_lifetimes)]
317impl<'a> std::fmt::Debug for MultiItemVariationStore<'a> {
318 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
319 (self as &dyn SomeTable<'a>).fmt(f)
320 }
321}
322
323#[derive(Debug, Clone, Copy)]
324#[doc(hidden)]
325pub struct SparseVariationRegionListMarker {
326 region_offsets_byte_len: usize,
327}
328
329impl SparseVariationRegionListMarker {
330 pub fn region_count_byte_range(&self) -> Range<usize> {
331 let start = 0;
332 start..start + u16::RAW_BYTE_LEN
333 }
334
335 pub fn region_offsets_byte_range(&self) -> Range<usize> {
336 let start = self.region_count_byte_range().end;
337 start..start + self.region_offsets_byte_len
338 }
339}
340
341impl MinByteRange for SparseVariationRegionListMarker {
342 fn min_byte_range(&self) -> Range<usize> {
343 0..self.region_offsets_byte_range().end
344 }
345}
346
347impl<'a> FontRead<'a> for SparseVariationRegionList<'a> {
348 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
349 let mut cursor = data.cursor();
350 let region_count: u16 = cursor.read()?;
351 let region_offsets_byte_len = (region_count as usize)
352 .checked_mul(Offset32::RAW_BYTE_LEN)
353 .ok_or(ReadError::OutOfBounds)?;
354 cursor.advance_by(region_offsets_byte_len);
355 cursor.finish(SparseVariationRegionListMarker {
356 region_offsets_byte_len,
357 })
358 }
359}
360
361pub type SparseVariationRegionList<'a> = TableRef<'a, SparseVariationRegionListMarker>;
362
363#[allow(clippy::needless_lifetimes)]
364impl<'a> SparseVariationRegionList<'a> {
365 pub fn region_count(&self) -> u16 {
366 let range = self.shape.region_count_byte_range();
367 self.data.read_at(range.start).unwrap()
368 }
369
370 pub fn region_offsets(&self) -> &'a [BigEndian<Offset32>] {
371 let range = self.shape.region_offsets_byte_range();
372 self.data.read_array(range).unwrap()
373 }
374
375 pub fn regions(&self) -> ArrayOfOffsets<'a, SparseVariationRegion<'a>, Offset32> {
377 let data = self.data;
378 let offsets = self.region_offsets();
379 ArrayOfOffsets::new(offsets, data, ())
380 }
381}
382
383#[cfg(feature = "experimental_traverse")]
384impl<'a> SomeTable<'a> for SparseVariationRegionList<'a> {
385 fn type_name(&self) -> &str {
386 "SparseVariationRegionList"
387 }
388 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
389 match idx {
390 0usize => Some(Field::new("region_count", self.region_count())),
391 1usize => Some({
392 let data = self.data;
393 Field::new(
394 "region_offsets",
395 FieldType::array_of_offsets(
396 better_type_name::<SparseVariationRegion>(),
397 self.region_offsets(),
398 move |off| {
399 let target = off.get().resolve::<SparseVariationRegion>(data);
400 FieldType::offset(off.get(), target)
401 },
402 ),
403 )
404 }),
405 _ => None,
406 }
407 }
408}
409
410#[cfg(feature = "experimental_traverse")]
411#[allow(clippy::needless_lifetimes)]
412impl<'a> std::fmt::Debug for SparseVariationRegionList<'a> {
413 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
414 (self as &dyn SomeTable<'a>).fmt(f)
415 }
416}
417
418#[derive(Debug, Clone, Copy)]
419#[doc(hidden)]
420pub struct SparseVariationRegionMarker {
421 region_axis_offsets_byte_len: usize,
422}
423
424impl SparseVariationRegionMarker {
425 pub fn region_axis_count_byte_range(&self) -> Range<usize> {
426 let start = 0;
427 start..start + u16::RAW_BYTE_LEN
428 }
429
430 pub fn region_axis_offsets_byte_range(&self) -> Range<usize> {
431 let start = self.region_axis_count_byte_range().end;
432 start..start + self.region_axis_offsets_byte_len
433 }
434}
435
436impl MinByteRange for SparseVariationRegionMarker {
437 fn min_byte_range(&self) -> Range<usize> {
438 0..self.region_axis_offsets_byte_range().end
439 }
440}
441
442impl<'a> FontRead<'a> for SparseVariationRegion<'a> {
443 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
444 let mut cursor = data.cursor();
445 let region_axis_count: u16 = cursor.read()?;
446 let region_axis_offsets_byte_len = (region_axis_count as usize)
447 .checked_mul(SparseRegionAxisCoordinates::RAW_BYTE_LEN)
448 .ok_or(ReadError::OutOfBounds)?;
449 cursor.advance_by(region_axis_offsets_byte_len);
450 cursor.finish(SparseVariationRegionMarker {
451 region_axis_offsets_byte_len,
452 })
453 }
454}
455
456pub type SparseVariationRegion<'a> = TableRef<'a, SparseVariationRegionMarker>;
457
458#[allow(clippy::needless_lifetimes)]
459impl<'a> SparseVariationRegion<'a> {
460 pub fn region_axis_count(&self) -> u16 {
461 let range = self.shape.region_axis_count_byte_range();
462 self.data.read_at(range.start).unwrap()
463 }
464
465 pub fn region_axis_offsets(&self) -> &'a [SparseRegionAxisCoordinates] {
466 let range = self.shape.region_axis_offsets_byte_range();
467 self.data.read_array(range).unwrap()
468 }
469}
470
471#[cfg(feature = "experimental_traverse")]
472impl<'a> SomeTable<'a> for SparseVariationRegion<'a> {
473 fn type_name(&self) -> &str {
474 "SparseVariationRegion"
475 }
476 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
477 match idx {
478 0usize => Some(Field::new("region_axis_count", self.region_axis_count())),
479 1usize => Some(Field::new(
480 "region_axis_offsets",
481 traversal::FieldType::array_of_records(
482 stringify!(SparseRegionAxisCoordinates),
483 self.region_axis_offsets(),
484 self.offset_data(),
485 ),
486 )),
487 _ => None,
488 }
489 }
490}
491
492#[cfg(feature = "experimental_traverse")]
493#[allow(clippy::needless_lifetimes)]
494impl<'a> std::fmt::Debug for SparseVariationRegion<'a> {
495 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
496 (self as &dyn SomeTable<'a>).fmt(f)
497 }
498}
499
500#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
501#[repr(C)]
502#[repr(packed)]
503pub struct SparseRegionAxisCoordinates {
504 pub axis_index: BigEndian<u16>,
505 pub start: BigEndian<F2Dot14>,
506 pub peak: BigEndian<F2Dot14>,
507 pub end: BigEndian<F2Dot14>,
508}
509
510impl SparseRegionAxisCoordinates {
511 pub fn axis_index(&self) -> u16 {
512 self.axis_index.get()
513 }
514
515 pub fn start(&self) -> F2Dot14 {
516 self.start.get()
517 }
518
519 pub fn peak(&self) -> F2Dot14 {
520 self.peak.get()
521 }
522
523 pub fn end(&self) -> F2Dot14 {
524 self.end.get()
525 }
526}
527
528impl FixedSize for SparseRegionAxisCoordinates {
529 const RAW_BYTE_LEN: usize =
530 u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN;
531}
532
533#[cfg(feature = "experimental_traverse")]
534impl<'a> SomeRecord<'a> for SparseRegionAxisCoordinates {
535 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
536 RecordResolver {
537 name: "SparseRegionAxisCoordinates",
538 get_field: Box::new(move |idx, _data| match idx {
539 0usize => Some(Field::new("axis_index", self.axis_index())),
540 1usize => Some(Field::new("start", self.start())),
541 2usize => Some(Field::new("peak", self.peak())),
542 3usize => Some(Field::new("end", self.end())),
543 _ => None,
544 }),
545 data,
546 }
547 }
548}
549
550impl Format<u8> for MultiItemVariationDataMarker {
551 const FORMAT: u8 = 1;
552}
553
554#[derive(Debug, Clone, Copy)]
555#[doc(hidden)]
556pub struct MultiItemVariationDataMarker {
557 region_indices_byte_len: usize,
558 raw_delta_sets_byte_len: usize,
559}
560
561impl MultiItemVariationDataMarker {
562 pub fn format_byte_range(&self) -> Range<usize> {
563 let start = 0;
564 start..start + u8::RAW_BYTE_LEN
565 }
566
567 pub fn region_index_count_byte_range(&self) -> Range<usize> {
568 let start = self.format_byte_range().end;
569 start..start + u16::RAW_BYTE_LEN
570 }
571
572 pub fn region_indices_byte_range(&self) -> Range<usize> {
573 let start = self.region_index_count_byte_range().end;
574 start..start + self.region_indices_byte_len
575 }
576
577 pub fn raw_delta_sets_byte_range(&self) -> Range<usize> {
578 let start = self.region_indices_byte_range().end;
579 start..start + self.raw_delta_sets_byte_len
580 }
581}
582
583impl MinByteRange for MultiItemVariationDataMarker {
584 fn min_byte_range(&self) -> Range<usize> {
585 0..self.raw_delta_sets_byte_range().end
586 }
587}
588
589impl<'a> FontRead<'a> for MultiItemVariationData<'a> {
590 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
591 let mut cursor = data.cursor();
592 cursor.advance::<u8>();
593 let region_index_count: u16 = cursor.read()?;
594 let region_indices_byte_len = (region_index_count as usize)
595 .checked_mul(u16::RAW_BYTE_LEN)
596 .ok_or(ReadError::OutOfBounds)?;
597 cursor.advance_by(region_indices_byte_len);
598 let raw_delta_sets_byte_len =
599 cursor.remaining_bytes() / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN;
600 cursor.advance_by(raw_delta_sets_byte_len);
601 cursor.finish(MultiItemVariationDataMarker {
602 region_indices_byte_len,
603 raw_delta_sets_byte_len,
604 })
605 }
606}
607
608pub type MultiItemVariationData<'a> = TableRef<'a, MultiItemVariationDataMarker>;
609
610#[allow(clippy::needless_lifetimes)]
611impl<'a> MultiItemVariationData<'a> {
612 pub fn format(&self) -> u8 {
613 let range = self.shape.format_byte_range();
614 self.data.read_at(range.start).unwrap()
615 }
616
617 pub fn region_index_count(&self) -> u16 {
618 let range = self.shape.region_index_count_byte_range();
619 self.data.read_at(range.start).unwrap()
620 }
621
622 pub fn region_indices(&self) -> &'a [BigEndian<u16>] {
623 let range = self.shape.region_indices_byte_range();
624 self.data.read_array(range).unwrap()
625 }
626
627 pub fn raw_delta_sets(&self) -> &'a [u8] {
628 let range = self.shape.raw_delta_sets_byte_range();
629 self.data.read_array(range).unwrap()
630 }
631}
632
633#[cfg(feature = "experimental_traverse")]
634impl<'a> SomeTable<'a> for MultiItemVariationData<'a> {
635 fn type_name(&self) -> &str {
636 "MultiItemVariationData"
637 }
638 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
639 match idx {
640 0usize => Some(Field::new("format", self.format())),
641 1usize => Some(Field::new("region_index_count", self.region_index_count())),
642 2usize => Some(Field::new("region_indices", self.region_indices())),
643 3usize => Some(Field::new("raw_delta_sets", self.raw_delta_sets())),
644 _ => None,
645 }
646 }
647}
648
649#[cfg(feature = "experimental_traverse")]
650#[allow(clippy::needless_lifetimes)]
651impl<'a> std::fmt::Debug for MultiItemVariationData<'a> {
652 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
653 (self as &dyn SomeTable<'a>).fmt(f)
654 }
655}
656
657#[derive(Debug, Clone, Copy)]
658#[doc(hidden)]
659pub struct ConditionListMarker {
660 condition_offsets_byte_len: usize,
661}
662
663impl ConditionListMarker {
664 pub fn condition_count_byte_range(&self) -> Range<usize> {
665 let start = 0;
666 start..start + u32::RAW_BYTE_LEN
667 }
668
669 pub fn condition_offsets_byte_range(&self) -> Range<usize> {
670 let start = self.condition_count_byte_range().end;
671 start..start + self.condition_offsets_byte_len
672 }
673}
674
675impl MinByteRange for ConditionListMarker {
676 fn min_byte_range(&self) -> Range<usize> {
677 0..self.condition_offsets_byte_range().end
678 }
679}
680
681impl<'a> FontRead<'a> for ConditionList<'a> {
682 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
683 let mut cursor = data.cursor();
684 let condition_count: u32 = cursor.read()?;
685 let condition_offsets_byte_len = (condition_count as usize)
686 .checked_mul(Offset32::RAW_BYTE_LEN)
687 .ok_or(ReadError::OutOfBounds)?;
688 cursor.advance_by(condition_offsets_byte_len);
689 cursor.finish(ConditionListMarker {
690 condition_offsets_byte_len,
691 })
692 }
693}
694
695pub type ConditionList<'a> = TableRef<'a, ConditionListMarker>;
696
697#[allow(clippy::needless_lifetimes)]
698impl<'a> ConditionList<'a> {
699 pub fn condition_count(&self) -> u32 {
700 let range = self.shape.condition_count_byte_range();
701 self.data.read_at(range.start).unwrap()
702 }
703
704 pub fn condition_offsets(&self) -> &'a [BigEndian<Offset32>] {
705 let range = self.shape.condition_offsets_byte_range();
706 self.data.read_array(range).unwrap()
707 }
708
709 pub fn conditions(&self) -> ArrayOfOffsets<'a, Condition<'a>, Offset32> {
711 let data = self.data;
712 let offsets = self.condition_offsets();
713 ArrayOfOffsets::new(offsets, data, ())
714 }
715}
716
717#[cfg(feature = "experimental_traverse")]
718impl<'a> SomeTable<'a> for ConditionList<'a> {
719 fn type_name(&self) -> &str {
720 "ConditionList"
721 }
722 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
723 match idx {
724 0usize => Some(Field::new("condition_count", self.condition_count())),
725 1usize => Some({
726 let data = self.data;
727 Field::new(
728 "condition_offsets",
729 FieldType::array_of_offsets(
730 better_type_name::<Condition>(),
731 self.condition_offsets(),
732 move |off| {
733 let target = off.get().resolve::<Condition>(data);
734 FieldType::offset(off.get(), target)
735 },
736 ),
737 )
738 }),
739 _ => None,
740 }
741 }
742}
743
744#[cfg(feature = "experimental_traverse")]
745#[allow(clippy::needless_lifetimes)]
746impl<'a> std::fmt::Debug for ConditionList<'a> {
747 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
748 (self as &dyn SomeTable<'a>).fmt(f)
749 }
750}
751
752#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
756#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
757#[repr(transparent)]
758pub struct VarcFlags {
759 bits: u32,
760}
761
762impl VarcFlags {
763 pub const RESET_UNSPECIFIED_AXES: Self = Self {
764 bits: 0b0000_0000_0000_0001,
765 };
766
767 pub const HAVE_AXES: Self = Self {
768 bits: 0b0000_0000_0000_0010,
769 };
770
771 pub const AXIS_VALUES_HAVE_VARIATION: Self = Self {
772 bits: 0b0000_0000_0000_0100,
773 };
774
775 pub const TRANSFORM_HAS_VARIATION: Self = Self {
776 bits: 0b0000_0000_0000_1000,
777 };
778
779 pub const HAVE_TRANSLATE_X: Self = Self {
780 bits: 0b0000_0000_0001_0000,
781 };
782
783 pub const HAVE_TRANSLATE_Y: Self = Self {
784 bits: 0b0000_0000_0010_0000,
785 };
786
787 pub const HAVE_ROTATION: Self = Self {
788 bits: 0b0000_0000_0100_0000,
789 };
790
791 pub const HAVE_CONDITION: Self = Self {
792 bits: 0b0000_0000_1000_0000,
793 };
794
795 pub const HAVE_SCALE_X: Self = Self {
796 bits: 0b0000_0001_0000_0000,
797 };
798
799 pub const HAVE_SCALE_Y: Self = Self {
800 bits: 0b0000_0010_0000_0000,
801 };
802
803 pub const HAVE_TCENTER_X: Self = Self {
804 bits: 0b0000_0100_0000_0000,
805 };
806
807 pub const HAVE_TCENTER_Y: Self = Self {
808 bits: 0b0000_1000_0000_0000,
809 };
810
811 pub const GID_IS_24BIT: Self = Self {
812 bits: 0b0001_0000_0000_0000,
813 };
814
815 pub const HAVE_SKEW_X: Self = Self {
816 bits: 0b0010_0000_0000_0000,
817 };
818
819 pub const HAVE_SKEW_Y: Self = Self {
820 bits: 0b0100_0000_0000_0000,
821 };
822
823 pub const RESERVED_MASK: Self = Self { bits: 0xFFFF8000 };
824}
825
826impl VarcFlags {
827 #[inline]
829 pub const fn empty() -> Self {
830 Self { bits: 0 }
831 }
832
833 #[inline]
835 pub const fn all() -> Self {
836 Self {
837 bits: Self::RESET_UNSPECIFIED_AXES.bits
838 | Self::HAVE_AXES.bits
839 | Self::AXIS_VALUES_HAVE_VARIATION.bits
840 | Self::TRANSFORM_HAS_VARIATION.bits
841 | Self::HAVE_TRANSLATE_X.bits
842 | Self::HAVE_TRANSLATE_Y.bits
843 | Self::HAVE_ROTATION.bits
844 | Self::HAVE_CONDITION.bits
845 | Self::HAVE_SCALE_X.bits
846 | Self::HAVE_SCALE_Y.bits
847 | Self::HAVE_TCENTER_X.bits
848 | Self::HAVE_TCENTER_Y.bits
849 | Self::GID_IS_24BIT.bits
850 | Self::HAVE_SKEW_X.bits
851 | Self::HAVE_SKEW_Y.bits
852 | Self::RESERVED_MASK.bits,
853 }
854 }
855
856 #[inline]
858 pub const fn bits(&self) -> u32 {
859 self.bits
860 }
861
862 #[inline]
865 pub const fn from_bits(bits: u32) -> Option<Self> {
866 if (bits & !Self::all().bits()) == 0 {
867 Some(Self { bits })
868 } else {
869 None
870 }
871 }
872
873 #[inline]
876 pub const fn from_bits_truncate(bits: u32) -> Self {
877 Self {
878 bits: bits & Self::all().bits,
879 }
880 }
881
882 #[inline]
884 pub const fn is_empty(&self) -> bool {
885 self.bits() == Self::empty().bits()
886 }
887
888 #[inline]
890 pub const fn intersects(&self, other: Self) -> bool {
891 !(Self {
892 bits: self.bits & other.bits,
893 })
894 .is_empty()
895 }
896
897 #[inline]
899 pub const fn contains(&self, other: Self) -> bool {
900 (self.bits & other.bits) == other.bits
901 }
902
903 #[inline]
905 pub fn insert(&mut self, other: Self) {
906 self.bits |= other.bits;
907 }
908
909 #[inline]
911 pub fn remove(&mut self, other: Self) {
912 self.bits &= !other.bits;
913 }
914
915 #[inline]
917 pub fn toggle(&mut self, other: Self) {
918 self.bits ^= other.bits;
919 }
920
921 #[inline]
932 #[must_use]
933 pub const fn intersection(self, other: Self) -> Self {
934 Self {
935 bits: self.bits & other.bits,
936 }
937 }
938
939 #[inline]
950 #[must_use]
951 pub const fn union(self, other: Self) -> Self {
952 Self {
953 bits: self.bits | other.bits,
954 }
955 }
956
957 #[inline]
970 #[must_use]
971 pub const fn difference(self, other: Self) -> Self {
972 Self {
973 bits: self.bits & !other.bits,
974 }
975 }
976}
977
978impl std::ops::BitOr for VarcFlags {
979 type Output = Self;
980
981 #[inline]
983 fn bitor(self, other: VarcFlags) -> Self {
984 Self {
985 bits: self.bits | other.bits,
986 }
987 }
988}
989
990impl std::ops::BitOrAssign for VarcFlags {
991 #[inline]
993 fn bitor_assign(&mut self, other: Self) {
994 self.bits |= other.bits;
995 }
996}
997
998impl std::ops::BitXor for VarcFlags {
999 type Output = Self;
1000
1001 #[inline]
1003 fn bitxor(self, other: Self) -> Self {
1004 Self {
1005 bits: self.bits ^ other.bits,
1006 }
1007 }
1008}
1009
1010impl std::ops::BitXorAssign for VarcFlags {
1011 #[inline]
1013 fn bitxor_assign(&mut self, other: Self) {
1014 self.bits ^= other.bits;
1015 }
1016}
1017
1018impl std::ops::BitAnd for VarcFlags {
1019 type Output = Self;
1020
1021 #[inline]
1023 fn bitand(self, other: Self) -> Self {
1024 Self {
1025 bits: self.bits & other.bits,
1026 }
1027 }
1028}
1029
1030impl std::ops::BitAndAssign for VarcFlags {
1031 #[inline]
1033 fn bitand_assign(&mut self, other: Self) {
1034 self.bits &= other.bits;
1035 }
1036}
1037
1038impl std::ops::Sub for VarcFlags {
1039 type Output = Self;
1040
1041 #[inline]
1043 fn sub(self, other: Self) -> Self {
1044 Self {
1045 bits: self.bits & !other.bits,
1046 }
1047 }
1048}
1049
1050impl std::ops::SubAssign for VarcFlags {
1051 #[inline]
1053 fn sub_assign(&mut self, other: Self) {
1054 self.bits &= !other.bits;
1055 }
1056}
1057
1058impl std::ops::Not for VarcFlags {
1059 type Output = Self;
1060
1061 #[inline]
1063 fn not(self) -> Self {
1064 Self { bits: !self.bits } & Self::all()
1065 }
1066}
1067
1068impl std::fmt::Debug for VarcFlags {
1069 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1070 let members: &[(&str, Self)] = &[
1071 ("RESET_UNSPECIFIED_AXES", Self::RESET_UNSPECIFIED_AXES),
1072 ("HAVE_AXES", Self::HAVE_AXES),
1073 (
1074 "AXIS_VALUES_HAVE_VARIATION",
1075 Self::AXIS_VALUES_HAVE_VARIATION,
1076 ),
1077 ("TRANSFORM_HAS_VARIATION", Self::TRANSFORM_HAS_VARIATION),
1078 ("HAVE_TRANSLATE_X", Self::HAVE_TRANSLATE_X),
1079 ("HAVE_TRANSLATE_Y", Self::HAVE_TRANSLATE_Y),
1080 ("HAVE_ROTATION", Self::HAVE_ROTATION),
1081 ("HAVE_CONDITION", Self::HAVE_CONDITION),
1082 ("HAVE_SCALE_X", Self::HAVE_SCALE_X),
1083 ("HAVE_SCALE_Y", Self::HAVE_SCALE_Y),
1084 ("HAVE_TCENTER_X", Self::HAVE_TCENTER_X),
1085 ("HAVE_TCENTER_Y", Self::HAVE_TCENTER_Y),
1086 ("GID_IS_24BIT", Self::GID_IS_24BIT),
1087 ("HAVE_SKEW_X", Self::HAVE_SKEW_X),
1088 ("HAVE_SKEW_Y", Self::HAVE_SKEW_Y),
1089 ("RESERVED_MASK", Self::RESERVED_MASK),
1090 ];
1091 let mut first = true;
1092 for (name, value) in members {
1093 if self.contains(*value) {
1094 if !first {
1095 f.write_str(" | ")?;
1096 }
1097 first = false;
1098 f.write_str(name)?;
1099 }
1100 }
1101 if first {
1102 f.write_str("(empty)")?;
1103 }
1104 Ok(())
1105 }
1106}
1107
1108impl std::fmt::Binary for VarcFlags {
1109 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1110 std::fmt::Binary::fmt(&self.bits, f)
1111 }
1112}
1113
1114impl std::fmt::Octal for VarcFlags {
1115 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1116 std::fmt::Octal::fmt(&self.bits, f)
1117 }
1118}
1119
1120impl std::fmt::LowerHex for VarcFlags {
1121 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1122 std::fmt::LowerHex::fmt(&self.bits, f)
1123 }
1124}
1125
1126impl std::fmt::UpperHex for VarcFlags {
1127 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1128 std::fmt::UpperHex::fmt(&self.bits, f)
1129 }
1130}
1131
1132impl font_types::Scalar for VarcFlags {
1133 type Raw = <u32 as font_types::Scalar>::Raw;
1134 fn to_raw(self) -> Self::Raw {
1135 self.bits().to_raw()
1136 }
1137 fn from_raw(raw: Self::Raw) -> Self {
1138 let t = <u32>::from_raw(raw);
1139 Self::from_bits_truncate(t)
1140 }
1141}
1142
1143#[cfg(feature = "experimental_traverse")]
1144impl<'a> From<VarcFlags> for FieldType<'a> {
1145 fn from(src: VarcFlags) -> FieldType<'a> {
1146 src.bits().into()
1147 }
1148}