1
0
Fork 0
forked from wry/wry

region: add tagged regions

This commit is contained in:
Julian Orth 2025-02-23 14:41:36 +01:00
parent 0872a1251d
commit 6243278f5f
6 changed files with 1087 additions and 99 deletions

View file

@ -7,8 +7,11 @@ use {
},
},
jay_algorithms::rect::{
RectRaw,
region::{extents, rects_to_bands, subtract, union},
RectRaw, Tag,
region::{
extents, intersect, intersect_tagged, rects_to_bands, rects_to_bands_tagged, subtract,
union,
},
},
smallvec::SmallVec,
std::{
@ -29,19 +32,6 @@ thread_local! {
}
impl Region {
pub fn new(rect: Rect) -> Rc<Self> {
Rc::new(Self::new2(rect))
}
pub fn new2(rect: Rect) -> Self {
let mut rects = SmallVec::new();
rects.push(rect.raw);
Self {
rects,
extents: rect,
}
}
pub fn empty() -> Rc<Self> {
EMPTY.with(|e| e.clone())
}
@ -96,13 +86,82 @@ impl Region {
})
}
#[cfg_attr(not(test), expect(dead_code))]
pub fn intersect(&self, other: &Region) -> Self {
if self.is_empty() || other.is_empty() {
return Self::default();
}
let rects = intersect(&self.rects, &other.rects);
Self {
extents: Rect {
raw: extents(&rects),
},
rects,
}
}
}
impl Region<u32> {
#[cfg_attr(not(test), expect(dead_code))]
pub fn from_rects_tagged(rects: &[Rect<u32>]) -> Self {
if rects.is_empty() {
return Self::default();
}
if rects.len() == 1 {
let mut rect = rects[0];
rect.raw.tag = rect.raw.tag.constrain();
return Self::new2(rect);
}
let rects = rects_to_bands_tagged(unsafe {
mem::transmute::<&[Rect<u32>], &[RectRaw<u32>]>(rects)
});
Self {
extents: Rect {
raw: extents(&rects),
},
rects,
}
}
#[cfg_attr(not(test), expect(dead_code))]
pub fn intersect_tagged(&self, other: &Region) -> Self {
if self.is_empty() || other.is_empty() {
return Self::default();
}
let rects = intersect_tagged(&self.rects, &other.rects);
Self {
extents: Rect {
raw: extents(&rects),
},
rects,
}
}
}
impl<T> Region<T>
where
T: Tag,
{
pub fn new(rect: Rect<T>) -> Rc<Self> {
Rc::new(Self::new2(rect))
}
pub fn new2(rect: Rect<T>) -> Self {
let mut rects = SmallVec::new();
rects.push(rect.raw);
Self {
rects,
extents: rect.untag(),
}
}
#[cfg_attr(not(feature = "it"), expect(dead_code))]
pub fn extents(&self) -> Rect {
self.extents
}
pub fn rects(&self) -> &[Rect] {
unsafe { mem::transmute::<&[RectRaw], &[Rect]>(&self.rects[..]) }
pub fn rects(&self) -> &[Rect<T>] {
unsafe { mem::transmute::<&[RectRaw<T>], &[Rect<T>]>(&self.rects[..]) }
}
pub fn contains(&self, x: i32, y: i32) -> bool {
@ -118,11 +177,14 @@ impl Region {
}
}
impl Deref for Region {
type Target = [Rect];
impl<T> Deref for Region<T>
where
T: Tag,
{
type Target = [Rect<T>];
fn deref(&self) -> &Self::Target {
unsafe { mem::transmute::<&[RectRaw], _>(&self.rects) }
unsafe { mem::transmute::<&[RectRaw<T>], _>(&self.rects) }
}
}