skia_safe/core/
point.rs

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(source.0, source.1)
314    }
315}
316
317impl From<(scalar, scalar)> for Point {
318    fn from(source: (scalar, scalar)) -> Self {
319        Point::new(source.0, 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}