mod core; mod lookup; mod manipulators; mod solvers; mod structs; mod transform; use crate::Bezier; pub use core::*; use std::fmt::{Debug, Formatter, Result}; use std::ops::{Index, IndexMut}; pub use structs::*; /// Structure used to represent a path composed of [Bezier] curves. #[derive(Clone, PartialEq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Subpath { manipulator_groups: Vec>, pub closed: bool, } #[cfg(feature = "dyn-any")] unsafe impl dyn_any::StaticType for Subpath { type Static = Subpath; } /// Iteration structure for iterating across each curve of a `Subpath`, using an intermediate `Bezier` representation. pub struct SubpathIter<'a, PointId: crate::Identifier> { index: usize, subpath: &'a Subpath, is_always_closed: bool, } impl Index for Subpath { type Output = ManipulatorGroup; fn index(&self, index: usize) -> &Self::Output { assert!(index < self.len(), "Index out of bounds in trait Index of SubPath."); &self.manipulator_groups[index] } } impl IndexMut for Subpath { fn index_mut(&mut self, index: usize) -> &mut Self::Output { assert!(index < self.len(), "Index out of bounds in trait IndexMut of SubPath."); &mut self.manipulator_groups[index] } } impl Iterator for SubpathIter<'_, PointId> { type Item = Bezier; // Returns the Bezier representation of each `Subpath` segment, defined between a pair of adjacent manipulator points. fn next(&mut self) -> Option { if self.subpath.is_empty() { return None; } let closed = if self.is_always_closed { true } else { self.subpath.closed }; let len = self.subpath.len() - 1 + if closed { 1 } else { 0 }; if self.index >= len { return None; } let start_index = self.index; let end_index = (self.index + 1) % self.subpath.len(); self.index += 1; Some(self.subpath[start_index].to_bezier(&self.subpath[end_index])) } } impl Debug for Subpath { fn fmt(&self, f: &mut Formatter<'_>) -> Result { f.debug_struct("Subpath").field("closed", &self.closed).field("manipulator_groups", &self.manipulator_groups).finish() } }