use std::sync::Arc;
#[derive(Clone, PartialEq, Debug, Default)]
pub struct StrokeStyle {
pub line_join: LineJoin,
pub line_cap: LineCap,
pub dash_pattern: StrokeDash,
pub dash_offset: f64,
}
#[derive(Debug, Default, Clone, PartialEq)]
pub struct StrokeDash {
slice: &'static [f64],
alloc: Option<Arc<[f64]>>,
}
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum LineJoin {
Miter {
limit: f64,
},
Round,
Bevel,
}
impl LineJoin {
pub const DEFAULT_MITER_LIMIT: f64 = 10.0;
}
#[derive(Default, Clone, Copy, PartialEq, Eq, Debug)]
pub enum LineCap {
#[default]
Butt,
Round,
Square,
}
impl StrokeStyle {
pub const fn new() -> StrokeStyle {
StrokeStyle {
dash_pattern: StrokeDash {
slice: &[],
alloc: None,
},
line_join: LineJoin::Miter {
limit: LineJoin::DEFAULT_MITER_LIMIT,
},
line_cap: LineCap::Butt,
dash_offset: 0.0,
}
}
pub const fn line_join(mut self, line_join: LineJoin) -> Self {
self.line_join = line_join;
self
}
pub const fn line_cap(mut self, line_cap: LineCap) -> Self {
self.line_cap = line_cap;
self
}
pub const fn dash_offset(mut self, offset: f64) -> Self {
self.dash_offset = offset;
self
}
pub const fn dash_pattern(mut self, lengths: &'static [f64]) -> Self {
self.dash_pattern.slice = lengths;
self
}
pub fn set_line_join(&mut self, line_join: LineJoin) {
self.line_join = line_join;
}
pub fn set_line_cap(&mut self, line_cap: LineCap) {
self.line_cap = line_cap;
}
pub fn set_dash_offset(&mut self, offset: f64) {
self.dash_offset = offset;
}
pub fn set_dash_pattern(&mut self, lengths: impl Into<Arc<[f64]>>) {
self.dash_pattern.alloc = Some(lengths.into())
}
pub fn miter_limit(&self) -> Option<f64> {
match self.line_join {
LineJoin::Miter { limit } => Some(limit),
_ => None,
}
}
}
impl Default for LineJoin {
fn default() -> Self {
LineJoin::Miter {
limit: LineJoin::DEFAULT_MITER_LIMIT,
}
}
}
impl std::ops::Deref for StrokeDash {
type Target = [f64];
fn deref(&self) -> &Self::Target {
self.alloc.as_deref().unwrap_or(self.slice)
}
}