mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
74 lines
1.9 KiB
Rust
74 lines
1.9 KiB
Rust
use super::*;
|
|
|
|
/// A scale-skew-translate transformation.
|
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
|
pub struct Transform {
|
|
pub sx: Relative,
|
|
pub ky: Relative,
|
|
pub kx: Relative,
|
|
pub sy: Relative,
|
|
pub tx: Length,
|
|
pub ty: Length,
|
|
}
|
|
|
|
impl Transform {
|
|
/// The identity transformation.
|
|
pub const fn identity() -> Self {
|
|
Self {
|
|
sx: Relative::one(),
|
|
ky: Relative::zero(),
|
|
kx: Relative::zero(),
|
|
sy: Relative::one(),
|
|
tx: Length::zero(),
|
|
ty: Length::zero(),
|
|
}
|
|
}
|
|
|
|
/// A translation transform.
|
|
pub const fn translation(tx: Length, ty: Length) -> Self {
|
|
Self { tx, ty, ..Self::identity() }
|
|
}
|
|
|
|
/// A scaling transform.
|
|
pub const fn scaling(sx: Relative, sy: Relative) -> Self {
|
|
Self { sx, sy, ..Self::identity() }
|
|
}
|
|
|
|
/// A rotation transform.
|
|
pub fn rotation(angle: Angle) -> Self {
|
|
let v = angle.to_rad();
|
|
let cos = Relative::new(v.cos());
|
|
let sin = Relative::new(v.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.resolve(prev.tx) + self.kx.resolve(prev.ty) + self.tx,
|
|
ty: self.ky.resolve(prev.tx) + self.sy.resolve(prev.ty) + self.ty,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for Transform {
|
|
fn default() -> Self {
|
|
Self::identity()
|
|
}
|
|
}
|