use kurbo::Affine;
#[allow(dead_code)]
fn skew_affine(kx: f64, ky: f64) -> Affine {
Affine::new([1.0, ky.tan(), kx.tan(), 1.0, 0.0, 0.0])
}
pub trait Transforms: Sized {
fn transform(&mut self, affine: &Affine) -> &mut Self;
#[inline]
fn translate(&mut self, dx: impl Into<f64>, dy: impl Into<f64>) -> &mut Self {
self.transform(&Affine::translate((dx.into(), dy.into())));
self
}
#[inline]
fn scale(&mut self, s: impl Into<f64>) -> &mut Self {
self.transform(&Affine::scale(s.into()));
self
}
#[inline]
fn scale_non_uniform(&mut self, sx: impl Into<f64>, sy: impl Into<f64>) -> &mut Self {
self.transform(&Affine::scale_non_uniform(sx.into(), sy.into()));
self
}
#[inline]
fn scale_around(
&mut self,
sx: impl Into<f64>,
sy: impl Into<f64>,
cx: impl Into<f64>,
cy: impl Into<f64>,
) -> &mut Self {
let (cx, cy) = (cx.into(), cy.into());
let transform = Affine::translate((cx, cy))
* Affine::scale_non_uniform(sx.into(), sy.into())
* Affine::translate((-cx, -cy));
self.transform(&transform);
self
}
#[inline]
fn rotate(&mut self, theta: impl Into<f64>) -> &mut Self {
self.transform(&Affine::rotate(theta.into()));
self
}
#[inline]
fn rotate_around(
&mut self,
theta: impl Into<f64>,
cx: impl Into<f64>,
cy: impl Into<f64>,
) -> &mut Self {
let (cx, cy) = (cx.into(), cy.into());
let transform = Affine::translate((cx, cy))
* Affine::rotate(theta.into())
* Affine::translate((-cx, -cy));
self.transform(&transform);
self
}
#[inline]
fn skew(&mut self, kx: impl Into<f64>, ky: impl Into<f64>) -> &mut Self {
self.transform(&skew_affine(kx.into(), ky.into()));
self
}
#[inline]
fn skew_around(
&mut self,
kx: impl Into<f64>,
ky: impl Into<f64>,
cx: impl Into<f64>,
cy: impl Into<f64>,
) -> &mut Self {
let (cx, cy) = (cx.into(), cy.into());
let transform = Affine::translate((cx, cy))
* skew_affine(kx.into(), ky.into())
* Affine::translate((-cx, -cy));
self.transform(&transform);
self
}
}