use std::ops::Mul;
use core_graphics::{
affine_transform::{CGAffineTransform, CGAffineTransformIdentity},
geometry::CGRect,
};
use crate::{geometry::FRect, matrix::MatrixBackend, Float};
#[derive(Clone, Debug, PartialEq)]
pub struct CoreGraphicsMatrix {
pub transform: CGAffineTransform,
}
impl Mul for CoreGraphicsMatrix {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
Self {
transform: self.transform.concat(&rhs.transform),
}
}
}
impl MatrixBackend for CoreGraphicsMatrix {
fn identity() -> Self {
Self {
transform: CGAffineTransformIdentity,
}
}
fn from_row(scx: Float, sky: Float, skx: Float, scy: Float, tx: Float, ty: Float) -> Self {
Self {
transform: CGAffineTransform {
a: scx,
b: sky,
c: skx,
d: scy,
tx,
ty,
},
}
}
fn from_translate(x: Float, y: Float) -> Self {
Self {
transform: CGAffineTransform::new_translate(x, y),
}
}
fn from_scale(x: Float, y: Float) -> Self {
Self {
transform: CGAffineTransform::new_scale(x, y),
}
}
fn from_rotate(angle: Float) -> Self {
Self {
transform: CGAffineTransform::new_rotate(angle),
}
}
fn pre_rotate(&mut self, angle: Float) {
self.transform = self.transform.concat(&CGAffineTransform::new_rotate(angle));
}
fn pre_translate(&mut self, x: Float, y: Float) {
self.transform = self.transform.concat(&CGAffineTransform::new_translate(x, y));
}
fn pre_scale(&mut self, x: Float, y: Float) {
self.transform = self.transform.concat(&CGAffineTransform::new_scale(x, y));
}
fn post_rotate(&mut self, angle: Float) {
self.transform = self.transform.rotate(angle);
}
fn post_scale(&mut self, x: Float, y: Float) {
self.transform = self.transform.scale(x, y);
}
fn post_translate(&mut self, x: Float, y: Float) {
self.transform = self.transform.translate(x, y);
}
fn map_rect(&self, rect: FRect) -> FRect {
let src_rect: CGRect = rect.into();
src_rect.apply_transform(&self.transform).into()
}
}
impl CoreGraphicsMatrix {
pub(super) fn from_transform(transform: CGAffineTransform) -> Self {
Self {
transform,
}
}
pub(super) fn transform(&self) -> CGAffineTransform {
self.transform
}
}