1 // Take a look at the license at the top of the repository in the LICENSE file. 2 3 //! # Cairo bindings 4 //! 5 //! This library contains safe Rust bindings for [Cairo](https://www.cairographics.org/). 6 //! It is a part of [gtk-rs](https://gtk-rs.org/). 7 //! 8 //! Cairo 1.14 is the lowest supported version for the underlying library. 9 //! 10 //! # Crate features 11 //! 12 //! ## Default-on features 13 //! 14 //! * **use_glib** - Use with [glib](mod@glib) 15 //! 16 //! ## Fileformat features 17 //! 18 //! * **png** - Reading and writing PNG images 19 //! * **pdf** - Rendering PDF documents 20 //! * **svg** - Rendering SVG documents 21 //! * **ps** - Rendering PostScript documents 22 //! 23 //! ## Cairo API version features 24 //! 25 //! * **v1_16** - Use Cairo 1.16 APIs 26 //! 27 //! ## Documentation features 28 //! 29 //! * **dox** - Used to keep system dependent items in documentation 30 //! 31 //! ## X Window features 32 //! 33 //! * **xcb** - X Window System rendering using the XCB library 34 //! * **xlib** - X Window System rendering using XLib 35 //! 36 //! ## Windows API features 37 //! 38 //! * **win32-surface** - Microsoft Windows surface support 39 40 #![cfg_attr(feature = "dox", feature(doc_cfg))] 41 #![allow(clippy::missing_safety_doc)] 42 #![allow(clippy::wrong_self_convention)] 43 44 pub use ffi; 45 #[cfg(feature = "freetype")] 46 pub use freetype_crate as freetype; 47 #[cfg(feature = "use_glib")] 48 pub use glib; 49 50 // Helper macro for our GValue related trait impls 51 #[cfg(feature = "use_glib")] 52 macro_rules! gvalue_impl { 53 ($name:ty, $ffi_name:ty, $get_type:expr) => { 54 #[allow(unused_imports)] 55 use glib::translate::*; 56 57 impl glib::types::StaticType for $name { 58 fn static_type() -> glib::types::Type { 59 unsafe { from_glib($get_type()) } 60 } 61 } 62 63 impl glib::value::ValueType for $name { 64 type Type = Self; 65 } 66 67 unsafe impl<'a> glib::value::FromValue<'a> for $name { 68 type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>; 69 70 unsafe fn from_value(value: &'a glib::Value) -> Self { 71 let ptr = glib::gobject_ffi::g_value_get_boxed( 72 glib::translate::ToGlibPtr::to_glib_none(value).0, 73 ); 74 assert!(!ptr.is_null()); 75 <$name as glib::translate::FromGlibPtrNone<*mut $ffi_name>>::from_glib_none( 76 ptr as *mut $ffi_name, 77 ) 78 } 79 } 80 81 impl glib::value::ToValue for $name { 82 fn to_value(&self) -> glib::Value { 83 unsafe { 84 let mut value = 85 glib::Value::from_type(<$name as glib::StaticType>::static_type()); 86 glib::gobject_ffi::g_value_set_boxed( 87 value.to_glib_none_mut().0, 88 self.to_glib_none().0 as *mut _, 89 ); 90 value 91 } 92 } 93 94 fn value_type(&self) -> glib::Type { 95 <$name as glib::StaticType>::static_type() 96 } 97 } 98 99 impl glib::value::ToValueOptional for $name { 100 fn to_value_optional(s: Option<&Self>) -> glib::Value { 101 let mut value = glib::Value::for_value_type::<Self>(); 102 unsafe { 103 glib::gobject_ffi::g_value_take_boxed( 104 value.to_glib_none_mut().0, 105 glib::translate::ToGlibPtr::to_glib_full(&s) as *mut _, 106 ); 107 } 108 109 value 110 } 111 } 112 }; 113 } 114 115 pub use crate::user_data::UserDataKey; 116 117 pub use crate::context::{Context, RectangleList}; 118 119 pub use crate::paths::{Path, PathSegment, PathSegments}; 120 121 pub use crate::device::Device; 122 123 pub use crate::enums::*; 124 125 pub use crate::error::{BorrowError, Error, IoError, Result}; 126 127 pub use crate::patterns::{ 128 Gradient, LinearGradient, Mesh, Pattern, RadialGradient, SolidPattern, SurfacePattern, 129 }; 130 131 pub use crate::font::{ 132 FontExtents, FontFace, FontOptions, FontSlant, FontType, FontWeight, Glyph, ScaledFont, 133 TextCluster, TextExtents, 134 }; 135 136 pub use crate::matrices::Matrix; 137 138 pub use crate::recording_surface::RecordingSurface; 139 pub use crate::rectangle::Rectangle; 140 pub use crate::rectangle_int::RectangleInt; 141 142 pub use crate::region::Region; 143 144 pub use crate::surface::{MappedImageSurface, Surface}; 145 146 pub use crate::image_surface::{ImageSurface, ImageSurfaceData, ImageSurfaceDataOwned}; 147 148 #[cfg(any(feature = "pdf", feature = "svg", feature = "ps", feature = "dox"))] 149 pub use stream::StreamWithError; 150 151 #[cfg(any(feature = "pdf", feature = "dox"))] 152 pub use pdf::PdfSurface; 153 154 #[cfg(any(feature = "ps", feature = "dox"))] 155 pub use ps::PsSurface; 156 157 #[cfg(any(feature = "svg", feature = "dox"))] 158 pub use svg::SvgSurface; 159 160 #[cfg(any(feature = "xcb", feature = "dox"))] 161 pub use xcb::{ 162 XCBConnection, XCBDrawable, XCBPixmap, XCBRenderPictFormInfo, XCBScreen, XCBSurface, 163 XCBVisualType, 164 }; 165 166 #[macro_use] 167 mod surface_macros; 168 #[macro_use] 169 mod user_data; 170 mod constants; 171 pub use crate::constants::*; 172 mod utils; 173 pub use crate::utils::{debug_reset_static_data, version_string, Version}; 174 mod context; 175 mod device; 176 mod enums; 177 mod error; 178 mod font; 179 mod image_surface; 180 #[cfg(any(feature = "png", feature = "dox"))] 181 mod image_surface_png; 182 mod matrices; 183 mod paths; 184 mod patterns; 185 mod recording_surface; 186 mod rectangle; 187 mod rectangle_int; 188 mod region; 189 mod surface; 190 #[cfg(any(feature = "xcb", feature = "dox"))] 191 mod xcb; 192 193 #[cfg(any(feature = "pdf", feature = "svg", feature = "ps", feature = "dox"))] 194 #[macro_use] 195 mod stream; 196 #[cfg(any(feature = "pdf", feature = "dox"))] 197 mod pdf; 198 #[cfg(any(feature = "ps", feature = "dox"))] 199 mod ps; 200 #[cfg(any(feature = "svg", feature = "dox"))] 201 mod svg; 202 203 #[cfg(any(target_os = "macos", feature = "dox"))] 204 mod quartz_surface; 205 #[cfg(any(target_os = "macos", feature = "dox"))] 206 pub use quartz_surface::QuartzSurface; 207 208 #[cfg(any(all(windows, feature = "win32-surface"), feature = "dox"))] 209 mod win32_surface; 210 211 #[cfg(any(all(windows, feature = "win32-surface"), feature = "dox"))] 212 pub use win32_surface::Win32Surface; 213 214 #[cfg(not(feature = "use_glib"))] 215 mod borrowed { 216 use std::mem; 217 218 /// Wrapper around values representing borrowed C memory. 219 /// 220 /// This is returned by `from_glib_borrow()` and ensures that the wrapped value 221 /// is never dropped when going out of scope. 222 /// 223 /// Borrowed values must never be passed by value or mutable reference to safe Rust code and must 224 /// not leave the C scope in which they are valid. 225 #[derive(Debug)] 226 pub struct Borrowed<T>(mem::ManuallyDrop<T>); 227 228 impl<T> Borrowed<T> { 229 /// Creates a new borrowed value. new(val: T) -> Self230 pub fn new(val: T) -> Self { 231 Self(mem::ManuallyDrop::new(val)) 232 } 233 234 /// Extracts the contained value. 235 /// 236 /// The returned value must never be dropped and instead has to be passed to `mem::forget()` or 237 /// be directly wrapped in `mem::ManuallyDrop` or another `Borrowed` wrapper. into_inner(self) -> T238 pub unsafe fn into_inner(self) -> T { 239 mem::ManuallyDrop::into_inner(self.0) 240 } 241 } 242 243 impl<T> AsRef<T> for Borrowed<T> { as_ref(&self) -> &T244 fn as_ref(&self) -> &T { 245 &*self.0 246 } 247 } 248 249 impl<T> std::ops::Deref for Borrowed<T> { 250 type Target = T; 251 deref(&self) -> &T252 fn deref(&self) -> &T { 253 &*self.0 254 } 255 } 256 } 257 258 #[cfg(not(feature = "use_glib"))] 259 pub use borrowed::Borrowed; 260 261 #[cfg(feature = "use_glib")] 262 pub(crate) use glib::translate::Borrowed; 263