1#[cfg(all(feature = "libm", not(feature = "std")))]
2use crate::nostd_float::FloatExt;
3
4/// An (x, y) coordinate.
5///
6/// # Example
7/// ```
8/// use ab_glyph_rasterizer::{point, Point};
9/// let p: Point = point(0.1, 23.2);
10/// ```
11#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
12pub struct Point {
13 pub x: f32,
14 pub y: f32,
15}
16
17impl core::fmt::Debug for Point {
18 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19 write!(f, "point({:?}, {:?})", self.x, self.y)
20 }
21}
22
23impl Point {
24 #[inline]
25 pub(crate) fn distance_to(self, other: Point) -> f32 {
26 let d: Point = other - self;
27 (d.x * d.x + d.y * d.y).sqrt()
28 }
29}
30
31/// [`Point`](struct.Point.html) constructor.
32///
33/// # Example
34/// ```
35/// # use ab_glyph_rasterizer::{point, Point};
36/// let p = point(0.1, 23.2);
37/// ```
38#[inline]
39pub fn point(x: f32, y: f32) -> Point {
40 Point { x, y }
41}
42
43/// Linear interpolation between points.
44#[inline]
45pub(crate) fn lerp(t: f32, p0: Point, p1: Point) -> Point {
46 point(x:p0.x + t * (p1.x - p0.x), y:p0.y + t * (p1.y - p0.y))
47}
48
49impl core::ops::Sub for Point {
50 type Output = Point;
51 /// Subtract rhs.x from x, rhs.y from y.
52 ///
53 /// ```
54 /// # use ab_glyph_rasterizer::*;
55 /// let p1 = point(1.0, 2.0) - point(2.0, 1.5);
56 ///
57 /// assert!((p1.x - -1.0).abs() <= core::f32::EPSILON);
58 /// assert!((p1.y - 0.5).abs() <= core::f32::EPSILON);
59 /// ```
60 #[inline]
61 fn sub(self, rhs: Point) -> Point {
62 point(self.x - rhs.x, self.y - rhs.y)
63 }
64}
65
66impl core::ops::Add for Point {
67 type Output = Point;
68 /// Add rhs.x to x, rhs.y to y.
69 ///
70 /// ```
71 /// # use ab_glyph_rasterizer::*;
72 /// let p1 = point(1.0, 2.0) + point(2.0, 1.5);
73 ///
74 /// assert!((p1.x - 3.0).abs() <= core::f32::EPSILON);
75 /// assert!((p1.y - 3.5).abs() <= core::f32::EPSILON);
76 /// ```
77 #[inline]
78 fn add(self, rhs: Point) -> Point {
79 point(self.x + rhs.x, self.y + rhs.y)
80 }
81}
82
83impl core::ops::AddAssign for Point {
84 /// ```
85 /// # use ab_glyph_rasterizer::*;
86 /// let mut p1 = point(1.0, 2.0);
87 /// p1 += point(2.0, 1.5);
88 ///
89 /// assert!((p1.x - 3.0).abs() <= core::f32::EPSILON);
90 /// assert!((p1.y - 3.5).abs() <= core::f32::EPSILON);
91 /// ```
92 #[inline]
93 fn add_assign(&mut self, other: Self) {
94 self.x += other.x;
95 self.y += other.y;
96 }
97}
98
99impl core::ops::SubAssign for Point {
100 /// ```
101 /// # use ab_glyph_rasterizer::*;
102 /// let mut p1 = point(1.0, 2.0);
103 /// p1 -= point(2.0, 1.5);
104 ///
105 /// assert!((p1.x - -1.0).abs() <= core::f32::EPSILON);
106 /// assert!((p1.y - 0.5).abs() <= core::f32::EPSILON);
107 /// ```
108 #[inline]
109 fn sub_assign(&mut self, other: Self) {
110 self.x -= other.x;
111 self.y -= other.y;
112 }
113}
114
115impl<F: Into<f32>> From<(F, F)> for Point {
116 /// ```
117 /// # use ab_glyph_rasterizer::*;
118 /// let p: Point = (23_f32, 34.5_f32).into();
119 /// let p2: Point = (5u8, 44u8).into();
120 /// ```
121 #[inline]
122 fn from((x: F, y: F): (F, F)) -> Self {
123 point(x:x.into(), y:y.into())
124 }
125}
126
127impl<F: Into<f32>> From<[F; 2]> for Point {
128 /// ```
129 /// # use ab_glyph_rasterizer::*;
130 /// let p: Point = [23_f32, 34.5].into();
131 /// let p2: Point = [5u8, 44].into();
132 /// ```
133 #[inline]
134 fn from([x: F, y: F]: [F; 2]) -> Self {
135 point(x:x.into(), y:y.into())
136 }
137}
138
139#[cfg(test)]
140mod test {
141 use super::*;
142
143 #[test]
144 fn distance_to() {
145 let distance = point(0.0, 0.0).distance_to(point(3.0, 4.0));
146 assert!((distance - 5.0).abs() <= core::f32::EPSILON);
147 }
148}
149

Provided by KDAB

Privacy Policy