1#![allow(clippy::clone_on_copy)]
8#![allow(clippy::neg_cmp_op_on_partial_ord)]
9
10use core::cmp;
11use core::convert::TryFrom;
12use core::num::NonZeroU16;
13
14use crate::glyf;
15use crate::parser::{LazyArray16, Offset, Offset16, Offset32, Stream, F2DOT14};
16use crate::{GlyphId, NormalizedCoordinate, OutlineBuilder, Rect, RectF, Transform};
17
18const PHANTOM_POINTS_LEN: usize = 4;
24
25#[derive(Clone, Copy)]
26enum GlyphVariationDataOffsets<'a> {
27 Short(LazyArray16<'a, Offset16>),
28 Long(LazyArray16<'a, Offset32>),
29}
30
31#[derive(Clone, Copy, Default, Debug)]
32struct PointAndDelta {
33 x: i16,
34 y: i16,
35 x_delta: f32,
36 y_delta: f32,
37}
38
39#[derive(Clone, Copy, Default)]
42struct VariationTuple<'a> {
43 set_points: Option<SetPointsIter<'a>>,
44 deltas: PackedDeltasIter<'a>,
45 prev_point: Option<PointAndDelta>,
48}
49
50const MAX_STACK_TUPLES_LEN: u16 = 32;
56
57enum VariationTuples<'a> {
63 Stack {
64 headers: [VariationTuple<'a>; MAX_STACK_TUPLES_LEN as usize],
65 len: u16,
66 },
67 #[cfg(feature = "gvar-alloc")]
68 Heap {
69 vec: std::vec::Vec<VariationTuple<'a>>,
70 },
71}
72
73impl<'a> Default for VariationTuples<'a> {
74 fn default() -> Self {
75 Self::Stack {
76 headers: [VariationTuple::default(); MAX_STACK_TUPLES_LEN as usize],
77 len: 0,
78 }
79 }
80}
81
82impl<'a> VariationTuples<'a> {
83 #[cfg(feature = "gvar-alloc")]
85 fn reserve(&mut self, capacity: u16) -> bool {
86 if capacity > MAX_STACK_TUPLES_LEN {
88 if let Self::Stack { headers, len } = self {
90 let mut vec = std::vec::Vec::with_capacity(capacity as usize);
91 for header in headers.iter_mut().take(*len as usize) {
92 let header = core::mem::take(header);
93 vec.push(header);
94 }
95
96 *self = Self::Heap { vec };
97 return true;
98 }
99 }
100
101 match self {
103 Self::Heap { vec } if vec.len() < capacity as usize => {
105 vec.reserve(capacity as usize - vec.len());
106 true
107 }
108 _ => true,
110 }
111 }
112
113 #[cfg(not(feature = "gvar-alloc"))]
115 fn reserve(&mut self, capacity: u16) -> bool {
116 capacity <= MAX_STACK_TUPLES_LEN
117 }
118
119 #[cfg_attr(not(feature = "gvar-alloc"), allow(dead_code))]
121 fn len(&self) -> u16 {
122 match self {
123 Self::Stack { len, .. } => *len,
124 #[cfg(feature = "gvar-alloc")]
125 Self::Heap { vec } => vec.len() as u16,
126 }
127 }
128
129 #[cfg(feature = "gvar-alloc")]
132 fn push(&mut self, header: VariationTuple<'a>) {
133 self.reserve(self.len() + 1);
136
137 match self {
138 Self::Stack { headers, len } => {
139 headers[usize::from(*len)] = header;
140 *len += 1;
141 }
142 Self::Heap { vec } => vec.push(header),
143 }
144 }
145
146 #[cfg(not(feature = "gvar-alloc"))]
149 #[inline]
150 fn push(&mut self, header: VariationTuple<'a>) {
151 match self {
152 Self::Stack { headers, len } => {
153 headers[usize::from(*len)] = header;
154 *len += 1;
155 }
156 }
157 }
158
159 fn clear(&mut self) {
161 match self {
162 Self::Stack { len, .. } => *len = 0,
163 #[cfg(feature = "gvar-alloc")]
164 Self::Heap { vec } => vec.clear(),
165 }
166 }
167
168 #[inline]
169 fn as_mut_slice(&mut self) -> &mut [VariationTuple<'a>] {
170 match self {
171 Self::Stack { headers, len } => &mut headers[0..usize::from(*len)],
172 #[cfg(feature = "gvar-alloc")]
173 Self::Heap { vec } => vec.as_mut_slice(),
174 }
175 }
176
177 fn apply(
178 &mut self,
179 all_points: glyf::GlyphPointsIter,
180 points: glyf::GlyphPointsIter,
181 point: glyf::GlyphPoint,
182 ) -> Option<(f32, f32)> {
183 let mut x = f32::from(point.x);
184 let mut y = f32::from(point.y);
185
186 for tuple in self.as_mut_slice() {
187 if let Some(ref mut set_points) = tuple.set_points {
188 if set_points.next()? {
189 if let Some((x_delta, y_delta)) = tuple.deltas.next() {
190 tuple.prev_point = Some(PointAndDelta {
192 x: point.x,
193 y: point.y,
194 x_delta,
195 y_delta,
196 });
197
198 x += x_delta;
199 y += y_delta;
200 } else {
201 let set_points = set_points.clone();
203 let (x_delta, y_delta) = infer_deltas(
204 tuple,
205 set_points,
206 points.clone(),
207 all_points.clone(),
208 point,
209 );
210
211 x += x_delta;
212 y += y_delta;
213 }
214 } else {
215 let set_points = set_points.clone();
217 let (x_delta, y_delta) =
218 infer_deltas(tuple, set_points, points.clone(), all_points.clone(), point);
219
220 x += x_delta;
221 y += y_delta;
222 }
223
224 if point.last_point {
225 tuple.prev_point = None;
226 }
227 } else {
228 if let Some((x_delta, y_delta)) = tuple.deltas.next() {
229 x += x_delta;
230 y += y_delta;
231 }
232 }
233 }
234
235 Some((x, y))
236 }
237
238 fn apply_null(&mut self) -> Option<(f32, f32)> {
242 let mut x = 0.0;
243 let mut y = 0.0;
244
245 for tuple in self.as_mut_slice() {
246 if let Some(ref mut set_points) = tuple.set_points {
247 if set_points.next()? {
248 if let Some((x_delta, y_delta)) = tuple.deltas.next() {
249 x += x_delta;
250 y += y_delta;
251 }
252 }
253 } else {
254 if let Some((x_delta, y_delta)) = tuple.deltas.next() {
255 x += x_delta;
256 y += y_delta;
257 }
258 }
259 }
260
261 Some((x, y))
262 }
263}
264
265#[derive(Clone, Copy, Default, Debug)]
266struct TupleVariationHeaderData {
267 scalar: f32,
268 has_private_point_numbers: bool,
269 serialized_data_len: u16,
270}
271
272fn parse_variation_tuples<'a>(
274 count: u16,
275 coordinates: &[NormalizedCoordinate],
276 shared_tuple_records: &LazyArray16<F2DOT14>,
277 shared_point_numbers: Option<PackedPointsIter<'a>>,
278 points_len: u16,
279 mut main_s: Stream<'a>,
280 mut serialized_s: Stream<'a>,
281 tuples: &mut VariationTuples<'a>,
282) -> Option<()> {
283 debug_assert!(core::mem::size_of::<VariationTuple>() <= 80);
284
285 for _ in 0..count {
287 let header = parse_tuple_variation_header(coordinates, shared_tuple_records, &mut main_s)?;
288 if !(header.scalar > 0.0) {
289 serialized_s.advance(usize::from(header.serialized_data_len));
291 continue;
292 }
293
294 let serialized_data_start = serialized_s.offset();
295
296 let point_numbers = if header.has_private_point_numbers {
298 PackedPointsIter::new(&mut serialized_s)?
299 } else {
300 shared_point_numbers.clone()
301 };
302
303 let deltas_count = if let Some(point_numbers) = point_numbers.clone() {
311 u16::try_from(point_numbers.clone().count()).ok()?
312 } else {
313 points_len
314 };
315
316 let deltas = {
317 let left = usize::from(header.serialized_data_len)
319 .checked_sub(serialized_s.offset() - serialized_data_start)?;
320 let deltas_data = serialized_s.read_bytes(left)?;
321 PackedDeltasIter::new(header.scalar, deltas_count, deltas_data)
322 };
323
324 let tuple = VariationTuple {
325 set_points: point_numbers.map(SetPointsIter::new),
326 deltas,
327 prev_point: None,
328 };
329
330 tuples.push(tuple);
331 }
332
333 Some(())
334}
335
336fn parse_tuple_variation_header(
338 coordinates: &[NormalizedCoordinate],
339 shared_tuple_records: &LazyArray16<F2DOT14>,
340 s: &mut Stream,
341) -> Option<TupleVariationHeaderData> {
342 const EMBEDDED_PEAK_TUPLE_FLAG: u16 = 0x8000;
343 const INTERMEDIATE_REGION_FLAG: u16 = 0x4000;
344 const PRIVATE_POINT_NUMBERS_FLAG: u16 = 0x2000;
345 const TUPLE_INDEX_MASK: u16 = 0x0FFF;
346
347 let serialized_data_size = s.read::<u16>()?;
348 let tuple_index = s.read::<u16>()?;
349
350 let has_embedded_peak_tuple = tuple_index & EMBEDDED_PEAK_TUPLE_FLAG != 0;
351 let has_intermediate_region = tuple_index & INTERMEDIATE_REGION_FLAG != 0;
352 let has_private_point_numbers = tuple_index & PRIVATE_POINT_NUMBERS_FLAG != 0;
353 let tuple_index = tuple_index & TUPLE_INDEX_MASK;
354
355 let axis_count = coordinates.len() as u16;
356
357 let peak_tuple = if has_embedded_peak_tuple {
358 s.read_array16::<F2DOT14>(axis_count)?
359 } else {
360 let start = tuple_index.checked_mul(axis_count)?;
362 let end = start.checked_add(axis_count)?;
363 shared_tuple_records.slice(start..end)?
364 };
365
366 let (start_tuple, end_tuple) = if has_intermediate_region {
367 (
368 s.read_array16::<F2DOT14>(axis_count)?,
369 s.read_array16::<F2DOT14>(axis_count)?,
370 )
371 } else {
372 (
373 LazyArray16::<F2DOT14>::default(),
374 LazyArray16::<F2DOT14>::default(),
375 )
376 };
377
378 let mut header = TupleVariationHeaderData {
379 scalar: 0.0,
380 has_private_point_numbers,
381 serialized_data_len: serialized_data_size,
382 };
383
384 let mut scalar = 1.0;
387 for i in 0..axis_count {
388 let v = coordinates[usize::from(i)].get();
389 let peak = peak_tuple.get(i)?.0;
390 if peak == 0 || v == peak {
391 continue;
392 }
393
394 if has_intermediate_region {
395 let start = start_tuple.get(i)?.0;
396 let end = end_tuple.get(i)?.0;
397 if start > peak || peak > end || (start < 0 && end > 0 && peak != 0) {
398 continue;
399 }
400
401 if v < start || v > end {
402 return Some(header);
403 }
404
405 if v < peak {
406 if peak != start {
407 scalar *= f32::from(v - start) / f32::from(peak - start);
408 }
409 } else {
410 if peak != end {
411 scalar *= f32::from(end - v) / f32::from(end - peak);
412 }
413 }
414 } else if v == 0 || v < cmp::min(0, peak) || v > cmp::max(0, peak) {
415 return Some(header);
418 } else {
419 scalar *= f32::from(v) / f32::from(peak);
420 }
421 }
422
423 header.scalar = scalar;
424 Some(header)
425}
426
427mod packed_points {
429 use crate::parser::{FromData, Stream};
430
431 struct Control(u8);
432
433 impl Control {
434 const POINTS_ARE_WORDS_FLAG: u8 = 0x80;
435 const POINT_RUN_COUNT_MASK: u8 = 0x7F;
436
437 #[inline]
438 fn is_points_are_words(&self) -> bool {
439 self.0 & Self::POINTS_ARE_WORDS_FLAG != 0
440 }
441
442 #[inline]
446 fn run_count(&self) -> u8 {
447 (self.0 & Self::POINT_RUN_COUNT_MASK) + 1
448 }
449 }
450
451 impl FromData for Control {
452 const SIZE: usize = 1;
453
454 #[inline]
455 fn parse(data: &[u8]) -> Option<Self> {
456 data.get(0).copied().map(Control)
457 }
458 }
459
460 #[derive(Clone, Copy, PartialEq)]
461 enum State {
462 Control,
463 ShortPoint,
464 LongPoint,
465 }
466
467 #[derive(Clone, Copy)]
471 pub struct PackedPointsIter<'a> {
472 data: &'a [u8],
473 offset: u16,
475 state: State,
476 points_left: u8,
477 }
478
479 impl<'a> PackedPointsIter<'a> {
480 pub fn new<'b>(s: &'b mut Stream<'a>) -> Option<Option<Self>> {
483 let b1 = s.read::<u8>()?;
486 let mut count = u16::from(b1);
487 if b1 & Control::POINTS_ARE_WORDS_FLAG != 0 {
488 let b2 = s.read::<u8>()?;
489 count = (u16::from(b1 & Control::POINT_RUN_COUNT_MASK) << 8) | u16::from(b2);
490 }
491
492 if count == 0 {
493 return Some(None);
495 }
496
497 let start = s.offset();
498 let tail = s.tail()?;
499
500 let mut i = 0;
504 while i < count {
505 let control = s.read::<Control>()?;
506 let run_count = u16::from(control.run_count());
507 let is_points_are_words = control.is_points_are_words();
508 s.advance_checked(
510 if is_points_are_words { 2 } else { 1 } * usize::from(run_count),
511 )?;
512 i += run_count;
513 }
514
515 if i == 0 {
516 return Some(None);
518 }
519
520 if i > count {
521 return None;
523 }
524
525 let data_len = s.offset() - start;
528 if data_len > usize::from(core::u16::MAX) {
529 return None;
530 }
531
532 Some(Some(PackedPointsIter {
533 data: &tail[0..data_len],
534 offset: 0,
535 state: State::Control,
536 points_left: 0,
537 }))
538 }
539 }
540
541 impl<'a> Iterator for PackedPointsIter<'a> {
542 type Item = u16;
543
544 fn next(&mut self) -> Option<Self::Item> {
545 if usize::from(self.offset) >= self.data.len() {
546 return None;
547 }
548
549 if self.state == State::Control {
550 let control = Control(self.data[usize::from(self.offset)]);
551 self.offset += 1;
552
553 self.points_left = control.run_count();
554 self.state = if control.is_points_are_words() {
555 State::LongPoint
556 } else {
557 State::ShortPoint
558 };
559
560 self.next()
561 } else {
562 let mut s = Stream::new_at(self.data, usize::from(self.offset))?;
563 let point = if self.state == State::LongPoint {
564 self.offset += 2;
565 s.read::<u16>()?
566 } else {
567 self.offset += 1;
568 u16::from(s.read::<u8>()?)
569 };
570
571 self.points_left -= 1;
572 if self.points_left == 0 {
573 self.state = State::Control;
574 }
575
576 Some(point)
577 }
578 }
579 }
580
581 #[derive(Clone, Copy)]
588 pub struct SetPointsIter<'a> {
589 iter: PackedPointsIter<'a>,
590 unref_count: u16,
591 }
592
593 impl<'a> SetPointsIter<'a> {
594 #[inline]
595 pub fn new(mut iter: PackedPointsIter<'a>) -> Self {
596 let unref_count = iter.next().unwrap_or(0);
597 SetPointsIter { iter, unref_count }
598 }
599
600 #[inline]
601 pub fn restart(self) -> Self {
602 let mut iter = self.iter.clone();
603 iter.offset = 0;
604 iter.state = State::Control;
605 iter.points_left = 0;
606
607 let unref_count = iter.next().unwrap_or(0);
608 SetPointsIter { iter, unref_count }
609 }
610 }
611
612 impl<'a> Iterator for SetPointsIter<'a> {
613 type Item = bool;
614
615 #[inline]
616 fn next(&mut self) -> Option<Self::Item> {
617 if self.unref_count != 0 {
618 self.unref_count -= 1;
619 return Some(false);
620 }
621
622 if let Some(unref_count) = self.iter.next() {
623 self.unref_count = unref_count;
624 if self.unref_count != 0 {
625 self.unref_count -= 1;
626 }
627 }
628
629 Some(true)
634 }
635 }
636
637 #[cfg(test)]
638 mod tests {
639 use super::*;
640
641 struct NewControl {
642 deltas_are_words: bool,
643 run_count: u8,
644 }
645
646 fn gen_control(control: NewControl) -> u8 {
647 assert!(control.run_count > 0, "run count cannot be zero");
648
649 let mut n = 0;
650 if control.deltas_are_words {
651 n |= 0x80;
652 }
653 n |= (control.run_count - 1) & 0x7F;
654 n
655 }
656
657 #[test]
658 fn empty() {
659 let mut s = Stream::new(&[]);
660 assert!(PackedPointsIter::new(&mut s).is_none());
661 }
662
663 #[test]
664 fn single_zero_control() {
665 let mut s = Stream::new(&[0]);
666 assert!(PackedPointsIter::new(&mut s).unwrap().is_none());
667 }
668
669 #[test]
670 fn single_point() {
671 let data = vec![
672 1, gen_control(NewControl {
674 deltas_are_words: false,
675 run_count: 1,
676 }),
677 1,
678 ];
679
680 let points_iter = PackedPointsIter::new(&mut Stream::new(&data))
681 .unwrap()
682 .unwrap();
683 let mut iter = SetPointsIter::new(points_iter);
684 assert_eq!(iter.next().unwrap(), false);
685 assert_eq!(iter.next().unwrap(), true);
686 assert_eq!(iter.next().unwrap(), true); }
688
689 #[test]
690 fn set_0_and_2() {
691 let data = vec![
692 2, gen_control(NewControl {
694 deltas_are_words: false,
695 run_count: 2,
696 }),
697 0,
698 2,
699 ];
700
701 let points_iter = PackedPointsIter::new(&mut Stream::new(&data))
702 .unwrap()
703 .unwrap();
704 let mut iter = SetPointsIter::new(points_iter);
705 assert_eq!(iter.next().unwrap(), true);
706 assert_eq!(iter.next().unwrap(), false);
707 assert_eq!(iter.next().unwrap(), true);
708 assert_eq!(iter.next().unwrap(), true); }
710
711 #[test]
712 fn set_1_and_2() {
713 let data = vec![
714 2, gen_control(NewControl {
716 deltas_are_words: false,
717 run_count: 2,
718 }),
719 1,
720 1,
721 ];
722
723 let points_iter = PackedPointsIter::new(&mut Stream::new(&data))
724 .unwrap()
725 .unwrap();
726 let mut iter = SetPointsIter::new(points_iter);
727 assert_eq!(iter.next().unwrap(), false);
728 assert_eq!(iter.next().unwrap(), true);
729 assert_eq!(iter.next().unwrap(), true);
730 assert_eq!(iter.next().unwrap(), true); }
732
733 #[test]
734 fn set_1_and_3() {
735 let data = vec![
736 2, gen_control(NewControl {
738 deltas_are_words: false,
739 run_count: 2,
740 }),
741 1,
742 2,
743 ];
744
745 let points_iter = PackedPointsIter::new(&mut Stream::new(&data))
746 .unwrap()
747 .unwrap();
748 let mut iter = SetPointsIter::new(points_iter);
749 assert_eq!(iter.next().unwrap(), false);
750 assert_eq!(iter.next().unwrap(), true);
751 assert_eq!(iter.next().unwrap(), false);
752 assert_eq!(iter.next().unwrap(), true);
753 assert_eq!(iter.next().unwrap(), true); }
755
756 #[test]
757 fn set_2_5_7() {
758 let data = vec![
759 3, gen_control(NewControl {
761 deltas_are_words: false,
762 run_count: 3,
763 }),
764 2,
765 3,
766 2,
767 ];
768
769 let points_iter = PackedPointsIter::new(&mut Stream::new(&data))
770 .unwrap()
771 .unwrap();
772 let mut iter = SetPointsIter::new(points_iter);
773 assert_eq!(iter.next().unwrap(), false);
774 assert_eq!(iter.next().unwrap(), false);
775 assert_eq!(iter.next().unwrap(), true);
776 assert_eq!(iter.next().unwrap(), false);
777 assert_eq!(iter.next().unwrap(), false);
778 assert_eq!(iter.next().unwrap(), true);
779 assert_eq!(iter.next().unwrap(), false);
780 assert_eq!(iter.next().unwrap(), true);
781 assert_eq!(iter.next().unwrap(), true); }
783
784 #[test]
785 fn more_than_127_points() {
786 let mut data = vec![];
787 data.push(Control::POINTS_ARE_WORDS_FLAG);
789 data.push(150);
790
791 data.push(gen_control(NewControl {
792 deltas_are_words: false,
793 run_count: 100,
794 }));
795 for _ in 0..100 {
796 data.push(2);
797 }
798 data.push(gen_control(NewControl {
799 deltas_are_words: false,
800 run_count: 50,
801 }));
802 for _ in 0..50 {
803 data.push(2);
804 }
805
806 let points_iter = PackedPointsIter::new(&mut Stream::new(&data))
807 .unwrap()
808 .unwrap();
809 let mut iter = SetPointsIter::new(points_iter);
810 assert_eq!(iter.next().unwrap(), false);
811 for _ in 0..150 {
812 assert_eq!(iter.next().unwrap(), false);
813 assert_eq!(iter.next().unwrap(), true);
814 }
815 assert_eq!(iter.next().unwrap(), true);
816 assert_eq!(iter.next().unwrap(), true); }
818
819 #[test]
820 fn long_points() {
821 let data = vec![
822 2, gen_control(NewControl {
824 deltas_are_words: true,
825 run_count: 2,
826 }),
827 0,
828 2,
829 0,
830 3,
831 ];
832
833 let points_iter = PackedPointsIter::new(&mut Stream::new(&data))
834 .unwrap()
835 .unwrap();
836 let mut iter = SetPointsIter::new(points_iter);
837 assert_eq!(iter.next().unwrap(), false);
838 assert_eq!(iter.next().unwrap(), false);
839 assert_eq!(iter.next().unwrap(), true);
840 assert_eq!(iter.next().unwrap(), false);
841 assert_eq!(iter.next().unwrap(), false);
842 assert_eq!(iter.next().unwrap(), true);
843 assert_eq!(iter.next().unwrap(), true); }
845
846 #[test]
847 fn multiple_runs() {
848 let data = vec![
849 5, gen_control(NewControl {
851 deltas_are_words: true,
852 run_count: 2,
853 }),
854 0,
855 2,
856 0,
857 3,
858 gen_control(NewControl {
859 deltas_are_words: false,
860 run_count: 3,
861 }),
862 2,
863 3,
864 2,
865 ];
866
867 let points_iter = PackedPointsIter::new(&mut Stream::new(&data))
868 .unwrap()
869 .unwrap();
870 let mut iter = SetPointsIter::new(points_iter);
871 assert_eq!(iter.next().unwrap(), false);
872 assert_eq!(iter.next().unwrap(), false);
873 assert_eq!(iter.next().unwrap(), true);
874 assert_eq!(iter.next().unwrap(), false);
875 assert_eq!(iter.next().unwrap(), false);
876 assert_eq!(iter.next().unwrap(), true);
877 assert_eq!(iter.next().unwrap(), false);
878 assert_eq!(iter.next().unwrap(), true);
879 assert_eq!(iter.next().unwrap(), false);
880 assert_eq!(iter.next().unwrap(), false);
881 assert_eq!(iter.next().unwrap(), true);
882 assert_eq!(iter.next().unwrap(), false);
883 assert_eq!(iter.next().unwrap(), true);
884 assert_eq!(iter.next().unwrap(), true); }
886
887 #[test]
888 fn runs_overflow() {
889 let data = vec![0xFF; 0xFFFF * 2];
891 assert!(PackedPointsIter::new(&mut Stream::new(&data)).is_none());
892 }
893 }
894}
895
896use packed_points::*;
897
898mod packed_deltas {
900 use crate::parser::Stream;
901
902 struct Control(u8);
903
904 impl Control {
905 const DELTAS_ARE_ZERO_FLAG: u8 = 0x80;
906 const DELTAS_ARE_WORDS_FLAG: u8 = 0x40;
907 const DELTA_RUN_COUNT_MASK: u8 = 0x3F;
908
909 #[inline]
910 fn is_deltas_are_zero(&self) -> bool {
911 self.0 & Self::DELTAS_ARE_ZERO_FLAG != 0
912 }
913
914 #[inline]
915 fn is_deltas_are_words(&self) -> bool {
916 self.0 & Self::DELTAS_ARE_WORDS_FLAG != 0
917 }
918
919 #[inline]
923 fn run_count(&self) -> u8 {
924 (self.0 & Self::DELTA_RUN_COUNT_MASK) + 1
925 }
926 }
927
928 #[derive(Clone, Copy, PartialEq, Debug)]
929 enum State {
930 Control,
931 ZeroDelta,
932 ShortDelta,
933 LongDelta,
934 }
935
936 impl Default for State {
937 #[inline]
938 fn default() -> Self {
939 State::Control
940 }
941 }
942
943 #[derive(Clone, Copy, Default)]
944 struct RunState {
945 data_offset: u16,
946 state: State,
947 run_deltas_left: u8,
948 }
949
950 impl RunState {
951 fn next(&mut self, data: &[u8], scalar: f32) -> Option<f32> {
952 if self.state == State::Control {
953 if usize::from(self.data_offset) == data.len() {
954 return None;
955 }
956
957 let control = Control(Stream::read_at::<u8>(data, usize::from(self.data_offset))?);
958 self.data_offset += 1;
959
960 self.run_deltas_left = control.run_count();
961 self.state = if control.is_deltas_are_zero() {
962 State::ZeroDelta
963 } else if control.is_deltas_are_words() {
964 State::LongDelta
965 } else {
966 State::ShortDelta
967 };
968
969 self.next(data, scalar)
970 } else {
971 let mut s = Stream::new_at(data, usize::from(self.data_offset))?;
972 let delta = if self.state == State::LongDelta {
973 self.data_offset += 2;
974 f32::from(s.read::<i16>()?) * scalar
975 } else if self.state == State::ZeroDelta {
976 0.0
977 } else {
978 self.data_offset += 1;
979 f32::from(s.read::<i8>()?) * scalar
980 };
981
982 self.run_deltas_left -= 1;
983 if self.run_deltas_left == 0 {
984 self.state = State::Control;
985 }
986
987 Some(delta)
988 }
989 }
990 }
991
992 #[derive(Clone, Copy, Default)]
996 pub struct PackedDeltasIter<'a> {
997 data: &'a [u8],
998 x_run: RunState,
999 y_run: RunState,
1000
1001 total_count: u16,
1005
1006 scalar: f32,
1007 }
1008
1009 impl<'a> PackedDeltasIter<'a> {
1010 pub fn new(scalar: f32, count: u16, data: &'a [u8]) -> Self {
1012 debug_assert!(core::mem::size_of::<PackedDeltasIter>() <= 32);
1013
1014 let mut iter = PackedDeltasIter {
1015 data,
1016 total_count: count,
1017 scalar,
1018 ..PackedDeltasIter::default()
1019 };
1020
1021 for _ in 0..count {
1030 iter.y_run.next(data, scalar);
1031 }
1032
1033 iter
1034 }
1035
1036 #[inline]
1037 pub fn restart(self) -> Self {
1038 PackedDeltasIter::new(self.scalar, self.total_count, self.data)
1039 }
1040
1041 #[inline]
1042 pub fn next(&mut self) -> Option<(f32, f32)> {
1043 let x = self.x_run.next(self.data, self.scalar)?;
1044 let y = self.y_run.next(self.data, self.scalar)?;
1045 Some((x, y))
1046 }
1047 }
1048
1049 #[cfg(test)]
1050 mod tests {
1051 use super::*;
1052
1053 struct NewControl {
1054 deltas_are_zero: bool,
1055 deltas_are_words: bool,
1056 run_count: u8,
1057 }
1058
1059 fn gen_control(control: NewControl) -> u8 {
1060 assert!(control.run_count > 0, "run count cannot be zero");
1061
1062 let mut n = 0;
1063 if control.deltas_are_zero {
1064 n |= 0x80;
1065 }
1066 if control.deltas_are_words {
1067 n |= 0x40;
1068 }
1069 n |= (control.run_count - 1) & 0x3F;
1070 n
1071 }
1072
1073 #[test]
1074 fn empty() {
1075 let mut iter = PackedDeltasIter::new(1.0, 1, &[]);
1076 assert!(iter.next().is_none());
1077 }
1078
1079 #[test]
1080 fn single_delta() {
1081 let data = vec![
1082 gen_control(NewControl {
1083 deltas_are_zero: false,
1084 deltas_are_words: false,
1085 run_count: 2,
1086 }),
1087 2,
1088 3,
1089 ];
1090
1091 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1092 assert_eq!(iter.next().unwrap(), (2.0, 3.0));
1093 assert!(iter.next().is_none());
1094 }
1095
1096 #[test]
1097 fn two_deltas() {
1098 let data = vec![
1099 gen_control(NewControl {
1100 deltas_are_zero: false,
1101 deltas_are_words: false,
1102 run_count: 4,
1103 }),
1104 2,
1105 3,
1106 4,
1107 5,
1108 ];
1109
1110 let mut iter = PackedDeltasIter::new(1.0, 2, &data);
1111 assert_eq!(iter.next().unwrap(), (2.0, 4.0));
1113 assert_eq!(iter.next().unwrap(), (3.0, 5.0));
1114 assert!(iter.next().is_none());
1115 }
1116
1117 #[test]
1118 fn single_long_delta() {
1119 let data = vec![
1120 gen_control(NewControl {
1121 deltas_are_zero: false,
1122 deltas_are_words: true,
1123 run_count: 2,
1124 }),
1125 0,
1126 2,
1127 0,
1128 3,
1129 ];
1130
1131 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1132 assert_eq!(iter.next().unwrap(), (2.0, 3.0));
1133 assert!(iter.next().is_none());
1134 }
1135
1136 #[test]
1137 fn zeros() {
1138 let data = vec![gen_control(NewControl {
1139 deltas_are_zero: true,
1140 deltas_are_words: false,
1141 run_count: 4,
1142 })];
1143
1144 let mut iter = PackedDeltasIter::new(1.0, 2, &data);
1145 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1146 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1147 assert!(iter.next().is_none());
1148 }
1149
1150 #[test]
1151 fn zero_words() {
1152 let data = vec![gen_control(NewControl {
1155 deltas_are_zero: true,
1156 deltas_are_words: true,
1157 run_count: 4,
1158 })];
1159
1160 let mut iter = PackedDeltasIter::new(1.0, 2, &data);
1161 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1162 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1163 assert!(iter.next().is_none());
1164 }
1165
1166 #[test]
1167 fn zero_runs() {
1168 let data = vec![
1169 gen_control(NewControl {
1170 deltas_are_zero: true,
1171 deltas_are_words: false,
1172 run_count: 2,
1173 }),
1174 gen_control(NewControl {
1175 deltas_are_zero: true,
1176 deltas_are_words: false,
1177 run_count: 4,
1178 }),
1179 gen_control(NewControl {
1180 deltas_are_zero: true,
1181 deltas_are_words: false,
1182 run_count: 6,
1183 }),
1184 ];
1185
1186 let mut iter = PackedDeltasIter::new(1.0, 6, &data);
1187 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1189 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1191 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1192 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1194 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1195 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1196 assert!(iter.next().is_none());
1197 }
1198
1199 #[test]
1200 fn delta_after_zeros() {
1201 let data = vec![
1202 gen_control(NewControl {
1203 deltas_are_zero: true,
1204 deltas_are_words: false,
1205 run_count: 2,
1206 }),
1207 gen_control(NewControl {
1208 deltas_are_zero: false,
1209 deltas_are_words: false,
1210 run_count: 2,
1211 }),
1212 2,
1213 3,
1214 ];
1215
1216 let mut iter = PackedDeltasIter::new(1.0, 2, &data);
1217 assert_eq!(iter.next().unwrap(), (0.0, 2.0));
1218 assert_eq!(iter.next().unwrap(), (0.0, 3.0));
1219 assert!(iter.next().is_none());
1220 }
1221
1222 #[test]
1223 fn unexpected_end_of_data_1() {
1224 let data = vec![gen_control(NewControl {
1225 deltas_are_zero: false,
1226 deltas_are_words: false,
1227 run_count: 2,
1228 })];
1229
1230 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1231 assert!(iter.next().is_none());
1232 }
1233
1234 #[test]
1235 fn unexpected_end_of_data_2() {
1236 let data = vec![
1239 gen_control(NewControl {
1240 deltas_are_zero: false,
1241 deltas_are_words: false,
1242 run_count: 2,
1243 }),
1244 1,
1245 ];
1246
1247 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1248 assert!(iter.next().is_none());
1249 }
1250
1251 #[test]
1252 fn unexpected_end_of_data_3() {
1253 let data = vec![gen_control(NewControl {
1254 deltas_are_zero: false,
1255 deltas_are_words: true,
1256 run_count: 2,
1257 })];
1258
1259 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1260 assert!(iter.next().is_none());
1261 }
1262
1263 #[test]
1264 fn unexpected_end_of_data_4() {
1265 let data = vec![
1268 gen_control(NewControl {
1269 deltas_are_zero: false,
1270 deltas_are_words: true,
1271 run_count: 2,
1272 }),
1273 1,
1274 ];
1275
1276 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1277 assert!(iter.next().is_none());
1278 }
1279
1280 #[test]
1281 fn unexpected_end_of_data_6() {
1282 let data = vec![
1285 gen_control(NewControl {
1286 deltas_are_zero: false,
1287 deltas_are_words: true,
1288 run_count: 2,
1289 }),
1290 0,
1291 1,
1292 ];
1293
1294 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1295 assert!(iter.next().is_none());
1296 }
1297
1298 #[test]
1299 fn unexpected_end_of_data_7() {
1300 let data = vec![
1303 gen_control(NewControl {
1304 deltas_are_zero: false,
1305 deltas_are_words: true,
1306 run_count: 2,
1307 }),
1308 0,
1309 1,
1310 0,
1311 ];
1312
1313 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1314 assert!(iter.next().is_none());
1315 }
1316
1317 #[test]
1318 fn single_run() {
1319 let data = vec![
1320 gen_control(NewControl {
1321 deltas_are_zero: false,
1322 deltas_are_words: false,
1323 run_count: 1,
1324 }),
1325 2,
1326 3,
1327 ];
1328
1329 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1330 assert!(iter.next().is_none());
1331 }
1332
1333 #[test]
1334 fn too_many_pairs() {
1335 let data = vec![
1336 gen_control(NewControl {
1337 deltas_are_zero: false,
1338 deltas_are_words: false,
1339 run_count: 2,
1340 }),
1341 2,
1342 3,
1343 ];
1344
1345 let mut iter = PackedDeltasIter::new(1.0, 10, &data);
1347 assert!(iter.next().is_none());
1348 }
1349
1350 #[test]
1351 fn invalid_number_of_pairs() {
1352 let data = vec![
1353 gen_control(NewControl {
1354 deltas_are_zero: false,
1355 deltas_are_words: false,
1356 run_count: 2,
1357 }),
1358 2,
1359 3,
1360 4,
1361 5,
1362 6,
1363 7,
1364 ];
1365
1366 let mut iter = PackedDeltasIter::new(1.0, 4, &data);
1371 assert_eq!(iter.next().unwrap(), (2.0, 7.0));
1372 assert!(iter.next().is_none());
1373 }
1374
1375 #[test]
1376 fn mixed_runs() {
1377 let data = vec![
1378 gen_control(NewControl {
1379 deltas_are_zero: false,
1380 deltas_are_words: false,
1381 run_count: 3,
1382 }),
1383 2,
1384 3,
1385 4,
1386 gen_control(NewControl {
1387 deltas_are_zero: false,
1388 deltas_are_words: true,
1389 run_count: 2,
1390 }),
1391 0,
1392 5,
1393 0,
1394 6,
1395 gen_control(NewControl {
1396 deltas_are_zero: true,
1397 deltas_are_words: false,
1398 run_count: 1,
1399 }),
1400 ];
1401
1402 let mut iter = PackedDeltasIter::new(1.0, 3, &data);
1403 assert_eq!(iter.next().unwrap(), (2.0, 5.0));
1404 assert_eq!(iter.next().unwrap(), (3.0, 6.0));
1405 assert_eq!(iter.next().unwrap(), (4.0, 0.0));
1406 assert!(iter.next().is_none());
1407 }
1408
1409 #[test]
1410 fn non_default_scalar() {
1411 let data = vec![
1412 gen_control(NewControl {
1413 deltas_are_zero: false,
1414 deltas_are_words: false,
1415 run_count: 2,
1416 }),
1417 2,
1418 3,
1419 ];
1420
1421 let mut iter = PackedDeltasIter::new(0.5, 1, &data);
1422 assert_eq!(iter.next().unwrap(), (1.0, 1.5));
1423 assert!(iter.next().is_none());
1424 }
1425
1426 #[test]
1427 fn runs_overflow() {
1428 let data = vec![0xFF; 0xFFFF];
1429 let mut iter = PackedDeltasIter::new(1.0, 0xFFFF, &data);
1430 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1432 }
1433 }
1434}
1435
1436use packed_deltas::PackedDeltasIter;
1437
1438fn infer_deltas(
1459 tuple: &VariationTuple,
1460 points_set: SetPointsIter,
1461 points: glyf::GlyphPointsIter,
1463 all_points: glyf::GlyphPointsIter,
1465 curr_point: glyf::GlyphPoint,
1466) -> (f32, f32) {
1467 let mut current_contour = points.current_contour();
1468 if curr_point.last_point && current_contour != 0 {
1469 current_contour -= 1;
1473 }
1474
1475 let prev_point = if let Some(prev_point) = tuple.prev_point {
1476 prev_point
1478 } else {
1479 let mut last_point = None;
1481 let mut deltas = tuple.deltas.clone();
1482 for (point, is_set) in points.clone().zip(points_set.clone()) {
1483 if is_set {
1484 if let Some((x_delta, y_delta)) = deltas.next() {
1485 last_point = Some(PointAndDelta {
1486 x: point.x,
1487 y: point.y,
1488 x_delta,
1489 y_delta,
1490 });
1491 }
1492 }
1493
1494 if point.last_point {
1495 break;
1496 }
1497 }
1498
1499 match last_point {
1501 Some(p) => p,
1502 None => return (0.0, 0.0),
1503 }
1504 };
1505
1506 let mut next_point = None;
1507 if !curr_point.last_point {
1508 let mut deltas = tuple.deltas.clone();
1511 for (point, is_set) in points.clone().zip(points_set.clone()) {
1512 if is_set {
1513 if let Some((x_delta, y_delta)) = deltas.next() {
1514 next_point = Some(PointAndDelta {
1515 x: point.x,
1516 y: point.y,
1517 x_delta,
1518 y_delta,
1519 });
1520 }
1521
1522 break;
1523 }
1524
1525 if point.last_point {
1526 break;
1527 }
1528 }
1529 }
1530
1531 if next_point.is_none() {
1532 let mut all_points = all_points.clone();
1541 let mut deltas = tuple.deltas.clone().restart();
1542 let mut points_set = points_set.clone().restart();
1543
1544 let mut contour = 0;
1545 while let (Some(point), Some(is_set)) = (all_points.next(), points_set.next()) {
1546 if contour != current_contour {
1548 if is_set {
1549 let _ = deltas.next();
1550 }
1551
1552 contour = all_points.current_contour();
1553 continue;
1554 }
1555
1556 if is_set {
1557 let (x_delta, y_delta) = deltas.next().unwrap_or((0.0, 0.0));
1558 next_point = Some(PointAndDelta {
1559 x: point.x,
1560 y: point.y,
1561 x_delta,
1562 y_delta,
1563 });
1564
1565 break;
1566 }
1567
1568 if point.last_point {
1569 break;
1570 }
1571 }
1572 }
1573
1574 let next_point = match next_point {
1576 Some(p) => p,
1577 None => return (0.0, 0.0),
1578 };
1579
1580 let dx = infer_delta(
1581 prev_point.x,
1582 curr_point.x,
1583 next_point.x,
1584 prev_point.x_delta,
1585 next_point.x_delta,
1586 );
1587
1588 let dy = infer_delta(
1589 prev_point.y,
1590 curr_point.y,
1591 next_point.y,
1592 prev_point.y_delta,
1593 next_point.y_delta,
1594 );
1595
1596 (dx, dy)
1597}
1598
1599fn infer_delta(
1600 prev_point: i16,
1601 target_point: i16,
1602 next_point: i16,
1603 prev_delta: f32,
1604 next_delta: f32,
1605) -> f32 {
1606 if prev_point == next_point {
1607 if prev_delta == next_delta {
1608 prev_delta
1609 } else {
1610 0.0
1611 }
1612 } else if target_point <= prev_point.min(next_point) {
1613 if prev_point < next_point {
1614 prev_delta
1615 } else {
1616 next_delta
1617 }
1618 } else if target_point >= prev_point.max(next_point) {
1619 if prev_point > next_point {
1620 prev_delta
1621 } else {
1622 next_delta
1623 }
1624 } else {
1625 let target_sub = target_point.checked_sub(prev_point);
1630 let next_sub = next_point.checked_sub(prev_point);
1631 let d = if let (Some(target_sub), Some(next_sub)) = (target_sub, next_sub) {
1632 f32::from(target_sub) / f32::from(next_sub)
1633 } else {
1634 return 0.0;
1635 };
1636 (1.0 - d) * prev_delta + d * next_delta
1637 }
1638}
1639
1640#[derive(Clone, Copy)]
1643pub struct Table<'a> {
1644 axis_count: NonZeroU16,
1645 shared_tuple_records: LazyArray16<'a, F2DOT14>,
1646 offsets: GlyphVariationDataOffsets<'a>,
1647 glyphs_variation_data: &'a [u8],
1648}
1649
1650impl<'a> Table<'a> {
1651 pub fn parse(data: &'a [u8]) -> Option<Self> {
1653 let mut s = Stream::new(data);
1654 let version = s.read::<u32>()?;
1655 if version != 0x00010000 {
1656 return None;
1657 }
1658
1659 let axis_count = s.read::<u16>()?;
1660 let shared_tuple_count = s.read::<u16>()?;
1661 let shared_tuples_offset = s.read::<Offset32>()?;
1662 let glyph_count = s.read::<u16>()?;
1663 let flags = s.read::<u16>()?;
1664 let glyph_variation_data_array_offset = s.read::<Offset32>()?;
1665
1666 let axis_count = NonZeroU16::new(axis_count)?;
1668
1669 let shared_tuple_records = {
1670 let mut sub_s = Stream::new_at(data, shared_tuples_offset.to_usize())?;
1671 sub_s.read_array16::<F2DOT14>(shared_tuple_count.checked_mul(axis_count.get())?)?
1672 };
1673
1674 let glyphs_variation_data = data.get(glyph_variation_data_array_offset.to_usize()..)?;
1675 let offsets = {
1676 let offsets_count = glyph_count.checked_add(1)?;
1677 let is_long_format = flags & 1 == 1; if is_long_format {
1679 GlyphVariationDataOffsets::Long(s.read_array16::<Offset32>(offsets_count)?)
1680 } else {
1681 GlyphVariationDataOffsets::Short(s.read_array16::<Offset16>(offsets_count)?)
1682 }
1683 };
1684
1685 Some(Table {
1686 axis_count,
1687 shared_tuple_records,
1688 offsets,
1689 glyphs_variation_data,
1690 })
1691 }
1692
1693 #[inline]
1694 fn parse_variation_data(
1695 &self,
1696 glyph_id: GlyphId,
1697 coordinates: &[NormalizedCoordinate],
1698 points_len: u16,
1699 tuples: &mut VariationTuples<'a>,
1700 ) -> Option<()> {
1701 tuples.clear();
1702
1703 if coordinates.len() != usize::from(self.axis_count.get()) {
1704 return None;
1705 }
1706
1707 let next_glyph_id = glyph_id.0.checked_add(1)?;
1708
1709 let (start, end) = match self.offsets {
1710 GlyphVariationDataOffsets::Short(ref array) => {
1711 (
1714 array.get(glyph_id.0)?.to_usize() * 2,
1715 array.get(next_glyph_id)?.to_usize() * 2,
1716 )
1717 }
1718 GlyphVariationDataOffsets::Long(ref array) => (
1719 array.get(glyph_id.0)?.to_usize(),
1720 array.get(next_glyph_id)?.to_usize(),
1721 ),
1722 };
1723
1724 if start == end {
1726 return Some(());
1727 }
1728
1729 let data = self.glyphs_variation_data.get(start..end)?;
1730 parse_variation_data(
1731 coordinates,
1732 &self.shared_tuple_records,
1733 points_len,
1734 data,
1735 tuples,
1736 )
1737 }
1738
1739 pub fn outline(
1741 &self,
1742 glyf_table: glyf::Table,
1743 coordinates: &[NormalizedCoordinate],
1744 glyph_id: GlyphId,
1745 builder: &mut dyn OutlineBuilder,
1746 ) -> Option<Rect> {
1747 let mut b = glyf::Builder::new(Transform::default(), RectF::new(), builder);
1748 let glyph_data = glyf_table.get(glyph_id)?;
1749 outline_var_impl(
1750 glyf_table,
1751 self,
1752 glyph_id,
1753 glyph_data,
1754 coordinates,
1755 0,
1756 &mut b,
1757 );
1758 b.bbox.to_rect()
1759 }
1760}
1761
1762impl core::fmt::Debug for Table<'_> {
1763 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1764 write!(f, "Table {{ ... }}")
1765 }
1766}
1767
1768#[allow(clippy::comparison_chain)]
1769fn outline_var_impl(
1770 glyf_table: glyf::Table,
1771 gvar_table: &Table,
1772 glyph_id: GlyphId,
1773 data: &[u8],
1774 coordinates: &[NormalizedCoordinate],
1775 depth: u8,
1776 builder: &mut glyf::Builder,
1777) -> Option<()> {
1778 if depth >= glyf::MAX_COMPONENTS {
1779 return None;
1780 }
1781
1782 let mut s = Stream::new(data);
1783 let number_of_contours = s.read::<i16>()?;
1784
1785 s.advance(8);
1791
1792 let mut tuples = VariationTuples::default();
1795
1796 if number_of_contours > 0 {
1797 let number_of_contours = NonZeroU16::new(number_of_contours as u16)?;
1800 let mut glyph_points = glyf::parse_simple_outline(s.tail()?, number_of_contours)?;
1801 let all_glyph_points = glyph_points.clone();
1802 let points_len = glyph_points.points_left;
1803 gvar_table.parse_variation_data(glyph_id, coordinates, points_len, &mut tuples)?;
1804
1805 while let Some(point) = glyph_points.next() {
1806 let (x, y) = tuples.apply(all_glyph_points.clone(), glyph_points.clone(), point)?;
1807 builder.push_point(x, y, point.on_curve_point, point.last_point);
1808 }
1809
1810 Some(())
1811 } else if number_of_contours < 0 {
1812 let components = glyf::CompositeGlyphIter::new(s.tail()?);
1823 let components_count = components.clone().count() as u16;
1824 gvar_table.parse_variation_data(glyph_id, coordinates, components_count, &mut tuples)?;
1825
1826 for component in components {
1827 let (tx, ty) = tuples.apply_null()?;
1828
1829 let mut transform = builder.transform;
1830
1831 if component.flags.args_are_xy_values() {
1834 transform = Transform::combine(transform, Transform::new_translate(tx, ty));
1835 }
1836
1837 transform = Transform::combine(transform, component.transform);
1838
1839 let mut b = glyf::Builder::new(transform, builder.bbox, builder.builder);
1840 let glyph_data = glyf_table.get(component.glyph_id)?;
1841 outline_var_impl(
1842 glyf_table,
1843 gvar_table,
1844 component.glyph_id,
1845 glyph_data,
1846 coordinates,
1847 depth + 1,
1848 &mut b,
1849 )?;
1850
1851 builder.bbox = b.bbox;
1853 }
1854
1855 Some(())
1856 } else {
1857 None
1859 }
1860}
1861
1862fn parse_variation_data<'a>(
1864 coordinates: &[NormalizedCoordinate],
1865 shared_tuple_records: &LazyArray16<F2DOT14>,
1866 points_len: u16,
1867 data: &'a [u8],
1868 tuples: &mut VariationTuples<'a>,
1869) -> Option<()> {
1870 const SHARED_POINT_NUMBERS_FLAG: u16 = 0x8000;
1871 const COUNT_MASK: u16 = 0x0FFF;
1872
1873 let mut main_stream = Stream::new(data);
1874 let tuple_variation_count = main_stream.read::<u16>()?;
1875 let data_offset = main_stream.read::<Offset16>()?;
1876
1877 let has_shared_point_numbers = tuple_variation_count & SHARED_POINT_NUMBERS_FLAG != 0;
1880 let tuple_variation_count = tuple_variation_count & COUNT_MASK;
1881
1882 if tuple_variation_count == 0 {
1885 return None;
1886 }
1887
1888 if !tuples.reserve(tuple_variation_count) {
1891 return None;
1892 }
1893
1894 let mut serialized_stream = Stream::new_at(data, data_offset.to_usize())?;
1899
1900 let mut shared_point_numbers = None;
1903 if has_shared_point_numbers {
1904 shared_point_numbers = PackedPointsIter::new(&mut serialized_stream)?;
1905 }
1906
1907 parse_variation_tuples(
1908 tuple_variation_count,
1909 coordinates,
1910 shared_tuple_records,
1911 shared_point_numbers,
1912 points_len.checked_add(PHANTOM_POINTS_LEN as u16)?,
1913 main_stream,
1914 serialized_stream,
1915 tuples,
1916 )
1917}