use super::*;
use canvas::*;
use std::f32;
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Rect {
pub x1: f32,
pub y1: f32,
pub x2: f32,
pub y2: f32
}
impl Rect {
pub fn new(top_left: PathPoint, bottom_right: PathPoint) -> Rect {
Rect {
x1: top_left.position.0,
y1: top_left.position.1,
x2: bottom_right.position.0,
y2: bottom_right.position.1
}
}
pub fn with_points(x1: f32, y1: f32, x2: f32, y2: f32) -> Rect {
Rect {
x1, y1, x2, y2
}
}
pub fn empty() -> Rect {
Rect {
x1: 0.0,
y1: 0.0,
x2: 0.0,
y2: 0.0
}
}
#[inline]
pub fn normalize(self) -> Rect {
Rect {
x1: f32::min(self.x1, self.x2),
y1: f32::min(self.y1, self.y2),
x2: f32::max(self.x1, self.x2),
y2: f32::max(self.y1, self.y2),
}
}
pub fn contains(&self, x: f32, y: f32) -> bool {
(f32::min(self.x1, self.x2) <= x) &&
(x <= f32::max(self.x1, self.x2)) &&
(f32::min(self.y1, self.y2) <= y) &&
(y <= f32::max(self.y1, self.y2))
}
#[inline]
pub fn is_zero_size(&self) -> bool {
self.x1 == self.x2 && self.y1 == self.y2
}
#[inline]
pub fn union(self, rhs: Rect) -> Rect {
if self.is_zero_size() {
rhs
} else if rhs.is_zero_size() {
self
} else {
Rect {
x1: f32::min(self.x1, f32::min(self.x2, f32::min(rhs.x1, rhs.x2))),
y1: f32::min(self.y1, f32::min(self.y2, f32::min(rhs.y1, rhs.y2))),
x2: f32::max(self.x1, f32::max(self.x2, f32::max(rhs.x1, rhs.x2))),
y2: f32::max(self.y1, f32::max(self.y2, f32::max(rhs.y1, rhs.y2))),
}
}
}
}
impl<'a> Into<Vec<Draw>> for &'a Rect {
fn into(self) -> Vec<Draw> {
vec![
Draw::Move(self.x1, self.y1),
Draw::Line(self.x2, self.y1),
Draw::Line(self.x2, self.y2),
Draw::Line(self.x1, self.y2),
Draw::ClosePath
]
}
}
impl Into<Vec<Draw>> for Rect {
fn into(self) -> Vec<Draw> {
(&self).into()
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn can_union_rects() {
assert!(Rect::with_points(30.0, 30.0, 60.0, 40.0).union(Rect::with_points(40.0, 20.0, 100.0, 30.0)) == Rect::with_points(30.0, 20.0, 100.0, 40.0));
}
#[test]
fn can_union_empty_rects_lhs() {
assert!(Rect::empty().union(Rect::with_points(40.0, 20.0, 100.0, 30.0)) == Rect::with_points(40.0, 20.0, 100.0, 30.0));
}
#[test]
fn can_union_empty_rects_rhs() {
assert!(Rect::with_points(30.0, 30.0, 60.0, 40.0).union(Rect::empty()) == Rect::with_points(30.0, 30.0, 60.0, 40.0));
}
}