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