mirror of
https://github.com/encounter/rust-sdl2.git
synced 2026-07-10 21:18:41 -07:00
rect: fix bug in rect; add doc; rename method.
This commit is contained in:
+69
-26
@@ -1,34 +1,38 @@
|
||||
/*!
|
||||
Rectangle Functions
|
||||
*/
|
||||
|
||||
use std::cast;
|
||||
use libc::c_int;
|
||||
use std::ptr;
|
||||
|
||||
#[deriving(Eq)]
|
||||
#[deriving(Clone)]
|
||||
pub struct Point{
|
||||
/// A structure that defines a two dimensional point.
|
||||
#[deriving(Eq, Clone, Show)]
|
||||
pub struct Point {
|
||||
pub x: i32,
|
||||
pub y: i32
|
||||
}
|
||||
|
||||
#[deriving(Eq)]
|
||||
#[deriving(Clone)]
|
||||
/// A structure that defines a rectangle, with the origin at the upper left.
|
||||
#[deriving(Eq, Clone, Show)]
|
||||
pub struct Rect {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub w: i32,
|
||||
pub h: i32
|
||||
pub h: i32
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod ll {
|
||||
|
||||
use libc::{c_int};
|
||||
use rect::Rect;
|
||||
use rect::Point;
|
||||
use libc::c_int;
|
||||
use super::Rect;
|
||||
use super::Point;
|
||||
|
||||
pub type SDL_Rect = Rect;
|
||||
pub type SDL_Point = Point;
|
||||
pub type SDL_bool = c_int;
|
||||
|
||||
|
||||
extern "C" {
|
||||
pub fn SDL_HasIntersection(A: *SDL_Rect, B: *SDL_Rect) -> SDL_bool;
|
||||
pub fn SDL_IntersectRect(A: *SDL_Rect, B: *SDL_Rect, result: *SDL_Rect) -> SDL_bool;
|
||||
@@ -38,10 +42,6 @@ pub mod ll {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn Point(x: i32, y: i32) -> Point {
|
||||
Point { x: x, y: y }
|
||||
}
|
||||
|
||||
impl Point {
|
||||
pub fn new(x: i32, y: i32) -> Point {
|
||||
Point {
|
||||
@@ -51,10 +51,6 @@ impl Point {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn Rect(x: i32, y: i32, w: i32, h: i32) -> Rect {
|
||||
Rect { x: x, y: y, w: w, h: h }
|
||||
}
|
||||
|
||||
impl Rect {
|
||||
pub fn new(x: i32, y: i32, w: i32, h: i32) -> Rect {
|
||||
Rect {
|
||||
@@ -65,16 +61,17 @@ impl Rect {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enclose_points(points: &[Point], clip: Option<Rect>) -> Option<Rect> {
|
||||
/// Calculate a minimal rectangle enclosing a set of points.
|
||||
pub fn from_enclose_points(points: &[Point], clip: Option<Rect>) -> Option<Rect> {
|
||||
let out: Rect = Rect::new(0, 0, 0, 0);
|
||||
|
||||
let result = unsafe {
|
||||
ll::SDL_EnclosePoints(
|
||||
cast::transmute(points.as_ptr()),
|
||||
points.len() as c_int,
|
||||
match clip { Some(ref rect) => cast::transmute(rect), None => ptr::null() },
|
||||
cast::transmute(clip.as_ref()),
|
||||
&out
|
||||
) == 0
|
||||
) != 0
|
||||
};
|
||||
|
||||
if result {
|
||||
@@ -84,21 +81,24 @@ impl Rect {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn empty(&self) -> bool {
|
||||
/// Check whether a rectangle has no area.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
(self.w <= 0) || (self.h <= 0)
|
||||
}
|
||||
|
||||
/// Determine whether two rectangles intersect.
|
||||
pub fn has_intersection(&self, other: &Rect) -> bool {
|
||||
unsafe {
|
||||
ll::SDL_HasIntersection(self, other) == 0
|
||||
ll::SDL_HasIntersection(self, other) != 0
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculate the intersection of two rectangles.
|
||||
pub fn intersection(&self, other: &Rect) -> Option<Rect> {
|
||||
let out: Rect = Rect::new(0, 0, 0, 0);
|
||||
|
||||
let result = unsafe {
|
||||
ll::SDL_IntersectRect(self, other, &out) == 0
|
||||
ll::SDL_IntersectRect(self, other, &out) != 0
|
||||
};
|
||||
|
||||
if result {
|
||||
@@ -108,6 +108,7 @@ impl Rect {
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculate the union of two rectangles.
|
||||
pub fn union(&self, other: &Rect) -> Rect {
|
||||
let out: Rect = Rect::new(0, 0, 0, 0);
|
||||
|
||||
@@ -118,12 +119,13 @@ impl Rect {
|
||||
out
|
||||
}
|
||||
|
||||
/// Calculate the intersection of a rectangle and line segment. return points of intersection.
|
||||
pub fn intersect_line(&self, start: &Point, end: &Point) -> Option<(Point, Point)> {
|
||||
let out_start: Point = start.clone();
|
||||
let out_end: Point = end.clone();
|
||||
|
||||
let result = unsafe {
|
||||
ll::SDL_IntersectRectAndLine(self, &out_start.x, &out_start.y, &out_end.x, &out_end.y) == 0
|
||||
ll::SDL_IntersectRectAndLine(self, &out_start.x, &out_start.y, &out_end.x, &out_end.y) != 0
|
||||
};
|
||||
|
||||
if result {
|
||||
@@ -133,3 +135,44 @@ impl Rect {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_from_enclose_points() {
|
||||
assert_eq!(Rect::from_enclose_points(&[Point::new(2, 4), Point::new(5,9)], None),
|
||||
Some(Rect::new(2, 4, 4, 6)));
|
||||
assert!(Rect::from_enclose_points(&[Point::new(0, 0), Point::new(10,10)],
|
||||
Some(Rect::new(3, 3, 1, 1))).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_has_intersection() {
|
||||
assert!(Rect::new(0, 0, 10, 10).has_intersection(&Rect::new(9, 9, 10, 10)));
|
||||
// edge
|
||||
assert!(! Rect::new(0, 0, 10, 10).has_intersection(&Rect::new(10, 10, 10, 10)));
|
||||
// out
|
||||
assert!(! Rect::new(0, 0, 10, 10).has_intersection(&Rect::new(11, 11, 10, 10)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intersection() {
|
||||
assert_eq!(Rect::new(0, 0, 10, 10).intersection(&Rect::new(9, 9, 10, 10)),
|
||||
Some(Rect::new(9, 9, 1, 1)));
|
||||
assert!(Rect::new(0, 0, 10, 10).intersection(&Rect::new(11, 11, 10, 10)).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_union() {
|
||||
assert_eq!(Rect::new(0, 0, 1, 1).union(&Rect::new(9, 9, 1, 1)),
|
||||
Rect::new(0, 0, 10, 10));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intersect_line() {
|
||||
assert_eq!(Rect::new(1, 1, 5, 5).intersect_line(&Point::new(0, 0), &Point::new(10, 10)),
|
||||
Some((Point::new(1, 1), Point::new(5, 5))));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user