Skip to main content

singe_npp/
types_geometry.rs

1use super::*;
2
3#[repr(C)]
4#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
5pub struct Size {
6    pub width: i32,
7    pub height: i32,
8}
9
10impl Size {
11    pub const fn new(width: i32, height: i32) -> Self {
12        assert!(width > 0, "width must be greater than 0");
13        assert!(height > 0, "height must be greater than 0");
14        Self { width, height }
15    }
16
17    pub const fn from_raw_parts(width: i32, height: i32) -> Self {
18        Self { width, height }
19    }
20
21    pub fn create(width: i32, height: i32) -> Result<Self> {
22        let size = Self::from_raw_parts(width, height);
23        size.validate()?;
24        Ok(size)
25    }
26
27    pub const fn is_positive(self) -> bool {
28        self.width > 0 && self.height > 0
29    }
30
31    pub fn validate(self) -> Result<()> {
32        if self.width <= 0 {
33            return Err(Error::ValueNotPositive {
34                name: "width".into(),
35            });
36        }
37        if self.height <= 0 {
38            return Err(Error::ValueNotPositive {
39                name: "height".into(),
40            });
41        }
42        Ok(())
43    }
44
45    pub fn rectangle(self) -> Rectangle {
46        Rectangle {
47            x: 0,
48            y: 0,
49            width: self.width,
50            height: self.height,
51        }
52    }
53
54    pub fn centered_rectangle(self) -> Rectangle {
55        let side = self.width.min(self.height);
56        Rectangle {
57            x: ((self.width - side) / 2),
58            y: ((self.height - side) / 2),
59            width: side,
60            height: side,
61        }
62    }
63}
64
65impl From<Size> for sys::NppiSize {
66    fn from(value: Size) -> Self {
67        Self {
68            width: value.width,
69            height: value.height,
70        }
71    }
72}
73
74impl From<sys::NppiSize> for Size {
75    fn from(value: sys::NppiSize) -> Self {
76        Self::from_raw_parts(value.width, value.height)
77    }
78}
79
80impl Display for Size {
81    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
82        write!(f, "{}x{}", self.width, self.height)
83    }
84}
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89
90    #[test]
91    fn size_create_rejects_nonpositive_width() {
92        assert!(matches!(
93            Size::create(0, 1),
94            Err(Error::ValueNotPositive { name }) if name == "width"
95        ));
96    }
97
98    #[test]
99    fn size_create_rejects_nonpositive_height() {
100        assert!(matches!(
101            Size::create(1, -1),
102            Err(Error::ValueNotPositive { name }) if name == "height"
103        ));
104    }
105
106    #[test]
107    fn size_raw_parts_preserves_ffi_values() {
108        let size = Size::from_raw_parts(0, -1);
109        assert_eq!(size.width, 0);
110        assert_eq!(size.height, -1);
111        assert!(!size.is_positive());
112    }
113}
114
115#[repr(C)]
116#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Default)]
117pub struct Rectangle {
118    pub x: i32,
119    pub y: i32,
120    pub width: i32,
121    pub height: i32,
122}
123
124impl Rectangle {
125    pub fn size(self) -> Size {
126        Size::from_raw_parts(self.width, self.height)
127    }
128}
129
130impl From<Rectangle> for sys::NppiRect {
131    fn from(value: Rectangle) -> Self {
132        Self {
133            x: value.x,
134            y: value.y,
135            width: value.width,
136            height: value.height,
137        }
138    }
139}
140
141impl From<sys::NppiRect> for Rectangle {
142    fn from(value: sys::NppiRect) -> Self {
143        Self {
144            x: value.x,
145            y: value.y,
146            width: value.width,
147            height: value.height,
148        }
149    }
150}
151
152#[repr(C)]
153#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Default)]
154pub struct Point {
155    pub x: i32,
156    pub y: i32,
157}
158
159impl Point {
160    pub const ZERO: Point = Point::new(0, 0);
161
162    pub const fn new(x: i32, y: i32) -> Self {
163        Point { x, y }
164    }
165}
166
167impl From<Point> for sys::NppiPoint {
168    fn from(value: Point) -> Self {
169        Self {
170            x: value.x,
171            y: value.y,
172        }
173    }
174}
175
176impl From<sys::NppiPoint> for Point {
177    fn from(value: sys::NppiPoint) -> Self {
178        Self {
179            x: value.x,
180            y: value.y,
181        }
182    }
183}
184
185#[derive(Debug, Clone, Copy, PartialOrd, PartialEq, Default)]
186pub struct Point32f {
187    pub x: f32,
188    pub y: f32,
189}
190
191impl From<Point32f> for sys::NppiPoint32f {
192    fn from(value: Point32f) -> Self {
193        Self {
194            x: value.x,
195            y: value.y,
196        }
197    }
198}
199
200impl From<sys::NppiPoint32f> for Point32f {
201    fn from(value: sys::NppiPoint32f) -> Self {
202        Self {
203            x: value.x,
204            y: value.y,
205        }
206    }
207}
208
209#[repr(C)]
210#[derive(Debug, Clone, Copy, PartialOrd, PartialEq, Default)]
211pub struct Point64f {
212    pub x: f64,
213    pub y: f64,
214}
215
216impl From<Point64f> for sys::NppiPoint64f {
217    fn from(value: Point64f) -> Self {
218        Self {
219            x: value.x,
220            y: value.y,
221        }
222    }
223}
224
225impl From<sys::NppiPoint64f> for Point64f {
226    fn from(value: sys::NppiPoint64f) -> Self {
227        Self {
228            x: value.x,
229            y: value.y,
230        }
231    }
232}
233
234impl From<[f64; 2]> for Point64f {
235    fn from(value: [f64; 2]) -> Self {
236        Self {
237            x: value[0],
238            y: value[1],
239        }
240    }
241}
242
243impl From<Point64f> for [f64; 2] {
244    fn from(value: Point64f) -> Self {
245        [value.x, value.y]
246    }
247}
248
249impl Point64f {
250    pub const fn to_array(self) -> [f64; 2] {
251        [self.x, self.y]
252    }
253}
254
255pub type PointF64 = Point64f;
256
257#[derive(Debug, Clone, Copy, PartialOrd, PartialEq, Default)]
258pub struct PointPolar {
259    pub rho: f32,
260    pub theta: f32,
261}
262
263impl From<PointPolar> for sys::NppPointPolar {
264    fn from(value: PointPolar) -> Self {
265        Self {
266            rho: value.rho,
267            theta: value.theta,
268        }
269    }
270}
271
272impl From<sys::NppPointPolar> for PointPolar {
273    fn from(value: sys::NppPointPolar) -> Self {
274        Self {
275            rho: value.rho,
276            theta: value.theta,
277        }
278    }
279}
280
281#[repr(C)]
282#[derive(Debug, Clone, Copy, PartialEq)]
283pub struct BoundF64 {
284    pub lower: PointF64,
285    pub upper: PointF64,
286}
287
288impl From<[[f64; 2]; 2]> for BoundF64 {
289    fn from(value: [[f64; 2]; 2]) -> Self {
290        Self {
291            lower: value[0].into(),
292            upper: value[1].into(),
293        }
294    }
295}
296
297impl From<BoundF64> for [[f64; 2]; 2] {
298    fn from(value: BoundF64) -> Self {
299        [value.lower.into(), value.upper.into()]
300    }
301}
302
303impl BoundF64 {
304    pub const fn as_ptr(&self) -> *const [f64; 2] {
305        (&self.lower as *const PointF64).cast()
306    }
307
308    pub const fn as_mut_ptr(&mut self) -> *mut [f64; 2] {
309        (&mut self.lower as *mut PointF64).cast()
310    }
311}
312
313#[repr(C)]
314#[derive(Debug, Clone, Copy, PartialEq)]
315pub struct QuadrangleF64 {
316    pub points: [PointF64; 4],
317}
318
319impl From<[[f64; 2]; 4]> for QuadrangleF64 {
320    fn from(value: [[f64; 2]; 4]) -> Self {
321        Self {
322            points: value.map(PointF64::from),
323        }
324    }
325}
326
327impl From<QuadrangleF64> for [[f64; 2]; 4] {
328    fn from(value: QuadrangleF64) -> Self {
329        value.points.map(Into::into)
330    }
331}
332
333impl QuadrangleF64 {
334    pub const fn as_ptr(&self) -> *const [f64; 2] {
335        self.points.as_ptr().cast()
336    }
337
338    pub fn as_mut_ptr(&mut self) -> *mut [f64; 2] {
339        self.points.as_mut_ptr().cast()
340    }
341}
342
343#[derive(Debug, Clone, Copy, PartialEq, Default)]
344pub struct AffineCoefficients {
345    pub values: [[f64; 3]; 2],
346}
347
348impl From<[[f64; 3]; 2]> for AffineCoefficients {
349    fn from(value: [[f64; 3]; 2]) -> Self {
350        Self { values: value }
351    }
352}
353
354impl From<AffineCoefficients> for [[f64; 3]; 2] {
355    fn from(value: AffineCoefficients) -> Self {
356        value.values
357    }
358}
359
360impl AffineCoefficients {
361    pub const fn as_ptr(&self) -> *const [f64; 3] {
362        self.values.as_ptr()
363    }
364
365    pub fn as_mut_ptr(&mut self) -> *mut [f64; 3] {
366        self.values.as_mut_ptr()
367    }
368}
369
370#[derive(Debug, Clone, Copy, PartialEq, Default)]
371pub struct PerspectiveCoefficients {
372    pub values: [[f64; 3]; 3],
373}
374
375impl From<[[f64; 3]; 3]> for PerspectiveCoefficients {
376    fn from(value: [[f64; 3]; 3]) -> Self {
377        Self { values: value }
378    }
379}
380
381impl From<PerspectiveCoefficients> for [[f64; 3]; 3] {
382    fn from(value: PerspectiveCoefficients) -> Self {
383        value.values
384    }
385}
386
387impl PerspectiveCoefficients {
388    pub const fn as_ptr(&self) -> *const [f64; 3] {
389        self.values.as_ptr()
390    }
391
392    pub fn as_mut_ptr(&mut self) -> *mut [f64; 3] {
393        self.values.as_mut_ptr()
394    }
395}