1 // Take a look at the license at the top of the repository in the LICENSE file.
2 
3 use crate::enums::RegionOverlap;
4 use crate::error::Error;
5 use crate::utils::status_to_result;
6 use crate::RectangleInt;
7 #[cfg(feature = "use_glib")]
8 use glib::translate::*;
9 use std::fmt;
10 use std::ptr;
11 
12 use crate::ffi::cairo_region_t;
13 
14 #[derive(Debug)]
15 pub struct Region(ptr::NonNull<cairo_region_t>);
16 
17 #[cfg(feature = "use_glib")]
18 #[doc(hidden)]
19 impl<'a> ToGlibPtr<'a, *mut ffi::cairo_region_t> for &'a Region {
20     type Storage = &'a Region;
21 
22     #[inline]
to_glib_none(&self) -> Stash<'a, *mut ffi::cairo_region_t, &'a Region>23     fn to_glib_none(&self) -> Stash<'a, *mut ffi::cairo_region_t, &'a Region> {
24         Stash(self.0.as_ptr(), *self)
25     }
26 
27     #[inline]
to_glib_full(&self) -> *mut ffi::cairo_region_t28     fn to_glib_full(&self) -> *mut ffi::cairo_region_t {
29         unsafe { ffi::cairo_region_reference(self.0.as_ptr()) }
30     }
31 }
32 
33 #[cfg(feature = "use_glib")]
34 #[doc(hidden)]
35 impl<'a> ToGlibPtrMut<'a, *mut ffi::cairo_region_t> for Region {
36     type Storage = &'a mut Self;
37 
38     // FIXME: This is unsafe: regions are reference counted, so we could get multiple mutable
39     // references here
40     #[inline]
to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut ffi::cairo_region_t, Self>41     fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut ffi::cairo_region_t, Self> {
42         StashMut(self.0.as_ptr(), self)
43     }
44 }
45 
46 #[cfg(feature = "use_glib")]
47 #[doc(hidden)]
48 impl FromGlibPtrNone<*mut ffi::cairo_region_t> for Region {
49     #[inline]
from_glib_none(ptr: *mut ffi::cairo_region_t) -> Region50     unsafe fn from_glib_none(ptr: *mut ffi::cairo_region_t) -> Region {
51         Self::from_raw_none(ptr)
52     }
53 }
54 
55 #[cfg(feature = "use_glib")]
56 #[doc(hidden)]
57 impl FromGlibPtrBorrow<*mut ffi::cairo_region_t> for Region {
58     #[inline]
from_glib_borrow(ptr: *mut ffi::cairo_region_t) -> crate::Borrowed<Region>59     unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_region_t) -> crate::Borrowed<Region> {
60         Self::from_raw_borrow(ptr)
61     }
62 }
63 
64 #[cfg(feature = "use_glib")]
65 #[doc(hidden)]
66 impl FromGlibPtrFull<*mut ffi::cairo_region_t> for Region {
67     #[inline]
from_glib_full(ptr: *mut ffi::cairo_region_t) -> Region68     unsafe fn from_glib_full(ptr: *mut ffi::cairo_region_t) -> Region {
69         Self::from_raw_full(ptr)
70     }
71 }
72 
73 #[cfg(feature = "use_glib")]
74 gvalue_impl!(
75     Region,
76     ffi::cairo_region_t,
77     ffi::gobject::cairo_gobject_region_get_type
78 );
79 
80 impl Clone for Region {
clone(&self) -> Region81     fn clone(&self) -> Region {
82         unsafe { Self::from_raw_none(self.to_raw_none()) }
83     }
84 }
85 
86 impl Drop for Region {
drop(&mut self)87     fn drop(&mut self) {
88         unsafe {
89             ffi::cairo_region_destroy(self.0.as_ptr());
90         }
91     }
92 }
93 
94 impl PartialEq for Region {
95     #[doc(alias = "cairo_region_equal")]
eq(&self, other: &Region) -> bool96     fn eq(&self, other: &Region) -> bool {
97         unsafe { ffi::cairo_region_equal(self.0.as_ptr(), other.0.as_ptr()).as_bool() }
98     }
99 }
100 
101 impl Eq for Region {}
102 
103 impl Region {
104     #[inline]
from_raw_none(ptr: *mut ffi::cairo_region_t) -> Region105     pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_region_t) -> Region {
106         assert!(!ptr.is_null());
107         ffi::cairo_region_reference(ptr);
108         Region(ptr::NonNull::new_unchecked(ptr))
109     }
110 
111     #[inline]
from_raw_borrow(ptr: *mut ffi::cairo_region_t) -> crate::Borrowed<Region>112     pub unsafe fn from_raw_borrow(ptr: *mut ffi::cairo_region_t) -> crate::Borrowed<Region> {
113         assert!(!ptr.is_null());
114         crate::Borrowed::new(Region(ptr::NonNull::new_unchecked(ptr)))
115     }
116 
117     #[inline]
from_raw_full(ptr: *mut ffi::cairo_region_t) -> Region118     pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_region_t) -> Region {
119         assert!(!ptr.is_null());
120         Region(ptr::NonNull::new_unchecked(ptr))
121     }
122 
to_raw_none(&self) -> *mut ffi::cairo_region_t123     pub fn to_raw_none(&self) -> *mut ffi::cairo_region_t {
124         self.0.as_ptr()
125     }
126 
127     #[doc(alias = "cairo_region_create")]
create() -> Region128     pub fn create() -> Region {
129         unsafe { Self::from_raw_full(ffi::cairo_region_create()) }
130     }
131 
132     #[doc(alias = "cairo_region_create_rectangle")]
create_rectangle(rectangle: &RectangleInt) -> Region133     pub fn create_rectangle(rectangle: &RectangleInt) -> Region {
134         unsafe { Self::from_raw_full(ffi::cairo_region_create_rectangle(rectangle.to_raw_none())) }
135     }
136 
137     #[doc(alias = "cairo_region_create_rectangles")]
create_rectangles(rectangles: &[RectangleInt]) -> Region138     pub fn create_rectangles(rectangles: &[RectangleInt]) -> Region {
139         unsafe {
140             Self::from_raw_full(ffi::cairo_region_create_rectangles(
141                 rectangles.as_ptr() as *mut ffi::cairo_rectangle_int_t,
142                 rectangles.len() as i32,
143             ))
144         }
145     }
146 
147     #[doc(alias = "cairo_region_copy")]
copy(&self) -> Region148     pub fn copy(&self) -> Region {
149         unsafe { Self::from_raw_full(ffi::cairo_region_copy(self.0.as_ptr())) }
150     }
151 
152     #[doc(alias = "get_extents")]
153     #[doc(alias = "cairo_region_get_extents")]
extents(&self, rectangle: &mut RectangleInt)154     pub fn extents(&self, rectangle: &mut RectangleInt) {
155         unsafe { ffi::cairo_region_get_extents(self.0.as_ptr(), rectangle.to_raw_none()) }
156     }
157 
158     #[doc(alias = "cairo_region_num_rectangles")]
num_rectangles(&self) -> i32159     pub fn num_rectangles(&self) -> i32 {
160         unsafe { ffi::cairo_region_num_rectangles(self.0.as_ptr()) }
161     }
162 
163     #[doc(alias = "get_rectangle")]
164     #[doc(alias = "cairo_region_get_rectangle")]
rectangle(&self, nth: i32) -> RectangleInt165     pub fn rectangle(&self, nth: i32) -> RectangleInt {
166         unsafe {
167             let rectangle: RectangleInt = ::std::mem::zeroed();
168             ffi::cairo_region_get_rectangle(self.0.as_ptr(), nth, rectangle.to_raw_none());
169             rectangle
170         }
171     }
172 
173     #[doc(alias = "cairo_region_is_empty")]
is_empty(&self) -> bool174     pub fn is_empty(&self) -> bool {
175         unsafe { ffi::cairo_region_is_empty(self.0.as_ptr()).as_bool() }
176     }
177 
178     #[doc(alias = "cairo_region_contains_point")]
contains_point(&self, x: i32, y: i32) -> bool179     pub fn contains_point(&self, x: i32, y: i32) -> bool {
180         unsafe { ffi::cairo_region_contains_point(self.0.as_ptr(), x, y).as_bool() }
181     }
182 
183     #[doc(alias = "cairo_region_contains_rectangle")]
contains_rectangle(&self, rectangle: &RectangleInt) -> RegionOverlap184     pub fn contains_rectangle(&self, rectangle: &RectangleInt) -> RegionOverlap {
185         unsafe {
186             RegionOverlap::from(ffi::cairo_region_contains_rectangle(
187                 self.0.as_ptr(),
188                 rectangle.to_raw_none(),
189             ))
190         }
191     }
192 
193     #[doc(alias = "cairo_region_translate")]
translate(&self, dx: i32, dy: i32)194     pub fn translate(&self, dx: i32, dy: i32) {
195         unsafe { ffi::cairo_region_translate(self.0.as_ptr(), dx, dy) }
196     }
197 
198     #[doc(alias = "cairo_region_intersect")]
intersect(&self, other: &Region) -> Result<(), Error>199     pub fn intersect(&self, other: &Region) -> Result<(), Error> {
200         unsafe {
201             let status = ffi::cairo_region_intersect(self.0.as_ptr(), other.0.as_ptr());
202             status_to_result(status)
203         }
204     }
205 
206     #[doc(alias = "cairo_region_intersect_rectangle")]
intersect_rectangle(&self, rectangle: &RectangleInt) -> Result<(), Error>207     pub fn intersect_rectangle(&self, rectangle: &RectangleInt) -> Result<(), Error> {
208         unsafe {
209             let status =
210                 ffi::cairo_region_intersect_rectangle(self.0.as_ptr(), rectangle.to_raw_none());
211             status_to_result(status)
212         }
213     }
214 
215     #[doc(alias = "cairo_region_subtract")]
subtract(&self, other: &Region) -> Result<(), Error>216     pub fn subtract(&self, other: &Region) -> Result<(), Error> {
217         unsafe {
218             let status = ffi::cairo_region_subtract(self.0.as_ptr(), other.0.as_ptr());
219             status_to_result(status)
220         }
221     }
222 
223     #[doc(alias = "cairo_region_subtract_rectangle")]
subtract_rectangle(&self, rectangle: &RectangleInt) -> Result<(), Error>224     pub fn subtract_rectangle(&self, rectangle: &RectangleInt) -> Result<(), Error> {
225         unsafe {
226             let status =
227                 ffi::cairo_region_subtract_rectangle(self.0.as_ptr(), rectangle.to_raw_none());
228             status_to_result(status)
229         }
230     }
231 
232     #[doc(alias = "cairo_region_union")]
union(&self, other: &Region) -> Result<(), Error>233     pub fn union(&self, other: &Region) -> Result<(), Error> {
234         unsafe {
235             let status = ffi::cairo_region_union(self.0.as_ptr(), other.0.as_ptr());
236             status_to_result(status)
237         }
238     }
239 
240     #[doc(alias = "cairo_region_union_rectangle")]
union_rectangle(&self, rectangle: &RectangleInt) -> Result<(), Error>241     pub fn union_rectangle(&self, rectangle: &RectangleInt) -> Result<(), Error> {
242         unsafe {
243             let status =
244                 ffi::cairo_region_union_rectangle(self.0.as_ptr(), rectangle.to_raw_none());
245             status_to_result(status)
246         }
247     }
248 
249     #[doc(alias = "cairo_region_xor")]
xor(&self, other: &Region) -> Result<(), Error>250     pub fn xor(&self, other: &Region) -> Result<(), Error> {
251         unsafe {
252             let status = ffi::cairo_region_xor(self.0.as_ptr(), other.0.as_ptr());
253             status_to_result(status)
254         }
255     }
256 
257     #[doc(alias = "cairo_region_xor_rectangle")]
xor_rectangle(&self, rectangle: &RectangleInt) -> Result<(), Error>258     pub fn xor_rectangle(&self, rectangle: &RectangleInt) -> Result<(), Error> {
259         unsafe {
260             let status = ffi::cairo_region_xor_rectangle(self.0.as_ptr(), rectangle.to_raw_none());
261             status_to_result(status)
262         }
263     }
264 
265     #[doc(alias = "cairo_region_status")]
status(&self) -> Result<(), Error>266     pub fn status(&self) -> Result<(), Error> {
267         let status = unsafe { ffi::cairo_region_status(self.0.as_ptr()) };
268         status_to_result(status)
269     }
270 }
271 
272 impl fmt::Display for Region {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result273     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
274         write!(f, "Region")
275     }
276 }
277