1use glib::translate::*;
4
5use crate::{ffi, Transform};
6
7impl Transform {
8 #[doc(alias = "gsk_transform_parse")]
9 pub fn parse(string: impl IntoGStr) -> Result<Self, glib::BoolError> {
10 assert_initialized_main_thread!();
11 unsafe {
12 string.run_with_gstr(|string| {
13 let mut out_transform = std::ptr::null_mut();
14 let ret = from_glib(ffi::gsk_transform_parse(
15 string.as_ptr(),
16 &mut out_transform,
17 ));
18 if ret {
19 Ok(from_glib_full(out_transform))
20 } else {
21 Err(glib::bool_error!("Can't parse Transform"))
22 }
23 })
24 }
25 }
26
27 #[doc(alias = "gsk_transform_invert")]
28 pub fn invert(self) -> Result<Self, glib::BoolError> {
29 unsafe {
30 let matrix = self.to_matrix();
31 if matrix == graphene::Matrix::new_identity() {
32 return Ok(self);
33 }
34
35 let res: Option<Self> = from_glib_full(ffi::gsk_transform_invert(self.into_glib_ptr()));
36 res.ok_or_else(|| glib::bool_error!("Failed to invert the transform"))
37 }
38 }
39
40 #[doc(alias = "gsk_transform_rotate")]
41 #[must_use]
42 pub fn rotate(self, angle: f32) -> Self {
43 unsafe {
44 let res: Option<Self> =
45 from_glib_full(ffi::gsk_transform_rotate(self.into_glib_ptr(), angle));
46 res.unwrap_or_default()
47 }
48 }
49
50 #[doc(alias = "gsk_transform_rotate_3d")]
51 #[must_use]
52 pub fn rotate_3d(self, angle: f32, axis: &graphene::Vec3) -> Self {
53 unsafe {
54 let res: Option<Self> = from_glib_full(ffi::gsk_transform_rotate_3d(
55 self.into_glib_ptr(),
56 angle,
57 axis.to_glib_none().0,
58 ));
59 res.unwrap_or_default()
60 }
61 }
62
63 #[doc(alias = "gsk_transform_scale")]
64 #[must_use]
65 pub fn scale(self, factor_x: f32, factor_y: f32) -> Self {
66 unsafe {
67 let res: Option<Self> = from_glib_full(ffi::gsk_transform_scale(
68 self.into_glib_ptr(),
69 factor_x,
70 factor_y,
71 ));
72 res.unwrap_or_default()
73 }
74 }
75
76 #[doc(alias = "gsk_transform_scale_3d")]
77 #[must_use]
78 pub fn scale_3d(self, factor_x: f32, factor_y: f32, factor_z: f32) -> Self {
79 unsafe {
80 let res: Option<Self> = from_glib_full(ffi::gsk_transform_scale_3d(
81 self.into_glib_ptr(),
82 factor_x,
83 factor_y,
84 factor_z,
85 ));
86 res.unwrap_or_default()
87 }
88 }
89
90 #[cfg(feature = "v4_6")]
91 #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
92 #[doc(alias = "gsk_transform_skew")]
93 #[must_use]
94 pub fn skew(self, skew_x: f32, skew_y: f32) -> Self {
95 unsafe {
96 let res: Option<Self> = from_glib_full(ffi::gsk_transform_skew(
97 self.into_glib_ptr(),
98 skew_x,
99 skew_y,
100 ));
101 res.unwrap_or_default()
102 }
103 }
104
105 #[doc(alias = "gsk_transform_transform")]
106 #[must_use]
107 pub fn transform(self, other: Option<&Self>) -> Self {
108 unsafe {
109 let res: Option<Self> = from_glib_full(ffi::gsk_transform_transform(
110 self.into_glib_ptr(),
111 other.to_glib_none().0,
112 ));
113 res.unwrap_or_default()
114 }
115 }
116
117 #[doc(alias = "gsk_transform_translate")]
118 #[must_use]
119 pub fn translate(self, point: &graphene::Point) -> Self {
120 unsafe {
121 let res: Option<Self> = from_glib_full(ffi::gsk_transform_translate(
122 self.into_glib_ptr(),
123 point.to_glib_none().0,
124 ));
125 res.unwrap_or_default()
126 }
127 }
128
129 #[doc(alias = "gsk_transform_translate_3d")]
130 #[must_use]
131 pub fn translate_3d(self, point: &graphene::Point3D) -> Self {
132 unsafe {
133 let res: Option<Self> = from_glib_full(ffi::gsk_transform_translate_3d(
134 self.into_glib_ptr(),
135 point.to_glib_none().0,
136 ));
137 res.unwrap_or_default()
138 }
139 }
140
141 #[cfg(feature = "v4_20")]
142 #[cfg_attr(docsrs, doc(cfg(feature = "v4_20")))]
143 #[doc(alias = "gsk_transform_matrix_2d")]
144 #[must_use]
145 pub fn matrix_2d(self, xx: f32, yx: f32, xy: f32, yy: f32, dx: f32, dy: f32) -> Transform {
146 unsafe {
147 let res: Option<Self> = from_glib_full(ffi::gsk_transform_matrix_2d(
148 self.into_glib_ptr(),
149 xx,
150 yx,
151 xy,
152 yy,
153 dx,
154 dy,
155 ));
156 res.unwrap_or_default()
157 }
158 }
159}
160
161impl std::str::FromStr for Transform {
162 type Err = glib::BoolError;
163 fn from_str(s: &str) -> Result<Self, Self::Err> {
164 skip_assert_initialized!();
165 Self::parse(s)
166 }
167}
168
169#[test]
170fn invert_identity_is_identity() {
171 let transform = Transform::new();
172 let output = transform.clone().invert();
173 assert_eq!(output.unwrap(), transform);
174}