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