Skip to main content

gdk/
cairo_interaction.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use crate::{Rectangle, Window, RGBA};
4use cairo::Surface;
5use cairo::{Context, Region};
6use gdk_pixbuf::Pixbuf;
7use glib::object::IsA;
8use glib::translate::*;
9
10pub trait GdkSurfaceExt {
11    #[doc(alias = "gdk_cairo_region_create_from_surface")]
12    fn create_region(&self) -> Option<Region>;
13}
14
15impl GdkSurfaceExt for Surface {
16    fn create_region(&self) -> Option<Region> {
17        unsafe {
18            from_glib_full(ffi::gdk_cairo_region_create_from_surface(
19                self.to_glib_none().0,
20            ))
21        }
22    }
23}
24
25pub trait GdkPixbufExt {
26    #[doc(alias = "gdk_cairo_surface_create_from_pixbuf")]
27    fn create_surface<W: IsA<Window>>(&self, scale: i32, for_window: Option<&W>)
28        -> Option<Surface>;
29}
30
31impl GdkPixbufExt for Pixbuf {
32    fn create_surface<W: IsA<Window>>(
33        &self,
34        scale: i32,
35        for_window: Option<&W>,
36    ) -> Option<Surface> {
37        unsafe {
38            from_glib_full(ffi::gdk_cairo_surface_create_from_pixbuf(
39                self.to_glib_none().0,
40                scale,
41                for_window.map(std::convert::AsRef::as_ref).to_glib_none().0,
42            ))
43        }
44    }
45}
46
47pub trait GdkContextExt {
48    fn create_from_window<W: IsA<Window>>(window: &W) -> Context;
49
50    #[allow(clippy::too_many_arguments)]
51    unsafe fn draw_from_gl<W: IsA<Window>>(
52        &self,
53        window: &W,
54        source: i32,
55        source_type: i32,
56        buffer_scale: i32,
57        x: i32,
58        y: i32,
59        width: i32,
60        height: i32,
61    );
62
63    #[doc(alias = "get_clip_rectangle")]
64    #[doc(alias = "gdk_cairo_get_clip_rectangle")]
65    fn clip_rectangle(&self) -> Option<Rectangle>;
66
67    #[doc(alias = "gdk_cairo_set_source_rgba")]
68    fn set_source_rgba(&self, rgba: &RGBA);
69
70    #[doc(alias = "gdk_cairo_set_source_pixbuf")]
71    fn set_source_pixbuf(&self, pixbuf: &Pixbuf, x: f64, y: f64);
72
73    #[doc(alias = "gdk_cairo_set_source_window")]
74    fn set_source_window<W: IsA<Window>>(&self, window: &W, x: f64, y: f64);
75
76    #[doc(alias = "gdk_cairo_rectangle")]
77    fn rectangle(&self, rectangle: &Rectangle);
78
79    fn add_region(&self, region: &Region);
80}
81
82impl GdkContextExt for Context {
83    fn create_from_window<W: IsA<Window>>(window: &W) -> Context {
84        skip_assert_initialized!();
85        unsafe { from_glib_full(ffi::gdk_cairo_create(window.as_ref().to_glib_none().0)) }
86    }
87
88    unsafe fn draw_from_gl<W: IsA<Window>>(
89        &self,
90        window: &W,
91        source: i32,
92        source_type: i32,
93        buffer_scale: i32,
94        x: i32,
95        y: i32,
96        width: i32,
97        height: i32,
98    ) {
99        skip_assert_initialized!();
100        ffi::gdk_cairo_draw_from_gl(
101            mut_override(self.to_glib_none().0),
102            window.as_ref().to_glib_none().0,
103            source,
104            source_type,
105            buffer_scale,
106            x,
107            y,
108            width,
109            height,
110        );
111    }
112
113    fn clip_rectangle(&self) -> Option<Rectangle> {
114        unsafe {
115            let mut rectangle = Rectangle::uninitialized();
116            if from_glib(ffi::gdk_cairo_get_clip_rectangle(
117                self.to_glib_none().0,
118                rectangle.to_glib_none_mut().0,
119            )) {
120                Some(rectangle)
121            } else {
122                None
123            }
124        }
125    }
126
127    fn set_source_rgba(&self, rgba: &RGBA) {
128        unsafe {
129            ffi::gdk_cairo_set_source_rgba(self.to_glib_none().0, rgba.to_glib_none().0);
130        }
131    }
132
133    fn set_source_pixbuf(&self, pixbuf: &Pixbuf, x: f64, y: f64) {
134        unsafe {
135            ffi::gdk_cairo_set_source_pixbuf(self.to_glib_none().0, pixbuf.to_glib_none().0, x, y);
136        }
137    }
138
139    fn set_source_window<W: IsA<Window>>(&self, window: &W, x: f64, y: f64) {
140        unsafe {
141            ffi::gdk_cairo_set_source_window(
142                self.to_glib_none().0,
143                window.as_ref().to_glib_none().0,
144                x,
145                y,
146            );
147        }
148    }
149
150    fn rectangle(&self, rectangle: &Rectangle) {
151        unsafe {
152            ffi::gdk_cairo_rectangle(self.to_glib_none().0, rectangle.to_glib_none().0);
153        }
154    }
155
156    fn add_region(&self, region: &Region) {
157        unsafe {
158            ffi::gdk_cairo_region(self.to_glib_none().0, region.to_glib_none().0);
159        }
160    }
161}