1#[cfg(feature = "use_glib")]
4use std::marker::PhantomData;
5use std::ptr;
6
7#[cfg(feature = "use_glib")]
8use glib::translate::*;
9
10use crate::{Error, RectangleInt, RegionOverlap, ffi, utils::status_to_result};
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 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 #[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 unsafe { 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 unsafe { 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 unsafe { 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 unsafe {
118 debug_assert!(!ptr.is_null());
119 ffi::cairo_region_reference(ptr);
120 Region(ptr::NonNull::new_unchecked(ptr))
121 }
122 }
123
124 #[inline]
125 pub unsafe fn from_raw_borrow(ptr: *mut ffi::cairo_region_t) -> crate::Borrowed<Region> {
126 unsafe {
127 debug_assert!(!ptr.is_null());
128 crate::Borrowed::new(Region(ptr::NonNull::new_unchecked(ptr)))
129 }
130 }
131
132 #[inline]
133 pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_region_t) -> Region {
134 unsafe {
135 debug_assert!(!ptr.is_null());
136 Region(ptr::NonNull::new_unchecked(ptr))
137 }
138 }
139
140 #[inline]
141 pub fn to_raw_none(&self) -> *mut ffi::cairo_region_t {
142 self.0.as_ptr()
143 }
144
145 #[doc(alias = "cairo_region_create")]
146 pub fn create() -> Region {
147 unsafe { Self::from_raw_full(ffi::cairo_region_create()) }
148 }
149
150 #[doc(alias = "cairo_region_create_rectangle")]
151 pub fn create_rectangle(rectangle: &RectangleInt) -> Region {
152 unsafe { Self::from_raw_full(ffi::cairo_region_create_rectangle(rectangle.to_raw_none())) }
153 }
154
155 #[doc(alias = "cairo_region_create_rectangles")]
156 pub fn create_rectangles(rectangles: &[RectangleInt]) -> Region {
157 unsafe {
158 Self::from_raw_full(ffi::cairo_region_create_rectangles(
159 rectangles.as_ptr() as *mut ffi::cairo_rectangle_int_t,
160 rectangles.len() as i32,
161 ))
162 }
163 }
164
165 #[doc(alias = "cairo_region_copy")]
166 #[must_use]
167 pub fn copy(&self) -> Region {
168 unsafe { Self::from_raw_full(ffi::cairo_region_copy(self.0.as_ptr())) }
169 }
170
171 #[doc(alias = "get_extents")]
172 #[doc(alias = "cairo_region_get_extents")]
173 pub fn extents(&self, rectangle: &RectangleInt) {
174 unsafe { ffi::cairo_region_get_extents(self.0.as_ptr(), rectangle.to_raw_none()) }
175 }
176
177 #[doc(alias = "cairo_region_num_rectangles")]
178 pub fn num_rectangles(&self) -> i32 {
179 unsafe { ffi::cairo_region_num_rectangles(self.0.as_ptr()) }
180 }
181
182 #[doc(alias = "get_rectangle")]
183 #[doc(alias = "cairo_region_get_rectangle")]
184 pub fn rectangle(&self, nth: i32) -> RectangleInt {
185 let total_rectangles = self.num_rectangles();
186 assert!(nth >= 0 && nth < total_rectangles, "nth is out of range");
187 unsafe {
188 let rectangle: RectangleInt = ::std::mem::zeroed();
189 ffi::cairo_region_get_rectangle(self.0.as_ptr(), nth, rectangle.to_raw_none());
190 rectangle
191 }
192 }
193
194 #[doc(alias = "cairo_region_is_empty")]
195 pub fn is_empty(&self) -> bool {
196 unsafe { ffi::cairo_region_is_empty(self.0.as_ptr()).as_bool() }
197 }
198
199 #[doc(alias = "cairo_region_contains_point")]
200 pub fn contains_point(&self, x: i32, y: i32) -> bool {
201 unsafe { ffi::cairo_region_contains_point(self.0.as_ptr(), x, y).as_bool() }
202 }
203
204 #[doc(alias = "cairo_region_contains_rectangle")]
205 pub fn contains_rectangle(&self, rectangle: &RectangleInt) -> RegionOverlap {
206 unsafe {
207 RegionOverlap::from(ffi::cairo_region_contains_rectangle(
208 self.0.as_ptr(),
209 rectangle.to_raw_none(),
210 ))
211 }
212 }
213
214 #[doc(alias = "cairo_region_translate")]
215 pub fn translate(&self, dx: i32, dy: i32) {
216 unsafe { ffi::cairo_region_translate(self.0.as_ptr(), dx, dy) }
217 }
218
219 #[doc(alias = "cairo_region_intersect")]
220 pub fn intersect(&self, other: &Region) -> Result<(), Error> {
221 unsafe {
222 let status = ffi::cairo_region_intersect(self.0.as_ptr(), other.0.as_ptr());
223 status_to_result(status)
224 }
225 }
226
227 #[doc(alias = "cairo_region_intersect_rectangle")]
228 pub fn intersect_rectangle(&self, rectangle: &RectangleInt) -> Result<(), Error> {
229 unsafe {
230 let status =
231 ffi::cairo_region_intersect_rectangle(self.0.as_ptr(), rectangle.to_raw_none());
232 status_to_result(status)
233 }
234 }
235
236 #[doc(alias = "cairo_region_subtract")]
237 pub fn subtract(&self, other: &Region) -> Result<(), Error> {
238 unsafe {
239 let status = ffi::cairo_region_subtract(self.0.as_ptr(), other.0.as_ptr());
240 status_to_result(status)
241 }
242 }
243
244 #[doc(alias = "cairo_region_subtract_rectangle")]
245 pub fn subtract_rectangle(&self, rectangle: &RectangleInt) -> Result<(), Error> {
246 unsafe {
247 let status =
248 ffi::cairo_region_subtract_rectangle(self.0.as_ptr(), rectangle.to_raw_none());
249 status_to_result(status)
250 }
251 }
252
253 #[doc(alias = "cairo_region_union")]
254 pub fn union(&self, other: &Region) -> Result<(), Error> {
255 unsafe {
256 let status = ffi::cairo_region_union(self.0.as_ptr(), other.0.as_ptr());
257 status_to_result(status)
258 }
259 }
260
261 #[doc(alias = "cairo_region_union_rectangle")]
262 pub fn union_rectangle(&self, rectangle: &RectangleInt) -> Result<(), Error> {
263 unsafe {
264 let status =
265 ffi::cairo_region_union_rectangle(self.0.as_ptr(), rectangle.to_raw_none());
266 status_to_result(status)
267 }
268 }
269
270 #[doc(alias = "cairo_region_xor")]
271 pub fn xor(&self, other: &Region) -> Result<(), Error> {
272 unsafe {
273 let status = ffi::cairo_region_xor(self.0.as_ptr(), other.0.as_ptr());
274 status_to_result(status)
275 }
276 }
277
278 #[doc(alias = "cairo_region_xor_rectangle")]
279 pub fn xor_rectangle(&self, rectangle: &RectangleInt) -> Result<(), Error> {
280 unsafe {
281 let status = ffi::cairo_region_xor_rectangle(self.0.as_ptr(), rectangle.to_raw_none());
282 status_to_result(status)
283 }
284 }
285
286 #[doc(alias = "cairo_region_status")]
287 pub fn status(&self) -> Result<(), Error> {
288 let status = unsafe { ffi::cairo_region_status(self.0.as_ptr()) };
289 status_to_result(status)
290 }
291}