1use point2f::Point2f;
4use point2u::Point2u;
5use vector2i::Vector2i;
6
7use std::ops::{Add, Sub};
8
9#[cfg(all(windows, feature = "d2d"))]
10use winapi::um::dcommon::D2D_POINT_2L;
11
12#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
14#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))]
15#[repr(C)]
16pub struct Point2i {
17 pub x: i32,
19 pub y: i32,
21}
22
23impl Point2i {
24 pub const ORIGIN: Point2i = Point2i { x: 0, y: 0 };
26
27 #[inline]
29 pub fn new(x: i32, y: i32) -> Point2i {
30 Point2i { x, y }
31 }
32
33 #[inline]
35 pub fn to_f32(self) -> Point2f {
36 Point2f {
37 x: self.x as f32,
38 y: self.y as f32,
39 }
40 }
41
42 #[inline]
45 pub fn to_u32(self) -> Point2u {
46 Point2u {
47 x: self.x as u32,
48 y: self.y as u32,
49 }
50 }
51}
52
53impl<V> Add<V> for Point2i
54where
55 V: Into<Vector2i>,
56{
57 type Output = Point2i;
58
59 #[inline]
60 fn add(self, rhs: V) -> Point2i {
61 let rhs = rhs.into();
62 Point2i {
63 x: self.x + rhs.x,
64 y: self.y + rhs.y,
65 }
66 }
67}
68
69impl Add<Point2i> for Vector2i {
70 type Output = Point2i;
71
72 #[inline]
73 fn add(self, rhs: Point2i) -> Point2i {
74 rhs + self
75 }
76}
77
78impl Add<(i32, i32)> for Vector2i {
79 type Output = Point2i;
80
81 #[inline]
82 fn add(self, rhs: (i32, i32)) -> Point2i {
83 Point2i::from(rhs) + self
84 }
85}
86
87impl Sub for Point2i {
88 type Output = Vector2i;
89
90 #[inline]
91 fn sub(self, rhs: Point2i) -> Vector2i {
92 Vector2i {
93 x: self.x - rhs.x,
94 y: self.y - rhs.y,
95 }
96 }
97}
98
99impl Sub<(i32, i32)> for Point2i {
100 type Output = Vector2i;
101
102 #[inline]
103 fn sub(self, rhs: (i32, i32)) -> Vector2i {
104 Vector2i {
105 x: self.x - rhs.0,
106 y: self.y - rhs.0,
107 }
108 }
109}
110
111impl<V> Sub<V> for Point2i
112where
113 V: Into<Vector2i>,
114{
115 type Output = Point2i;
116
117 #[inline]
118 fn sub(self, rhs: V) -> Point2i {
119 let rhs = rhs.into();
120 Point2i {
121 x: self.x - rhs.x,
122 y: self.y - rhs.y,
123 }
124 }
125}
126
127impl From<(i32, i32)> for Point2i {
128 #[inline]
129 fn from((x, y): (i32, i32)) -> Point2i {
130 Point2i { x, y }
131 }
132}
133
134impl From<[i32; 2]> for Point2i {
135 #[inline]
136 fn from(p: [i32; 2]) -> Point2i {
137 Point2i { x: p[0], y: p[0] }
138 }
139}
140
141impl From<Point2i> for [i32; 2] {
142 #[inline]
143 fn from(p: Point2i) -> [i32; 2] {
144 [p.x, p.y]
145 }
146}
147
148#[cfg(all(windows, feature = "d2d"))]
149impl From<Point2i> for D2D_POINT_2L {
150 #[inline]
151 fn from(point: Point2i) -> D2D_POINT_2L {
152 D2D_POINT_2L {
153 x: point.x,
154 y: point.y,
155 }
156 }
157}
158
159#[cfg(all(windows, feature = "d2d"))]
160impl From<D2D_POINT_2L> for Point2i {
161 #[inline]
162 fn from(point: D2D_POINT_2L) -> Point2i {
163 Point2i {
164 x: point.x,
165 y: point.y,
166 }
167 }
168}
169
170#[cfg(feature = "mint")]
171impl From<Point2i> for mint::Point2<i32> {
172 #[inline]
173 fn from(p: Point2i) -> mint::Point2<i32> {
174 mint::Point2 { x: p.x, y: p.y }
175 }
176}
177
178#[cfg(feature = "mint")]
179impl From<mint::Point2<i32>> for Point2i {
180 #[inline]
181 fn from(p: mint::Point2<i32>) -> Point2i {
182 Point2i { x: p.x, y: p.y }
183 }
184}
185
186#[cfg(all(test, windows, feature = "d2d"))]
187#[test]
188fn pt2i_d2d_bin_compat() {
189 use std::mem::size_of_val;
190
191 fn ptr_eq<T>(a: &T, b: &T) -> bool {
192 (a as *const T) == (b as *const T)
193 }
194
195 let pt = Point2i::ORIGIN;
196 let d2d = unsafe { &*((&pt) as *const _ as *const D2D_POINT_2L) };
197
198 assert!(ptr_eq(&pt.x, &d2d.x));
199 assert!(ptr_eq(&pt.y, &d2d.y));
200 assert_eq!(size_of_val(&pt), size_of_val(d2d));
201}