use crate::color::Color;
#[derive(Clone, Debug, PartialEq)]
pub struct DashPattern {
pub dashes: Vec<f64>,
pub offset: f64,
}
impl DashPattern {
pub fn new(dashes: &[f64]) -> Self {
Self {
dashes: dashes.to_vec(),
offset: 0.0,
}
}
pub fn to_svg_string(&self) -> String {
self.dashes
.iter()
.map(|d| format!("{d}"))
.collect::<Vec<_>>()
.join(",")
}
}
#[derive(Clone, Debug)]
pub struct Stroke {
pub color: Color,
pub width: f64,
pub dash: Option<DashPattern>,
pub line_cap: LineCap,
pub line_join: LineJoin,
}
impl Stroke {
pub fn solid(color: Color, width: f64) -> Self {
Self {
color,
width,
dash: None,
line_cap: LineCap::Butt,
line_join: LineJoin::Miter,
}
}
pub fn dashed(color: Color, width: f64, dashes: &[f64]) -> Self {
Self {
color,
width,
dash: Some(DashPattern::new(dashes)),
line_cap: LineCap::Butt,
line_join: LineJoin::Miter,
}
}
}
impl Default for Stroke {
fn default() -> Self {
Self::solid(Color::BLACK, 1.0)
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum LineCap {
#[default]
Butt,
Round,
Square,
}
impl LineCap {
pub fn as_svg_str(self) -> &'static str {
match self {
Self::Butt => "butt",
Self::Round => "round",
Self::Square => "square",
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum LineJoin {
#[default]
Miter,
Round,
Bevel,
}
impl LineJoin {
pub fn as_svg_str(self) -> &'static str {
match self {
Self::Miter => "miter",
Self::Round => "round",
Self::Bevel => "bevel",
}
}
}
#[derive(Clone, Debug, Default)]
pub enum Fill {
#[default]
None,
Solid(Color),
Gradient(String),
}
impl Fill {
pub fn to_svg_string(&self) -> String {
match self {
Self::None => "none".to_string(),
Self::Solid(c) => c.to_svg_string(),
Self::Gradient(id) => format!("url(#{id})"),
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum TextAnchor {
#[default]
Start,
Middle,
End,
}
impl TextAnchor {
pub fn as_svg_str(self) -> &'static str {
match self {
Self::Start => "start",
Self::Middle => "middle",
Self::End => "end",
}
}
}
#[derive(Clone, Debug)]
pub struct FontStyle {
pub family: String,
pub size: f64,
pub weight: u16,
pub color: Color,
pub anchor: TextAnchor,
}
impl FontStyle {
pub fn new(size: f64) -> Self {
Self {
family: "sans-serif".to_string(),
size,
weight: 400,
color: Color::BLACK,
anchor: TextAnchor::Start,
}
}
}
impl Default for FontStyle {
fn default() -> Self {
Self::new(12.0)
}
}