math2d/
recti.rs

1//! Axis-aligned rectangle defined by the lines of its 4 edges.
2
3use rectf::Rectf;
4use rectu::Rectu;
5
6#[cfg(all(windows, feature = "d2d"))]
7use winapi::um::dcommon::D2D_RECT_L;
8
9/// Represents a rectangle defined by the coordinates of the upper-left corner
10/// (left, top) and the coordinates of the lower-right corner (right, bottom).
11#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
12#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))]
13#[repr(C)]
14pub struct Recti {
15    /// The x-coordinate of the upper-left corner of the rectangle.
16    pub left: i32,
17    /// The y-coordinate of the upper-left corner of the rectangle.
18    pub top: i32,
19    /// The x-coordinate of the lower-right corner of the rectangle.
20    pub right: i32,
21    /// The y-coordinate of the lower-right corner of the rectangle.
22    pub bottom: i32,
23}
24
25impl Recti {
26    /// Constructs the rectangle from components.
27    #[inline]
28    pub fn new(left: i32, top: i32, right: i32, bottom: i32) -> Recti {
29        Recti {
30            left,
31            top,
32            right,
33            bottom,
34        }
35    }
36
37    /// Converts the rectangle to floating point values.
38    #[inline]
39    pub fn to_f32(&self) -> Rectf {
40        Rectf {
41            left: self.left as f32,
42            top: self.top as f32,
43            right: self.right as f32,
44            bottom: self.bottom as f32,
45        }
46    }
47
48    /// Converts the components of the rectangle to unsigned integers. Beware
49    /// this conversion if the components could be negative, you will experience
50    /// unsigned casting underflow.
51    #[inline]
52    pub fn to_u32(&self) -> Rectu {
53        Rectu {
54            left: self.left as u32,
55            top: self.top as u32,
56            right: self.right as u32,
57            bottom: self.bottom as u32,
58        }
59    }
60}
61
62#[cfg(all(windows, feature = "d2d"))]
63impl From<Recti> for D2D_RECT_L {
64    #[inline]
65    fn from(rect: Recti) -> D2D_RECT_L {
66        D2D_RECT_L {
67            left: rect.left,
68            top: rect.top,
69            right: rect.right,
70            bottom: rect.bottom,
71        }
72    }
73}
74
75#[cfg(all(windows, feature = "d2d"))]
76impl From<D2D_RECT_L> for Recti {
77    #[inline]
78    fn from(rect: D2D_RECT_L) -> Recti {
79        Recti {
80            left: rect.left,
81            top: rect.top,
82            right: rect.right,
83            bottom: rect.bottom,
84        }
85    }
86}
87
88#[cfg(all(test, windows, feature = "d2d"))]
89#[test]
90fn recti_d2d_bin_compat() {
91    use std::mem::size_of_val;
92
93    fn ptr_eq<T>(a: &T, b: &T) -> bool {
94        (a as *const T) == (b as *const T)
95    }
96
97    let rect = Recti::new(0, 0, 0, 0);
98    let d2d = unsafe { &*((&rect) as *const _ as *const D2D_RECT_L) };
99
100    assert!(ptr_eq(&rect.left, &d2d.left));
101    assert!(ptr_eq(&rect.top, &d2d.top));
102    assert!(ptr_eq(&rect.right, &d2d.right));
103    assert!(ptr_eq(&rect.bottom, &d2d.bottom));
104    assert_eq!(size_of_val(&rect), size_of_val(d2d));
105}