1 | #[cfg (all(feature = "libm" , not(feature = "std" )))] |
2 | use 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)] |
12 | pub struct Point { |
13 | pub x: f32, |
14 | pub y: f32, |
15 | } |
16 | |
17 | impl 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 | |
23 | impl 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 ] |
39 | pub fn point(x: f32, y: f32) -> Point { |
40 | Point { x, y } |
41 | } |
42 | |
43 | /// Linear interpolation between points. |
44 | #[inline ] |
45 | pub(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 | |
49 | impl 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 | |
66 | impl 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 | |
83 | impl 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 | |
99 | impl 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 | |
115 | impl<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 | |
127 | impl<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)] |
140 | mod 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 | |