gsk4/
transform.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use 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}