1use crate::{prelude::*, scalar, ISize, Size};
2use skia_bindings::{self as sb, SkIPoint, SkPoint};
3use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
4
5pub use IPoint as IVector;
6
7#[repr(C)]
8#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)]
9pub struct IPoint {
10 pub x: i32,
11 pub y: i32,
12}
13
14native_transmutable!(SkIPoint, IPoint, ipoint_layout);
15
16impl Neg for IPoint {
17 type Output = IPoint;
18 fn neg(self) -> Self::Output {
19 IPoint::new(-self.x, -self.y)
20 }
21}
22
23impl 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
30impl 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
37impl 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
44impl 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
51impl 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
58impl 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
65impl 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
72impl 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
79impl 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
97pub type Vector = Point;
98
99#[repr(C)]
100#[derive(Copy, Clone, PartialEq, Default, Debug)]
101pub struct Point {
102 pub x: scalar,
103 pub y: scalar,
104}
105
106native_transmutable!(SkPoint, Point, point_layout);
107
108impl Neg for Point {
109 type Output = Point;
110 fn neg(self) -> Self::Output {
111 Point::new(-self.x, -self.y)
112 }
113}
114
115impl 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
122impl 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
129impl 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
136impl 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
143impl 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
150impl 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
157impl 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
164impl 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
171impl 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
178impl 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
187impl 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
194impl DivAssign<scalar> for Point {
195 fn div_assign(&mut self, rhs: scalar) {
196 self.x /= rhs;
197 self.y /= rhs;
198 }
199}
200
201impl 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
311impl From<(i32, i32)> for IPoint {
312 fn from(source: (i32, i32)) -> Self {
313 IPoint::new(x:source.0, y:source.1)
314 }
315}
316
317impl From<(scalar, scalar)> for Point {
318 fn from(source: (scalar, scalar)) -> Self {
319 Point::new(x:source.0, y:source.1)
320 }
321}
322
323impl From<IPoint> for Point {
324 fn from(source: IPoint) -> Self {
325 Self::new(source.x as _, source.y as _)
326 }
327}
328
329impl 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