use super::Contour;
use crate::point::{Handle, Point, PointData, PointType};
pub trait Reverse: Sized + Clone {
fn to_reversed(&self) -> Self;
fn reverse(&mut self) {
let reversed = self.clone().to_reversed();
*self = reversed;
}
}
impl<PD: PointData> Reverse for Contour<PD> {
fn to_reversed(&self) -> Contour<PD> {
let mut new_c = Contour::with_capacity(self.len());
let open_contour = self.first().unwrap().ptype == PointType::Move && self.len() > 1;
let (mut iter_t1, mut iter_t2);
let iter: &mut dyn Iterator<Item = &Point<PD>> = if !open_contour {
iter_t1 = self[0..1].iter().chain(self[1..].iter().rev());
&mut iter_t1
} else {
iter_t2 = self.iter().rev();
&mut iter_t2
};
for p in iter {
let mut new_p = p.clone();
let a = p.a;
let b = p.b;
new_p.a = b;
new_p.b = a;
new_c.push(new_p);
}
let c_len = new_c.len();
if open_contour {
new_c[0].ptype = PointType::Move;
let ptype = if c_len >= 3 {
match (new_c[c_len - 2].a, new_c[c_len - 1].b) {
(Handle::At(..), _) | (_, Handle::At(..)) => PointType::Curve,
(Handle::Colocated, Handle::Colocated) => PointType::Line,
}
} else if c_len == 2 {
match (new_c[0].a, new_c[1].b) {
(Handle::At(..), _) | (_, Handle::At(..)) => PointType::Curve,
(Handle::Colocated, Handle::Colocated) => PointType::Line,
}
} else {
log::error!("You probably should not be trying to reverse single-point contours. 気をつけてくださいね。");
return new_c
};
new_c[c_len - 1].ptype = ptype;
debug_assert!(new_c[0].b == Handle::Colocated);
debug_assert!(new_c[c_len - 1].a == Handle::Colocated);
}
new_c
}
}