shapes/
rect.rs

1use std::convert::From;
2use graphics::math::{ self, Scalar };
3
4use { Point, Size };
5
6/// A rectangle.
7#[derive(Clone, Copy, Debug)]
8pub struct Rect {
9    /// The position of the top left corner of the rectangle.
10    pub pos: Point,
11    /// The width and height of the rectangle.
12    pub size: Size,
13}
14
15impl<P: Into<Point>, S: Into<Size>> From<(P, S)> for Rect {
16    /// Creates a rectangle from the position of its top left corner and its size.
17    fn from((pos, size): (P, S)) -> Rect {
18        let (pos, size): (Point, Size) = (pos.into(), size.into());
19        Rect { pos: pos, size: size }
20    }
21}
22
23impl From<Rect> for [Scalar; 4] {
24    fn from(rect: Rect) -> [Scalar; 4] {
25        [rect.pos.x, rect.pos.y, rect.size.w, rect.size.h]
26    }
27}
28
29impl From<[Scalar; 4]> for Rect {
30    /// Creates a rectangle from an array.
31    fn from(v: [Scalar; 4]) -> Rect {
32        Rect {
33            pos: Point { x: v[0], y: v[1] },
34            size: Size { w: v[2], h: v[3] },
35        }
36    }
37}
38
39impl From<(Scalar, Scalar, Scalar, Scalar)> for Rect {
40    fn from((x, y, w, h): (Scalar, Scalar, Scalar, Scalar)) -> Rect {
41        Rect {
42            pos: Point { x: x, y: y },
43            size: Size { w: w, h: h },
44        }
45    }
46}
47
48impl Rect {
49    /// Returns the position of the bottom side of the rectangle.
50    pub fn bottom(&self) -> Scalar {
51        self.pos.y + self.size.h
52    }
53
54    /// Computes a rectangle with quadruple the surface area of self and with center
55    /// (self.x, self.y).
56    pub fn centered(self) -> Rect {
57        Rect {
58            pos: Point {
59                 x: self.pos.x - self.size.w,
60                 y: self.pos.y - self.size.h,
61            },
62            size: self.size * 2.0,
63        }
64    }
65
66    /// Compute whether or not the point is inside the rectangle.
67    #[inline(always)]
68    pub fn contains<T: Into<Point>>(&self, point: T) -> bool {
69        let point: Point = point.into();
70        self.left() < point.x && point.x < self.right() &&
71        self.top() < point.y && point.y < self.bottom()
72    }
73
74    /// Create a rectangle that circumscribes the given circle.
75    pub fn new_circle<T: Into<Point>>(center: T, radius: Scalar) -> Rect {
76        let center: Point = center.into();
77        Rect {
78            pos: Point {
79                x: center.x - radius,
80                y: center.y - radius,
81            },
82            size: Size {
83                w: 2.0 * radius,
84                h: 2.0 * radius,
85            },
86        }
87    }
88
89    /// Create a square rectangle with sides of length len and top left corner at pos.
90    pub fn new_square<T: Into<Point>>(pos: T, len: Scalar) -> Rect {
91        let pos: Point = pos.into();
92        Rect {
93            pos: pos,
94            size: Size { w: len, h: len },
95        }
96    }
97
98    /// Returns the position of the left side of the rectangle.
99    pub fn left(&self) -> Scalar {
100        self.pos.x
101    }
102
103    /// Computes a rectangle whose perimeter forms the inside edge of margin with size m for self.
104    #[inline(always)]
105    pub fn margin(self, m: Scalar) -> Rect {
106        math::margin_rectangle(self.into(), m).into()
107    }
108
109    /// Computes a rectangle translated (slid) in the direction of the vector a distance relative
110    /// to the size of the rectangle. For example, self.relative([1.0, 1.0]) returns a rectangle
111    /// one rectangle to the right and down from the original.
112    #[inline(always)]
113    pub fn relative<T: Into<Point>>(self, v: T) -> Rect {
114        let v: Point = v.into();
115        Rect {
116            pos: Point {
117                x: self.pos.x + self.size.w * v.x,
118                y: self.pos.y + self.size.h * v.y,
119            },
120            size: self.size,
121        }
122    }
123
124    /// Returns the position of the right side of the rectangle.
125    pub fn right(&self) -> Scalar {
126        self.pos.x + self.size.w
127    }
128
129    /// Computes a scaled rectangle with the same position as self.
130    pub fn scaled<T: Into<Size>>(self, v: T) -> Rect {
131        let v: Size = v.into();
132        Rect {
133            pos: self.pos,
134            size: self.size * v,
135        }
136    }
137
138    /// Returns the position of the top side of the rectangle.
139    pub fn top(&self) -> Scalar {
140        self.pos.y
141    }
142}