1use crate::{RGBA, Rectangle, Window, ffi};
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 unsafe {
100 skip_assert_initialized!();
101 ffi::gdk_cairo_draw_from_gl(
102 mut_override(self.to_glib_none().0),
103 window.as_ref().to_glib_none().0,
104 source,
105 source_type,
106 buffer_scale,
107 x,
108 y,
109 width,
110 height,
111 );
112 }
113 }
114
115 fn clip_rectangle(&self) -> Option<Rectangle> {
116 unsafe {
117 let mut rectangle = Rectangle::uninitialized();
118 if from_glib(ffi::gdk_cairo_get_clip_rectangle(
119 self.to_glib_none().0,
120 rectangle.to_glib_none_mut().0,
121 )) {
122 Some(rectangle)
123 } else {
124 None
125 }
126 }
127 }
128
129 fn set_source_rgba(&self, rgba: &RGBA) {
130 unsafe {
131 ffi::gdk_cairo_set_source_rgba(self.to_glib_none().0, rgba.to_glib_none().0);
132 }
133 }
134
135 fn set_source_pixbuf(&self, pixbuf: &Pixbuf, x: f64, y: f64) {
136 unsafe {
137 ffi::gdk_cairo_set_source_pixbuf(self.to_glib_none().0, pixbuf.to_glib_none().0, x, y);
138 }
139 }
140
141 fn set_source_window<W: IsA<Window>>(&self, window: &W, x: f64, y: f64) {
142 unsafe {
143 ffi::gdk_cairo_set_source_window(
144 self.to_glib_none().0,
145 window.as_ref().to_glib_none().0,
146 x,
147 y,
148 );
149 }
150 }
151
152 fn rectangle(&self, rectangle: &Rectangle) {
153 unsafe {
154 ffi::gdk_cairo_rectangle(self.to_glib_none().0, rectangle.to_glib_none().0);
155 }
156 }
157
158 fn add_region(&self, region: &Region) {
159 unsafe {
160 ffi::gdk_cairo_region(self.to_glib_none().0, region.to_glib_none().0);
161 }
162 }
163}