1#[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 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 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 let total_rectangles = self.num_rectangles();
180 assert!(nth >= 0 && nth < total_rectangles, "nth is out of range");
181 unsafe {
182 let rectangle: RectangleInt = ::std::mem::zeroed();
183 ffi::cairo_region_get_rectangle(self.0.as_ptr(), nth, rectangle.to_raw_none());
184 rectangle
185 }
186 }
187
188 #[doc(alias = "cairo_region_is_empty")]
189 pub fn is_empty(&self) -> bool {
190 unsafe { ffi::cairo_region_is_empty(self.0.as_ptr()).as_bool() }
191 }
192
193 #[doc(alias = "cairo_region_contains_point")]
194 pub fn contains_point(&self, x: i32, y: i32) -> bool {
195 unsafe { ffi::cairo_region_contains_point(self.0.as_ptr(), x, y).as_bool() }
196 }
197
198 #[doc(alias = "cairo_region_contains_rectangle")]
199 pub fn contains_rectangle(&self, rectangle: &RectangleInt) -> RegionOverlap {
200 unsafe {
201 RegionOverlap::from(ffi::cairo_region_contains_rectangle(
202 self.0.as_ptr(),
203 rectangle.to_raw_none(),
204 ))
205 }
206 }
207
208 #[doc(alias = "cairo_region_translate")]
209 pub fn translate(&self, dx: i32, dy: i32) {
210 unsafe { ffi::cairo_region_translate(self.0.as_ptr(), dx, dy) }
211 }
212
213 #[doc(alias = "cairo_region_intersect")]
214 pub fn intersect(&self, other: &Region) -> Result<(), Error> {
215 unsafe {
216 let status = ffi::cairo_region_intersect(self.0.as_ptr(), other.0.as_ptr());
217 status_to_result(status)
218 }
219 }
220
221 #[doc(alias = "cairo_region_intersect_rectangle")]
222 pub fn intersect_rectangle(&self, rectangle: &RectangleInt) -> Result<(), Error> {
223 unsafe {
224 let status =
225 ffi::cairo_region_intersect_rectangle(self.0.as_ptr(), rectangle.to_raw_none());
226 status_to_result(status)
227 }
228 }
229
230 #[doc(alias = "cairo_region_subtract")]
231 pub fn subtract(&self, other: &Region) -> Result<(), Error> {
232 unsafe {
233 let status = ffi::cairo_region_subtract(self.0.as_ptr(), other.0.as_ptr());
234 status_to_result(status)
235 }
236 }
237
238 #[doc(alias = "cairo_region_subtract_rectangle")]
239 pub fn subtract_rectangle(&self, rectangle: &RectangleInt) -> Result<(), Error> {
240 unsafe {
241 let status =
242 ffi::cairo_region_subtract_rectangle(self.0.as_ptr(), rectangle.to_raw_none());
243 status_to_result(status)
244 }
245 }
246
247 #[doc(alias = "cairo_region_union")]
248 pub fn union(&self, other: &Region) -> Result<(), Error> {
249 unsafe {
250 let status = ffi::cairo_region_union(self.0.as_ptr(), other.0.as_ptr());
251 status_to_result(status)
252 }
253 }
254
255 #[doc(alias = "cairo_region_union_rectangle")]
256 pub fn union_rectangle(&self, rectangle: &RectangleInt) -> Result<(), Error> {
257 unsafe {
258 let status =
259 ffi::cairo_region_union_rectangle(self.0.as_ptr(), rectangle.to_raw_none());
260 status_to_result(status)
261 }
262 }
263
264 #[doc(alias = "cairo_region_xor")]
265 pub fn xor(&self, other: &Region) -> Result<(), Error> {
266 unsafe {
267 let status = ffi::cairo_region_xor(self.0.as_ptr(), other.0.as_ptr());
268 status_to_result(status)
269 }
270 }
271
272 #[doc(alias = "cairo_region_xor_rectangle")]
273 pub fn xor_rectangle(&self, rectangle: &RectangleInt) -> Result<(), Error> {
274 unsafe {
275 let status = ffi::cairo_region_xor_rectangle(self.0.as_ptr(), rectangle.to_raw_none());
276 status_to_result(status)
277 }
278 }
279
280 #[doc(alias = "cairo_region_status")]
281 pub fn status(&self) -> Result<(), Error> {
282 let status = unsafe { ffi::cairo_region_status(self.0.as_ptr()) };
283 status_to_result(status)
284 }
285}