1 // Take a look at the license at the top of the repository in the LICENSE file. 2 3 use crate::enums::DeviceType; 4 use crate::error::Error; 5 use crate::utils::status_to_result; 6 7 use std::fmt; 8 use std::ptr; 9 10 #[cfg(feature = "use_glib")] 11 use glib::translate::*; 12 13 #[cfg(any(feature = "script", feature = "dox"))] 14 use crate::enums::Content; 15 #[cfg(any(feature = "script", feature = "dox"))] 16 use crate::enums::ScriptMode; 17 #[cfg(any(feature = "script", feature = "dox"))] 18 use crate::recording_surface::RecordingSurface; 19 #[cfg(any(feature = "script", feature = "dox"))] 20 use crate::surface::Surface; 21 #[cfg(any(feature = "script", feature = "dox"))] 22 use std::ffi::CString; 23 #[cfg(any(feature = "script", feature = "dox"))] 24 use std::path::Path; 25 26 #[derive(Debug)] 27 pub struct DeviceAcquireGuard<'a>(&'a Device); 28 29 impl<'a> Drop for DeviceAcquireGuard<'a> { drop(&mut self)30 fn drop(&mut self) { 31 self.0.release(); 32 } 33 } 34 35 #[derive(Debug)] 36 #[doc(alias = "cairo_device_t")] 37 pub struct Device(ptr::NonNull<ffi::cairo_device_t>); 38 39 impl Device { from_raw_none(ptr: *mut ffi::cairo_device_t) -> Device40 pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_device_t) -> Device { 41 assert!(!ptr.is_null()); 42 ffi::cairo_device_reference(ptr); 43 Device(ptr::NonNull::new_unchecked(ptr)) 44 } 45 from_raw_borrow(ptr: *mut ffi::cairo_device_t) -> crate::Borrowed<Device>46 pub unsafe fn from_raw_borrow(ptr: *mut ffi::cairo_device_t) -> crate::Borrowed<Device> { 47 assert!(!ptr.is_null()); 48 crate::Borrowed::new(Device(ptr::NonNull::new_unchecked(ptr))) 49 } 50 from_raw_full(ptr: *mut ffi::cairo_device_t) -> Device51 pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_device_t) -> Device { 52 assert!(!ptr.is_null()); 53 Device(ptr::NonNull::new_unchecked(ptr)) 54 } 55 to_raw_none(&self) -> *mut ffi::cairo_device_t56 pub fn to_raw_none(&self) -> *mut ffi::cairo_device_t { 57 self.0.as_ptr() 58 } 59 60 #[cfg(any(feature = "script", feature = "dox"))] 61 #[doc(alias = "cairo_script_create")] create<P: AsRef<Path>>(filename: P) -> Option<Device>62 pub fn create<P: AsRef<Path>>(filename: P) -> Option<Device> { 63 unsafe { 64 let filename = filename.as_ref().to_string_lossy().into_owned(); 65 let filename = CString::new(filename).unwrap(); 66 let p = ffi::cairo_script_create(filename.as_ptr()); 67 if p.is_null() { 68 None 69 } else { 70 Some(Self::from_raw_full(p)) 71 } 72 } 73 } 74 75 #[cfg(any(feature = "script", feature = "dox"))] 76 #[doc(alias = "cairo_script_from_recording_surface")] from_recording_surface(&self, surface: &RecordingSurface) -> Result<(), Error>77 pub fn from_recording_surface(&self, surface: &RecordingSurface) -> Result<(), Error> { 78 unsafe { 79 let status = 80 ffi::cairo_script_from_recording_surface(self.to_raw_none(), surface.to_raw_none()); 81 status_to_result(status) 82 } 83 } 84 85 #[cfg(any(feature = "script", feature = "dox"))] 86 #[doc(alias = "cairo_script_get_mode")] 87 #[doc(alias = "get_mode")] mode(&self) -> ScriptMode88 pub fn mode(&self) -> ScriptMode { 89 unsafe { ScriptMode::from(ffi::cairo_script_get_mode(self.to_raw_none())) } 90 } 91 92 #[cfg(any(feature = "script", feature = "dox"))] 93 #[doc(alias = "cairo_script_set_mode")] set_mode(&self, mode: ScriptMode)94 pub fn set_mode(&self, mode: ScriptMode) { 95 unsafe { ffi::cairo_script_set_mode(self.to_raw_none(), mode.into()) } 96 } 97 98 #[cfg(any(feature = "script", feature = "dox"))] 99 #[doc(alias = "cairo_script_surface_create")] surface_create( &self, content: Content, width: f64, height: f64, ) -> Result<Surface, Error>100 pub fn surface_create( 101 &self, 102 content: Content, 103 width: f64, 104 height: f64, 105 ) -> Result<Surface, Error> { 106 unsafe { 107 Surface::from_raw_full(ffi::cairo_script_surface_create( 108 self.to_raw_none(), 109 content.into(), 110 width, 111 height, 112 )) 113 } 114 } 115 116 #[cfg(any(feature = "script", feature = "dox"))] 117 #[doc(alias = "cairo_script_surface_create_for_target")] surface_create_for_target(&self, target: &Surface) -> Result<Surface, Error>118 pub fn surface_create_for_target(&self, target: &Surface) -> Result<Surface, Error> { 119 target.status()?; 120 unsafe { 121 Surface::from_raw_full(ffi::cairo_script_surface_create_for_target( 122 self.to_raw_none(), 123 target.to_raw_none(), 124 )) 125 } 126 } 127 128 #[cfg(any(feature = "script", feature = "dox"))] 129 #[doc(alias = "cairo_script_write_comment")] write_comment(&self, comment: &str)130 pub fn write_comment(&self, comment: &str) { 131 unsafe { 132 let len = comment.len(); 133 let comment = CString::new(comment).unwrap(); 134 ffi::cairo_script_write_comment(self.to_raw_none(), comment.as_ptr(), len as i32) 135 } 136 } 137 138 #[doc(alias = "cairo_device_finish")] finish(&self)139 pub fn finish(&self) { 140 unsafe { ffi::cairo_device_finish(self.to_raw_none()) } 141 } 142 143 #[doc(alias = "cairo_device_flush")] flush(&self)144 pub fn flush(&self) { 145 unsafe { ffi::cairo_device_flush(self.to_raw_none()) } 146 } 147 148 #[doc(alias = "cairo_device_get_type")] 149 #[doc(alias = "get_type")] type_(&self) -> DeviceType150 pub fn type_(&self) -> DeviceType { 151 unsafe { DeviceType::from(ffi::cairo_device_get_type(self.to_raw_none())) } 152 } 153 154 #[doc(alias = "cairo_device_acquire")] acquire(&self) -> Result<DeviceAcquireGuard, Error>155 pub fn acquire(&self) -> Result<DeviceAcquireGuard, Error> { 156 unsafe { 157 let status = ffi::cairo_device_acquire(self.to_raw_none()); 158 status_to_result(status)?; 159 } 160 Ok(DeviceAcquireGuard { 0: self }) 161 } 162 163 #[doc(alias = "cairo_device_release")] release(&self)164 fn release(&self) { 165 unsafe { ffi::cairo_device_release(self.to_raw_none()) } 166 } 167 168 #[doc(alias = "cairo_device_observer_elapsed")] observer_elapsed(&self) -> f64169 pub fn observer_elapsed(&self) -> f64 { 170 unsafe { ffi::cairo_device_observer_elapsed(self.to_raw_none()) } 171 } 172 173 #[doc(alias = "cairo_device_observer_fill_elapsed")] observer_fill_elapsed(&self) -> f64174 pub fn observer_fill_elapsed(&self) -> f64 { 175 unsafe { ffi::cairo_device_observer_fill_elapsed(self.to_raw_none()) } 176 } 177 178 #[doc(alias = "cairo_device_observer_glyphs_elapsed")] observer_glyphs_elapsed(&self) -> f64179 pub fn observer_glyphs_elapsed(&self) -> f64 { 180 unsafe { ffi::cairo_device_observer_glyphs_elapsed(self.to_raw_none()) } 181 } 182 183 #[doc(alias = "cairo_device_observer_mask_elapsed")] observer_mask_elapsed(&self) -> f64184 pub fn observer_mask_elapsed(&self) -> f64 { 185 unsafe { ffi::cairo_device_observer_mask_elapsed(self.to_raw_none()) } 186 } 187 188 #[doc(alias = "cairo_device_observer_paint_elapsed")] observer_paint_elapsed(&self) -> f64189 pub fn observer_paint_elapsed(&self) -> f64 { 190 unsafe { ffi::cairo_device_observer_paint_elapsed(self.to_raw_none()) } 191 } 192 193 #[doc(alias = "cairo_device_observer_stroke_elapsed")] observer_stroke_elapsed(&self) -> f64194 pub fn observer_stroke_elapsed(&self) -> f64 { 195 unsafe { ffi::cairo_device_observer_stroke_elapsed(self.to_raw_none()) } 196 } 197 198 #[cfg(any(feature = "xlib", feature = "xcb", feature = "dox"))] 199 #[doc(alias = "cairo_xlib_device_debug_cap_xrender_version")] 200 #[doc(alias = "cairo_xcb_device_debug_cap_xrender_version")] debug_cap_xrender_version(&self, major_version: i32, minor_version: i32)201 pub fn debug_cap_xrender_version(&self, major_version: i32, minor_version: i32) { 202 unsafe { 203 match self.type_() { 204 DeviceType::Xlib => { 205 #[cfg(feature = "xlib")] 206 { 207 ffi::cairo_xlib_device_debug_cap_xrender_version( 208 self.to_raw_none(), 209 major_version, 210 minor_version, 211 ) 212 } 213 #[cfg(not(feature = "xlib"))] 214 { 215 panic!("you need to enable \"xlib\" feature") 216 } 217 } 218 DeviceType::Xcb => { 219 #[cfg(feature = "xcb")] 220 { 221 ffi::cairo_xcb_device_debug_cap_xrender_version( 222 self.to_raw_none(), 223 major_version, 224 minor_version, 225 ) 226 } 227 #[cfg(not(feature = "xcb"))] 228 { 229 panic!("you need to enable \"xcb\" feature") 230 } 231 } 232 d => panic!("invalid device type: {}", d), 233 } 234 } 235 } 236 237 #[cfg(any(feature = "xlib", feature = "xcb", feature = "dox"))] 238 #[doc(alias = "cairo_xlib_device_debug_get_precision")] 239 #[doc(alias = "cairo_xcb_device_debug_get_precision")] debug_get_precision(&self) -> i32240 pub fn debug_get_precision(&self) -> i32 { 241 unsafe { 242 match self.type_() { 243 DeviceType::Xlib => { 244 #[cfg(feature = "xlib")] 245 { 246 ffi::cairo_xlib_device_debug_get_precision(self.to_raw_none()) 247 } 248 #[cfg(not(feature = "xlib"))] 249 { 250 panic!("you need to enable \"xlib\" feature") 251 } 252 } 253 DeviceType::Xcb => { 254 #[cfg(feature = "xcb")] 255 { 256 ffi::cairo_xcb_device_debug_get_precision(self.to_raw_none()) 257 } 258 #[cfg(not(feature = "xcb"))] 259 { 260 panic!("you need to enable \"xcb\" feature") 261 } 262 } 263 d => panic!("invalid device type: {}", d), 264 } 265 } 266 } 267 268 #[cfg(any(feature = "xlib", feature = "xcb", feature = "dox"))] 269 #[doc(alias = "cairo_xlib_device_debug_set_precision")] 270 #[doc(alias = "cairo_xcb_device_debug_set_precision")] debug_set_precision(&self, precision: i32)271 pub fn debug_set_precision(&self, precision: i32) { 272 unsafe { 273 match self.type_() { 274 DeviceType::Xlib => { 275 #[cfg(feature = "xlib")] 276 { 277 ffi::cairo_xlib_device_debug_set_precision(self.to_raw_none(), precision) 278 } 279 #[cfg(not(feature = "xlib"))] 280 { 281 panic!("you need to enable \"xlib\" feature") 282 } 283 } 284 DeviceType::Xcb => { 285 #[cfg(feature = "xcb")] 286 { 287 ffi::cairo_xcb_device_debug_set_precision(self.to_raw_none(), precision) 288 } 289 #[cfg(not(feature = "xcb"))] 290 { 291 panic!("you need to enable \"xcb\" feature") 292 } 293 } 294 d => panic!("invalid device type: {}", d), 295 } 296 } 297 } 298 299 #[doc(alias = "cairo_device_status")] status(&self) -> Result<(), Error>300 pub fn status(&self) -> Result<(), Error> { 301 let status = unsafe { ffi::cairo_device_status(self.to_raw_none()) }; 302 status_to_result(status) 303 } 304 305 user_data_methods! { 306 ffi::cairo_device_get_user_data, 307 ffi::cairo_device_set_user_data, 308 } 309 } 310 311 #[cfg(feature = "use_glib")] 312 impl<'a> ToGlibPtr<'a, *mut ffi::cairo_device_t> for Device { 313 type Storage = &'a Device; 314 315 #[inline] to_glib_none(&'a self) -> Stash<'a, *mut ffi::cairo_device_t, Self>316 fn to_glib_none(&'a self) -> Stash<'a, *mut ffi::cairo_device_t, Self> { 317 Stash(self.to_raw_none(), self) 318 } 319 320 #[inline] to_glib_full(&self) -> *mut ffi::cairo_device_t321 fn to_glib_full(&self) -> *mut ffi::cairo_device_t { 322 unsafe { ffi::cairo_device_reference(self.to_raw_none()) } 323 } 324 } 325 326 #[cfg(feature = "use_glib")] 327 impl FromGlibPtrNone<*mut ffi::cairo_device_t> for Device { 328 #[inline] from_glib_none(ptr: *mut ffi::cairo_device_t) -> Device329 unsafe fn from_glib_none(ptr: *mut ffi::cairo_device_t) -> Device { 330 Self::from_raw_none(ptr) 331 } 332 } 333 334 #[cfg(feature = "use_glib")] 335 impl FromGlibPtrBorrow<*mut ffi::cairo_device_t> for Device { 336 #[inline] from_glib_borrow(ptr: *mut ffi::cairo_device_t) -> crate::Borrowed<Device>337 unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_device_t) -> crate::Borrowed<Device> { 338 Self::from_raw_borrow(ptr) 339 } 340 } 341 342 #[cfg(feature = "use_glib")] 343 impl FromGlibPtrFull<*mut ffi::cairo_device_t> for Device { 344 #[inline] from_glib_full(ptr: *mut ffi::cairo_device_t) -> Device345 unsafe fn from_glib_full(ptr: *mut ffi::cairo_device_t) -> Device { 346 Self::from_raw_full(ptr) 347 } 348 } 349 350 #[cfg(feature = "use_glib")] 351 gvalue_impl!( 352 Device, 353 ffi::cairo_device_t, 354 ffi::gobject::cairo_gobject_device_get_type 355 ); 356 357 impl Clone for Device { clone(&self) -> Device358 fn clone(&self) -> Device { 359 unsafe { Self::from_raw_none(ffi::cairo_device_reference(self.0.as_ptr())) } 360 } 361 } 362 363 impl Drop for Device { drop(&mut self)364 fn drop(&mut self) { 365 unsafe { 366 ffi::cairo_device_destroy(self.0.as_ptr()); 367 } 368 } 369 } 370 371 impl fmt::Display for Device { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result372 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 373 write!(f, "Device") 374 } 375 } 376