cairo/
region.rs

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