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