typst/src/geom/transform.rs
2022-06-14 13:53:02 +02:00

78 lines
1.9 KiB
Rust

use super::*;
/// A scale-skew-translate transformation.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Transform {
pub sx: Ratio,
pub ky: Ratio,
pub kx: Ratio,
pub sy: Ratio,
pub tx: Length,
pub ty: Length,
}
impl Transform {
/// The identity transformation.
pub const fn identity() -> Self {
Self {
sx: Ratio::one(),
ky: Ratio::zero(),
kx: Ratio::zero(),
sy: Ratio::one(),
tx: Length::zero(),
ty: Length::zero(),
}
}
/// A translate transform.
pub const fn translate(tx: Length, ty: Length) -> Self {
Self { tx, ty, ..Self::identity() }
}
/// A scale transform.
pub const fn scale(sx: Ratio, sy: Ratio) -> Self {
Self { sx, sy, ..Self::identity() }
}
/// A rotate transform.
pub fn rotate(angle: Angle) -> Self {
let cos = Ratio::new(angle.cos());
let sin = Ratio::new(angle.sin());
Self {
sx: cos,
ky: sin,
kx: -sin,
sy: cos,
..Self::default()
}
}
/// Whether this is the identity transformation.
pub fn is_identity(self) -> bool {
self == Self::identity()
}
/// Pre-concatenate another transformation.
pub fn pre_concat(self, prev: Self) -> Self {
Transform {
sx: self.sx * prev.sx + self.kx * prev.ky,
ky: self.ky * prev.sx + self.sy * prev.ky,
kx: self.sx * prev.kx + self.kx * prev.sy,
sy: self.ky * prev.kx + self.sy * prev.sy,
tx: self.sx.of(prev.tx) + self.kx.of(prev.ty) + self.tx,
ty: self.ky.of(prev.tx) + self.sy.of(prev.ty) + self.ty,
}
}
/// Post-concatenate another transformation.
pub fn post_concat(self, next: Self) -> Self {
next.pre_concat(self)
}
}
impl Default for Transform {
fn default() -> Self {
Self::identity()
}
}