1
0
Fork 0
forked from wry/wry

utils: move damage algorithms to algorithm crate

This commit is contained in:
Julian Orth 2022-06-03 21:01:20 +02:00
parent 259340938b
commit 6e244a08ab
12 changed files with 710 additions and 542 deletions

View file

@ -5,36 +5,26 @@ mod tests;
pub use region::RegionBuilder;
use {
algorithms::rect::RectRaw,
smallvec::SmallVec,
std::fmt::{Debug, Formatter},
};
#[derive(Copy, Clone, Eq, PartialEq, Default)]
#[repr(transparent)]
pub struct Rect {
x1: i32,
y1: i32,
x2: i32,
y2: i32,
raw: RectRaw,
}
type Container = SmallVec<[Rect; 1]>;
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct Region {
rects: Container,
rects: SmallVec<[RectRaw; 1]>,
extents: Rect,
}
impl Debug for Rect {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Rect")
.field("x1", &self.x1)
.field("y1", &self.y1)
.field("x2", &self.x2)
.field("y2", &self.y2)
.field("width", &(self.x2 - self.x1))
.field("height", &(self.y2 - self.y1))
.finish()
Debug::fmt(&self.raw, f)
}
}
@ -64,10 +54,12 @@ impl Rect {
#[allow(dead_code)]
pub fn new_empty(x: i32, y: i32) -> Self {
Self {
x1: x,
y1: y,
x2: x,
y2: y,
raw: RectRaw {
x1: x,
y1: y,
x2: x,
y2: y,
},
}
}
@ -75,12 +67,16 @@ impl Rect {
if x2 < x1 || y2 < y1 {
return None;
}
Some(Self { x1, y1, x2, y2 })
Some(Self {
raw: RectRaw { x1, y1, x2, y2 },
})
}
#[allow(dead_code)]
fn new_unchecked(x1: i32, y1: i32, x2: i32, y2: i32) -> Self {
Self { x1, y1, x2, y2 }
Self {
raw: RectRaw { x1, y1, x2, y2 },
}
}
pub fn new_sized(x1: i32, y1: i32, width: i32, height: i32) -> Option<Self> {
@ -92,113 +88,129 @@ impl Rect {
pub fn union(&self, other: Self) -> Self {
Self {
x1: self.x1.min(other.x1),
y1: self.y1.min(other.y1),
x2: self.x2.max(other.x2),
y2: self.y2.max(other.y2),
raw: RectRaw {
x1: self.raw.x1.min(other.raw.x1),
y1: self.raw.y1.min(other.raw.y1),
x2: self.raw.x2.max(other.raw.x2),
y2: self.raw.y2.max(other.raw.y2),
},
}
}
pub fn intersects(&self, other: &Self) -> bool {
self.x1 < other.x2 && other.x1 < self.x2 && self.y1 < other.y2 && other.y1 < self.y2
self.raw.x1 < other.raw.x2
&& other.raw.x1 < self.raw.x2
&& self.raw.y1 < other.raw.y2
&& other.raw.y1 < self.raw.y2
}
pub fn intersect(&self, other: Self) -> Self {
let x1 = self.x1.max(other.x1);
let y1 = self.y1.max(other.y1);
let x2 = self.x2.min(other.x2).max(x1);
let y2 = self.y2.min(other.y2).max(y1);
Self { x1, y1, x2, y2 }
let x1 = self.raw.x1.max(other.raw.x1);
let y1 = self.raw.y1.max(other.raw.y1);
let x2 = self.raw.x2.min(other.raw.x2).max(x1);
let y2 = self.raw.y2.min(other.raw.y2).max(y1);
Self {
raw: RectRaw { x1, y1, x2, y2 },
}
}
pub fn contains(&self, x: i32, y: i32) -> bool {
self.x1 <= x && self.y1 <= y && self.x2 > x && self.y2 > y
self.raw.x1 <= x && self.raw.y1 <= y && self.raw.x2 > x && self.raw.y2 > y
}
#[allow(dead_code)]
pub fn contains_rect(&self, rect: &Self) -> bool {
self.x1 <= rect.x1 && self.y1 <= rect.x1 && rect.x2 <= self.x2 && rect.y2 <= self.y2
self.raw.x1 <= rect.raw.x1
&& self.raw.y1 <= rect.raw.x1
&& rect.raw.x2 <= self.raw.x2
&& rect.raw.y2 <= self.raw.y2
}
pub fn get_overflow(&self, child: &Self) -> RectOverflow {
RectOverflow {
left: self.x1 - child.x1,
right: child.x2 - self.x2,
top: self.y1 - child.y1,
bottom: child.y2 - self.y2,
left: self.raw.x1 - child.raw.x1,
right: child.raw.x2 - self.raw.x2,
top: self.raw.y1 - child.raw.y1,
bottom: child.raw.y2 - self.raw.y2,
}
}
pub fn is_empty(&self) -> bool {
self.x1 == self.x2 || self.y1 == self.y2
self.raw.x1 == self.raw.x2 || self.raw.y1 == self.raw.y2
}
#[allow(dead_code)]
pub fn to_origin(&self) -> Self {
Self {
x1: 0,
y1: 0,
x2: self.x2 - self.x1,
y2: self.y2 - self.y1,
raw: RectRaw {
x1: 0,
y1: 0,
x2: self.raw.x2 - self.raw.x1,
y2: self.raw.y2 - self.raw.y1,
},
}
}
pub fn move_(&self, dx: i32, dy: i32) -> Self {
Self {
x1: self.x1.saturating_add(dx),
y1: self.y1.saturating_add(dy),
x2: self.x2.saturating_add(dx),
y2: self.y2.saturating_add(dy),
raw: RectRaw {
x1: self.raw.x1.saturating_add(dx),
y1: self.raw.y1.saturating_add(dy),
x2: self.raw.x2.saturating_add(dx),
y2: self.raw.y2.saturating_add(dy),
},
}
}
pub fn at_point(&self, x1: i32, y1: i32) -> Self {
Self {
x1,
y1,
x2: x1 + self.x2 - self.x1,
y2: y1 + self.y2 - self.y1,
raw: RectRaw {
x1,
y1,
x2: x1 + self.raw.x2 - self.raw.x1,
y2: y1 + self.raw.y2 - self.raw.y1,
},
}
}
pub fn with_size(&self, width: i32, height: i32) -> Option<Self> {
Self::new_sized(self.x1, self.y1, width, height)
Self::new_sized(self.raw.x1, self.raw.y1, width, height)
}
pub fn translate(&self, x: i32, y: i32) -> (i32, i32) {
(x.wrapping_sub(self.x1), y.wrapping_sub(self.y1))
(x.wrapping_sub(self.raw.x1), y.wrapping_sub(self.raw.y1))
}
pub fn translate_inv(&self, x: i32, y: i32) -> (i32, i32) {
(x.wrapping_add(self.x1), y.wrapping_add(self.y1))
(x.wrapping_add(self.raw.x1), y.wrapping_add(self.raw.y1))
}
pub fn x1(&self) -> i32 {
self.x1
self.raw.x1
}
pub fn x2(&self) -> i32 {
self.x2
self.raw.x2
}
pub fn y1(&self) -> i32 {
self.y1
self.raw.y1
}
pub fn y2(&self) -> i32 {
self.y2
self.raw.y2
}
pub fn width(&self) -> i32 {
self.x2 - self.x1
self.raw.x2 - self.raw.x1
}
pub fn height(&self) -> i32 {
self.y2 - self.y1
self.raw.y2 - self.raw.y1
}
pub fn position(&self) -> (i32, i32) {
(self.x1, self.y1)
(self.raw.x1, self.raw.y1)
}
pub fn size(&self) -> (i32, i32) {