1 | use crate::{prelude::*, scalar, ISize, Size}; |
2 | use skia_bindings::{self as sb, SkIPoint, SkPoint}; |
3 | use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; |
4 | |
5 | pub use IPoint as IVector; |
6 | |
7 | #[repr (C)] |
8 | #[derive (Copy, Clone, PartialEq, Eq, Default, Debug)] |
9 | pub struct IPoint { |
10 | pub x: i32, |
11 | pub y: i32, |
12 | } |
13 | |
14 | native_transmutable!(SkIPoint, IPoint, ipoint_layout); |
15 | |
16 | impl Neg for IPoint { |
17 | type Output = IPoint; |
18 | fn neg(self) -> Self::Output { |
19 | IPoint::new(-self.x, -self.y) |
20 | } |
21 | } |
22 | |
23 | impl Add<IVector> for IPoint { |
24 | type Output = IPoint; |
25 | fn add(self, rhs: IVector) -> Self { |
26 | IPoint::new(self.x + rhs.x, self.y + rhs.y) |
27 | } |
28 | } |
29 | |
30 | impl AddAssign<IVector> for IPoint { |
31 | fn add_assign(&mut self, rhs: IVector) { |
32 | self.x += rhs.x; |
33 | self.y += self.y; |
34 | } |
35 | } |
36 | |
37 | impl Add<ISize> for IPoint { |
38 | type Output = IPoint; |
39 | fn add(self, rhs: ISize) -> Self::Output { |
40 | IPoint::new(self.x + rhs.width, self.y + rhs.height) |
41 | } |
42 | } |
43 | |
44 | impl AddAssign<ISize> for IPoint { |
45 | fn add_assign(&mut self, rhs: ISize) { |
46 | self.x += rhs.width; |
47 | self.y += rhs.height; |
48 | } |
49 | } |
50 | |
51 | impl Sub for IPoint { |
52 | type Output = Self; |
53 | fn sub(self, rhs: Self) -> Self { |
54 | IPoint::new(self.x - rhs.x, self.y - rhs.y) |
55 | } |
56 | } |
57 | |
58 | impl SubAssign<IVector> for IPoint { |
59 | fn sub_assign(&mut self, rhs: Self) { |
60 | self.x -= rhs.x; |
61 | self.y -= rhs.y; |
62 | } |
63 | } |
64 | |
65 | impl Sub<ISize> for IPoint { |
66 | type Output = IPoint; |
67 | fn sub(self, rhs: ISize) -> Self::Output { |
68 | IPoint::new(self.x - rhs.width, self.y - rhs.height) |
69 | } |
70 | } |
71 | |
72 | impl SubAssign<ISize> for IPoint { |
73 | fn sub_assign(&mut self, rhs: ISize) { |
74 | self.x -= rhs.width; |
75 | self.y -= rhs.height; |
76 | } |
77 | } |
78 | |
79 | impl IPoint { |
80 | pub const fn new(x: i32, y: i32) -> Self { |
81 | IPoint { x, y } |
82 | } |
83 | |
84 | pub fn is_zero(self) -> bool { |
85 | (self.x | self.y) == 0 |
86 | } |
87 | |
88 | pub fn set(&mut self, x: i32, y: i32) { |
89 | *self = IPoint::new(x, y); |
90 | } |
91 | |
92 | pub fn equals(self, x: i32, y: i32) -> bool { |
93 | self == IPoint::new(x, y) |
94 | } |
95 | } |
96 | |
97 | pub type Vector = Point; |
98 | |
99 | #[repr (C)] |
100 | #[derive (Copy, Clone, PartialEq, Default, Debug)] |
101 | pub struct Point { |
102 | pub x: scalar, |
103 | pub y: scalar, |
104 | } |
105 | |
106 | native_transmutable!(SkPoint, Point, point_layout); |
107 | |
108 | impl Neg for Point { |
109 | type Output = Point; |
110 | fn neg(self) -> Self::Output { |
111 | Point::new(-self.x, -self.y) |
112 | } |
113 | } |
114 | |
115 | impl Add<Vector> for Point { |
116 | type Output = Self; |
117 | fn add(self, rhs: Vector) -> Self { |
118 | Point::new(self.x + rhs.x, self.y + rhs.y) |
119 | } |
120 | } |
121 | |
122 | impl AddAssign<Vector> for Point { |
123 | fn add_assign(&mut self, rhs: Vector) { |
124 | self.x += rhs.x; |
125 | self.y += rhs.y; |
126 | } |
127 | } |
128 | |
129 | impl Add<Size> for Point { |
130 | type Output = Self; |
131 | fn add(self, rhs: Size) -> Self { |
132 | Point::new(self.x + rhs.width, self.y + rhs.height) |
133 | } |
134 | } |
135 | |
136 | impl AddAssign<Size> for Point { |
137 | fn add_assign(&mut self, rhs: Size) { |
138 | self.x += rhs.width; |
139 | self.y += rhs.height; |
140 | } |
141 | } |
142 | |
143 | impl Sub for Point { |
144 | type Output = Point; |
145 | fn sub(self, rhs: Self) -> Self { |
146 | Point::new(self.x - rhs.x, self.y - rhs.y) |
147 | } |
148 | } |
149 | |
150 | impl SubAssign<Vector> for Point { |
151 | fn sub_assign(&mut self, rhs: Vector) { |
152 | self.x -= rhs.x; |
153 | self.y -= rhs.y; |
154 | } |
155 | } |
156 | |
157 | impl Sub<Size> for Point { |
158 | type Output = Self; |
159 | fn sub(self, rhs: Size) -> Self { |
160 | Point::new(self.x - rhs.width, self.y - rhs.height) |
161 | } |
162 | } |
163 | |
164 | impl SubAssign<Size> for Point { |
165 | fn sub_assign(&mut self, rhs: Size) { |
166 | self.x -= rhs.width; |
167 | self.y -= rhs.height; |
168 | } |
169 | } |
170 | |
171 | impl Mul<scalar> for Point { |
172 | type Output = Self; |
173 | fn mul(self, rhs: scalar) -> Self { |
174 | Self::new(self.x * rhs, self.y * rhs) |
175 | } |
176 | } |
177 | |
178 | impl MulAssign<scalar> for Point { |
179 | fn mul_assign(&mut self, rhs: scalar) { |
180 | self.x *= rhs; |
181 | self.y *= rhs; |
182 | } |
183 | } |
184 | |
185 | // `SkPoint.h` does not define a `/` operator, but we add it to complement Mul<>. |
186 | |
187 | impl Div<scalar> for Point { |
188 | type Output = Self; |
189 | fn div(self, rhs: scalar) -> Self { |
190 | Self::new(self.x / rhs, self.y / rhs) |
191 | } |
192 | } |
193 | |
194 | impl DivAssign<scalar> for Point { |
195 | fn div_assign(&mut self, rhs: scalar) { |
196 | self.x /= rhs; |
197 | self.y /= rhs; |
198 | } |
199 | } |
200 | |
201 | impl Point { |
202 | pub const fn new(x: scalar, y: scalar) -> Self { |
203 | Self { x, y } |
204 | } |
205 | |
206 | pub fn is_zero(self) -> bool { |
207 | self.x == 0.0 && self.y == 0.0 |
208 | } |
209 | |
210 | pub fn set(&mut self, x: scalar, y: scalar) { |
211 | *self = Self::new(x, y); |
212 | } |
213 | |
214 | pub fn iset(&mut self, p: impl Into<IPoint>) { |
215 | let p = p.into(); |
216 | self.x = p.x as scalar; |
217 | self.y = p.y as scalar; |
218 | } |
219 | |
220 | pub fn set_abs(&mut self, p: impl Into<Point>) { |
221 | let p = p.into(); |
222 | self.x = p.x.abs(); |
223 | self.y = p.y.abs(); |
224 | } |
225 | |
226 | pub fn offset_points(points: &mut [Point], offset: impl Into<Vector>) { |
227 | let offset = offset.into(); |
228 | points.iter_mut().for_each(|p| p.offset(offset)); |
229 | } |
230 | |
231 | pub fn offset(&mut self, d: impl Into<Vector>) { |
232 | *self += d.into(); |
233 | } |
234 | |
235 | pub fn length(self) -> scalar { |
236 | unsafe { SkPoint::Length(self.x, self.y) } |
237 | } |
238 | |
239 | pub fn distance_to_origin(self) -> scalar { |
240 | self.length() |
241 | } |
242 | |
243 | pub fn normalize(&mut self) -> bool { |
244 | unsafe { self.native_mut().normalize() } |
245 | } |
246 | |
247 | pub fn set_normalize(&mut self, x: scalar, y: scalar) -> bool { |
248 | unsafe { self.native_mut().setNormalize(x, y) } |
249 | } |
250 | |
251 | pub fn set_length(&mut self, length: scalar) -> bool { |
252 | unsafe { self.native_mut().setLength(length) } |
253 | } |
254 | |
255 | pub fn set_length_xy(&mut self, x: scalar, y: scalar, length: scalar) -> bool { |
256 | unsafe { self.native_mut().setLength1(x, y, length) } |
257 | } |
258 | |
259 | #[must_use ] |
260 | pub fn scaled(self, scale: scalar) -> Self { |
261 | let mut p = Point::default(); |
262 | unsafe { self.native().scale(scale, p.native_mut()) } |
263 | p |
264 | } |
265 | |
266 | pub fn scale(&mut self, scale: scalar) { |
267 | *self = self.scaled(scale); |
268 | } |
269 | |
270 | pub fn negate(&mut self) { |
271 | *self = -*self; |
272 | } |
273 | |
274 | pub fn is_finite(self) -> bool { |
275 | unsafe { sb::C_SkPoint_isFinite(self.native()) } |
276 | } |
277 | |
278 | pub fn equals(self, x: scalar, y: scalar) -> bool { |
279 | self == Point::new(x, y) |
280 | } |
281 | |
282 | pub fn length_xy(x: scalar, y: scalar) -> scalar { |
283 | unsafe { SkPoint::Length(x, y) } |
284 | } |
285 | |
286 | pub fn normalize_vector(v: &mut Vector) -> scalar { |
287 | unsafe { SkPoint::Normalize(v.native_mut()) } |
288 | } |
289 | |
290 | pub fn distance(a: Self, b: Self) -> scalar { |
291 | unsafe { SkPoint::Length(a.x - b.x, a.y - b.y) } |
292 | } |
293 | |
294 | pub fn dot_product(a: Self, b: Self) -> scalar { |
295 | a.x * b.x + a.y * b.y |
296 | } |
297 | |
298 | pub fn cross_product(a: Self, b: Self) -> scalar { |
299 | a.x * b.y - a.y * b.x |
300 | } |
301 | |
302 | pub fn cross(self, vec: Vector) -> scalar { |
303 | Self::cross_product(self, vec) |
304 | } |
305 | |
306 | pub fn dot(self, vec: Vector) -> scalar { |
307 | Self::dot_product(self, vec) |
308 | } |
309 | } |
310 | |
311 | impl From<(i32, i32)> for IPoint { |
312 | fn from(source: (i32, i32)) -> Self { |
313 | IPoint::new(x:source.0, y:source.1) |
314 | } |
315 | } |
316 | |
317 | impl From<(scalar, scalar)> for Point { |
318 | fn from(source: (scalar, scalar)) -> Self { |
319 | Point::new(x:source.0, y:source.1) |
320 | } |
321 | } |
322 | |
323 | impl From<IPoint> for Point { |
324 | fn from(source: IPoint) -> Self { |
325 | Self::new(source.x as _, source.y as _) |
326 | } |
327 | } |
328 | |
329 | impl From<(i32, i32)> for Point { |
330 | fn from(source: (i32, i32)) -> Self { |
331 | (source.0 as scalar, source.1 as scalar).into() |
332 | } |
333 | } |
334 | |