pango/matrix.rs
1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::fmt;
4
5use glib::translate::*;
6
7use crate::{Matrix, Rectangle, ffi};
8
9impl Matrix {
10 pub fn new(xx: f64, xy: f64, yx: f64, yy: f64, x0: f64, y0: f64) -> Self {
11 unsafe {
12 Self::unsafe_from(ffi::PangoMatrix {
13 xx,
14 xy,
15 yx,
16 yy,
17 x0,
18 y0,
19 })
20 }
21 }
22
23 /// First transforms the @rect using @self, then calculates the bounding box
24 /// of the transformed rectangle.
25 ///
26 /// This function is useful for example when you want to draw a rotated
27 /// @PangoLayout to an image buffer, and want to know how large the image
28 /// should be and how much you should shift the layout when rendering.
29 ///
30 /// For better accuracy, you should use [`transform_rectangle()`][Self::transform_rectangle()]
31 /// on original rectangle in Pango units and convert to pixels afterward
32 /// using [`extents_to_pixels()`][crate::extents_to_pixels()]'s first argument.
33 ///
34 /// # Returns
35 ///
36 ///
37 /// ## `rect`
38 /// in/out bounding box in device units
39 #[doc(alias = "pango_matrix_transform_pixel_rectangle")]
40 pub fn transform_pixel_rectangle(&self, rect: &mut Rectangle) {
41 unsafe {
42 ffi::pango_matrix_transform_pixel_rectangle(
43 self.to_glib_none().0,
44 rect.to_glib_none_mut().0,
45 )
46 }
47 }
48
49 /// First transforms @rect using @self, then calculates the bounding box
50 /// of the transformed rectangle.
51 ///
52 /// This function is useful for example when you want to draw a rotated
53 /// @PangoLayout to an image buffer, and want to know how large the image
54 /// should be and how much you should shift the layout when rendering.
55 ///
56 /// If you have a rectangle in device units (pixels), use
57 /// [`transform_pixel_rectangle()`][Self::transform_pixel_rectangle()].
58 ///
59 /// If you have the rectangle in Pango units and want to convert to
60 /// transformed pixel bounding box, it is more accurate to transform it first
61 /// (using this function) and pass the result to pango_extents_to_pixels(),
62 /// first argument, for an inclusive rounded rectangle.
63 /// However, there are valid reasons that you may want to convert
64 /// to pixels first and then transform, for example when the transformed
65 /// coordinates may overflow in Pango units (large matrix translation for
66 /// example).
67 ///
68 /// # Returns
69 ///
70 ///
71 /// ## `rect`
72 /// in/out bounding box in Pango units
73 #[doc(alias = "pango_matrix_transform_rectangle")]
74 pub fn transform_rectangle(&self, rect: &mut Rectangle) {
75 unsafe {
76 ffi::pango_matrix_transform_rectangle(self.to_glib_none().0, rect.to_glib_none_mut().0)
77 }
78 }
79
80 pub fn xx(&self) -> f64 {
81 self.inner.xx
82 }
83
84 pub fn xy(&self) -> f64 {
85 self.inner.xy
86 }
87
88 pub fn yx(&self) -> f64 {
89 self.inner.yx
90 }
91
92 pub fn yy(&self) -> f64 {
93 self.inner.yy
94 }
95
96 pub fn x0(&self) -> f64 {
97 self.inner.x0
98 }
99
100 pub fn y0(&self) -> f64 {
101 self.inner.y0
102 }
103}
104
105impl fmt::Debug for Matrix {
106 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107 f.debug_struct("Matrix")
108 .field("xx", &self.xx())
109 .field("xy", &self.xy())
110 .field("yx", &self.yx())
111 .field("yy", &self.yy())
112 .field("x0", &self.x0())
113 .field("y0", &self.y0())
114 .finish()
115 }
116}