gdk/
cairo_interaction.rs

1// Copyright 2013-2015, The Gtk-rs Project Developers.
2// See the COPYRIGHT file at the top-level directory of this distribution.
3// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>
4
5use cairo::Surface;
6use cairo::{Context, Region};
7use gdk_pixbuf::Pixbuf;
8use gdk_sys;
9use glib::object::IsA;
10use glib::translate::*;
11use {Rectangle, Window, RGBA};
12
13pub trait SurfaceExt {
14    fn create_region(&self) -> Option<Region>;
15}
16
17impl SurfaceExt for Surface {
18    fn create_region(&self) -> Option<Region> {
19        unsafe {
20            from_glib_full(gdk_sys::gdk_cairo_region_create_from_surface(
21                self.to_glib_none().0,
22            ))
23        }
24    }
25}
26
27pub trait PixbufExt {
28    fn create_surface(&self, scale: i32, for_window: &Window) -> Option<Surface>;
29}
30
31impl PixbufExt for Pixbuf {
32    fn create_surface(&self, scale: i32, for_window: &Window) -> Option<Surface> {
33        unsafe {
34            from_glib_full(gdk_sys::gdk_cairo_surface_create_from_pixbuf(
35                self.to_glib_none().0,
36                scale,
37                for_window.to_glib_none().0,
38            ))
39        }
40    }
41}
42
43pub trait ContextExt {
44    fn create_from_window(window: &Window) -> Context;
45
46    #[cfg(any(feature = "v3_16", feature = "dox"))]
47    fn cairo_draw_from_gl(
48        cr: &Context,
49        window: &Window,
50        source: i32,
51        source_type: i32,
52        buffer_scale: i32,
53        x: i32,
54        y: i32,
55        width: i32,
56        height: i32,
57    );
58
59    fn cairo_surface_create_from_pixbuf<T: IsA<Window>>(
60        pixbuf: &Pixbuf,
61        scale: i32,
62        for_window: Option<&T>,
63    ) -> Option<Surface>;
64
65    fn get_clip_rectangle(&self) -> Option<Rectangle>;
66
67    fn set_source_rgba(&self, rgba: &RGBA);
68
69    fn set_source_pixbuf(&self, pixbuf: &Pixbuf, x: f64, y: f64);
70
71    fn set_source_window(&self, window: &Window, x: f64, y: f64);
72
73    fn rectangle(&self, rectangle: &Rectangle);
74
75    fn add_region(&self, region: &Region);
76}
77
78impl ContextExt for Context {
79    fn create_from_window(window: &Window) -> Context {
80        skip_assert_initialized!();
81        unsafe { from_glib_full(gdk_sys::gdk_cairo_create(window.to_glib_none().0)) }
82    }
83
84    #[cfg(any(feature = "v3_16", feature = "dox"))]
85    fn cairo_draw_from_gl(
86        cr: &Context,
87        window: &Window,
88        source: i32,
89        source_type: i32,
90        buffer_scale: i32,
91        x: i32,
92        y: i32,
93        width: i32,
94        height: i32,
95    ) {
96        skip_assert_initialized!();
97        unsafe {
98            gdk_sys::gdk_cairo_draw_from_gl(
99                mut_override(cr.to_glib_none().0),
100                window.to_glib_none().0,
101                source,
102                source_type,
103                buffer_scale,
104                x,
105                y,
106                width,
107                height,
108            );
109        }
110    }
111
112    fn cairo_surface_create_from_pixbuf<T: IsA<Window>>(
113        pixbuf: &Pixbuf,
114        scale: i32,
115        for_window: Option<&T>,
116    ) -> Option<Surface> {
117        assert_initialized_main_thread!();
118        let for_window = for_window.map(|f| f.as_ref());
119        let for_window = for_window.to_glib_none();
120        unsafe {
121            from_glib_full(gdk_sys::gdk_cairo_surface_create_from_pixbuf(
122                pixbuf.to_glib_none().0,
123                scale,
124                for_window.0,
125            ))
126        }
127    }
128
129    fn get_clip_rectangle(&self) -> Option<Rectangle> {
130        unsafe {
131            let mut rectangle = Rectangle::uninitialized();
132            if from_glib(gdk_sys::gdk_cairo_get_clip_rectangle(
133                self.to_glib_none().0,
134                rectangle.to_glib_none_mut().0,
135            )) {
136                Some(rectangle)
137            } else {
138                None
139            }
140        }
141    }
142
143    fn set_source_rgba(&self, rgba: &RGBA) {
144        unsafe {
145            gdk_sys::gdk_cairo_set_source_rgba(self.to_glib_none().0, rgba.to_glib_none().0);
146        }
147    }
148
149    fn set_source_pixbuf(&self, pixbuf: &Pixbuf, x: f64, y: f64) {
150        unsafe {
151            gdk_sys::gdk_cairo_set_source_pixbuf(
152                self.to_glib_none().0,
153                pixbuf.to_glib_none().0,
154                x,
155                y,
156            );
157        }
158    }
159
160    fn set_source_window(&self, window: &Window, x: f64, y: f64) {
161        unsafe {
162            gdk_sys::gdk_cairo_set_source_window(
163                self.to_glib_none().0,
164                window.to_glib_none().0,
165                x,
166                y,
167            );
168        }
169    }
170
171    fn rectangle(&self, rectangle: &Rectangle) {
172        unsafe {
173            gdk_sys::gdk_cairo_rectangle(self.to_glib_none().0, rectangle.to_glib_none().0);
174        }
175    }
176
177    fn add_region(&self, region: &Region) {
178        unsafe {
179            gdk_sys::gdk_cairo_region(self.to_glib_none().0, region.to_glib_none().0);
180        }
181    }
182}