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