use skia_safe::utils::parse_path;
use skia_safe::{Path as SkPath, PathFillType};
use crate::native::error::NativeError;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum FillRule {
#[default]
NonZero,
EvenOdd,
}
impl FillRule {
pub(crate) fn to_skia(self) -> PathFillType {
match self {
Self::NonZero => PathFillType::Winding,
Self::EvenOdd => PathFillType::EvenOdd,
}
}
}
pub struct NativePath {
pub(crate) inner: SkPath,
}
impl NativePath {
pub fn from_svg(data: &str, fill_rule: FillRule) -> Result<Self, NativeError> {
let mut path = parse_path::from_svg(data).ok_or_else(|| NativeError::InvalidSvgPath {
reason: format!("could not parse SVG path data: {data:?}"),
})?;
path.set_fill_type(fill_rule.to_skia());
Ok(Self { inner: path })
}
pub fn fill_rule(&self) -> FillRule {
match self.inner.fill_type() {
PathFillType::EvenOdd | PathFillType::InverseEvenOdd => FillRule::EvenOdd,
_ => FillRule::NonZero,
}
}
pub fn set_fill_rule(&mut self, fill_rule: FillRule) {
self.inner.set_fill_type(fill_rule.to_skia());
}
}
impl Clone for NativePath {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}
impl std::fmt::Debug for NativePath {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("NativePath")
.field("fill_rule", &self.fill_rule())
.finish()
}
}