1use crate::{prelude::*, scalar, Point, Size, Vector};
2use skia_bindings::SkRSXform;
3
4#[derive(Copy, Clone, PartialEq, Debug)]
5#[repr(C)]
6pub struct RSXform {
7 pub scos: scalar,
8 pub ssin: scalar,
9 // don't use Vector here to keep this struct Skia-like.
10 pub tx: scalar,
11 pub ty: scalar,
12}
13
14native_transmutable!(SkRSXform, RSXform, rsxform_layout);
15
16impl RSXform {
17 pub fn new(scos: scalar, ssin: scalar, t: impl Into<Vector>) -> Self {
18 let t = t.into();
19 Self {
20 scos,
21 ssin,
22 tx: t.x,
23 ty: t.y,
24 }
25 }
26
27 pub fn from_radians(
28 scale: scalar,
29 radians: scalar,
30 t: impl Into<Vector>,
31 a: impl Into<Point>,
32 ) -> Self {
33 let t = t.into();
34 let a = a.into();
35
36 let s = radians.sin() * scale;
37 let c = radians.cos() * scale;
38 Self::new(c, s, (t.x + -c * a.x + s * a.y, t.y + -s * a.x - c * a.y))
39 }
40
41 pub fn rect_stays_rect(&self) -> bool {
42 self.scos == 0.0 || self.ssin == 0.0
43 }
44
45 pub fn set_identity(&mut self) {
46 self.set(1.0, 0.0, Vector::default())
47 }
48
49 pub fn set(&mut self, scos: scalar, ssin: scalar, t: impl Into<Vector>) {
50 let t = t.into();
51 self.scos = scos;
52 self.ssin = ssin;
53 self.tx = t.x;
54 self.ty = t.y;
55 }
56
57 pub fn to_quad(self, size: impl Into<Size>) -> [Point; 4] {
58 let size = size.into();
59 let mut quad: [Point; 4] = Default::default();
60 unsafe {
61 self.native()
62 .toQuad(size.width, size.height, quad.native_mut().as_mut_ptr())
63 }
64 quad
65 }
66
67 pub fn to_tri_strip(self, size: impl Into<Size>) -> [Point; 4] {
68 let size = size.into();
69 let mut strip: [Point; 4] = Default::default();
70 unsafe {
71 self.native()
72 .toTriStrip(size.width, size.height, strip.native_mut().as_mut_ptr())
73 }
74 strip
75 }
76}
77