mirror of
https://github.com/typst/typst
synced 2025-05-13 12:36:23 +08:00
78 lines
1.9 KiB
Rust
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()
|
|
}
|
|
}
|