pixelutil_image/
coordinate.rs

1use crate::index::ImageAxisIndex;
2
3/// Trait for types that can represent image coordinates
4pub trait ImageCoordinate {
5    /// Return the `(x, y)` pixel indices, or [`None`] if the coordinate is invalid.
6    fn image_coordinate(&self) -> Option<(u32, u32)>;
7
8    /// Return clamped `(x, y)` pixel indices within the given bounds.
9    /// Bounds are `(0, 0)` and `(right, bottom)`.
10    fn image_coordinate_clamped(&self, right: u32, bottom: u32) -> (u32, u32);
11}
12
13impl<T: ImageAxisIndex> ImageCoordinate for (T, T) {
14    #[inline]
15    fn image_coordinate(&self) -> Option<(u32, u32)> {
16        let (x, y) = *self;
17        x.to_image_axis_index().zip(y.to_image_axis_index())
18    }
19
20    #[inline]
21    fn image_coordinate_clamped(&self, right: u32, bottom: u32) -> (u32, u32) {
22        let (x, y) = *self;
23        (
24            x.clamp_image_axis_index(right),
25            y.clamp_image_axis_index(bottom),
26        )
27    }
28}
29
30impl<T: ImageAxisIndex> ImageCoordinate for [T; 2] {
31    #[inline]
32    fn image_coordinate(&self) -> Option<(u32, u32)> {
33        let [x, y] = *self;
34        x.to_image_axis_index().zip(y.to_image_axis_index())
35    }
36
37    #[inline]
38    fn image_coordinate_clamped(&self, right: u32, bottom: u32) -> (u32, u32) {
39        let [x, y] = *self;
40        (
41            x.clamp_image_axis_index(right),
42            y.clamp_image_axis_index(bottom),
43        )
44    }
45}
46
47#[cfg(feature = "nalgebra")]
48impl<T: ImageAxisIndex + nalgebra::Scalar> ImageCoordinate for nalgebra::OPoint<T, nalgebra::Const<2>> {
49    #[inline]
50    fn image_coordinate(&self) -> Option<(u32, u32)> {
51        let [x, y] = self.coords.into();
52        x.to_image_axis_index().zip(y.to_image_axis_index())
53    }
54
55    #[inline]
56    fn image_coordinate_clamped(&self, right: u32, bottom: u32) -> (u32, u32) {
57        let [x, y] = self.coords.into();
58        (
59            x.clamp_image_axis_index(right),
60            y.clamp_image_axis_index(bottom),
61        )
62    }
63}
64
65#[cfg(feature = "nalgebra")]
66impl<T: ImageAxisIndex + nalgebra::Scalar> ImageCoordinate for nalgebra::coordinates::XY<T> {
67    fn image_coordinate(&self) -> Option<(u32, u32)> {
68        self.x
69            .to_image_axis_index()
70            .zip(self.y.to_image_axis_index())
71    }
72
73    fn image_coordinate_clamped(&self, right: u32, bottom: u32) -> (u32, u32) {
74        (
75            self.x.clamp_image_axis_index(right),
76            self.y.clamp_image_axis_index(bottom),
77        )
78    }
79}