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::parser::{LazyArray16, Offset, Offset16, Offset32, Stream, F2DOT14};
15use crate::{glyf, PhantomPoints, PointF};
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<PointF> {
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(PointF { x, y })
236 }
237
238 fn apply_null(&mut self) -> Option<PointF> {
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(PointF { 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(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 let points_iter = PackedPointsIter::new(&mut Stream::new(&data))
806 .unwrap()
807 .unwrap();
808 let mut iter = SetPointsIter::new(points_iter);
809 assert_eq!(iter.next().unwrap(), false);
810 for _ in 0..150 {
811 assert_eq!(iter.next().unwrap(), false);
812 assert_eq!(iter.next().unwrap(), true);
813 }
814 assert_eq!(iter.next().unwrap(), true);
815 assert_eq!(iter.next().unwrap(), true); }
817
818 #[test]
819 fn long_points() {
820 let data = vec![
821 2, gen_control(NewControl {
823 deltas_are_words: true,
824 run_count: 2,
825 }),
826 0,
827 2,
828 0,
829 3,
830 ];
831
832 let points_iter = PackedPointsIter::new(&mut Stream::new(&data))
833 .unwrap()
834 .unwrap();
835 let mut iter = SetPointsIter::new(points_iter);
836 assert_eq!(iter.next().unwrap(), false);
837 assert_eq!(iter.next().unwrap(), false);
838 assert_eq!(iter.next().unwrap(), true);
839 assert_eq!(iter.next().unwrap(), false);
840 assert_eq!(iter.next().unwrap(), false);
841 assert_eq!(iter.next().unwrap(), true);
842 assert_eq!(iter.next().unwrap(), true); }
844
845 #[test]
846 fn multiple_runs() {
847 let data = vec![
848 5, gen_control(NewControl {
850 deltas_are_words: true,
851 run_count: 2,
852 }),
853 0,
854 2,
855 0,
856 3,
857 gen_control(NewControl {
858 deltas_are_words: false,
859 run_count: 3,
860 }),
861 2,
862 3,
863 2,
864 ];
865
866 let points_iter = PackedPointsIter::new(&mut Stream::new(&data))
867 .unwrap()
868 .unwrap();
869 let mut iter = SetPointsIter::new(points_iter);
870 assert_eq!(iter.next().unwrap(), false);
871 assert_eq!(iter.next().unwrap(), false);
872 assert_eq!(iter.next().unwrap(), true);
873 assert_eq!(iter.next().unwrap(), false);
874 assert_eq!(iter.next().unwrap(), false);
875 assert_eq!(iter.next().unwrap(), true);
876 assert_eq!(iter.next().unwrap(), false);
877 assert_eq!(iter.next().unwrap(), true);
878 assert_eq!(iter.next().unwrap(), false);
879 assert_eq!(iter.next().unwrap(), false);
880 assert_eq!(iter.next().unwrap(), true);
881 assert_eq!(iter.next().unwrap(), false);
882 assert_eq!(iter.next().unwrap(), true);
883 assert_eq!(iter.next().unwrap(), true); }
885
886 #[test]
887 fn runs_overflow() {
888 let data = vec![0xFF; 0xFFFF * 2];
890 assert!(PackedPointsIter::new(&mut Stream::new(&data)).is_none());
891 }
892 }
893}
894
895use packed_points::*;
896
897mod packed_deltas {
899 use crate::parser::Stream;
900
901 struct Control(u8);
902
903 impl Control {
904 const DELTAS_ARE_ZERO_FLAG: u8 = 0x80;
905 const DELTAS_ARE_WORDS_FLAG: u8 = 0x40;
906 const DELTA_RUN_COUNT_MASK: u8 = 0x3F;
907
908 #[inline]
909 fn is_deltas_are_zero(&self) -> bool {
910 self.0 & Self::DELTAS_ARE_ZERO_FLAG != 0
911 }
912
913 #[inline]
914 fn is_deltas_are_words(&self) -> bool {
915 self.0 & Self::DELTAS_ARE_WORDS_FLAG != 0
916 }
917
918 #[inline]
922 fn run_count(&self) -> u8 {
923 (self.0 & Self::DELTA_RUN_COUNT_MASK) + 1
924 }
925 }
926
927 #[derive(Clone, Copy, PartialEq, Debug)]
928 enum State {
929 Control,
930 ZeroDelta,
931 ShortDelta,
932 LongDelta,
933 }
934
935 impl Default for State {
936 #[inline]
937 fn default() -> Self {
938 State::Control
939 }
940 }
941
942 #[derive(Clone, Copy, Default)]
943 struct RunState {
944 data_offset: u16,
945 state: State,
946 run_deltas_left: u8,
947 }
948
949 impl RunState {
950 fn next(&mut self, data: &[u8], scalar: f32) -> Option<f32> {
951 if self.state == State::Control {
952 if usize::from(self.data_offset) == data.len() {
953 return None;
954 }
955
956 let control = Control(Stream::read_at::<u8>(data, usize::from(self.data_offset))?);
957 self.data_offset += 1;
958
959 self.run_deltas_left = control.run_count();
960 self.state = if control.is_deltas_are_zero() {
961 State::ZeroDelta
962 } else if control.is_deltas_are_words() {
963 State::LongDelta
964 } else {
965 State::ShortDelta
966 };
967
968 self.next(data, scalar)
969 } else {
970 let mut s = Stream::new_at(data, usize::from(self.data_offset))?;
971 let delta = if self.state == State::LongDelta {
972 self.data_offset += 2;
973 f32::from(s.read::<i16>()?) * scalar
974 } else if self.state == State::ZeroDelta {
975 0.0
976 } else {
977 self.data_offset += 1;
978 f32::from(s.read::<i8>()?) * scalar
979 };
980
981 self.run_deltas_left -= 1;
982 if self.run_deltas_left == 0 {
983 self.state = State::Control;
984 }
985
986 Some(delta)
987 }
988 }
989 }
990
991 #[derive(Clone, Copy, Default)]
995 pub struct PackedDeltasIter<'a> {
996 data: &'a [u8],
997 x_run: RunState,
998 y_run: RunState,
999
1000 total_count: u16,
1004
1005 scalar: f32,
1006 }
1007
1008 impl<'a> PackedDeltasIter<'a> {
1009 pub fn new(scalar: f32, count: u16, data: &'a [u8]) -> Self {
1011 debug_assert!(core::mem::size_of::<PackedDeltasIter>() <= 32);
1012
1013 let mut iter = PackedDeltasIter {
1014 data,
1015 total_count: count,
1016 scalar,
1017 ..PackedDeltasIter::default()
1018 };
1019
1020 for _ in 0..count {
1029 iter.y_run.next(data, scalar);
1030 }
1031
1032 iter
1033 }
1034
1035 #[inline]
1036 pub fn restart(self) -> Self {
1037 PackedDeltasIter::new(self.scalar, self.total_count, self.data)
1038 }
1039
1040 #[inline]
1041 pub fn next(&mut self) -> Option<(f32, f32)> {
1042 let x = self.x_run.next(self.data, self.scalar)?;
1043 let y = self.y_run.next(self.data, self.scalar)?;
1044 Some((x, y))
1045 }
1046 }
1047
1048 #[cfg(test)]
1049 mod tests {
1050 use super::*;
1051
1052 struct NewControl {
1053 deltas_are_zero: bool,
1054 deltas_are_words: bool,
1055 run_count: u8,
1056 }
1057
1058 fn gen_control(control: NewControl) -> u8 {
1059 assert!(control.run_count > 0, "run count cannot be zero");
1060
1061 let mut n = 0;
1062 if control.deltas_are_zero {
1063 n |= 0x80;
1064 }
1065 if control.deltas_are_words {
1066 n |= 0x40;
1067 }
1068 n |= (control.run_count - 1) & 0x3F;
1069 n
1070 }
1071
1072 #[test]
1073 fn empty() {
1074 let mut iter = PackedDeltasIter::new(1.0, 1, &[]);
1075 assert!(iter.next().is_none());
1076 }
1077
1078 #[test]
1079 fn single_delta() {
1080 let data = vec![
1081 gen_control(NewControl {
1082 deltas_are_zero: false,
1083 deltas_are_words: false,
1084 run_count: 2,
1085 }),
1086 2,
1087 3,
1088 ];
1089
1090 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1091 assert_eq!(iter.next().unwrap(), (2.0, 3.0));
1092 assert!(iter.next().is_none());
1093 }
1094
1095 #[test]
1096 fn two_deltas() {
1097 let data = vec![
1098 gen_control(NewControl {
1099 deltas_are_zero: false,
1100 deltas_are_words: false,
1101 run_count: 4,
1102 }),
1103 2,
1104 3,
1105 4,
1106 5,
1107 ];
1108
1109 let mut iter = PackedDeltasIter::new(1.0, 2, &data);
1110 assert_eq!(iter.next().unwrap(), (2.0, 4.0));
1112 assert_eq!(iter.next().unwrap(), (3.0, 5.0));
1113 assert!(iter.next().is_none());
1114 }
1115
1116 #[test]
1117 fn single_long_delta() {
1118 let data = vec![
1119 gen_control(NewControl {
1120 deltas_are_zero: false,
1121 deltas_are_words: true,
1122 run_count: 2,
1123 }),
1124 0,
1125 2,
1126 0,
1127 3,
1128 ];
1129
1130 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1131 assert_eq!(iter.next().unwrap(), (2.0, 3.0));
1132 assert!(iter.next().is_none());
1133 }
1134
1135 #[test]
1136 fn zeros() {
1137 let data = vec![gen_control(NewControl {
1138 deltas_are_zero: true,
1139 deltas_are_words: false,
1140 run_count: 4,
1141 })];
1142
1143 let mut iter = PackedDeltasIter::new(1.0, 2, &data);
1144 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1145 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1146 assert!(iter.next().is_none());
1147 }
1148
1149 #[test]
1150 fn zero_words() {
1151 let data = vec![gen_control(NewControl {
1154 deltas_are_zero: true,
1155 deltas_are_words: true,
1156 run_count: 4,
1157 })];
1158
1159 let mut iter = PackedDeltasIter::new(1.0, 2, &data);
1160 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1161 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1162 assert!(iter.next().is_none());
1163 }
1164
1165 #[test]
1166 fn zero_runs() {
1167 let data = vec![
1168 gen_control(NewControl {
1169 deltas_are_zero: true,
1170 deltas_are_words: false,
1171 run_count: 2,
1172 }),
1173 gen_control(NewControl {
1174 deltas_are_zero: true,
1175 deltas_are_words: false,
1176 run_count: 4,
1177 }),
1178 gen_control(NewControl {
1179 deltas_are_zero: true,
1180 deltas_are_words: false,
1181 run_count: 6,
1182 }),
1183 ];
1184
1185 let mut iter = PackedDeltasIter::new(1.0, 6, &data);
1186 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1188 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1190 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1191 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1193 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1194 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1195 assert!(iter.next().is_none());
1196 }
1197
1198 #[test]
1199 fn delta_after_zeros() {
1200 let data = vec![
1201 gen_control(NewControl {
1202 deltas_are_zero: true,
1203 deltas_are_words: false,
1204 run_count: 2,
1205 }),
1206 gen_control(NewControl {
1207 deltas_are_zero: false,
1208 deltas_are_words: false,
1209 run_count: 2,
1210 }),
1211 2,
1212 3,
1213 ];
1214
1215 let mut iter = PackedDeltasIter::new(1.0, 2, &data);
1216 assert_eq!(iter.next().unwrap(), (0.0, 2.0));
1217 assert_eq!(iter.next().unwrap(), (0.0, 3.0));
1218 assert!(iter.next().is_none());
1219 }
1220
1221 #[test]
1222 fn unexpected_end_of_data_1() {
1223 let data = vec![gen_control(NewControl {
1224 deltas_are_zero: false,
1225 deltas_are_words: false,
1226 run_count: 2,
1227 })];
1228
1229 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1230 assert!(iter.next().is_none());
1231 }
1232
1233 #[test]
1234 fn unexpected_end_of_data_2() {
1235 let data = vec![
1238 gen_control(NewControl {
1239 deltas_are_zero: false,
1240 deltas_are_words: false,
1241 run_count: 2,
1242 }),
1243 1,
1244 ];
1245
1246 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1247 assert!(iter.next().is_none());
1248 }
1249
1250 #[test]
1251 fn unexpected_end_of_data_3() {
1252 let data = vec![gen_control(NewControl {
1253 deltas_are_zero: false,
1254 deltas_are_words: true,
1255 run_count: 2,
1256 })];
1257
1258 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1259 assert!(iter.next().is_none());
1260 }
1261
1262 #[test]
1263 fn unexpected_end_of_data_4() {
1264 let data = vec![
1267 gen_control(NewControl {
1268 deltas_are_zero: false,
1269 deltas_are_words: true,
1270 run_count: 2,
1271 }),
1272 1,
1273 ];
1274
1275 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1276 assert!(iter.next().is_none());
1277 }
1278
1279 #[test]
1280 fn unexpected_end_of_data_6() {
1281 let data = vec![
1284 gen_control(NewControl {
1285 deltas_are_zero: false,
1286 deltas_are_words: true,
1287 run_count: 2,
1288 }),
1289 0,
1290 1,
1291 ];
1292
1293 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1294 assert!(iter.next().is_none());
1295 }
1296
1297 #[test]
1298 fn unexpected_end_of_data_7() {
1299 let data = vec![
1302 gen_control(NewControl {
1303 deltas_are_zero: false,
1304 deltas_are_words: true,
1305 run_count: 2,
1306 }),
1307 0,
1308 1,
1309 0,
1310 ];
1311
1312 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1313 assert!(iter.next().is_none());
1314 }
1315
1316 #[test]
1317 fn single_run() {
1318 let data = vec![
1319 gen_control(NewControl {
1320 deltas_are_zero: false,
1321 deltas_are_words: false,
1322 run_count: 1,
1323 }),
1324 2,
1325 3,
1326 ];
1327
1328 let mut iter = PackedDeltasIter::new(1.0, 1, &data);
1329 assert!(iter.next().is_none());
1330 }
1331
1332 #[test]
1333 fn too_many_pairs() {
1334 let data = vec![
1335 gen_control(NewControl {
1336 deltas_are_zero: false,
1337 deltas_are_words: false,
1338 run_count: 2,
1339 }),
1340 2,
1341 3,
1342 ];
1343
1344 let mut iter = PackedDeltasIter::new(1.0, 10, &data);
1346 assert!(iter.next().is_none());
1347 }
1348
1349 #[test]
1350 fn invalid_number_of_pairs() {
1351 let data = vec![
1352 gen_control(NewControl {
1353 deltas_are_zero: false,
1354 deltas_are_words: false,
1355 run_count: 2,
1356 }),
1357 2,
1358 3,
1359 4,
1360 5,
1361 6,
1362 7,
1363 ];
1364
1365 let mut iter = PackedDeltasIter::new(1.0, 4, &data);
1370 assert_eq!(iter.next().unwrap(), (2.0, 7.0));
1371 assert!(iter.next().is_none());
1372 }
1373
1374 #[test]
1375 fn mixed_runs() {
1376 let data = vec![
1377 gen_control(NewControl {
1378 deltas_are_zero: false,
1379 deltas_are_words: false,
1380 run_count: 3,
1381 }),
1382 2,
1383 3,
1384 4,
1385 gen_control(NewControl {
1386 deltas_are_zero: false,
1387 deltas_are_words: true,
1388 run_count: 2,
1389 }),
1390 0,
1391 5,
1392 0,
1393 6,
1394 gen_control(NewControl {
1395 deltas_are_zero: true,
1396 deltas_are_words: false,
1397 run_count: 1,
1398 }),
1399 ];
1400
1401 let mut iter = PackedDeltasIter::new(1.0, 3, &data);
1402 assert_eq!(iter.next().unwrap(), (2.0, 5.0));
1403 assert_eq!(iter.next().unwrap(), (3.0, 6.0));
1404 assert_eq!(iter.next().unwrap(), (4.0, 0.0));
1405 assert!(iter.next().is_none());
1406 }
1407
1408 #[test]
1409 fn non_default_scalar() {
1410 let data = vec![
1411 gen_control(NewControl {
1412 deltas_are_zero: false,
1413 deltas_are_words: false,
1414 run_count: 2,
1415 }),
1416 2,
1417 3,
1418 ];
1419
1420 let mut iter = PackedDeltasIter::new(0.5, 1, &data);
1421 assert_eq!(iter.next().unwrap(), (1.0, 1.5));
1422 assert!(iter.next().is_none());
1423 }
1424
1425 #[test]
1426 fn runs_overflow() {
1427 let data = vec![0xFF; 0xFFFF];
1428 let mut iter = PackedDeltasIter::new(1.0, 0xFFFF, &data);
1429 assert_eq!(iter.next().unwrap(), (0.0, 0.0));
1431 }
1432 }
1433}
1434
1435use packed_deltas::PackedDeltasIter;
1436
1437fn infer_deltas(
1458 tuple: &VariationTuple,
1459 points_set: SetPointsIter,
1460 points: glyf::GlyphPointsIter,
1462 all_points: glyf::GlyphPointsIter,
1464 curr_point: glyf::GlyphPoint,
1465) -> (f32, f32) {
1466 let mut current_contour = points.current_contour();
1467 if curr_point.last_point && current_contour != 0 {
1468 current_contour -= 1;
1472 }
1473
1474 let prev_point = if let Some(prev_point) = tuple.prev_point {
1475 prev_point
1477 } else {
1478 let mut last_point = None;
1480 let mut deltas = tuple.deltas.clone();
1481 for (point, is_set) in points.clone().zip(points_set.clone()) {
1482 if is_set {
1483 if let Some((x_delta, y_delta)) = deltas.next() {
1484 last_point = Some(PointAndDelta {
1485 x: point.x,
1486 y: point.y,
1487 x_delta,
1488 y_delta,
1489 });
1490 }
1491 }
1492
1493 if point.last_point {
1494 break;
1495 }
1496 }
1497
1498 match last_point {
1500 Some(p) => p,
1501 None => return (0.0, 0.0),
1502 }
1503 };
1504
1505 let mut next_point = None;
1506 if !curr_point.last_point {
1507 let mut deltas = tuple.deltas.clone();
1510 for (point, is_set) in points.clone().zip(points_set.clone()) {
1511 if is_set {
1512 if let Some((x_delta, y_delta)) = deltas.next() {
1513 next_point = Some(PointAndDelta {
1514 x: point.x,
1515 y: point.y,
1516 x_delta,
1517 y_delta,
1518 });
1519 }
1520
1521 break;
1522 }
1523
1524 if point.last_point {
1525 break;
1526 }
1527 }
1528 }
1529
1530 if next_point.is_none() {
1531 let mut all_points = all_points.clone();
1540 let mut deltas = tuple.deltas.clone().restart();
1541 let mut points_set = points_set.clone().restart();
1542
1543 let mut contour = 0;
1544 while let (Some(point), Some(is_set)) = (all_points.next(), points_set.next()) {
1545 if contour != current_contour {
1547 if is_set {
1548 let _ = deltas.next();
1549 }
1550
1551 contour = all_points.current_contour();
1552 continue;
1553 }
1554
1555 if is_set {
1556 let (x_delta, y_delta) = deltas.next().unwrap_or((0.0, 0.0));
1557 next_point = Some(PointAndDelta {
1558 x: point.x,
1559 y: point.y,
1560 x_delta,
1561 y_delta,
1562 });
1563
1564 break;
1565 }
1566
1567 if point.last_point {
1568 break;
1569 }
1570 }
1571 }
1572
1573 let next_point = match next_point {
1575 Some(p) => p,
1576 None => return (0.0, 0.0),
1577 };
1578
1579 let dx = infer_delta(
1580 prev_point.x,
1581 curr_point.x,
1582 next_point.x,
1583 prev_point.x_delta,
1584 next_point.x_delta,
1585 );
1586
1587 let dy = infer_delta(
1588 prev_point.y,
1589 curr_point.y,
1590 next_point.y,
1591 prev_point.y_delta,
1592 next_point.y_delta,
1593 );
1594
1595 (dx, dy)
1596}
1597
1598fn infer_delta(
1599 prev_point: i16,
1600 target_point: i16,
1601 next_point: i16,
1602 prev_delta: f32,
1603 next_delta: f32,
1604) -> f32 {
1605 if prev_point == next_point {
1606 if prev_delta == next_delta {
1607 prev_delta
1608 } else {
1609 0.0
1610 }
1611 } else if target_point <= prev_point.min(next_point) {
1612 if prev_point < next_point {
1613 prev_delta
1614 } else {
1615 next_delta
1616 }
1617 } else if target_point >= prev_point.max(next_point) {
1618 if prev_point > next_point {
1619 prev_delta
1620 } else {
1621 next_delta
1622 }
1623 } else {
1624 let target_sub = target_point.checked_sub(prev_point);
1629 let next_sub = next_point.checked_sub(prev_point);
1630 let d = if let (Some(target_sub), Some(next_sub)) = (target_sub, next_sub) {
1631 f32::from(target_sub) / f32::from(next_sub)
1632 } else {
1633 return 0.0;
1634 };
1635 (1.0 - d) * prev_delta + d * next_delta
1636 }
1637}
1638
1639#[derive(Clone, Copy)]
1642pub struct Table<'a> {
1643 axis_count: NonZeroU16,
1644 shared_tuple_records: LazyArray16<'a, F2DOT14>,
1645 offsets: GlyphVariationDataOffsets<'a>,
1646 glyphs_variation_data: &'a [u8],
1647}
1648
1649impl<'a> Table<'a> {
1650 pub fn parse(data: &'a [u8]) -> Option<Self> {
1652 let mut s = Stream::new(data);
1653 let version = s.read::<u32>()?;
1654 if version != 0x00010000 {
1655 return None;
1656 }
1657
1658 let axis_count = s.read::<u16>()?;
1659 let shared_tuple_count = s.read::<u16>()?;
1660 let shared_tuples_offset = s.read::<Offset32>()?;
1661 let glyph_count = s.read::<u16>()?;
1662 let flags = s.read::<u16>()?;
1663 let glyph_variation_data_array_offset = s.read::<Offset32>()?;
1664
1665 let axis_count = NonZeroU16::new(axis_count)?;
1667
1668 let shared_tuple_records = {
1669 let mut sub_s = Stream::new_at(data, shared_tuples_offset.to_usize())?;
1670 sub_s.read_array16::<F2DOT14>(shared_tuple_count.checked_mul(axis_count.get())?)?
1671 };
1672
1673 let glyphs_variation_data = data.get(glyph_variation_data_array_offset.to_usize()..)?;
1674 let offsets = {
1675 let offsets_count = glyph_count.checked_add(1)?;
1676 let is_long_format = flags & 1 == 1; if is_long_format {
1678 GlyphVariationDataOffsets::Long(s.read_array16::<Offset32>(offsets_count)?)
1679 } else {
1680 GlyphVariationDataOffsets::Short(s.read_array16::<Offset16>(offsets_count)?)
1681 }
1682 };
1683
1684 Some(Table {
1685 axis_count,
1686 shared_tuple_records,
1687 offsets,
1688 glyphs_variation_data,
1689 })
1690 }
1691
1692 #[inline]
1693 fn parse_variation_data(
1694 &self,
1695 glyph_id: GlyphId,
1696 coordinates: &[NormalizedCoordinate],
1697 points_len: u16,
1698 tuples: &mut VariationTuples<'a>,
1699 ) -> Option<()> {
1700 tuples.clear();
1701
1702 if coordinates.len() != usize::from(self.axis_count.get()) {
1703 return None;
1704 }
1705
1706 let next_glyph_id = glyph_id.0.checked_add(1)?;
1707
1708 let (start, end) = match self.offsets {
1709 GlyphVariationDataOffsets::Short(ref array) => {
1710 (
1713 array.get(glyph_id.0)?.to_usize() * 2,
1714 array.get(next_glyph_id)?.to_usize() * 2,
1715 )
1716 }
1717 GlyphVariationDataOffsets::Long(ref array) => (
1718 array.get(glyph_id.0)?.to_usize(),
1719 array.get(next_glyph_id)?.to_usize(),
1720 ),
1721 };
1722
1723 if start == end {
1725 return Some(());
1726 }
1727
1728 let data = self.glyphs_variation_data.get(start..end)?;
1729 parse_variation_data(
1730 coordinates,
1731 &self.shared_tuple_records,
1732 points_len,
1733 data,
1734 tuples,
1735 )
1736 }
1737
1738 pub fn outline(
1740 &self,
1741 glyf_table: glyf::Table,
1742 coordinates: &[NormalizedCoordinate],
1743 glyph_id: GlyphId,
1744 builder: &mut dyn OutlineBuilder,
1745 ) -> Option<Rect> {
1746 let mut b = glyf::Builder::new(Transform::default(), RectF::new(), builder);
1747 let glyph_data = glyf_table.get(glyph_id)?;
1748 outline_var_impl(
1749 glyf_table,
1750 self,
1751 glyph_id,
1752 glyph_data,
1753 coordinates,
1754 0,
1755 &mut b,
1756 );
1757 b.bbox.to_rect()
1758 }
1759
1760 pub(crate) fn phantom_points(
1761 &self,
1762 glyf_table: glyf::Table,
1763 coordinates: &[NormalizedCoordinate],
1764 glyph_id: GlyphId,
1765 ) -> Option<PhantomPoints> {
1766 let outline_points = glyf_table.outline_points(glyph_id);
1767 let mut tuples = VariationTuples::default();
1768 self.parse_variation_data(glyph_id, coordinates, outline_points, &mut tuples)?;
1769
1770 for _ in 0..outline_points {
1772 tuples.apply_null()?;
1773 }
1774
1775 Some(PhantomPoints {
1776 left: tuples.apply_null()?,
1777 right: tuples.apply_null()?,
1778 top: tuples.apply_null()?,
1779 bottom: tuples.apply_null()?,
1780 })
1781 }
1782}
1783
1784impl core::fmt::Debug for Table<'_> {
1785 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1786 write!(f, "Table {{ ... }}")
1787 }
1788}
1789
1790#[allow(clippy::comparison_chain)]
1791fn outline_var_impl(
1792 glyf_table: glyf::Table,
1793 gvar_table: &Table,
1794 glyph_id: GlyphId,
1795 data: &[u8],
1796 coordinates: &[NormalizedCoordinate],
1797 depth: u8,
1798 builder: &mut glyf::Builder,
1799) -> Option<()> {
1800 if depth >= glyf::MAX_COMPONENTS {
1801 return None;
1802 }
1803
1804 let mut s = Stream::new(data);
1805 let number_of_contours = s.read::<i16>()?;
1806
1807 s.advance(8);
1813
1814 let mut tuples = VariationTuples::default();
1817
1818 if number_of_contours > 0 {
1819 let number_of_contours = NonZeroU16::new(number_of_contours as u16)?;
1822 let mut glyph_points = glyf::parse_simple_outline(s.tail()?, number_of_contours)?;
1823 let all_glyph_points = glyph_points.clone();
1824 let points_len = glyph_points.points_left;
1825 gvar_table.parse_variation_data(glyph_id, coordinates, points_len, &mut tuples)?;
1826
1827 while let Some(point) = glyph_points.next() {
1828 let p = tuples.apply(all_glyph_points.clone(), glyph_points.clone(), point)?;
1829 builder.push_point(p.x, p.y, point.on_curve_point, point.last_point);
1830 }
1831
1832 Some(())
1833 } else if number_of_contours < 0 {
1834 let components = glyf::CompositeGlyphIter::new(s.tail()?);
1845 let components_count = components.clone().count() as u16;
1846 gvar_table.parse_variation_data(glyph_id, coordinates, components_count, &mut tuples)?;
1847
1848 for component in components {
1849 let t = tuples.apply_null()?;
1850
1851 let mut transform = builder.transform;
1852
1853 if component.flags.args_are_xy_values() {
1856 transform = Transform::combine(transform, Transform::new_translate(t.x, t.y));
1857 }
1858
1859 transform = Transform::combine(transform, component.transform);
1860
1861 let mut b = glyf::Builder::new(transform, builder.bbox, builder.builder);
1862 if let Some(glyph_data) = glyf_table.get(component.glyph_id) {
1863 outline_var_impl(
1864 glyf_table,
1865 gvar_table,
1866 component.glyph_id,
1867 glyph_data,
1868 coordinates,
1869 depth + 1,
1870 &mut b,
1871 )?;
1872
1873 builder.bbox = b.bbox;
1875 }
1876 }
1877
1878 Some(())
1879 } else {
1880 None
1882 }
1883}
1884
1885fn parse_variation_data<'a>(
1887 coordinates: &[NormalizedCoordinate],
1888 shared_tuple_records: &LazyArray16<F2DOT14>,
1889 points_len: u16,
1890 data: &'a [u8],
1891 tuples: &mut VariationTuples<'a>,
1892) -> Option<()> {
1893 const SHARED_POINT_NUMBERS_FLAG: u16 = 0x8000;
1894 const COUNT_MASK: u16 = 0x0FFF;
1895
1896 let mut main_stream = Stream::new(data);
1897 let tuple_variation_count = main_stream.read::<u16>()?;
1898 let data_offset = main_stream.read::<Offset16>()?;
1899
1900 let has_shared_point_numbers = tuple_variation_count & SHARED_POINT_NUMBERS_FLAG != 0;
1903 let tuple_variation_count = tuple_variation_count & COUNT_MASK;
1904
1905 if tuple_variation_count == 0 {
1908 return None;
1909 }
1910
1911 if !tuples.reserve(tuple_variation_count) {
1914 return None;
1915 }
1916
1917 let mut serialized_stream = Stream::new_at(data, data_offset.to_usize())?;
1922
1923 let mut shared_point_numbers = None;
1926 if has_shared_point_numbers {
1927 shared_point_numbers = PackedPointsIter::new(&mut serialized_stream)?;
1928 }
1929
1930 parse_variation_tuples(
1931 tuple_variation_count,
1932 coordinates,
1933 shared_tuple_records,
1934 shared_point_numbers,
1935 points_len.checked_add(PHANTOM_POINTS_LEN as u16)?,
1936 main_stream,
1937 serialized_stream,
1938 tuples,
1939 )
1940}