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::{ffi, Matrix, Rectangle};
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    /// ## `rect`
34    /// in/out bounding box in device units
35    #[doc(alias = "pango_matrix_transform_pixel_rectangle")]
36    pub fn transform_pixel_rectangle(&self, rect: &mut Rectangle) {
37        unsafe {
38            ffi::pango_matrix_transform_pixel_rectangle(
39                self.to_glib_none().0,
40                rect.to_glib_none_mut().0,
41            )
42        }
43    }
44
45    /// First transforms @rect using @self, then calculates the bounding box
46    /// of the transformed rectangle.
47    ///
48    /// This function is useful for example when you want to draw a rotated
49    /// @PangoLayout to an image buffer, and want to know how large the image
50    /// should be and how much you should shift the layout when rendering.
51    ///
52    /// If you have a rectangle in device units (pixels), use
53    /// [`transform_pixel_rectangle()`][Self::transform_pixel_rectangle()].
54    ///
55    /// If you have the rectangle in Pango units and want to convert to
56    /// transformed pixel bounding box, it is more accurate to transform it first
57    /// (using this function) and pass the result to pango_extents_to_pixels(),
58    /// first argument, for an inclusive rounded rectangle.
59    /// However, there are valid reasons that you may want to convert
60    /// to pixels first and then transform, for example when the transformed
61    /// coordinates may overflow in Pango units (large matrix translation for
62    /// example).
63    /// ## `rect`
64    /// in/out bounding box in Pango units
65    #[doc(alias = "pango_matrix_transform_rectangle")]
66    pub fn transform_rectangle(&self, rect: &mut Rectangle) {
67        unsafe {
68            ffi::pango_matrix_transform_rectangle(self.to_glib_none().0, rect.to_glib_none_mut().0)
69        }
70    }
71
72    pub fn xx(&self) -> f64 {
73        self.inner.xx
74    }
75
76    pub fn xy(&self) -> f64 {
77        self.inner.xy
78    }
79
80    pub fn yx(&self) -> f64 {
81        self.inner.yx
82    }
83
84    pub fn yy(&self) -> f64 {
85        self.inner.yy
86    }
87
88    pub fn x0(&self) -> f64 {
89        self.inner.x0
90    }
91
92    pub fn y0(&self) -> f64 {
93        self.inner.y0
94    }
95}
96
97impl fmt::Debug for Matrix {
98    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99        f.debug_struct("Matrix")
100            .field("xx", &self.xx())
101            .field("xy", &self.xy())
102            .field("yx", &self.yx())
103            .field("yy", &self.yy())
104            .field("x0", &self.x0())
105            .field("y0", &self.y0())
106            .finish()
107    }
108}