cairo/
region.rs

1// Copyright 2013-2017, The Gtk-rs Project Developers.
2// See the COPYRIGHT file at the top-level directory of this distribution.
3// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>
4
5use enums::{RegionOverlap, Status};
6use ffi;
7#[cfg(feature = "use_glib")]
8use glib::translate::*;
9use std::fmt;
10use RectangleInt;
11
12use ffi::cairo_region_t;
13
14#[derive(Debug)]
15pub struct Region(*mut cairo_region_t, bool);
16
17#[cfg(feature = "use_glib")]
18#[doc(hidden)]
19impl<'a> ToGlibPtr<'a, *mut ffi::cairo_region_t> for &'a Region {
20    type Storage = &'a Region;
21
22    #[inline]
23    fn to_glib_none(&self) -> Stash<'a, *mut ffi::cairo_region_t, &'a Region> {
24        Stash(self.0, *self)
25    }
26
27    #[inline]
28    fn to_glib_full(&self) -> *mut ffi::cairo_region_t {
29        unsafe { ffi::cairo_region_reference(self.0) }
30    }
31}
32
33#[cfg(feature = "use_glib")]
34#[doc(hidden)]
35impl<'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]
41    fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut ffi::cairo_region_t, Self> {
42        StashMut(self.0, self)
43    }
44}
45
46#[cfg(feature = "use_glib")]
47#[doc(hidden)]
48impl FromGlibPtrNone<*mut ffi::cairo_region_t> for Region {
49    #[inline]
50    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)]
57impl FromGlibPtrBorrow<*mut ffi::cairo_region_t> for Region {
58    #[inline]
59    unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_region_t) -> Region {
60        Self::from_raw_borrow(ptr)
61    }
62}
63
64#[cfg(feature = "use_glib")]
65#[doc(hidden)]
66impl FromGlibPtrFull<*mut ffi::cairo_region_t> for Region {
67    #[inline]
68    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")]
74gvalue_impl!(
75    Region,
76    ffi::cairo_region_t,
77    ffi::gobject::cairo_gobject_region_get_type
78);
79
80impl Clone for Region {
81    fn clone(&self) -> Region {
82        unsafe { Self::from_raw_none(self.to_raw_none()) }
83    }
84}
85
86impl Drop for Region {
87    fn drop(&mut self) {
88        if !self.1 {
89            unsafe {
90                ffi::cairo_region_destroy(self.0);
91            }
92        }
93    }
94}
95
96impl PartialEq for Region {
97    fn eq(&self, other: &Region) -> bool {
98        unsafe { ffi::cairo_region_equal(self.0, other.0).as_bool() }
99    }
100}
101
102impl Eq for Region {}
103
104impl Region {
105    #[inline]
106    pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_region_t) -> Region {
107        assert!(!ptr.is_null());
108        ffi::cairo_region_reference(ptr);
109        Region(ptr, false)
110    }
111
112    #[inline]
113    pub unsafe fn from_raw_borrow(ptr: *mut ffi::cairo_region_t) -> Region {
114        assert!(!ptr.is_null());
115        Region(ptr, true)
116    }
117
118    #[inline]
119    pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_region_t) -> Region {
120        assert!(!ptr.is_null());
121        Region(ptr, false)
122    }
123
124    pub fn to_raw_none(&self) -> *mut ffi::cairo_region_t {
125        self.0
126    }
127
128    pub fn create() -> Region {
129        unsafe { Self::from_raw_full(ffi::cairo_region_create()) }
130    }
131
132    pub fn create_rectangle(rectangle: &RectangleInt) -> Region {
133        unsafe { Self::from_raw_full(ffi::cairo_region_create_rectangle(rectangle.to_raw_none())) }
134    }
135
136    pub fn create_rectangles(rectangles: &[RectangleInt]) -> Region {
137        unsafe {
138            Self::from_raw_full(ffi::cairo_region_create_rectangles(
139                rectangles.as_ptr() as *mut ffi::cairo_rectangle_int_t,
140                rectangles.len() as i32,
141            ))
142        }
143    }
144
145    pub fn copy(&self) -> Region {
146        unsafe { Self::from_raw_full(ffi::cairo_region_copy(self.0)) }
147    }
148
149    pub fn status(&self) -> Status {
150        unsafe { Status::from(ffi::cairo_region_status(self.0)) }
151    }
152
153    pub fn get_extents(&self, rectangle: &mut RectangleInt) {
154        unsafe { ffi::cairo_region_get_extents(self.0, rectangle.to_raw_none()) }
155    }
156
157    pub fn num_rectangles(&self) -> i32 {
158        unsafe { ffi::cairo_region_num_rectangles(self.0) }
159    }
160
161    pub fn get_rectangle(&self, nth: i32) -> RectangleInt {
162        unsafe {
163            let rectangle: RectangleInt = ::std::mem::zeroed();
164            ffi::cairo_region_get_rectangle(self.0, nth, rectangle.to_raw_none());
165            rectangle
166        }
167    }
168
169    pub fn is_empty(&self) -> bool {
170        unsafe { ffi::cairo_region_is_empty(self.0).as_bool() }
171    }
172
173    pub fn contains_point(&self, x: i32, y: i32) -> bool {
174        unsafe { ffi::cairo_region_contains_point(self.0, x, y).as_bool() }
175    }
176
177    pub fn contains_rectangle(&self, rectangle: &RectangleInt) -> RegionOverlap {
178        unsafe {
179            RegionOverlap::from(ffi::cairo_region_contains_rectangle(
180                self.0,
181                rectangle.to_raw_none(),
182            ))
183        }
184    }
185
186    pub fn translate(&self, dx: i32, dy: i32) {
187        unsafe { ffi::cairo_region_translate(self.0, dx, dy) }
188    }
189
190    pub fn intersect(&self, other: &Region) -> Status {
191        unsafe { Status::from(ffi::cairo_region_intersect(self.0, other.0)) }
192    }
193
194    pub fn intersect_rectangle(&self, rectangle: &RectangleInt) -> Status {
195        unsafe {
196            Status::from(ffi::cairo_region_intersect_rectangle(
197                self.0,
198                rectangle.to_raw_none(),
199            ))
200        }
201    }
202
203    pub fn subtract(&self, other: &Region) -> Status {
204        unsafe { Status::from(ffi::cairo_region_subtract(self.0, other.0)) }
205    }
206
207    pub fn subtract_rectangle(&self, rectangle: &RectangleInt) -> Status {
208        unsafe {
209            Status::from(ffi::cairo_region_subtract_rectangle(
210                self.0,
211                rectangle.to_raw_none(),
212            ))
213        }
214    }
215
216    pub fn union(&self, other: &Region) -> Status {
217        unsafe { Status::from(ffi::cairo_region_union(self.0, other.0)) }
218    }
219
220    pub fn union_rectangle(&self, rectangle: &RectangleInt) -> Status {
221        unsafe {
222            Status::from(ffi::cairo_region_union_rectangle(
223                self.0,
224                rectangle.to_raw_none(),
225            ))
226        }
227    }
228
229    pub fn xor(&self, other: &Region) -> Status {
230        unsafe { Status::from(ffi::cairo_region_xor(self.0, other.0)) }
231    }
232
233    pub fn xor_rectangle(&self, rectangle: &RectangleInt) -> Status {
234        unsafe {
235            Status::from(ffi::cairo_region_xor_rectangle(
236                self.0,
237                rectangle.to_raw_none(),
238            ))
239        }
240    }
241}
242
243impl fmt::Display for Region {
244    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
245        write!(f, "Region")
246    }
247}