use crate::prelude::*;
use nalgebra::Transform2;
pub trait Export<E>
where
E: Exporter,
{
fn write_into_exporter(
&self,
exporter: &mut E,
parent_transform: &Transform2<f32>,
style_position: StylePosition,
) -> Result<(), <E as Exporter>::Error>;
}
impl<E> Export<E> for Shape
where
E: Exporter,
{
fn write_into_exporter(
&self,
exporter: &mut E,
parent_transform: &Transform2<f32>,
StylePosition { fill, stroke }: StylePosition,
) -> Result<(), <E as Exporter>::Error> {
match self {
Shape::Group(Group {
local_transform,
shapes,
metadata,
}) => {
exporter.start_block(metadata.as_slice())?;
let parent_transform = parent_transform * local_transform;
for shape in shapes {
shape.write_into_exporter(
exporter,
&parent_transform,
StylePosition { fill, stroke },
)?;
}
exporter.end_block(metadata.as_slice())?;
Ok(())
}
Shape::Style {
fill,
stroke,
shape,
} => {
let style = StylePosition {
fill: fill.clone(),
stroke: stroke.clone().map(|v| *parent_transform * v),
};
exporter.start_style(style)?;
shape.write_into_exporter(exporter, parent_transform, style)?;
exporter.end_style()
}
Shape::Image(image) => exporter.export_image(image.position(parent_transform)),
Shape::Ellipse(ellipse) => {
if E::CAN_EXPORT_ELLIPSE {
exporter.export_ellipse(
ellipse.position(parent_transform),
StylePosition { fill, stroke },
)
} else {
exporter.export_curve(
ellipse.as_curve().position(parent_transform),
StylePosition { fill, stroke },
)
}
}
Shape::Curve(curve) => exporter.export_curve(
curve.position(parent_transform),
StylePosition { fill, stroke },
),
Shape::Text(text) => exporter.export_text(
text.position(parent_transform),
StylePosition { fill, stroke },
),
Shape::Dynamic {
local_transform,
shaper,
} => {
let shape = shaper();
let parent_transform = parent_transform * local_transform;
shape.write_into_exporter(
exporter,
&parent_transform,
StylePosition { fill, stroke },
)
}
}
}
}
pub trait Exporter {
type Error;
const CAN_EXPORT_ELLIPSE: bool = true;
fn start_style(&mut self, style: StylePosition) -> Result<(), Self::Error>;
fn end_style(&mut self) -> Result<(), Self::Error>;
fn start_block(&mut self, _metadata: &[(String, String)]) -> Result<(), Self::Error> {
Ok(())
}
fn end_block(&mut self, _metadata: &[(String, String)]) -> Result<(), Self::Error> {
Ok(())
}
fn export_image(&mut self, image: ImagePosition) -> Result<(), Self::Error>;
fn export_ellipse(
&mut self,
_ellipse: EllipsePosition,
_style: StylePosition,
) -> Result<(), Self::Error> {
Ok(())
}
fn export_curve(
&mut self,
curve: CurvePosition,
style_position: StylePosition,
) -> Result<(), Self::Error>;
fn export_text(&mut self, text: TextPosition, style: StylePosition) -> Result<(), Self::Error>;
}