math2d/
rectu.rs

1//! Axis-aligned rectangle defined by the lines of its 4 edges.
2
3use rectf::Rectf;
4use recti::Recti;
5
6#[cfg(all(windows, feature = "d2d"))]
7use winapi::um::dcommon::D2D_RECT_U;
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 Rectu {
15    /// The x-coordinate of the upper-left corner of the rectangle.
16    pub left: u32,
17    /// The y-coordinate of the upper-left corner of the rectangle.
18    pub top: u32,
19    /// The x-coordinate of the lower-right corner of the rectangle.
20    pub right: u32,
21    /// The y-coordinate of the lower-right corner of the rectangle.
22    pub bottom: u32,
23}
24
25impl Rectu {
26    /// Constructs the rectangle from components.
27    #[inline]
28    pub fn new(left: u32, top: u32, right: u32, bottom: u32) -> Rectu {
29        Rectu {
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 rectangle to signed integer values. Beware of casting
49    /// overflow if any of the components are greater than i32::MAX.
50    #[inline]
51    pub fn to_i32(&self) -> Recti {
52        Recti {
53            left: self.left as i32,
54            top: self.top as i32,
55            right: self.right as i32,
56            bottom: self.bottom as i32,
57        }
58    }
59}
60
61#[cfg(all(windows, feature = "d2d"))]
62impl From<Rectu> for D2D_RECT_U {
63    #[inline]
64    fn from(rect: Rectu) -> D2D_RECT_U {
65        D2D_RECT_U {
66            left: rect.left,
67            top: rect.top,
68            right: rect.right,
69            bottom: rect.bottom,
70        }
71    }
72}
73
74#[cfg(all(windows, feature = "d2d"))]
75impl From<D2D_RECT_U> for Rectu {
76    #[inline]
77    fn from(rect: D2D_RECT_U) -> Rectu {
78        Rectu {
79            left: rect.left,
80            top: rect.top,
81            right: rect.right,
82            bottom: rect.bottom,
83        }
84    }
85}
86
87#[cfg(all(test, windows, feature = "d2d"))]
88#[test]
89fn rectu_d2d_bin_compat() {
90    use std::mem::size_of_val;
91
92    fn ptr_eq<T>(a: &T, b: &T) -> bool {
93        (a as *const T) == (b as *const T)
94    }
95
96    let rect = Rectu::new(0, 0, 0, 0);
97    let d2d = unsafe { &*((&rect) as *const _ as *const D2D_RECT_U) };
98
99    assert!(ptr_eq(&rect.left, &d2d.left));
100    assert!(ptr_eq(&rect.top, &d2d.top));
101    assert!(ptr_eq(&rect.right, &d2d.right));
102    assert!(ptr_eq(&rect.bottom, &d2d.bottom));
103    assert_eq!(size_of_val(&rect), size_of_val(d2d));
104}
105