skrifa/color/
transform.rs1use super::instance::ResolvedPaint;
4#[cfg(feature = "libm")]
5#[allow(unused_imports)]
6use core_maths::*;
7use read_fonts::{types::Matrix, ReadError};
8
9pub type Transform = Matrix<f32>;
11
12impl TryFrom<&ResolvedPaint<'_>> for Transform {
13 type Error = ReadError;
14
15 fn try_from(paint: &ResolvedPaint<'_>) -> Result<Self, Self::Error> {
16 match paint {
17 ResolvedPaint::Rotate {
18 angle,
19 around_center,
20 ..
21 } => {
22 let sin_v = (angle * 180.0).to_radians().sin();
23 let cos_v = (angle * 180.0).to_radians().cos();
24 let mut out_transform = Transform {
25 xx: cos_v,
26 xy: -sin_v,
27 yx: sin_v,
28 yy: cos_v,
29 ..Default::default()
30 };
31
32 fn scalar_dot_product(a: f32, b: f32, c: f32, d: f32) -> f32 {
33 a * b + c * d
34 }
35
36 if let Some(center) = around_center {
37 out_transform.dx = scalar_dot_product(sin_v, center.y, 1.0 - cos_v, center.x);
38 out_transform.dy = scalar_dot_product(-sin_v, center.x, 1.0 - cos_v, center.y);
39 }
40 Ok(out_transform)
41 }
42 ResolvedPaint::Scale {
43 scale_x,
44 scale_y,
45 around_center,
46 paint: _,
47 } => {
48 let mut out_transform = Transform {
49 xx: *scale_x,
50 yy: *scale_y,
51 ..Transform::default()
52 };
53
54 if let Some(center) = around_center {
55 out_transform.dx = center.x - scale_x * center.x;
56 out_transform.dy = center.y - scale_y * center.y;
57 }
58 Ok(out_transform)
59 }
60 ResolvedPaint::Skew {
61 x_skew_angle,
62 y_skew_angle,
63 around_center,
64 paint: _,
65 } => {
66 let tan_x = (x_skew_angle * 180.0).to_radians().tan();
67 let tan_y = (y_skew_angle * 180.0).to_radians().tan();
68 let mut out_transform = Transform {
69 xy: -tan_x,
70 yx: tan_y,
71 ..Transform::default()
72 };
73
74 if let Some(center) = around_center {
75 out_transform.dx = tan_x * center.y;
76 out_transform.dy = -tan_y * center.x;
77 }
78 Ok(out_transform)
79 }
80 ResolvedPaint::Transform {
81 xx,
82 yx,
83 xy,
84 yy,
85 dx,
86 dy,
87 paint: _,
88 } => Ok(Transform {
89 xx: *xx,
90 yx: *yx,
91 xy: *xy,
92 yy: *yy,
93 dx: *dx,
94 dy: *dy,
95 }),
96 ResolvedPaint::Translate { dx, dy, .. } => Ok(Transform {
97 dx: *dx,
98 dy: *dy,
99 ..Default::default()
100 }),
101 _ => Err(ReadError::MalformedData(
102 "ResolvedPaint cannot be converted into a transform.",
103 )),
104 }
105 }
106}