diff --git a/partitionfinder/src/legalizer.rs b/partitionfinder/src/legalizer.rs new file mode 100644 index 00000000..ce55e479 --- /dev/null +++ b/partitionfinder/src/legalizer.rs @@ -0,0 +1,92 @@ +// partitionfinder/legalizer.rs + +use euclid::Point2D; +use std::u32; +use {ControlPoints, Endpoint, Subpath}; + +pub struct Legalizer { + endpoints: Vec, + control_points: Vec, + subpaths: Vec, +} + +impl Legalizer { + #[inline] + pub fn new() -> Legalizer { + Legalizer { + endpoints: vec![], + control_points: vec![], + subpaths: vec![], + } + } + + #[inline] + pub fn endpoints(&self) -> &[Endpoint] { + &self.endpoints + } + + #[inline] + pub fn control_points(&self) -> &[ControlPoints] { + &self.control_points + } + + #[inline] + pub fn subpaths(&self) -> &[Subpath] { + &self.subpaths + } + + pub fn move_to(&mut self, position: &Point2D) { + self.subpaths.push(Subpath { + first_endpoint_index: self.endpoints.len() as u32, + last_endpoint_index: self.endpoints.len() as u32 + 1, + }); + self.endpoints.push(Endpoint { + position: *position, + control_points_index: u32::MAX, + subpath_index: (self.subpaths.len() - 1) as u32, + }) + } + + #[inline] + pub fn close_path(&mut self) { + // All paths are implicitly closed. + } + + pub fn line_to(&mut self, endpoint: &Point2D) { + self.subpaths + .last_mut() + .expect("`line_to()` called with no current subpath") + .last_endpoint_index += 1; + self.endpoints.push(Endpoint { + position: *endpoint, + control_points_index: u32::MAX, + subpath_index: (self.subpaths.len() - 1) as u32, + }) + } + + #[inline] + pub fn quadratic_curve_to(&mut self, control_point: &Point2D, endpoint: &Point2D) { + self.bezier_curve_to(control_point, control_point, endpoint) + } + + pub fn bezier_curve_to(&mut self, + point1: &Point2D, + point2: &Point2D, + endpoint: &Point2D) { + // TODO(pcwalton): Make sure curve points are monotonically increasing in X. de Casteljau + // subdivide if not. + self.subpaths + .last_mut() + .expect("`bezier_curve_to()` called with no current subpath") + .last_endpoint_index += 1; + self.control_points.push(ControlPoints { + point1: *point1, + point2: *point2, + }); + self.endpoints.push(Endpoint { + position: *endpoint, + control_points_index: (self.control_points.len() - 1) as u32, + subpath_index: (self.subpaths.len() - 1) as u32, + }) + } +} \ No newline at end of file diff --git a/partitionfinder/src/lib.rs b/partitionfinder/src/lib.rs index de2f2073..3f103f5e 100644 --- a/partitionfinder/src/lib.rs +++ b/partitionfinder/src/lib.rs @@ -16,6 +16,7 @@ use std::u32; pub mod capi; pub mod geometry; +pub mod legalizer; pub mod partitioner; pub mod tessellator;