1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8impl<'a> MinByteRange<'a> for Gvar<'a> {
9 fn min_byte_range(&self) -> Range<usize> {
10 0..self.glyph_variation_data_offsets_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 Gvar<'_> {
19 const TAG: Tag = Tag::new(b"gvar");
21}
22
23impl ReadArgs for Gvar<'_> {
24 type Args = ();
25}
26
27impl<'a> FontRead<'a> for Gvar<'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)]
39pub struct Gvar<'a> {
40 data: FontData<'a>,
41}
42
43#[allow(clippy::needless_lifetimes)]
44impl<'a> Gvar<'a> {
45 pub const MIN_SIZE: usize = (MajorMinor::RAW_BYTE_LEN
46 + u16::RAW_BYTE_LEN
47 + u16::RAW_BYTE_LEN
48 + Offset32::RAW_BYTE_LEN
49 + u16::RAW_BYTE_LEN
50 + GvarFlags::RAW_BYTE_LEN
51 + u32::RAW_BYTE_LEN);
52 basic_table_impls!(impl_the_methods);
53
54 pub fn version(&self) -> MajorMinor {
56 let range = self.version_byte_range();
57 self.data.read_at(range.start).ok().unwrap()
58 }
59
60 pub fn axis_count(&self) -> u16 {
63 let range = self.axis_count_byte_range();
64 self.data.read_at(range.start).ok().unwrap()
65 }
66
67 pub fn shared_tuple_count(&self) -> u16 {
72 let range = self.shared_tuple_count_byte_range();
73 self.data.read_at(range.start).ok().unwrap()
74 }
75
76 pub fn glyph_count(&self) -> u16 {
79 let range = self.glyph_count_byte_range();
80 self.data.read_at(range.start).ok().unwrap()
81 }
82
83 pub fn flags(&self) -> GvarFlags {
87 let range = self.flags_byte_range();
88 self.data.read_at(range.start).ok().unwrap()
89 }
90
91 pub fn glyph_variation_data_array_offset(&self) -> u32 {
94 let range = self.glyph_variation_data_array_offset_byte_range();
95 self.data.read_at(range.start).ok().unwrap()
96 }
97
98 pub fn glyph_variation_data_offsets(&self) -> ComputedArray<'a, U16Or32> {
101 let range = self.glyph_variation_data_offsets_byte_range();
102 ComputedArray::new(self.data, range, self.flags()).unwrap_or_default()
103 }
104
105 pub fn version_byte_range(&self) -> Range<usize> {
106 let start = 0;
107 let end = start + MajorMinor::RAW_BYTE_LEN;
108 start..end
109 }
110
111 pub fn axis_count_byte_range(&self) -> Range<usize> {
112 let start = self.version_byte_range().end;
113 let end = start + u16::RAW_BYTE_LEN;
114 start..end
115 }
116
117 pub fn shared_tuple_count_byte_range(&self) -> Range<usize> {
118 let start = self.axis_count_byte_range().end;
119 let end = start + u16::RAW_BYTE_LEN;
120 start..end
121 }
122
123 pub fn shared_tuples_offset_byte_range(&self) -> Range<usize> {
124 let start = self.shared_tuple_count_byte_range().end;
125 let end = start + Offset32::RAW_BYTE_LEN;
126 start..end
127 }
128
129 pub fn glyph_count_byte_range(&self) -> Range<usize> {
130 let start = self.shared_tuples_offset_byte_range().end;
131 let end = start + u16::RAW_BYTE_LEN;
132 start..end
133 }
134
135 pub fn flags_byte_range(&self) -> Range<usize> {
136 let start = self.glyph_count_byte_range().end;
137 let end = start + GvarFlags::RAW_BYTE_LEN;
138 start..end
139 }
140
141 pub fn glyph_variation_data_array_offset_byte_range(&self) -> Range<usize> {
142 let start = self.flags_byte_range().end;
143 let end = start + u32::RAW_BYTE_LEN;
144 start..end
145 }
146
147 pub fn glyph_variation_data_offsets_byte_range(&self) -> Range<usize> {
148 let glyph_count = self.glyph_count();
149 let start = self.glyph_variation_data_array_offset_byte_range().end;
150 let end = start
151 + (transforms::add(glyph_count, 1_usize))
152 .saturating_mul(<U16Or32 as ComputeSize>::compute_size(self.flags()).unwrap_or(0));
153 start..end
154 }
155}
156
157const _: () = assert!(FontData::default_data_long_enough(Gvar::MIN_SIZE));
158
159impl Default for Gvar<'_> {
160 fn default() -> Self {
161 Self {
162 data: FontData::default_table_data(),
163 }
164 }
165}
166
167#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
168#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
169#[repr(transparent)]
170pub struct GvarFlags {
171 bits: u16,
172}
173
174impl GvarFlags {
175 pub const LONG_OFFSETS: Self = Self { bits: 1 };
177}
178
179impl GvarFlags {
180 #[inline]
182 pub const fn empty() -> Self {
183 Self { bits: 0 }
184 }
185
186 #[inline]
188 pub const fn all() -> Self {
189 Self {
190 bits: Self::LONG_OFFSETS.bits,
191 }
192 }
193
194 #[inline]
196 pub const fn bits(&self) -> u16 {
197 self.bits
198 }
199
200 #[inline]
203 pub const fn from_bits(bits: u16) -> Option<Self> {
204 if (bits & !Self::all().bits()) == 0 {
205 Some(Self { bits })
206 } else {
207 None
208 }
209 }
210
211 #[inline]
214 pub const fn from_bits_truncate(bits: u16) -> Self {
215 Self {
216 bits: bits & Self::all().bits,
217 }
218 }
219
220 #[inline]
222 pub const fn is_empty(&self) -> bool {
223 self.bits() == Self::empty().bits()
224 }
225
226 #[inline]
228 pub const fn intersects(&self, other: Self) -> bool {
229 !(Self {
230 bits: self.bits & other.bits,
231 })
232 .is_empty()
233 }
234
235 #[inline]
237 pub const fn contains(&self, other: Self) -> bool {
238 (self.bits & other.bits) == other.bits
239 }
240
241 #[inline]
243 pub fn insert(&mut self, other: Self) {
244 self.bits |= other.bits;
245 }
246
247 #[inline]
249 pub fn remove(&mut self, other: Self) {
250 self.bits &= !other.bits;
251 }
252
253 #[inline]
255 pub fn toggle(&mut self, other: Self) {
256 self.bits ^= other.bits;
257 }
258
259 #[inline]
270 #[must_use]
271 pub const fn intersection(self, other: Self) -> Self {
272 Self {
273 bits: self.bits & other.bits,
274 }
275 }
276
277 #[inline]
288 #[must_use]
289 pub const fn union(self, other: Self) -> Self {
290 Self {
291 bits: self.bits | other.bits,
292 }
293 }
294
295 #[inline]
308 #[must_use]
309 pub const fn difference(self, other: Self) -> Self {
310 Self {
311 bits: self.bits & !other.bits,
312 }
313 }
314}
315
316impl std::ops::BitOr for GvarFlags {
317 type Output = Self;
318
319 #[inline]
321 fn bitor(self, other: GvarFlags) -> Self {
322 Self {
323 bits: self.bits | other.bits,
324 }
325 }
326}
327
328impl std::ops::BitOrAssign for GvarFlags {
329 #[inline]
331 fn bitor_assign(&mut self, other: Self) {
332 self.bits |= other.bits;
333 }
334}
335
336impl std::ops::BitXor for GvarFlags {
337 type Output = Self;
338
339 #[inline]
341 fn bitxor(self, other: Self) -> Self {
342 Self {
343 bits: self.bits ^ other.bits,
344 }
345 }
346}
347
348impl std::ops::BitXorAssign for GvarFlags {
349 #[inline]
351 fn bitxor_assign(&mut self, other: Self) {
352 self.bits ^= other.bits;
353 }
354}
355
356impl std::ops::BitAnd for GvarFlags {
357 type Output = Self;
358
359 #[inline]
361 fn bitand(self, other: Self) -> Self {
362 Self {
363 bits: self.bits & other.bits,
364 }
365 }
366}
367
368impl std::ops::BitAndAssign for GvarFlags {
369 #[inline]
371 fn bitand_assign(&mut self, other: Self) {
372 self.bits &= other.bits;
373 }
374}
375
376impl std::ops::Sub for GvarFlags {
377 type Output = Self;
378
379 #[inline]
381 fn sub(self, other: Self) -> Self {
382 Self {
383 bits: self.bits & !other.bits,
384 }
385 }
386}
387
388impl std::ops::SubAssign for GvarFlags {
389 #[inline]
391 fn sub_assign(&mut self, other: Self) {
392 self.bits &= !other.bits;
393 }
394}
395
396impl std::ops::Not for GvarFlags {
397 type Output = Self;
398
399 #[inline]
401 fn not(self) -> Self {
402 Self { bits: !self.bits } & Self::all()
403 }
404}
405
406impl std::fmt::Debug for GvarFlags {
407 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
408 let members: &[(&str, Self)] = &[("LONG_OFFSETS", Self::LONG_OFFSETS)];
409 let mut first = true;
410 for (name, value) in members {
411 if self.contains(*value) {
412 if !first {
413 f.write_str(" | ")?;
414 }
415 first = false;
416 f.write_str(name)?;
417 }
418 }
419 if first {
420 f.write_str("(empty)")?;
421 }
422 Ok(())
423 }
424}
425
426impl std::fmt::Binary for GvarFlags {
427 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
428 std::fmt::Binary::fmt(&self.bits, f)
429 }
430}
431
432impl std::fmt::Octal for GvarFlags {
433 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
434 std::fmt::Octal::fmt(&self.bits, f)
435 }
436}
437
438impl std::fmt::LowerHex for GvarFlags {
439 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
440 std::fmt::LowerHex::fmt(&self.bits, f)
441 }
442}
443
444impl std::fmt::UpperHex for GvarFlags {
445 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
446 std::fmt::UpperHex::fmt(&self.bits, f)
447 }
448}
449
450impl font_types::Scalar for GvarFlags {
451 type Raw = <u16 as font_types::Scalar>::Raw;
452 fn to_raw(self) -> Self::Raw {
453 self.bits().to_raw()
454 }
455 fn from_raw(raw: Self::Raw) -> Self {
456 let t = <u16>::from_raw(raw);
457 Self::from_bits_truncate(t)
458 }
459}
460
461impl<'a> MinByteRange<'a> for SharedTuples<'a> {
462 fn min_byte_range(&self) -> Range<usize> {
463 0..self.tuples_byte_range().end
464 }
465 fn min_table_bytes(&self) -> &'a [u8] {
466 let range = self.min_byte_range();
467 self.data.as_bytes().get(range).unwrap_or_default()
468 }
469}
470
471impl ReadArgs for SharedTuples<'_> {
472 type Args = (u16, u16);
473}
474
475impl<'a> FontRead<'a> for SharedTuples<'a> {
476 fn read_with_args(data: FontData<'a>, args: (u16, u16)) -> Result<Self, ReadError> {
477 let (shared_tuple_count, axis_count) = args;
478
479 #[allow(clippy::absurd_extreme_comparisons)]
480 if data.len() < Self::MIN_SIZE {
481 return Err(ReadError::OutOfBounds);
482 }
483 Ok(Self {
484 data,
485 shared_tuple_count,
486 axis_count,
487 })
488 }
489}
490
491impl<'a> SharedTuples<'a> {
492 pub fn read(
497 data: FontData<'a>,
498 shared_tuple_count: u16,
499 axis_count: u16,
500 ) -> Result<Self, ReadError> {
501 let args = (shared_tuple_count, axis_count);
502 Self::read_with_args(data, args)
503 }
504}
505
506#[derive(Clone)]
508pub struct SharedTuples<'a> {
509 data: FontData<'a>,
510 shared_tuple_count: u16,
511 axis_count: u16,
512}
513
514#[allow(clippy::needless_lifetimes)]
515impl<'a> SharedTuples<'a> {
516 pub const MIN_SIZE: usize = 0;
517 basic_table_impls!(impl_the_methods);
518
519 pub fn tuples(&self) -> ComputedArray<'a, Tuple<'a>> {
520 let range = self.tuples_byte_range();
521 ComputedArray::new(self.data, range, self.axis_count()).unwrap_or_default()
522 }
523
524 pub(crate) fn shared_tuple_count(&self) -> u16 {
525 self.shared_tuple_count
526 }
527
528 pub(crate) fn axis_count(&self) -> u16 {
529 self.axis_count
530 }
531
532 pub fn tuples_byte_range(&self) -> Range<usize> {
533 let shared_tuple_count = self.shared_tuple_count();
534 let start = 0;
535 let end = start
536 + (transforms::to_usize(shared_tuple_count)).saturating_mul(
537 <Tuple as ComputeSize>::compute_size(self.axis_count()).unwrap_or(0),
538 );
539 start..end
540 }
541}
542
543#[allow(clippy::absurd_extreme_comparisons)]
544const _: () = assert!(FontData::default_data_long_enough(SharedTuples::MIN_SIZE));
545
546impl Default for SharedTuples<'_> {
547 fn default() -> Self {
548 Self {
549 data: FontData::default_table_data(),
550 shared_tuple_count: Default::default(),
551 axis_count: Default::default(),
552 }
553 }
554}
555
556impl<'a> MinByteRange<'a> for GlyphVariationDataHeader<'a> {
557 fn min_byte_range(&self) -> Range<usize> {
558 0..self.tuple_variation_headers_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 GlyphVariationDataHeader<'_> {
567 type Args = ();
568}
569
570impl<'a> FontRead<'a> for GlyphVariationDataHeader<'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)]
582pub struct GlyphVariationDataHeader<'a> {
583 data: FontData<'a>,
584}
585
586#[allow(clippy::needless_lifetimes)]
587impl<'a> GlyphVariationDataHeader<'a> {
588 pub const MIN_SIZE: usize = (TupleVariationCount::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN);
589 basic_table_impls!(impl_the_methods);
590
591 pub fn tuple_variation_count(&self) -> TupleVariationCount {
596 let range = self.tuple_variation_count_byte_range();
597 self.data.read_at(range.start).ok().unwrap()
598 }
599
600 pub fn serialized_data_offset(&self) -> Offset16 {
603 let range = self.serialized_data_offset_byte_range();
604 self.data.read_at(range.start).ok().unwrap()
605 }
606
607 pub fn serialized_data(&self) -> Result<FontData<'a>, ReadError> {
609 let data = self.data;
610 self.serialized_data_offset().resolve(data)
611 }
612
613 pub fn tuple_variation_headers(&self) -> VarLenArray<'a, TupleVariationHeader<'a>> {
615 let range = self.tuple_variation_headers_byte_range();
616 self.data
617 .split_off(range.start)
618 .and_then(|d| VarLenArray::read(d).ok())
619 .unwrap_or_default()
620 }
621
622 pub fn tuple_variation_count_byte_range(&self) -> Range<usize> {
623 let start = 0;
624 let end = start + TupleVariationCount::RAW_BYTE_LEN;
625 start..end
626 }
627
628 pub fn serialized_data_offset_byte_range(&self) -> Range<usize> {
629 let start = self.tuple_variation_count_byte_range().end;
630 let end = start + Offset16::RAW_BYTE_LEN;
631 start..end
632 }
633
634 pub fn tuple_variation_headers_byte_range(&self) -> Range<usize> {
635 let start = self.serialized_data_offset_byte_range().end;
636 let end = start + self.data.len().saturating_sub(start);
637 start..end
638 }
639}
640
641const _: () = assert!(FontData::default_data_long_enough(
642 GlyphVariationDataHeader::MIN_SIZE
643));
644
645impl Default for GlyphVariationDataHeader<'_> {
646 fn default() -> Self {
647 Self {
648 data: FontData::default_table_data(),
649 }
650 }
651}