1pub mod bytecode;
4mod hint_reliant;
5pub mod outline;
6
7pub use hint_reliant::is_hint_reliant;
8
9use bytemuck::AnyBitPattern;
10use core::ops::{Add, AddAssign, Div, Mul, MulAssign, Sub};
11use types::{F26Dot6, Point};
12
13include!("../../generated/generated_glyf.rs");
14
15pub const PHANTOM_POINT_COUNT: usize = 4;
23
24#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)]
27pub struct PointMarker(u8);
28
29impl PointMarker {
30 pub const HAS_DELTA: Self = Self(0x4);
33
34 pub const TOUCHED_X: Self = Self(0x10);
37
38 pub const TOUCHED_Y: Self = Self(0x20);
41
42 pub const TOUCHED: Self = Self(Self::TOUCHED_X.0 | Self::TOUCHED_Y.0);
45
46 pub const WEAK_INTERPOLATION: Self = Self(0x2);
50
51 pub const NEAR: PointMarker = Self(0x8);
55}
56
57impl core::ops::BitOr for PointMarker {
58 type Output = Self;
59
60 fn bitor(self, rhs: Self) -> Self::Output {
61 Self(self.0 | rhs.0)
62 }
63}
64
65#[derive(
71 Copy, Clone, PartialEq, Eq, Default, Debug, bytemuck::AnyBitPattern, bytemuck::NoUninit,
72)]
73#[repr(transparent)]
74pub struct PointFlags(u8);
75
76impl PointFlags {
77 const ON_CURVE: u8 = SimpleGlyphFlags::ON_CURVE_POINT.bits;
80 const OFF_CURVE_CUBIC: u8 = SimpleGlyphFlags::CUBIC.bits;
81 const CURVE_MASK: u8 = Self::ON_CURVE | Self::OFF_CURVE_CUBIC;
82
83 pub const fn on_curve() -> Self {
85 Self(Self::ON_CURVE)
86 }
87
88 pub const fn off_curve_quad() -> Self {
90 Self(0)
91 }
92
93 pub const fn off_curve_cubic() -> Self {
95 Self(Self::OFF_CURVE_CUBIC)
96 }
97
98 pub const fn from_bits(bits: u8) -> Self {
101 Self(bits & Self::CURVE_MASK)
102 }
103
104 #[inline]
106 pub const fn is_on_curve(self) -> bool {
107 self.0 & Self::ON_CURVE != 0
108 }
109
110 #[inline]
112 pub const fn is_off_curve_quad(self) -> bool {
113 self.0 & Self::CURVE_MASK == 0
114 }
115
116 #[inline]
118 pub const fn is_off_curve_cubic(self) -> bool {
119 self.0 & Self::CURVE_MASK == Self::OFF_CURVE_CUBIC
120 }
121
122 pub const fn is_off_curve(self) -> bool {
123 self.is_off_curve_quad() || self.is_off_curve_cubic()
124 }
125
126 pub fn flip_on_curve(&mut self) {
130 self.0 ^= 1;
131 }
132
133 pub fn set_on_curve(&mut self) {
137 self.0 |= Self::ON_CURVE;
138 }
139
140 pub fn clear_on_curve(&mut self) {
144 self.0 &= !Self::ON_CURVE;
145 }
146
147 pub fn has_marker(self, marker: PointMarker) -> bool {
149 self.0 & marker.0 != 0
150 }
151
152 pub fn set_marker(&mut self, marker: PointMarker) {
154 self.0 |= marker.0;
155 }
156
157 pub fn clear_marker(&mut self, marker: PointMarker) {
159 self.0 &= !marker.0
160 }
161
162 pub const fn without_markers(self) -> Self {
164 Self(self.0 & Self::CURVE_MASK)
165 }
166
167 pub const fn to_bits(self) -> u8 {
169 self.0
170 }
171}
172
173pub trait PointCoord:
175 Copy
176 + Default
177 + AnyBitPattern
179 + PartialEq
181 + PartialOrd
182 + Add<Output = Self>
184 + AddAssign
185 + Sub<Output = Self>
186 + Div<Output = Self>
187 + Mul<Output = Self>
188 + MulAssign {
189 fn from_fixed(x: Fixed) -> Self;
190 fn from_i32(x: i32) -> Self;
191 fn to_f32(self) -> f32;
192 fn midpoint(self, other: Self) -> Self;
193}
194
195impl<'a> SimpleGlyph<'a> {
196 pub fn num_points(&self) -> usize {
198 self.end_pts_of_contours()
199 .last()
200 .map(|last| last.get() as usize + 1)
201 .unwrap_or(0)
202 }
203
204 pub fn has_overlapping_contours(&self) -> bool {
206 FontData::new(self.glyph_data())
210 .read_at::<SimpleGlyphFlags>(0)
211 .map(|flag| flag.contains(SimpleGlyphFlags::OVERLAP_SIMPLE))
212 .unwrap_or_default()
213 }
214
215 pub fn read_points_fast<C: PointCoord>(
226 &self,
227 points: &mut [Point<C>],
228 flags: &mut [PointFlags],
229 ) -> Result<(), ReadError> {
230 let n_points = self.num_points();
231 if points.len() != n_points || flags.len() != n_points {
232 return Err(ReadError::InvalidArrayLen);
233 }
234 if n_points == 0 {
235 return Ok(());
236 }
237 let mut cursor = FontData::new(self.glyph_data()).cursor();
238 let flags_data = cursor.read_array::<u8>(cursor.remaining_bytes())?;
242 let mut flags_iter = flags_data.iter().copied();
243 let mut read_flags_bytes = 0;
246 let mut i = 0;
247 while let Some(flag_bits) = flags_iter.next() {
248 read_flags_bytes += 1;
249 if SimpleGlyphFlags::from_bits_truncate(flag_bits)
250 .contains(SimpleGlyphFlags::REPEAT_FLAG)
251 {
252 let count = (flags_iter.next().ok_or(ReadError::OutOfBounds)? as usize + 1)
253 .min(n_points - i);
254 read_flags_bytes += 1;
255 for f in &mut flags[i..i + count] {
256 f.0 = flag_bits;
257 }
258 i += count;
259 } else {
260 flags[i].0 = flag_bits;
261 i += 1;
262 }
263 if i == n_points {
264 break;
265 }
266 }
267 let coords = self
274 .glyph_data()
275 .get(read_flags_bytes..)
276 .ok_or(ReadError::OutOfBounds)?;
277 let mut bytes = coords.iter();
278 let mut x = 0i32;
279 for (&point_flags, point) in flags.iter().zip(points.as_mut()) {
280 let mut delta = 0i32;
281 let flag = SimpleGlyphFlags::from_bits_truncate(point_flags.0);
282 if flag.contains(SimpleGlyphFlags::X_SHORT_VECTOR) {
283 delta = *bytes.next().ok_or(ReadError::OutOfBounds)? as i32;
284 if !flag.contains(SimpleGlyphFlags::X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR) {
285 delta = -delta;
286 }
287 } else if !flag.contains(SimpleGlyphFlags::X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR) {
288 let hi = *bytes.next().ok_or(ReadError::OutOfBounds)?;
289 let lo = *bytes.next().ok_or(ReadError::OutOfBounds)?;
290 delta = i16::from_be_bytes([hi, lo]) as i32;
291 }
292 x = x.wrapping_add(delta);
293 point.x = C::from_i32(x);
294 }
295 let mut y = 0i32;
296 for (point_flags, point) in flags.iter_mut().zip(points.as_mut()) {
297 let mut delta = 0i32;
298 let flag = SimpleGlyphFlags::from_bits_truncate(point_flags.0);
299 if flag.contains(SimpleGlyphFlags::Y_SHORT_VECTOR) {
300 delta = *bytes.next().ok_or(ReadError::OutOfBounds)? as i32;
301 if !flag.contains(SimpleGlyphFlags::Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR) {
302 delta = -delta;
303 }
304 } else if !flag.contains(SimpleGlyphFlags::Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR) {
305 let hi = *bytes.next().ok_or(ReadError::OutOfBounds)?;
306 let lo = *bytes.next().ok_or(ReadError::OutOfBounds)?;
307 delta = i16::from_be_bytes([hi, lo]) as i32;
308 }
309 y = y.wrapping_add(delta);
310 point.y = C::from_i32(y);
311 point_flags.0 &= PointFlags::CURVE_MASK;
312 }
313 Ok(())
314 }
315
316 pub fn points(&self) -> impl Iterator<Item = CurvePoint> + 'a + Clone {
323 self.points_impl()
324 .unwrap_or_else(|| PointIter::new(&[], &[], &[]))
325 }
326
327 fn points_impl(&self) -> Option<PointIter<'a>> {
328 let end_points = self.end_pts_of_contours();
329 let n_points = end_points.last()?.get().checked_add(1)?;
330 let data = self.glyph_data();
331 let lens = resolve_coords_len(data, n_points).ok()?;
332 let total_len = lens.flags + lens.x_coords + lens.y_coords;
333 if data.len() < total_len as usize {
334 return None;
335 }
336
337 let (flags, data) = data.split_at(lens.flags as usize);
338 let (x_coords, y_coords) = data.split_at(lens.x_coords as usize);
339
340 Some(PointIter::new(flags, x_coords, y_coords))
341 }
342}
343
344#[derive(Clone, Copy, Debug, PartialEq, Eq)]
348pub struct CurvePoint {
349 pub x: i16,
351 pub y: i16,
353 pub on_curve: bool,
355 pub cubic: bool,
357}
358
359impl CurvePoint {
360 pub fn new(x: i16, y: i16, on_curve: bool) -> Self {
362 Self {
363 x,
364 y,
365 on_curve,
366 cubic: false,
367 }
368 }
369
370 pub fn on_curve(x: i16, y: i16) -> Self {
372 Self::new(x, y, true)
373 }
374
375 pub fn off_curve(x: i16, y: i16) -> Self {
377 Self::new(x, y, false)
378 }
379
380 pub fn off_curve_cubic(x: i16, y: i16) -> Self {
382 Self {
383 cubic: true,
384 ..Self::off_curve(x, y)
385 }
386 }
387}
388
389#[derive(Clone)]
390struct PointIter<'a> {
391 flags: Cursor<'a>,
392 x_coords: Cursor<'a>,
393 y_coords: Cursor<'a>,
394 flag_repeats: u16,
395 cur_flags: SimpleGlyphFlags,
396 cur_x: i16,
397 cur_y: i16,
398}
399
400impl Iterator for PointIter<'_> {
401 type Item = CurvePoint;
402 fn next(&mut self) -> Option<Self::Item> {
403 self.advance_flags()?;
404 self.advance_points();
405 Some(CurvePoint {
406 x: self.cur_x,
407 y: self.cur_y,
408 on_curve: self.cur_flags.contains(SimpleGlyphFlags::ON_CURVE_POINT),
409 cubic: self.cur_flags.contains(SimpleGlyphFlags::CUBIC),
410 })
411 }
412}
413
414impl<'a> PointIter<'a> {
415 fn new(flags: &'a [u8], x_coords: &'a [u8], y_coords: &'a [u8]) -> Self {
416 Self {
417 flags: FontData::new(flags).cursor(),
418 x_coords: FontData::new(x_coords).cursor(),
419 y_coords: FontData::new(y_coords).cursor(),
420 flag_repeats: 0,
421 cur_flags: SimpleGlyphFlags::empty(),
422 cur_x: 0,
423 cur_y: 0,
424 }
425 }
426
427 fn advance_flags(&mut self) -> Option<()> {
428 if self.flag_repeats == 0 {
429 self.cur_flags = SimpleGlyphFlags::from_bits_truncate(self.flags.read().ok()?);
430 self.flag_repeats = self
431 .cur_flags
432 .contains(SimpleGlyphFlags::REPEAT_FLAG)
433 .then(|| self.flags.read::<u8>().ok())
434 .flatten()
435 .unwrap_or(0) as u16
436 + 1;
437 }
438 self.flag_repeats -= 1;
439 Some(())
440 }
441
442 fn advance_points(&mut self) {
443 let x_short = self.cur_flags.contains(SimpleGlyphFlags::X_SHORT_VECTOR);
444 let x_same_or_pos = self
445 .cur_flags
446 .contains(SimpleGlyphFlags::X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR);
447 let y_short = self.cur_flags.contains(SimpleGlyphFlags::Y_SHORT_VECTOR);
448 let y_same_or_pos = self
449 .cur_flags
450 .contains(SimpleGlyphFlags::Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR);
451
452 let delta_x = match (x_short, x_same_or_pos) {
453 (true, false) => -(self.x_coords.read::<u8>().unwrap_or(0) as i16),
454 (true, true) => self.x_coords.read::<u8>().unwrap_or(0) as i16,
455 (false, false) => self.x_coords.read::<i16>().unwrap_or(0),
456 _ => 0,
457 };
458
459 let delta_y = match (y_short, y_same_or_pos) {
460 (true, false) => -(self.y_coords.read::<u8>().unwrap_or(0) as i16),
461 (true, true) => self.y_coords.read::<u8>().unwrap_or(0) as i16,
462 (false, false) => self.y_coords.read::<i16>().unwrap_or(0),
463 _ => 0,
464 };
465
466 self.cur_x = self.cur_x.wrapping_add(delta_x);
467 self.cur_y = self.cur_y.wrapping_add(delta_y);
468 }
469}
470
471fn resolve_coords_len(data: &[u8], points_total: u16) -> Result<FieldLengths, ReadError> {
476 let mut cursor = FontData::new(data).cursor();
477 let mut flags_left = u32::from(points_total);
478 let mut x_coords_len = 0;
480 let mut y_coords_len = 0;
481 while flags_left > 0 {
483 let flags: SimpleGlyphFlags = cursor.read()?;
484
485 let repeats = if flags.contains(SimpleGlyphFlags::REPEAT_FLAG) {
487 let repeats: u8 = cursor.read()?;
488 u32::from(repeats) + 1
489 } else {
490 1
491 };
492
493 if repeats > flags_left {
494 return Err(ReadError::MalformedData("repeat count too large in glyf"));
495 }
496
497 let x_short = SimpleGlyphFlags::X_SHORT_VECTOR;
515 let x_long = SimpleGlyphFlags::X_SHORT_VECTOR
516 | SimpleGlyphFlags::X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR;
517 let y_short = SimpleGlyphFlags::Y_SHORT_VECTOR;
518 let y_long = SimpleGlyphFlags::Y_SHORT_VECTOR
519 | SimpleGlyphFlags::Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR;
520 x_coords_len += ((flags & x_short).bits() != 0) as u32 * repeats;
521 x_coords_len += ((flags & x_long).bits() == 0) as u32 * repeats * 2;
522
523 y_coords_len += ((flags & y_short).bits() != 0) as u32 * repeats;
524 y_coords_len += ((flags & y_long).bits() == 0) as u32 * repeats * 2;
525
526 flags_left -= repeats;
527 }
528
529 Ok(FieldLengths {
530 flags: cursor.position()? as u32,
531 x_coords: x_coords_len,
532 y_coords: y_coords_len,
533 })
534 }
536
537struct FieldLengths {
538 flags: u32,
539 x_coords: u32,
540 y_coords: u32,
541}
542
543#[derive(Clone, Copy, Debug, PartialEq, Eq)]
545pub struct Transform {
546 pub xx: F2Dot14,
548 pub yx: F2Dot14,
550 pub xy: F2Dot14,
552 pub yy: F2Dot14,
554}
555
556impl Default for Transform {
557 fn default() -> Self {
558 Self {
559 xx: F2Dot14::from_f32(1.0),
560 yx: F2Dot14::from_f32(0.0),
561 xy: F2Dot14::from_f32(0.0),
562 yy: F2Dot14::from_f32(1.0),
563 }
564 }
565}
566
567#[derive(Clone, Debug, PartialEq, Eq)]
569pub struct Component {
570 pub flags: CompositeGlyphFlags,
572 pub glyph: GlyphId,
574 pub anchor: Anchor,
576 pub transform: Transform,
578}
579
580#[derive(Clone, Copy, Debug, PartialEq, Eq)]
582pub enum Anchor {
583 Offset { x: i16, y: i16 },
584 Point { base: u16, component: u16 },
585}
586
587impl<'a> CompositeGlyph<'a> {
588 pub fn components(&self) -> impl Iterator<Item = Component> + 'a + Clone {
590 ComponentIter {
591 cur_flags: CompositeGlyphFlags::empty(),
592 done: false,
593 cursor: FontData::new(self.component_data()).cursor(),
594 }
595 }
596
597 pub fn component_glyphs_and_flags(
600 &self,
601 ) -> impl Iterator<Item = (GlyphId, CompositeGlyphFlags)> + 'a + Clone {
602 ComponentGlyphIdFlagsIter {
603 cur_flags: CompositeGlyphFlags::empty(),
604 done: false,
605 cursor: FontData::new(self.component_data()).cursor(),
606 }
607 }
608
609 pub fn count_and_instructions(&self) -> (usize, Option<&'a [u8]>) {
612 let mut iter = ComponentGlyphIdFlagsIter {
613 cur_flags: CompositeGlyphFlags::empty(),
614 done: false,
615 cursor: FontData::new(self.component_data()).cursor(),
616 };
617 let mut count = 0;
618 let mut has_instructions = false;
619 for (_, flags) in iter.by_ref() {
620 count += 1;
621 has_instructions |= flags.contains(CompositeGlyphFlags::WE_HAVE_INSTRUCTIONS);
623 }
624 let instructions = if has_instructions {
625 iter.cursor
626 .read::<u16>()
627 .ok()
628 .map(|len| len as usize)
629 .and_then(|len| iter.cursor.read_array(len).ok())
630 } else {
631 None
632 };
633 (count, instructions)
634 }
635
636 pub fn instructions(&self) -> Option<&'a [u8]> {
638 self.count_and_instructions().1
639 }
640}
641
642#[derive(Clone)]
643struct ComponentIter<'a> {
644 cur_flags: CompositeGlyphFlags,
645 done: bool,
646 cursor: Cursor<'a>,
647}
648
649fn read_component_glyph(cursor: &mut Cursor<'_>, flags: CompositeGlyphFlags) -> Option<GlyphId> {
650 if flags.contains(CompositeGlyphFlags::GID_IS_24_BIT) {
651 Some(GlyphId::new(cursor.read::<Uint24>().ok()?.to_u32()))
652 } else {
653 Some(cursor.read::<GlyphId16>().ok()?.into())
654 }
655}
656
657impl Iterator for ComponentIter<'_> {
658 type Item = Component;
659
660 fn next(&mut self) -> Option<Self::Item> {
661 if self.done {
662 return None;
663 }
664 let flags: CompositeGlyphFlags = self.cursor.read().ok()?;
665 self.cur_flags = flags;
666 let glyph = read_component_glyph(&mut self.cursor, flags)?;
667 let args_are_words = flags.contains(CompositeGlyphFlags::ARG_1_AND_2_ARE_WORDS);
668 let args_are_xy_values = flags.contains(CompositeGlyphFlags::ARGS_ARE_XY_VALUES);
669 let anchor = match (args_are_xy_values, args_are_words) {
670 (true, true) => Anchor::Offset {
671 x: self.cursor.read().ok()?,
672 y: self.cursor.read().ok()?,
673 },
674 (true, false) => Anchor::Offset {
675 x: self.cursor.read::<i8>().ok()? as _,
676 y: self.cursor.read::<i8>().ok()? as _,
677 },
678 (false, true) => Anchor::Point {
679 base: self.cursor.read().ok()?,
680 component: self.cursor.read().ok()?,
681 },
682 (false, false) => Anchor::Point {
683 base: self.cursor.read::<u8>().ok()? as _,
684 component: self.cursor.read::<u8>().ok()? as _,
685 },
686 };
687 let mut transform = Transform::default();
688 if flags.contains(CompositeGlyphFlags::WE_HAVE_A_SCALE) {
689 transform.xx = self.cursor.read().ok()?;
690 transform.yy = transform.xx;
691 } else if flags.contains(CompositeGlyphFlags::WE_HAVE_AN_X_AND_Y_SCALE) {
692 transform.xx = self.cursor.read().ok()?;
693 transform.yy = self.cursor.read().ok()?;
694 } else if flags.contains(CompositeGlyphFlags::WE_HAVE_A_TWO_BY_TWO) {
695 transform.xx = self.cursor.read().ok()?;
696 transform.yx = self.cursor.read().ok()?;
697 transform.xy = self.cursor.read().ok()?;
698 transform.yy = self.cursor.read().ok()?;
699 }
700 self.done = !flags.contains(CompositeGlyphFlags::MORE_COMPONENTS);
701
702 Some(Component {
703 flags,
704 glyph,
705 anchor,
706 transform,
707 })
708 }
709}
710
711#[derive(Clone)]
716struct ComponentGlyphIdFlagsIter<'a> {
717 cur_flags: CompositeGlyphFlags,
718 done: bool,
719 cursor: Cursor<'a>,
720}
721
722impl Iterator for ComponentGlyphIdFlagsIter<'_> {
723 type Item = (GlyphId, CompositeGlyphFlags);
724
725 fn next(&mut self) -> Option<Self::Item> {
726 if self.done {
727 return None;
728 }
729 let flags: CompositeGlyphFlags = self.cursor.read().ok()?;
730 self.cur_flags = flags;
731 let glyph = read_component_glyph(&mut self.cursor, flags)?;
732 let args_are_words = flags.contains(CompositeGlyphFlags::ARG_1_AND_2_ARE_WORDS);
733 if args_are_words {
734 self.cursor.advance_by(4);
735 } else {
736 self.cursor.advance_by(2);
737 }
738 if flags.contains(CompositeGlyphFlags::WE_HAVE_A_SCALE) {
739 self.cursor.advance_by(2);
740 } else if flags.contains(CompositeGlyphFlags::WE_HAVE_AN_X_AND_Y_SCALE) {
741 self.cursor.advance_by(4);
742 } else if flags.contains(CompositeGlyphFlags::WE_HAVE_A_TWO_BY_TWO) {
743 self.cursor.advance_by(8);
744 }
745 self.done = !flags.contains(CompositeGlyphFlags::MORE_COMPONENTS);
746 Some((glyph, flags))
747 }
748}
749
750impl Anchor {
751 pub fn compute_flags(&self) -> CompositeGlyphFlags {
753 const I8_RANGE: Range<i16> = i8::MIN as i16..i8::MAX as i16 + 1;
754 const U8_MAX: u16 = u8::MAX as u16;
755
756 let mut flags = CompositeGlyphFlags::empty();
757 match self {
758 Anchor::Offset { x, y } => {
759 flags |= CompositeGlyphFlags::ARGS_ARE_XY_VALUES;
760 if !I8_RANGE.contains(x) || !I8_RANGE.contains(y) {
761 flags |= CompositeGlyphFlags::ARG_1_AND_2_ARE_WORDS;
762 }
763 }
764 Anchor::Point { base, component } => {
765 if base > &U8_MAX || component > &U8_MAX {
766 flags |= CompositeGlyphFlags::ARG_1_AND_2_ARE_WORDS;
767 }
768 }
769 }
770 flags
771 }
772}
773
774impl Transform {
775 pub fn compute_flags(&self) -> CompositeGlyphFlags {
777 if self.yx != F2Dot14::ZERO || self.xy != F2Dot14::ZERO {
778 CompositeGlyphFlags::WE_HAVE_A_TWO_BY_TWO
779 } else if self.xx != self.yy {
780 CompositeGlyphFlags::WE_HAVE_AN_X_AND_Y_SCALE
781 } else if self.xx != F2Dot14::ONE {
782 CompositeGlyphFlags::WE_HAVE_A_SCALE
783 } else {
784 CompositeGlyphFlags::empty()
785 }
786 }
787}
788
789impl PointCoord for F26Dot6 {
790 fn from_fixed(x: Fixed) -> Self {
791 x.to_f26dot6()
792 }
793
794 #[inline]
795 fn from_i32(x: i32) -> Self {
796 Self::from_i32(x)
797 }
798
799 #[inline]
800 fn to_f32(self) -> f32 {
801 self.to_f32()
802 }
803
804 #[inline]
805 fn midpoint(self, other: Self) -> Self {
806 Self::from_bits(midpoint_i32(self.to_bits(), other.to_bits()))
809 }
810}
811
812impl PointCoord for Fixed {
813 fn from_fixed(x: Fixed) -> Self {
814 x
815 }
816
817 fn from_i32(x: i32) -> Self {
818 Self::from_i32(x)
819 }
820
821 fn to_f32(self) -> f32 {
822 self.to_f32()
823 }
824
825 fn midpoint(self, other: Self) -> Self {
826 Self::from_bits(midpoint_i32(self.to_bits(), other.to_bits()))
827 }
828}
829
830impl PointCoord for i32 {
831 fn from_fixed(x: Fixed) -> Self {
832 x.to_i32()
833 }
834
835 fn from_i32(x: i32) -> Self {
836 x
837 }
838
839 fn to_f32(self) -> f32 {
840 self as f32
841 }
842
843 fn midpoint(self, other: Self) -> Self {
844 midpoint_i32(self, other)
845 }
846}
847
848#[inline(always)]
850fn midpoint_i32(a: i32, b: i32) -> i32 {
851 a.wrapping_add(b) / 2
857}
858
859impl PointCoord for f32 {
860 fn from_fixed(x: Fixed) -> Self {
861 x.to_f32()
862 }
863
864 fn from_i32(x: i32) -> Self {
865 x as f32
866 }
867
868 fn to_f32(self) -> f32 {
869 self
870 }
871
872 fn midpoint(self, other: Self) -> Self {
873 self + 0.5 * (other - self)
876 }
877}
878
879#[cfg(test)]
880mod tests {
881 use super::*;
882 use crate::{FontRef, GlyphId, TableProvider};
883
884 #[test]
885 fn simple_glyph() {
886 let font = FontRef::new(font_test_data::COLR_GRADIENT_RECT).unwrap();
887 let loca = font.loca(None).unwrap();
888 let glyf = font.glyf().unwrap();
889 let glyph = loca
890 .get(GlyphId::new(0), &glyf)
891 .and_then(|g| g.into_glyph())
892 .unwrap();
893 assert_eq!(glyph.number_of_contours(), 2);
894 let simple_glyph = if let Glyph::Simple(simple) = glyph {
895 simple
896 } else {
897 panic!("expected simple glyph");
898 };
899 assert_eq!(
900 simple_glyph
901 .end_pts_of_contours()
902 .iter()
903 .map(|x| x.get())
904 .collect::<Vec<_>>(),
905 &[3, 7]
906 );
907 assert_eq!(
908 simple_glyph
909 .points()
910 .map(|pt| (pt.x, pt.y, pt.on_curve))
911 .collect::<Vec<_>>(),
912 &[
913 (5, 0, true),
914 (5, 100, true),
915 (45, 100, true),
916 (45, 0, true),
917 (10, 5, true),
918 (40, 5, true),
919 (40, 95, true),
920 (10, 95, true),
921 ]
922 );
923 }
924
925 fn all_glyphs(font_data: &[u8]) -> impl Iterator<Item = Option<Glyph<'_>>> {
927 let font = FontRef::new(font_data).unwrap();
928 let loca = font.loca(None).unwrap();
929 let glyf = font.glyf().unwrap();
930 let glyph_count = font.maxp().unwrap().num_glyphs() as u32;
931 (0..glyph_count).map(move |gid| {
932 loca.get(GlyphId::new(gid), &glyf)
933 .and_then(|g| g.into_glyph())
934 })
935 }
936
937 #[test]
938 fn simple_glyph_overlapping_contour_flag() {
939 let gids_with_overlap: Vec<_> = all_glyphs(font_test_data::VAZIRMATN_VAR)
940 .enumerate()
941 .filter_map(|(gid, glyph)| match glyph {
942 Some(Glyph::Simple(glyph)) if glyph.has_overlapping_contours() => Some(gid),
943 _ => None,
944 })
945 .collect();
946 let expected_gids_with_overlap = vec![3];
948 assert_eq!(expected_gids_with_overlap, gids_with_overlap);
949 }
950
951 #[test]
952 fn composite_glyph_overlapping_contour_flag() {
953 let gids_components_with_overlap: Vec<_> = all_glyphs(font_test_data::VAZIRMATN_VAR)
954 .enumerate()
955 .filter_map(|(gid, glyph)| match glyph {
956 Some(Glyph::Composite(glyph)) => Some((gid, glyph)),
957 _ => None,
958 })
959 .flat_map(|(gid, glyph)| {
960 glyph
961 .components()
962 .enumerate()
963 .filter_map(move |(comp_ix, comp)| {
964 comp.flags
965 .contains(CompositeGlyphFlags::OVERLAP_COMPOUND)
966 .then_some((gid, comp_ix))
967 })
968 })
969 .collect();
970 let expected_gids_components_with_overlap = vec![(2, 1)];
972 assert_eq!(
973 expected_gids_components_with_overlap,
974 gids_components_with_overlap
975 );
976 }
977
978 #[test]
979 fn composite_instructions_flag_on_any_component() {
980 use font_test_data::bebuffer::BeBuffer;
981
982 let instructions = [0x40_u8, 0x01, 0x2A];
983 for wide_first in [false, true] {
984 for (first_flag, last_flag) in
985 [(true, false), (false, true), (true, true), (false, false)]
986 {
987 let mut first_flags =
988 CompositeGlyphFlags::ARGS_ARE_XY_VALUES | CompositeGlyphFlags::MORE_COMPONENTS;
989 let mut last_flags = CompositeGlyphFlags::ARGS_ARE_XY_VALUES;
990 if wide_first {
991 first_flags |= CompositeGlyphFlags::GID_IS_24_BIT;
992 }
993 if first_flag {
994 first_flags |= CompositeGlyphFlags::WE_HAVE_INSTRUCTIONS;
995 }
996 if last_flag {
997 last_flags |= CompositeGlyphFlags::WE_HAVE_INSTRUCTIONS;
998 }
999 let mut buf = BeBuffer::new()
1000 .push(-1_i16)
1001 .extend([0_i16; 4])
1002 .push(first_flags.bits());
1003 buf = if wide_first {
1004 buf.push(Uint24::new(65536))
1005 } else {
1006 buf.push(1_u16)
1007 };
1008 buf = buf
1009 .extend([0_i8; 2])
1010 .push(last_flags.bits())
1011 .push(2_u16)
1012 .extend([0_i8; 2]);
1013 let expected = (first_flag || last_flag).then_some(instructions.as_slice());
1014 if expected.is_some() {
1015 buf = buf.push(instructions.len() as u16).extend(instructions);
1016 }
1017 let glyph = CompositeGlyph::read(buf.data().into()).unwrap();
1018 assert_eq!(glyph.components().count(), 2);
1019 assert_eq!(glyph.count_and_instructions(), (2, expected));
1020 assert_eq!(glyph.instructions(), expected);
1021 }
1022 }
1023 }
1024
1025 #[test]
1026 fn compute_anchor_flags() {
1027 let anchor = Anchor::Offset { x: -128, y: 127 };
1028 assert_eq!(
1029 anchor.compute_flags(),
1030 CompositeGlyphFlags::ARGS_ARE_XY_VALUES
1031 );
1032
1033 let anchor = Anchor::Offset { x: -129, y: 127 };
1034 assert_eq!(
1035 anchor.compute_flags(),
1036 CompositeGlyphFlags::ARGS_ARE_XY_VALUES | CompositeGlyphFlags::ARG_1_AND_2_ARE_WORDS
1037 );
1038 let anchor = Anchor::Offset { x: -1, y: 128 };
1039 assert_eq!(
1040 anchor.compute_flags(),
1041 CompositeGlyphFlags::ARGS_ARE_XY_VALUES | CompositeGlyphFlags::ARG_1_AND_2_ARE_WORDS
1042 );
1043
1044 let anchor = Anchor::Point {
1045 base: 255,
1046 component: 20,
1047 };
1048 assert_eq!(anchor.compute_flags(), CompositeGlyphFlags::empty());
1049
1050 let anchor = Anchor::Point {
1051 base: 256,
1052 component: 20,
1053 };
1054 assert_eq!(
1055 anchor.compute_flags(),
1056 CompositeGlyphFlags::ARG_1_AND_2_ARE_WORDS
1057 )
1058 }
1059
1060 #[test]
1061 fn compute_transform_flags() {
1062 fn make_xform(xx: f32, yx: f32, xy: f32, yy: f32) -> Transform {
1063 Transform {
1064 xx: F2Dot14::from_f32(xx),
1065 yx: F2Dot14::from_f32(yx),
1066 xy: F2Dot14::from_f32(xy),
1067 yy: F2Dot14::from_f32(yy),
1068 }
1069 }
1070
1071 assert_eq!(
1072 make_xform(1.0, 0., 0., 1.0).compute_flags(),
1073 CompositeGlyphFlags::empty()
1074 );
1075 assert_eq!(
1076 make_xform(2.0, 0., 0., 2.0).compute_flags(),
1077 CompositeGlyphFlags::WE_HAVE_A_SCALE
1078 );
1079 assert_eq!(
1080 make_xform(2.0, 0., 0., 1.0).compute_flags(),
1081 CompositeGlyphFlags::WE_HAVE_AN_X_AND_Y_SCALE
1082 );
1083 assert_eq!(
1084 make_xform(2.0, 0., 1.0, 1.0).compute_flags(),
1085 CompositeGlyphFlags::WE_HAVE_A_TWO_BY_TWO
1086 );
1087 }
1088
1089 #[test]
1090 fn point_flags_and_marker_bits() {
1091 let bits = [
1092 PointFlags::OFF_CURVE_CUBIC,
1093 PointFlags::ON_CURVE,
1094 PointMarker::HAS_DELTA.0,
1095 PointMarker::TOUCHED_X.0,
1096 PointMarker::TOUCHED_Y.0,
1097 ];
1098 for (i, a) in bits.iter().enumerate() {
1100 for b in &bits[i + 1..] {
1101 assert_eq!(a & b, 0);
1102 }
1103 }
1104 }
1105
1106 #[test]
1107 fn cubic_glyf() {
1108 let font = FontRef::new(font_test_data::CUBIC_GLYF).unwrap();
1109 let loca = font.loca(None).unwrap();
1110 let glyf = font.glyf().unwrap();
1111 let glyph = loca
1112 .get(GlyphId::new(2), &glyf)
1113 .and_then(|g| g.into_glyph())
1114 .unwrap();
1115 assert_eq!(glyph.number_of_contours(), 1);
1116 let simple_glyph = if let Glyph::Simple(simple) = glyph {
1117 simple
1118 } else {
1119 panic!("expected simple glyph");
1120 };
1121 assert_eq!(
1122 simple_glyph
1123 .points()
1124 .map(|pt| (pt.x, pt.y, pt.on_curve))
1125 .collect::<Vec<_>>(),
1126 &[
1127 (278, 710, true),
1128 (278, 470, true),
1129 (300, 500, false),
1130 (800, 500, false),
1131 (998, 470, true),
1132 (998, 710, true),
1133 ]
1134 );
1135 }
1136
1137 #[test]
1141 fn avoid_midpoint_overflow() {
1142 let a = F26Dot6::from_bits(1084092352);
1143 let b = F26Dot6::from_bits(1085243712);
1144 let expected = (a + b).to_bits() / 2;
1145 let midpoint = a.midpoint(b);
1147 assert_eq!(midpoint.to_bits(), expected);
1148 }
1149
1150 #[test]
1158 fn simple_glyph_truncated_data() {
1159 use font_test_data::bebuffer::BeBuffer;
1160
1161 let buf = BeBuffer::new()
1166 .push(100_i16) .push(0_i16) .push(0_i16) .push(0_i16) .push(0_i16) .push(0_u16); let glyph = SimpleGlyph::read(buf.data().into()).unwrap();
1175 assert_eq!(glyph.number_of_contours(), 100);
1176
1177 assert_eq!(glyph.instruction_length(), 0);
1179 }
1180
1181 #[test]
1185 fn read_points_fast_long_flags() {
1186 use font_test_data::bebuffer::BeBuffer;
1187 let buf = BeBuffer::new()
1192 .push(1_i16) .extend([0_i16; 4]) .push(2_u16) .push(0_u16) .extend([0x39u8, 0x00, 0x39, 0x00, 0x39, 0x00]);
1197
1198 let glyph = SimpleGlyph::read(buf.data().into()).unwrap();
1199 assert_eq!(glyph.num_points(), 3);
1200
1201 let expected: Vec<_> = glyph.points().map(|p| (p.x as i32, p.y as i32)).collect();
1202
1203 let mut points = vec![Point::default(); 3];
1204 let mut flags = vec![PointFlags::default(); 3];
1205 glyph
1206 .read_points_fast::<i32>(&mut points, &mut flags)
1207 .unwrap();
1208 let actual: Vec<_> = points.iter().map(|p| (p.x, p.y)).collect();
1209
1210 assert_eq!(actual, expected);
1211 }
1212
1213 #[test]
1214 fn point_iter_repeat_count_255_does_not_overflow() {
1215 let flags = [SimpleGlyphFlags::REPEAT_FLAG.bits(), 0xFF];
1217 let coords = [0u8; 256 * 2];
1219 let iter = PointIter::new(&flags, &coords, &coords);
1220 assert_eq!(iter.count(), 256);
1221 }
1222
1223 #[test]
1224 fn read_points_fast_does_not_panic_on_empty_glyph_with_padding() {
1225 let glyph_bytes: &[u8] = &[
1226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
1231 let glyph = SimpleGlyph::read(FontData::new(glyph_bytes)).expect("parses");
1232 assert_eq!(glyph.num_points(), 0);
1233 let mut points: Vec<Point<f32>> = vec![];
1234 let mut flags: Vec<PointFlags> = vec![];
1235 assert!(glyph.read_points_fast(&mut points, &mut flags).is_ok());
1236 }
1237}