use std::ops::Mul;
use crate::{geometry::FRect, DefaultMatrix, Float};
pub trait MatrixBackend: Clone + Mul<Self, Output = Self> + Sized {
fn identity() -> Self
where
Self: Sized;
fn from_row(scx: Float, sky: Float, skx: Float, scy: Float, tx: Float, ty: Float) -> Self
where
Self: Sized;
fn from_translate(x: Float, y: Float) -> Self
where
Self: Sized;
fn from_scale(x: Float, y: Float) -> Self
where
Self: Sized;
fn from_rotate(angle: Float) -> Self
where
Self: Sized;
fn pre_rotate(&mut self, angle: Float);
fn pre_scale(&mut self, x: Float, y: Float);
fn pre_translate(&mut self, x: Float, y: Float);
fn post_rotate(&mut self, angle: Float);
fn post_scale(&mut self, x: Float, y: Float);
fn post_translate(&mut self, x: Float, y: Float);
fn map_rect(&self, rect: FRect) -> FRect;
}
impl<T: MatrixBackend> Default for Matrix<T> {
fn default() -> Self {
Self::identity()
}
}
pub struct Matrix<T: MatrixBackend> {
pub(crate) backend: T,
}
impl<T: MatrixBackend> Matrix<T> {
pub fn identity() -> Self {
Self {
backend: T::identity(),
}
}
pub fn from_row(scx: Float, sky: Float, skx: Float, scy: Float, tx: Float, ty: Float) -> Self {
Self {
backend: T::from_row(scx, sky, skx, scy, tx, ty),
}
}
pub fn from_translate(x: Float, y: Float) -> Self {
Self {
backend: T::from_translate(x, y),
}
}
pub fn from_scale(x: Float, y: Float) -> Self {
Self {
backend: T::from_scale(x, y),
}
}
pub fn from_rotate(angle: Float) -> Self {
Self {
backend: T::from_rotate(angle),
}
}
pub fn pre_rotate(&mut self, angle: Float) {
self.backend.pre_rotate(angle)
}
pub fn pre_scale(&mut self, x: Float, y: Float) {
self.backend.pre_scale(x, y)
}
pub fn pre_translate(&mut self, x: Float, y: Float) {
self.backend.pre_translate(x, y)
}
pub fn post_rotate(&mut self, angle: Float) {
self.backend.post_rotate(angle)
}
pub fn post_scale(&mut self, x: Float, y: Float) {
self.backend.post_scale(x, y)
}
pub fn post_translate(&mut self, x: Float, y: Float) {
self.backend.post_translate(x, y)
}
pub fn map_rect(&self, rect: FRect) -> FRect {
self.backend.map_rect(rect)
}
}
impl Matrix<DefaultMatrix> {
pub fn default_identity() -> Self {
Self::identity()
}
pub fn default_from_row(scx: Float, sky: Float, skx: Float, scy: Float, tx: Float, ty: Float) -> Self {
Self::from_row(scx, sky, skx, scy, tx, ty)
}
pub fn default_from_translate(x: Float, y: Float) -> Self {
Self::from_translate(x, y)
}
pub fn default_from_scale(x: Float, y: Float) -> Self {
Self::from_scale(x, y)
}
pub fn default_from_rotate(angle: Float) -> Self {
Self::from_rotate(angle)
}
}