1use 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}