Skip to main content

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}