cairo/
surface_macros.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3// e.g. declare_surface(ImageSurface, SurfaceType::Image)
4macro_rules! declare_surface {
5    ($surf_name:ident, $surf_type:expr) => {
6        #[derive(Debug)]
7        #[repr(transparent)]
8        pub struct $surf_name(Surface);
9
10        impl TryFrom<Surface> for $surf_name {
11            type Error = Surface;
12
13            #[inline]
14            fn try_from(surface: Surface) -> Result<$surf_name, Surface> {
15                if surface.type_() == $surf_type {
16                    Ok($surf_name(surface))
17                } else {
18                    Err(surface)
19                }
20            }
21        }
22
23        impl $surf_name {
24            #[inline]
25            pub unsafe fn from_raw_full(
26                ptr: *mut crate::ffi::cairo_surface_t,
27            ) -> Result<$surf_name, crate::error::Error> {
28                let surface = Surface::from_raw_full(ptr)?;
29                Self::try_from(surface).map_err(|_| crate::error::Error::SurfaceTypeMismatch)
30            }
31
32            #[inline]
33            pub unsafe fn from_raw_none(
34                ptr: *mut crate::ffi::cairo_surface_t,
35            ) -> Result<$surf_name, crate::error::Error> {
36                let surface = Surface::from_raw_none(ptr);
37                Self::try_from(surface).map_err(|_| crate::error::Error::SurfaceTypeMismatch)
38            }
39        }
40
41        #[cfg(feature = "use_glib")]
42        impl IntoGlibPtr<*mut crate::ffi::cairo_surface_t> for $surf_name {
43            #[inline]
44            unsafe fn into_glib_ptr(self) -> *mut crate::ffi::cairo_surface_t {
45                std::mem::ManuallyDrop::new(self).to_glib_none().0
46            }
47        }
48
49        #[cfg(feature = "use_glib")]
50        impl<'a> ToGlibPtr<'a, *mut crate::ffi::cairo_surface_t> for $surf_name {
51            type Storage = std::marker::PhantomData<&'a Surface>;
52
53            #[inline]
54            fn to_glib_none(&'a self) -> Stash<'a, *mut crate::ffi::cairo_surface_t, Self> {
55                let stash = self.0.to_glib_none();
56                Stash(stash.0, stash.1)
57            }
58
59            #[inline]
60            fn to_glib_full(&self) -> *mut crate::ffi::cairo_surface_t {
61                unsafe { crate::ffi::cairo_surface_reference(self.to_glib_none().0) }
62            }
63        }
64
65        #[cfg(feature = "use_glib")]
66        impl FromGlibPtrNone<*mut crate::ffi::cairo_surface_t> for $surf_name {
67            #[inline]
68            unsafe fn from_glib_none(ptr: *mut crate::ffi::cairo_surface_t) -> $surf_name {
69                Self::try_from(from_glib_none::<_, Surface>(ptr)).unwrap()
70            }
71        }
72
73        #[cfg(feature = "use_glib")]
74        impl FromGlibPtrBorrow<*mut crate::ffi::cairo_surface_t> for $surf_name {
75            #[inline]
76            unsafe fn from_glib_borrow(
77                ptr: *mut crate::ffi::cairo_surface_t,
78            ) -> crate::Borrowed<$surf_name> {
79                let surface = from_glib_borrow::<_, Surface>(ptr);
80                let surface = Self::try_from(surface.into_inner())
81                    .map_err(std::mem::forget)
82                    .unwrap();
83                crate::Borrowed::new(surface)
84            }
85        }
86
87        #[cfg(feature = "use_glib")]
88        impl FromGlibPtrFull<*mut crate::ffi::cairo_surface_t> for $surf_name {
89            #[inline]
90            unsafe fn from_glib_full(ptr: *mut crate::ffi::cairo_surface_t) -> $surf_name {
91                Self::from_raw_full(ptr).unwrap()
92            }
93        }
94
95        #[cfg(feature = "use_glib")]
96        gvalue_impl!(
97            $surf_name,
98            crate::ffi::cairo_surface_t,
99            crate::ffi::gobject::cairo_gobject_surface_get_type
100        );
101
102        impl Deref for $surf_name {
103            type Target = Surface;
104
105            #[inline]
106            fn deref(&self) -> &Surface {
107                &self.0
108            }
109        }
110
111        impl AsRef<Surface> for $surf_name {
112            #[inline]
113            fn as_ref(&self) -> &Surface {
114                &self.0
115            }
116        }
117
118        impl Clone for $surf_name {
119            #[inline]
120            fn clone(&self) -> $surf_name {
121                $surf_name(self.0.clone())
122            }
123        }
124    };
125}