pub mod custom;
pub mod guides;
pub mod presets;
use crate::model::dimension::{Dimension, SixtieThousandthDeg};
use crate::model::ShapeGeometry;
use crate::render::dimension::Pt;
use crate::render::geometry::{PtOffset, PtRect, PtSize};
#[derive(Clone, Debug)]
pub struct ShapePath {
pub paths: Vec<SubPath>,
pub text_rect: Option<PtRect>,
}
#[derive(Clone, Debug)]
pub struct SubPath {
pub verbs: Vec<PathVerb>,
pub fill_mode: crate::model::PathFillMode,
pub stroked: bool,
}
#[derive(Clone, Debug)]
pub enum PathVerb {
MoveTo(PtOffset),
LineTo(PtOffset),
QuadTo(PtOffset, PtOffset),
CubicTo(PtOffset, PtOffset, PtOffset),
ArcTo {
radii: PtSize,
start_angle: Dimension<SixtieThousandthDeg>,
swing_angle: Dimension<SixtieThousandthDeg>,
},
Close,
}
pub fn build_geometry(geometry: &ShapeGeometry, extent: PtSize) -> Option<ShapePath> {
if extent.width <= Pt::ZERO && extent.height <= Pt::ZERO {
return None;
}
match geometry {
ShapeGeometry::Preset(def) => presets::build_preset(def, extent),
ShapeGeometry::Custom(def) => custom::build_custom(def, extent),
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::model::{PresetGeometryDef, PresetShapeType, ShapeGeometry};
fn preset(preset: PresetShapeType) -> ShapeGeometry {
ShapeGeometry::Preset(PresetGeometryDef {
preset,
adjust_values: vec![],
})
}
#[test]
fn zero_extent_returns_none() {
let g = preset(PresetShapeType::Rect);
assert!(build_geometry(&g, PtSize::new(Pt::ZERO, Pt::ZERO)).is_none());
}
#[test]
fn single_zero_dimension_still_builds() {
let g = preset(PresetShapeType::Line);
assert!(build_geometry(&g, PtSize::new(Pt::ZERO, Pt::new(40.0))).is_some());
assert!(build_geometry(&g, PtSize::new(Pt::new(40.0), Pt::ZERO)).is_some());
}
#[test]
fn preset_dispatch_builds_supported_shapes() {
let extent = PtSize::new(Pt::new(30.0), Pt::new(20.0));
assert!(build_geometry(&preset(PresetShapeType::Rect), extent).is_some());
assert!(build_geometry(&preset(PresetShapeType::Line), extent).is_some());
}
#[test]
fn unimplemented_preset_returns_none() {
let extent = PtSize::new(Pt::new(30.0), Pt::new(20.0));
assert!(build_geometry(&preset(PresetShapeType::Star12), extent).is_none());
}
}