use super::*;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum ClipMode {
#[default]
Coverage,
Geometric,
}
impl From<PathClip> for ShapeClip {
fn from(clip: PathClip) -> Self {
Self {
geometry: ClipGeometry::Path(clip.path),
transform: clip.transform,
rule: clip.rule,
}
}
}
impl From<RectClip> for ShapeClip {
fn from(clip: RectClip) -> Self {
Self {
geometry: ClipGeometry::Rectangle(clip.bounds),
transform: clip.transform,
rule: FillRule::NonZero,
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct PathClip {
pub path: Arc<Path2D>,
pub transform: Transform,
pub rule: FillRule,
}
impl PathClip {
pub fn new(path: Path2D) -> Self {
Self {
path: Arc::new(path),
transform: Transform::IDENTITY,
rule: FillRule::NonZero,
}
}
}
impl From<Path2D> for PathClip {
fn from(path: Path2D) -> Self {
Self::new(path)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct RectClip {
pub bounds: Rect,
pub transform: Transform,
}
impl RectClip {
pub const fn new(bounds: Rect) -> Self {
Self {
bounds,
transform: Transform::IDENTITY,
}
}
}
impl From<Rect> for RectClip {
fn from(bounds: Rect) -> Self {
Self::new(bounds)
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct ShapeClip {
pub geometry: ClipGeometry,
pub transform: Transform,
pub rule: FillRule,
}
#[derive(Clone, Debug, PartialEq)]
pub enum ClipGeometry {
Rectangle(Rect),
Path(Arc<Path2D>),
}
impl ShapeClip {
pub fn new(shape: &(impl Shape + ?Sized)) -> Self {
Self {
geometry: shape.as_rect().map_or_else(
|| ClipGeometry::Path(Arc::new(shape.path())),
ClipGeometry::Rectangle,
),
transform: Transform::IDENTITY,
rule: FillRule::NonZero,
}
}
pub fn validate(&self, path: &str) -> Result<usize, ValidationError> {
match &self.geometry {
ClipGeometry::Rectangle(bounds) => {
crate::display_list::mapped_bounds(*bounds, self.transform, path)?;
Ok(0)
}
ClipGeometry::Path(geometry) => {
crate::display_list::validate_path(geometry, self.transform, path)?;
Ok(geometry.verbs().len())
}
}
}
}
impl<Geometry: Shape> From<Geometry> for ShapeClip {
fn from(shape: Geometry) -> Self {
Self::new(&shape)
}
}