1#![cfg_attr(docsrs, feature(doc_cfg))]
4#![allow(clippy::missing_safety_doc)]
5#![doc = include_str!("../README.md")]
6
7pub use cairo_sys as ffi;
8#[cfg(feature = "freetype")]
9#[cfg_attr(docsrs, doc(cfg(feature = "freetype")))]
10pub use freetype;
11#[cfg(feature = "use_glib")]
12#[cfg_attr(docsrs, doc(cfg(feature = "use_glib")))]
13pub use glib;
14
15#[cfg(feature = "use_glib")]
17#[cfg_attr(docsrs, doc(cfg(feature = "use_glib")))]
18macro_rules! gvalue_impl_inner {
19 ($name:ty, $ffi_name:ty, $get_type:expr) => {
20 #[allow(unused_imports)]
21 use glib::translate::*;
22
23 impl glib::prelude::StaticType for $name {
24 #[inline]
25 fn static_type() -> glib::types::Type {
26 unsafe { from_glib($get_type()) }
27 }
28 }
29
30 impl glib::value::ValueType for $name {
31 type Type = Self;
32 }
33
34 impl glib::value::ValueTypeOptional for $name {}
35 };
36}
37
38#[cfg(feature = "use_glib")]
39#[cfg_attr(docsrs, doc(cfg(feature = "use_glib")))]
40macro_rules! gvalue_impl {
41 ($name:ty, $ffi_name:ty, $get_type:expr) => {
42 gvalue_impl_inner!($name, $ffi_name, $get_type);
43
44 unsafe impl<'a> glib::value::FromValue<'a> for $name {
45 type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
46
47 unsafe fn from_value(value: &'a glib::Value) -> Self {
48 unsafe {
49 let ptr = glib::gobject_ffi::g_value_dup_boxed(
50 glib::translate::ToGlibPtr::to_glib_none(value).0,
51 );
52 debug_assert!(!ptr.is_null());
53 <$name as glib::translate::FromGlibPtrFull<*mut $ffi_name>>::from_glib_full(
54 ptr as *mut $ffi_name,
55 )
56 }
57 }
58 }
59
60 unsafe impl<'a> glib::value::FromValue<'a> for &'a $name {
61 type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
62
63 unsafe fn from_value(value: &'a glib::Value) -> Self {
64 unsafe {
65 debug_assert_eq!(
66 std::mem::size_of::<Self>(),
67 std::mem::size_of::<glib::ffi::gpointer>()
68 );
69 let value = &*(value as *const glib::Value as *const glib::gobject_ffi::GValue);
70 let ptr = &value.data[0].v_pointer as *const glib::ffi::gpointer
71 as *const *const $ffi_name;
72 debug_assert!(!(*ptr).is_null());
73 &*(ptr as *const $name)
74 }
75 }
76 }
77
78 impl glib::value::ToValue for $name {
79 fn to_value(&self) -> glib::Value {
80 unsafe {
81 let mut value = glib::Value::from_type_unchecked(
82 <$name as glib::prelude::StaticType>::static_type(),
83 );
84 glib::gobject_ffi::g_value_take_boxed(
85 value.to_glib_none_mut().0,
86 self.to_glib_full() as *mut _,
87 );
88 value
89 }
90 }
91
92 fn value_type(&self) -> glib::Type {
93 <$name as glib::prelude::StaticType>::static_type()
94 }
95 }
96
97 impl From<$name> for glib::Value {
98 fn from(v: $name) -> Self {
99 unsafe {
100 let mut value = glib::Value::from_type_unchecked(
101 <$name as glib::prelude::StaticType>::static_type(),
102 );
103 glib::gobject_ffi::g_value_take_boxed(
104 value.to_glib_none_mut().0,
105 glib::translate::IntoGlibPtr::into_glib_ptr(v) as *mut _,
106 );
107 value
108 }
109 }
110 }
111
112 impl glib::value::ToValueOptional for $name {
113 fn to_value_optional(s: Option<&Self>) -> glib::Value {
114 let mut value = glib::Value::for_value_type::<Self>();
115 unsafe {
116 glib::gobject_ffi::g_value_take_boxed(
117 value.to_glib_none_mut().0,
118 glib::translate::ToGlibPtr::to_glib_full(&s) as *mut _,
119 );
120 }
121
122 value
123 }
124 }
125 };
126}
127
128#[cfg(feature = "use_glib")]
129#[cfg_attr(docsrs, doc(cfg(feature = "use_glib")))]
130macro_rules! gvalue_impl_inline {
131 ($name:ty, $ffi_name:ty, $get_type:expr) => {
132 gvalue_impl_inner!($name, $ffi_name, $get_type);
133
134 unsafe impl<'a> glib::value::FromValue<'a> for $name {
135 type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
136
137 unsafe fn from_value(value: &'a glib::Value) -> Self {
138 unsafe {
139 let ptr = glib::gobject_ffi::g_value_get_boxed(
140 glib::translate::ToGlibPtr::to_glib_none(value).0,
141 );
142 debug_assert!(!ptr.is_null());
143 <$name as glib::translate::FromGlibPtrNone<*mut $ffi_name>>::from_glib_none(
144 ptr as *mut $ffi_name,
145 )
146 }
147 }
148 }
149
150 unsafe impl<'a> glib::value::FromValue<'a> for &'a $name {
151 type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
152
153 unsafe fn from_value(value: &'a glib::Value) -> Self {
154 unsafe {
155 let ptr = glib::gobject_ffi::g_value_get_boxed(
156 glib::translate::ToGlibPtr::to_glib_none(value).0,
157 );
158 debug_assert!(!ptr.is_null());
159 &*(ptr as *mut $name)
160 }
161 }
162 }
163
164 impl glib::value::ToValue for $name {
165 fn to_value(&self) -> glib::Value {
166 unsafe {
167 let ptr =
168 glib::ffi::g_malloc0(std::mem::size_of::<$ffi_name>()) as *mut $ffi_name;
169 ptr.write(self.0);
170 let mut value = glib::Value::from_type_unchecked(
171 <$name as glib::prelude::StaticType>::static_type(),
172 );
173 glib::gobject_ffi::g_value_take_boxed(
174 value.to_glib_none_mut().0,
175 ptr as *mut _,
176 );
177 value
178 }
179 }
180
181 fn value_type(&self) -> glib::Type {
182 <$name as glib::prelude::StaticType>::static_type()
183 }
184 }
185
186 impl glib::value::ToValueOptional for $name {
187 fn to_value_optional(s: Option<&Self>) -> glib::Value {
188 let ptr: *mut $ffi_name = match s {
189 Some(s) => unsafe {
190 let ptr = glib::ffi::g_malloc0(std::mem::size_of::<$ffi_name>())
191 as *mut $ffi_name;
192 ptr.write(s.0);
193 ptr
194 },
195 None => std::ptr::null_mut(),
196 };
197 let mut value = glib::Value::for_value_type::<Self>();
198 unsafe {
199 glib::gobject_ffi::g_value_take_boxed(
200 value.to_glib_none_mut().0,
201 ptr as *mut _,
202 );
203 }
204
205 value
206 }
207 }
208 };
209}
210
211#[cfg(feature = "pdf")]
212#[cfg_attr(docsrs, doc(cfg(feature = "pdf")))]
213pub use pdf::PdfSurface;
214#[cfg(feature = "ps")]
215#[cfg_attr(docsrs, doc(cfg(feature = "ps")))]
216pub use ps::PsSurface;
217#[cfg(any(feature = "pdf", feature = "svg", feature = "ps"))]
218#[cfg_attr(
219 docsrs,
220 doc(cfg(any(feature = "pdf", feature = "svg", feature = "ps")))
221)]
222pub use stream::StreamWithError;
223#[cfg(feature = "svg")]
224#[cfg_attr(docsrs, doc(cfg(feature = "svg")))]
225pub use svg::SvgSurface;
226#[cfg(feature = "xcb")]
227#[cfg_attr(docsrs, doc(cfg(feature = "xcb")))]
228pub use xcb::{
229 XCBConnection, XCBDrawable, XCBPixmap, XCBRenderPictFormInfo, XCBScreen, XCBSurface,
230 XCBVisualType,
231};
232
233pub use crate::{
234 context::{Context, RectangleList},
235 device::Device,
236 enums::*,
237 error::{BorrowError, Error, IoError, Result},
238 font::{
239 Antialias, FontExtents, FontFace, FontOptions, FontSlant, FontType, FontWeight, Glyph,
240 HintMetrics, HintStyle, ScaledFont, SubpixelOrder, TextCluster, TextExtents, UserFontFace,
241 },
242 image_surface::{ImageSurface, ImageSurfaceData, ImageSurfaceDataOwned},
243 matrices::Matrix,
244 paths::{Path, PathSegment, PathSegments},
245 patterns::{
246 Gradient, LinearGradient, Mesh, Pattern, RadialGradient, SolidPattern, SurfacePattern,
247 },
248 recording_surface::RecordingSurface,
249 rectangle::Rectangle,
250 rectangle_int::RectangleInt,
251 region::Region,
252 surface::{MappedImageSurface, Surface},
253 user_data::UserDataKey,
254};
255
256#[macro_use]
257mod surface_macros;
258#[macro_use]
259mod user_data;
260mod constants;
261pub use crate::constants::*;
262mod utils;
263pub use crate::utils::{Version, debug_reset_static_data, version_string};
264mod context;
265mod device;
266mod enums;
267mod error;
268mod font;
269mod image_surface;
270mod matrices;
271mod paths;
272mod patterns;
273mod recording_surface;
274mod rectangle;
275mod rectangle_int;
276mod region;
277mod surface;
278#[cfg(feature = "png")]
279mod surface_png;
280#[cfg(feature = "xcb")]
281mod xcb;
282
283#[cfg(any(feature = "pdf", feature = "svg", feature = "ps"))]
284#[macro_use]
285mod stream;
286#[cfg(feature = "pdf")]
287mod pdf;
288#[cfg(feature = "ps")]
289mod ps;
290#[cfg(feature = "svg")]
291mod svg;
292
293#[cfg(all(target_os = "macos", feature = "quartz-surface"))]
294mod quartz_surface;
295#[cfg(all(target_os = "macos", feature = "quartz-surface"))]
296pub use quartz_surface::QuartzSurface;
297
298#[cfg(all(windows, feature = "win32-surface"))]
299mod win32_surface;
300
301#[cfg(all(windows, feature = "win32-surface"))]
302#[cfg_attr(docsrs, doc(cfg(all(windows, feature = "win32-surface"))))]
303pub use win32_surface::Win32Surface;
304
305#[cfg(not(feature = "use_glib"))]
306#[cfg_attr(docsrs, doc(cfg(not(feature = "use_glib"))))]
307mod borrowed {
308 use std::mem;
309
310 #[derive(Debug)]
318 pub struct Borrowed<T>(mem::ManuallyDrop<T>);
319
320 impl<T> Borrowed<T> {
321 #[inline]
323 pub fn new(val: T) -> Self {
324 Self(mem::ManuallyDrop::new(val))
325 }
326
327 #[inline]
332 pub unsafe fn into_inner(self) -> T {
333 mem::ManuallyDrop::into_inner(self.0)
334 }
335 }
336
337 impl<T> AsRef<T> for Borrowed<T> {
338 #[inline]
339 fn as_ref(&self) -> &T {
340 &*self.0
341 }
342 }
343
344 impl<T> std::ops::Deref for Borrowed<T> {
345 type Target = T;
346
347 #[inline]
348 fn deref(&self) -> &T {
349 &*self.0
350 }
351 }
352}
353
354#[cfg(not(feature = "use_glib"))]
355#[cfg_attr(docsrs, doc(cfg(not(feature = "use_glib"))))]
356pub use borrowed::Borrowed;
357#[cfg(feature = "use_glib")]
358pub(crate) use glib::translate::Borrowed;