use super::geometry::{Point, Transform};
use super::mask::Mask;
use super::path_data::PathData;
use super::scratch::Scratch;
use super::style::{Fill, Style};
use core::cell::RefCell;
pub struct HitTest<'a, 's, D> {
data: D,
style: Style<'a>,
transform: Option<Transform>,
threshold: u8,
scratch: RefCell<Option<&'s mut Scratch>>,
}
impl<'a, 's, D> HitTest<'a, 's, D>
where
D: PathData,
{
pub fn new(data: D) -> Self {
Self {
data,
style: Style::Fill(Fill::NonZero),
transform: None,
threshold: 0,
scratch: RefCell::new(None),
}
}
pub fn with_scratch(data: D, scratch: &'s mut Scratch) -> Self {
Self {
data,
style: Style::Fill(Fill::NonZero),
transform: None,
threshold: 0,
scratch: RefCell::new(Some(scratch)),
}
}
pub fn style(&mut self, style: impl Into<Style<'a>>) -> &mut Self {
self.style = style.into();
self
}
pub fn transform(&mut self, transform: Option<Transform>) -> &mut Self {
self.transform = transform;
self
}
pub fn threshold(&mut self, threshold: u8) -> &mut Self {
self.threshold = threshold;
self
}
pub fn test(&self, point: impl Into<Point>) -> bool {
let mut scratch = self.scratch.borrow_mut();
let mut buf = [0u8; 1];
let p = point.into() * -1.;
if let Some(scratch) = scratch.as_mut() {
Mask::with_scratch(&self.data, scratch)
.style(self.style)
.offset(p)
.transform(self.transform)
.size(1, 1)
.render_into(&mut buf, None);
} else {
Mask::new(&self.data)
.style(self.style)
.offset(p)
.transform(self.transform)
.size(1, 1)
.render_into(&mut buf, None);
}
if self.threshold == 0xFF {
buf[0] >= self.threshold
} else {
buf[0] > self.threshold
}
}
}