use serde::{Deserialize, Serialize};
use crate::items::PathData;
use crate::primitives::{
BorderRadius, ColorF, ImageKey, LayoutPoint, LayoutRect, LayoutTransform, LayoutVector2D,
MixBlendMode,
};
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ClipSpec {
pub kind: ClipKind,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum ClipKind {
Rect(LayoutRect),
RoundedRect {
rect: LayoutRect,
radius: BorderRadius,
clip_out: bool,
},
Path(PathData),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct TransformSpec {
pub origin: LayoutPoint,
pub transform: LayoutTransform,
pub kind: TransformKind,
}
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub enum TransformKind {
#[default]
Standard,
Preserve3D,
Perspective,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct LayerSpec {
pub origin: LayoutPoint,
pub opacity: f32,
pub mix_blend_mode: MixBlendMode,
pub filters: Vec<FilterOp>,
pub raster_space: RasterSpace,
pub flags: LayerFlags,
pub mask: Option<LayerMask>,
}
impl Default for LayerSpec {
fn default() -> Self {
Self {
origin: LayoutPoint::new(0.0, 0.0),
opacity: 1.0,
mix_blend_mode: MixBlendMode::Normal,
filters: Vec::new(),
raster_space: RasterSpace::default(),
flags: LayerFlags::empty(),
mask: None,
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct LayerMask {
pub mask_rect: LayoutRect,
pub image_mask: Option<ImageKey>,
}
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub enum RasterSpace {
#[default]
Screen,
Local,
}
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct LayerFlags(pub u32);
impl LayerFlags {
pub const BLEND_CONTAINER: Self = Self(1 << 0);
pub const BACKDROP_ROOT: Self = Self(1 << 1);
pub const HAS_SCROLL_LINKED_EFFECT: Self = Self(1 << 2);
pub const fn empty() -> Self {
Self(0)
}
pub fn contains(&self, other: Self) -> bool {
(self.0 & other.0) == other.0
}
}
impl std::ops::BitOr for LayerFlags {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
Self(self.0 | rhs.0)
}
}
impl std::ops::BitOrAssign for LayerFlags {
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0;
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum FilterOp {
Blur(f32),
Brightness(f32),
Contrast(f32),
Grayscale(f32),
HueRotate(f32),
Invert(f32),
Opacity(f32),
Saturate(f32),
Sepia(f32),
DropShadow {
offset: LayoutVector2D,
color: ColorF,
blur_radius: f32,
},
ColorMatrix([f32; 20]),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ShadowSpec {
pub offset: LayoutVector2D,
pub color: ColorF,
pub blur_radius: f32,
}