cairo-rs-0.7.1/.gitignore010066400017500001750000000001561350466631400134630ustar0000000000000000test/bin/ target/ doc/ configure.in config.log config.status *.dylib Makefile .rust *.so *.o *.swp Cargo.lock cairo-rs-0.7.1/.travis.yml010066400017500001750000000033421350734563600136100ustar0000000000000000dist: xenial language: rust matrix: include: - os: linux rust: nightly env: GTK=3.14 FEATURES= - os: linux rust: nightly env: GTK=3.24 FEATURES= - os: linux rust: beta env: GTK=3.14 FEATURES= - os: linux rust: beta env: GTK=3.24 FEATURES= - os: linux rust: 1.34.0 env: GTK=3.14 FEATURES= - os: linux rust: 1.34.0 env: GTK=3.24 FEATURES= - os: osx rust: nightly env: GTK=3.14 FEATURES= # - os: osx # rust: nightly # env: GTK=3.24 FEATURES=v3_16 - os: osx rust: beta env: GTK=3.14 FEATURES= # - os: osx # rust: beta # env: GTK=3.24 FEATURES=v3_16 - os: osx rust: stable env: GTK=3.14 FEATURES= # - os: osx # rust: stable # env: GTK=3.24 FEATURES=v3_16 sudo: true addons: apt: packages: - libgtk-3-dev - libmount-dev before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install gtk+3 cairo atk; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/opt/X11/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig; fi script: - rustc --version - cargo doc --features "dox,embed-lgpl-docs" - cargo test --features "$FEATURES,png,pdf,svg,pdf,xcb" - cargo test --no-default-features --features "$FEATURES,png,pdf,svg,pdf,xcb" # catch any sneaked in lgpl docs - cargo build --features purge-lgpl-docs - git diff -R --exit-code - mkdir .cargo - echo 'paths = [".", "./cairo-sys-rs"]' > .cargo/config - git clone -q --depth 50 -b pending https://github.com/gtk-rs/examples _examples - cd _examples - ./build_travis.sh cairo-rs-0.7.1/COPYRIGHT010066400017500001750000000050021350466626300127640ustar0000000000000000The Gtk-rs Project is copyright 2013-2016, The Gtk-rs Project Developers: Adam Crume Adolfo Ochagavía Andre Bogus Anton Konjahin Arne Dussin Boden Garman Brian Kropf Bryant Mairs Chris Greenaway Chris Palmer Corey Farwell Daniel Zalevskiy David Li Edward Shaw Edward Yang Esption Evgenii Pashkin Geoffrey French Gleb Kozyrev Glenn Watson Google Inc. Guillaume Gomez Gulshan Singh Jakob Gillich James Shepherdson Jeremy Letang John Vrbanac kennytm Laurence Tratt Lionel Flandrin Lucas Werkmeister Lukas Diekmann Mathijs Henquet Maxwell Koo mitaa Nick Herman Nicolas Koch Oliver Schneider Ömer Sinan Ağacan Ralph Giles Paul Dennis Paul Hendry Philipp Brüschweiler Raphael Nestler Robertas Romain Gauthier S.J.R. van Schaik Sebastian Schulze Silvio Fricke Simon Sapin Steve Klabnik Tobias Bales trolleyman Umur Gedik UrKr Vojtech Kral Zach Oakes Zach Ploskey The Gtk-rs Project is licensed under the MIT license, see the LICENSE file or . This project provides interoperability with various GNOME libraries but doesn't distribute any parts of them. Distributing compiled libraries and executables that link to those libraries may be subject to terms of the GNU LGPL, see the LGPL file. cairo-rs-0.7.1/Cargo.toml.orig010066400017500001750000000024631350734600700143620ustar0000000000000000[package] name = "cairo-rs" license = "MIT" homepage = "http://gtk-rs.org/" authors = ["The Gtk-rs Project Developers"] keywords = ["cairo", "gtk-rs", "gnome", "GUI"] readme = "README.md" documentation = "http://gtk-rs.org/docs/cairo/" version = "0.7.1" description = "Rust bindings for the Cairo library" repository = "https://github.com/gtk-rs/cairo" build = "build.rs" [badges] appveyor = { repository = "GuillaumeGomez/cairo", service = "github" } travis-ci = { repository = "gtk-rs/cairo" } [lib] name = "cairo" [features] purge-lgpl-docs = ["gtk-rs-lgpl-docs"] png = ["cairo-sys-rs/png"] pdf = ["cairo-sys-rs/pdf"] svg = ["cairo-sys-rs/svg"] ps = ["cairo-sys-rs/ps"] use_glib = ["glib", "glib-sys", "gobject-sys", "cairo-sys-rs/use_glib"] embed-lgpl-docs = ["gtk-rs-lgpl-docs"] v1_14 = ["cairo-sys-rs/v1_14"] v1_16 = ["v1_14", "cairo-sys-rs/v1_16"] default = ["use_glib"] xcb = ["cairo-sys-rs/xcb"] xlib = ["cairo-sys-rs/xlib"] dox = ["cairo-sys-rs/dox", "glib/dox"] [build-dependencies.gtk-rs-lgpl-docs] version = "0.1.8" optional = true [dependencies.glib] version = "0.8.0" optional = true [dependencies.glib-sys] version = "0.9.0" optional = true [dependencies.gobject-sys] version = "0.9.0" optional = true [dependencies] cairo-sys-rs = "0.9.0" libc = "0.2" bitflags = "1.0" [dev-dependencies] tempfile = "3.0" cairo-rs-0.7.1/Cargo.toml0000644000000035700000000000000106220ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g. crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] name = "cairo-rs" version = "0.7.1" authors = ["The Gtk-rs Project Developers"] build = "build.rs" description = "Rust bindings for the Cairo library" homepage = "http://gtk-rs.org/" documentation = "http://gtk-rs.org/docs/cairo/" readme = "README.md" keywords = ["cairo", "gtk-rs", "gnome", "GUI"] license = "MIT" repository = "https://github.com/gtk-rs/cairo" [lib] name = "cairo" [dependencies.bitflags] version = "1.0" [dependencies.cairo-sys-rs] version = "0.9.0" [dependencies.glib] version = "0.8.0" optional = true [dependencies.glib-sys] version = "0.9.0" optional = true [dependencies.gobject-sys] version = "0.9.0" optional = true [dependencies.libc] version = "0.2" [dev-dependencies.tempfile] version = "3.0" [build-dependencies.gtk-rs-lgpl-docs] version = "0.1.8" optional = true [features] default = ["use_glib"] dox = ["cairo-sys-rs/dox", "glib/dox"] embed-lgpl-docs = ["gtk-rs-lgpl-docs"] pdf = ["cairo-sys-rs/pdf"] png = ["cairo-sys-rs/png"] ps = ["cairo-sys-rs/ps"] purge-lgpl-docs = ["gtk-rs-lgpl-docs"] svg = ["cairo-sys-rs/svg"] use_glib = ["glib", "glib-sys", "gobject-sys", "cairo-sys-rs/use_glib"] v1_14 = ["cairo-sys-rs/v1_14"] v1_16 = ["v1_14", "cairo-sys-rs/v1_16"] xcb = ["cairo-sys-rs/xcb"] xlib = ["cairo-sys-rs/xlib"] [badges.appveyor] repository = "GuillaumeGomez/cairo" service = "github" [badges.travis-ci] repository = "gtk-rs/cairo" cairo-rs-0.7.1/Cargo.toml.orig0000644000000035710000000000000115620ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] name = "cairo-rs" version = "0.7.1" authors = ["The Gtk-rs Project Developers"] build = "build.rs" description = "Rust bindings for the Cairo library" homepage = "http://gtk-rs.org/" documentation = "http://gtk-rs.org/docs/cairo/" readme = "README.md" keywords = ["cairo", "gtk-rs", "gnome", "GUI"] license = "MIT" repository = "https://github.com/gtk-rs/cairo" [lib] name = "cairo" [dependencies.bitflags] version = "1.0" [dependencies.cairo-sys-rs] version = "0.9.0" [dependencies.glib] version = "0.8.0" optional = true [dependencies.glib-sys] version = "0.9.0" optional = true [dependencies.gobject-sys] version = "0.9.0" optional = true [dependencies.libc] version = "0.2" [dev-dependencies.tempfile] version = "3.0" [build-dependencies.gtk-rs-lgpl-docs] version = "0.1.8" optional = true [features] default = ["use_glib"] dox = ["cairo-sys-rs/dox", "glib/dox"] embed-lgpl-docs = ["gtk-rs-lgpl-docs"] pdf = ["cairo-sys-rs/pdf"] png = ["cairo-sys-rs/png"] ps = ["cairo-sys-rs/ps"] purge-lgpl-docs = ["gtk-rs-lgpl-docs"] svg = ["cairo-sys-rs/svg"] use_glib = ["glib", "glib-sys", "gobject-sys", "cairo-sys-rs/use_glib"] v1_14 = ["cairo-sys-rs/v1_14"] v1_16 = ["v1_14", "cairo-sys-rs/v1_16"] xcb = ["cairo-sys-rs/xcb"] xlib = ["cairo-sys-rs/xlib"] [badges.appveyor] repository = "GuillaumeGomez/cairo" service = "github" [badges.travis-ci] repository = "gtk-rs/cairo" cairo-rs-0.7.1/LICENSE010066400017500001750000000021201350466626300124740ustar0000000000000000The MIT License (MIT) Copyright (c) 2013-2015, The Gtk-rs Project Developers. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. cairo-rs-0.7.1/README.md010066400017500001750000000012271350466626500127570ustar0000000000000000# cairo [![Build Status](https://travis-ci.org/gtk-rs/cairo.png?branch=master)](https://travis-ci.org/gtk-rs/cairo) [![Build status](https://ci.appveyor.com/api/projects/status/9q998histb9vk2o2?svg=true)](https://ci.appveyor.com/project/GuillaumeGomez/cairo-p0df1) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/gtk-rs/gtk) Cairo bindings for Rust. - [Gtk-rs project site](http://gtk-rs.org/) - [Online documentation](http://gtk-rs.org/docs/) - [Readme](https://github.com/gtk-rs/gtk/blob/master/README.md) in our [main repo](https://github.com/gtk-rs/gtk) ![screenshot](http://guillaume-gomez.fr/image/cairo.png) ## License MIT cairo-rs-0.7.1/appveyor.yml010066400017500001750000000021561350466626300140700ustar0000000000000000environment: matrix: - RUST: stable BITS: 32 - RUST: stable BITS: 64 install: - IF "%BITS%" == "32" SET ARCH=i686 - IF "%BITS%" == "64" SET ARCH=x86_64 - curl -sSf -o rustup-init.exe https://win.rustup.rs - rustup-init.exe --default-host "%ARCH%-pc-windows-gnu" --default-toolchain %RUST% -y # Remove old dll that broke test. See https://github.com/gtk-rs/cairo/pull/160 - IF "%BITS%" == "32" ren C:\Users\appveyor\.rustup\toolchains\stable-i686-pc-windows-gnu\bin\libgcc_s_dw2-1.dll _libgcc_s_dw2-1.dll - SET PATH=C:\Users\appveyor\.cargo\bin;C:\msys64\mingw%BITS%\bin;%PATH%;C:\msys64\usr\bin - rustc -Vv - cargo -Vv - pacman -Sy - pacman --noconfirm -S mingw-w64-%ARCH%-gtk3 build_script: - cargo doc --features "dox" - cargo test --features "png,pdf,svg,pdf" - cargo test --no-default-features --features "png,pdf,svg,pdf" - mkdir .cargo - echo paths = [".", "./cairo-sys-rs"] > .cargo\config - git clone -q --depth 50 -b pending https://github.com/gtk-rs/examples _examples - cd _examples - cargo build - cargo build --features "cairo-rs/png gtk_3_24" test: false cairo-rs-0.7.1/build.rs010066400017500001750000000007531350466626500131500ustar0000000000000000fn main() { manage_docs(); } #[cfg(any(feature = "embed-lgpl-docs", feature = "purge-lgpl-docs"))] fn manage_docs() { extern crate lgpl_docs; const PATH: &'static str = "src"; const IGNORES: &'static [&'static str] = &[]; lgpl_docs::purge(PATH, IGNORES); if cfg!(feature = "embed-lgpl-docs") { lgpl_docs::embed(lgpl_docs::Library::Cairo, PATH, IGNORES); } } #[cfg(not(any(feature = "embed-lgpl-docs", feature = "purge-lgpl-docs")))] fn manage_docs() {} cairo-rs-0.7.1/src/constants.rs010066400017500001750000000030431350466626300146450ustar0000000000000000// Copyright 2013-2019, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or pub const MIME_TYPE_JPEG: &str = "image/jpeg"; pub const MIME_TYPE_PNG: &str = "image/png"; pub const MIME_TYPE_JP2: &str = "image/jp2"; pub const MIME_TYPE_URI: &str = "text/x-uri"; pub const MIME_TYPE_UNIQUE_ID: &str = "application/x-cairo.uuid"; #[cfg(any(feature = "v1_14", feature = "dox"))] pub const MIME_TYPE_JBIG2: &str = "application/x-cairo.jbig2"; #[cfg(any(feature = "v1_14", feature = "dox"))] pub const MIME_TYPE_JBIG2_GLOBAL: &str = "application/x-cairo.jbig2-global"; #[cfg(any(feature = "v1_14", feature = "dox"))] pub const MIME_TYPE_JBIG2_GLOBAL_ID: &str = "application/x-cairo.jbig2-global-id"; #[cfg(any(feature = "v1_16", feature = "dox"))] pub const MIME_TYPE_CCITT_FAX: &str = "image/g3fax"; #[cfg(any(feature = "v1_16", feature = "dox"))] pub const MIME_TYPE_CCITT_FAX_PARAMS: &str = "application/x-cairo.ccitt.params"; #[cfg(any(feature = "v1_16", feature = "dox"))] pub const MIME_TYPE_EPS: &str = "application/postscript"; #[cfg(any(feature = "v1_16", feature = "dox"))] pub const MIME_TYPE_EPS_PARAMS: &str = "application/x-cairo.eps.params"; #[cfg(any(feature = "v1_16", feature = "dox"))] pub const PDF_OUTLINE_ROOT: i32 = 0; #[cfg(any(feature = "v1_16", feature = "dox"))] pub const CAIRO_TAG_DEST: &str = "cairo.dest"; #[cfg(any(feature = "v1_16", feature = "dox"))] pub const CAIRO_TAG_LINK: &str = "Link"; cairo-rs-0.7.1/src/context.rs010066400017500001750000000522201350734563600143170ustar0000000000000000// Copyright 2013-2015, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use ffi; use font::{FontExtents, FontFace, FontOptions, Glyph, ScaledFont, TextCluster, TextExtents}; #[cfg(feature = "use_glib")] use glib::translate::*; use libc::c_int; use matrices::Matrix; use paths::Path; use std::ffi::CString; use std::fmt; use std::ops; use std::slice; use Rectangle; use { Antialias, Content, FillRule, FontSlant, FontWeight, LineCap, LineJoin, Operator, Status, TextClusterFlags, }; use ffi::{cairo_rectangle_list_t, cairo_t}; use patterns::Pattern; use surface::Surface; pub struct RectangleList { ptr: *mut cairo_rectangle_list_t, } impl ops::Deref for RectangleList { type Target = [Rectangle]; fn deref(&self) -> &[Rectangle] { unsafe { let ptr = (*self.ptr).rectangles as *mut Rectangle; let len = (*self.ptr).num_rectangles; if ptr.is_null() || len == 0 { &[] } else { slice::from_raw_parts(ptr, len as usize) } } } } impl Drop for RectangleList { fn drop(&mut self) { unsafe { ffi::cairo_rectangle_list_destroy(self.ptr); } } } impl fmt::Debug for RectangleList { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("RectangleList").field(&*self).finish() } } impl fmt::Display for RectangleList { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "RectangleList") } } #[derive(Debug)] pub struct Context(*mut cairo_t, bool); #[cfg(feature = "use_glib")] impl<'a> ToGlibPtr<'a, *mut ffi::cairo_t> for &'a Context { type Storage = &'a Context; #[inline] fn to_glib_none(&self) -> Stash<'a, *mut ffi::cairo_t, &'a Context> { Stash(self.0, *self) } #[inline] fn to_glib_full(&self) -> *mut ffi::cairo_t { unsafe { ffi::cairo_reference(self.0) } } } #[cfg(feature = "use_glib")] impl FromGlibPtrNone<*mut ffi::cairo_t> for Context { #[inline] unsafe fn from_glib_none(ptr: *mut ffi::cairo_t) -> Context { Self::from_raw_none(ptr) } } #[cfg(feature = "use_glib")] impl FromGlibPtrBorrow<*mut ffi::cairo_t> for Context { #[inline] unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_t) -> Context { Self::from_raw_borrow(ptr) } } #[cfg(feature = "use_glib")] impl FromGlibPtrFull<*mut ffi::cairo_t> for Context { #[inline] unsafe fn from_glib_full(ptr: *mut ffi::cairo_t) -> Context { Self::from_raw_full(ptr) } } #[cfg(feature = "use_glib")] gvalue_impl!( Context, cairo_t, ffi::gobject::cairo_gobject_context_get_type ); impl Clone for Context { fn clone(&self) -> Context { unsafe { Self::from_raw_none(self.to_raw_none()) } } } impl Drop for Context { fn drop(&mut self) { if !self.1 { unsafe { ffi::cairo_destroy(self.0); } } } } impl Context { #[inline] pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_t) -> Context { assert!(!ptr.is_null()); ffi::cairo_reference(ptr); Context(ptr, false) } #[inline] pub unsafe fn from_raw_borrow(ptr: *mut ffi::cairo_t) -> Context { assert!(!ptr.is_null()); Context(ptr, true) } #[inline] pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_t) -> Context { assert!(!ptr.is_null()); Context(ptr, false) } pub fn to_raw_none(&self) -> *mut ffi::cairo_t { self.0 } pub fn ensure_status(&self) { self.status().ensure_valid(); } pub fn new(target: &Surface) -> Context { unsafe { Self::from_raw_full(ffi::cairo_create(target.to_raw_none())) } } pub fn status(&self) -> Status { unsafe { Status::from(ffi::cairo_status(self.0)) } } pub fn save(&self) { unsafe { ffi::cairo_save(self.0) } self.ensure_status() } pub fn restore(&self) { unsafe { ffi::cairo_restore(self.0) } self.ensure_status() } pub fn get_target(&self) -> Surface { unsafe { Surface::from_raw_none(ffi::cairo_get_target(self.0)) } } pub fn push_group(&self) { unsafe { ffi::cairo_push_group(self.0) } } pub fn push_group_with_content(&self, content: Content) { unsafe { ffi::cairo_push_group_with_content(self.0, content.into()) } } pub fn pop_group(&self) -> Pattern { unsafe { Pattern::from_raw_full(ffi::cairo_pop_group(self.0)) } } pub fn pop_group_to_source(&self) { unsafe { ffi::cairo_pop_group_to_source(self.0) } } pub fn get_group_target(&self) -> Surface { unsafe { Surface::from_raw_none(ffi::cairo_get_group_target(self.0)) } } pub fn set_source_rgb(&self, red: f64, green: f64, blue: f64) { unsafe { ffi::cairo_set_source_rgb(self.0, red, green, blue) } } pub fn set_source_rgba(&self, red: f64, green: f64, blue: f64, alpha: f64) { unsafe { ffi::cairo_set_source_rgba(self.0, red, green, blue, alpha) } } pub fn set_source(&self, source: &Pattern) { unsafe { ffi::cairo_set_source(self.0, source.to_raw_none()); } self.ensure_status(); } pub fn get_source(&self) -> Pattern { unsafe { Pattern::from_raw_none(ffi::cairo_get_source(self.0)) } } pub fn set_source_surface(&self, surface: &Surface, x: f64, y: f64) { unsafe { ffi::cairo_set_source_surface(self.0, surface.to_raw_none(), x, y); } } pub fn set_antialias(&self, antialias: Antialias) { unsafe { ffi::cairo_set_antialias(self.0, antialias.into()) } self.ensure_status() } pub fn get_antialias(&self) -> Antialias { unsafe { Antialias::from(ffi::cairo_get_antialias(self.0)) } } pub fn set_dash(&self, dashes: &[f64], offset: f64) { unsafe { ffi::cairo_set_dash(self.0, dashes.as_ptr(), dashes.len() as i32, offset) } self.ensure_status(); //Possible invalid dashes value } pub fn get_dash_count(&self) -> i32 { unsafe { ffi::cairo_get_dash_count(self.0) } } pub fn get_dash(&self) -> (Vec, f64) { let dash_count = self.get_dash_count() as usize; let mut dashes: Vec = Vec::with_capacity(dash_count); let mut offset: f64 = 0.0; unsafe { ffi::cairo_get_dash(self.0, dashes.as_mut_ptr(), &mut offset); dashes.set_len(dash_count); (dashes, offset) } } pub fn get_dash_dashes(&self) -> Vec { let (dashes, _) = self.get_dash(); dashes } pub fn get_dash_offset(&self) -> f64 { let (_, offset) = self.get_dash(); offset } pub fn set_fill_rule(&self, fill_rule: FillRule) { unsafe { ffi::cairo_set_fill_rule(self.0, fill_rule.into()); } self.ensure_status(); } pub fn get_fill_rule(&self) -> FillRule { unsafe { FillRule::from(ffi::cairo_get_fill_rule(self.0)) } } pub fn set_line_cap(&self, arg: LineCap) { unsafe { ffi::cairo_set_line_cap(self.0, arg.into()) } self.ensure_status(); } pub fn get_line_cap(&self) -> LineCap { unsafe { LineCap::from(ffi::cairo_get_line_cap(self.0)) } } pub fn set_line_join(&self, arg: LineJoin) { unsafe { ffi::cairo_set_line_join(self.0, arg.into()) } self.ensure_status(); } pub fn get_line_join(&self) -> LineJoin { unsafe { LineJoin::from(ffi::cairo_get_line_join(self.0)) } } pub fn set_line_width(&self, arg: f64) { unsafe { ffi::cairo_set_line_width(self.0, arg) } self.ensure_status(); } pub fn get_line_width(&self) -> f64 { unsafe { ffi::cairo_get_line_width(self.0) } } pub fn set_miter_limit(&self, arg: f64) { unsafe { ffi::cairo_set_miter_limit(self.0, arg) } self.ensure_status(); } pub fn get_miter_limit(&self) -> f64 { unsafe { ffi::cairo_get_miter_limit(self.0) } } pub fn set_operator(&self, op: Operator) { unsafe { ffi::cairo_set_operator(self.0, op.into()); } } pub fn get_operator(&self) -> Operator { unsafe { Operator::from(ffi::cairo_get_operator(self.0)) } } pub fn set_tolerance(&self, arg: f64) { unsafe { ffi::cairo_set_tolerance(self.0, arg) } self.ensure_status(); } pub fn get_tolerance(&self) -> f64 { unsafe { ffi::cairo_get_tolerance(self.0) } } pub fn clip(&self) { unsafe { ffi::cairo_clip(self.0) } } pub fn clip_preserve(&self) { unsafe { ffi::cairo_clip_preserve(self.0) } } pub fn clip_extents(&self) -> (f64, f64, f64, f64) { let mut x1: f64 = 0.0; let mut y1: f64 = 0.0; let mut x2: f64 = 0.0; let mut y2: f64 = 0.0; unsafe { ffi::cairo_clip_extents(self.0, &mut x1, &mut y1, &mut x2, &mut y2); } (x1, y1, x2, y2) } pub fn in_clip(&self, x: f64, y: f64) -> bool { unsafe { ffi::cairo_in_clip(self.0, x, y).as_bool() } } pub fn reset_clip(&self) { unsafe { ffi::cairo_reset_clip(self.0) } self.ensure_status() } pub fn copy_clip_rectangle_list(&self) -> RectangleList { unsafe { let rectangle_list = ffi::cairo_copy_clip_rectangle_list(self.0); Status::from((*rectangle_list).status).ensure_valid(); RectangleList { ptr: rectangle_list, } } } pub fn fill(&self) { unsafe { ffi::cairo_fill(self.0) } } pub fn fill_preserve(&self) { unsafe { ffi::cairo_fill_preserve(self.0) } } pub fn fill_extents(&self) -> (f64, f64, f64, f64) { let mut x1: f64 = 0.0; let mut y1: f64 = 0.0; let mut x2: f64 = 0.0; let mut y2: f64 = 0.0; unsafe { ffi::cairo_fill_extents(self.0, &mut x1, &mut y1, &mut x2, &mut y2); } (x1, y1, x2, y2) } pub fn in_fill(&self, x: f64, y: f64) -> bool { unsafe { ffi::cairo_in_fill(self.0, x, y).as_bool() } } pub fn mask(&self, pattern: &Pattern) { unsafe { ffi::cairo_mask(self.0, pattern.to_raw_none()) } } pub fn mask_surface(&self, surface: &Surface, x: f64, y: f64) { unsafe { ffi::cairo_mask_surface(self.0, surface.to_raw_none(), x, y); } } pub fn paint(&self) { unsafe { ffi::cairo_paint(self.0) } } pub fn paint_with_alpha(&self, alpha: f64) { unsafe { ffi::cairo_paint_with_alpha(self.0, alpha) } } pub fn stroke(&self) { unsafe { ffi::cairo_stroke(self.0) } } pub fn stroke_preserve(&self) { unsafe { ffi::cairo_stroke_preserve(self.0) } } pub fn stroke_extents(&self) -> (f64, f64, f64, f64) { let mut x1: f64 = 0.0; let mut y1: f64 = 0.0; let mut x2: f64 = 0.0; let mut y2: f64 = 0.0; unsafe { ffi::cairo_stroke_extents(self.0, &mut x1, &mut y1, &mut x2, &mut y2); } (x1, y1, x2, y2) } pub fn in_stroke(&self, x: f64, y: f64) -> bool { unsafe { ffi::cairo_in_stroke(self.0, x, y).as_bool() } } pub fn copy_page(&self) { unsafe { ffi::cairo_copy_page(self.0) } } pub fn show_page(&self) { unsafe { ffi::cairo_show_page(self.0) } } pub fn get_reference_count(&self) -> u32 { unsafe { ffi::cairo_get_reference_count(self.0) } } // transformations stuff pub fn translate(&self, tx: f64, ty: f64) { unsafe { ffi::cairo_translate(self.0, tx, ty) } } pub fn scale(&self, sx: f64, sy: f64) { unsafe { ffi::cairo_scale(self.0, sx, sy) } } pub fn rotate(&self, angle: f64) { unsafe { ffi::cairo_rotate(self.0, angle) } } pub fn transform(&self, matrix: Matrix) { unsafe { ffi::cairo_transform(self.0, matrix.ptr()); } } pub fn set_matrix(&self, matrix: Matrix) { unsafe { ffi::cairo_set_matrix(self.0, matrix.ptr()); } } pub fn get_matrix(&self) -> Matrix { let mut matrix = Matrix::null(); unsafe { ffi::cairo_get_matrix(self.0, matrix.mut_ptr()); } matrix } pub fn identity_matrix(&self) { unsafe { ffi::cairo_identity_matrix(self.0) } } pub fn user_to_device(&self, mut x: f64, mut y: f64) -> (f64, f64) { unsafe { ffi::cairo_user_to_device(self.0, &mut x, &mut y); (x, y) } } pub fn user_to_device_distance(&self, mut dx: f64, mut dy: f64) -> (f64, f64) { unsafe { ffi::cairo_user_to_device_distance(self.0, &mut dx, &mut dy); (dx, dy) } } pub fn device_to_user(&self, mut x: f64, mut y: f64) -> (f64, f64) { unsafe { ffi::cairo_device_to_user(self.0, &mut x, &mut y); (x, y) } } pub fn device_to_user_distance(&self, mut dx: f64, mut dy: f64) -> (f64, f64) { unsafe { ffi::cairo_device_to_user_distance(self.0, &mut dx, &mut dy); (dx, dy) } } // font stuff pub fn select_font_face(&self, family: &str, slant: FontSlant, weight: FontWeight) { unsafe { let family = CString::new(family).unwrap(); ffi::cairo_select_font_face(self.0, family.as_ptr(), slant.into(), weight.into()) } } pub fn set_font_size(&self, size: f64) { unsafe { ffi::cairo_set_font_size(self.0, size) } } // FIXME probably needs a heap allocation pub fn set_font_matrix(&self, matrix: Matrix) { unsafe { ffi::cairo_set_font_matrix(self.0, matrix.ptr()) } } pub fn get_font_matrix(&self) -> Matrix { let mut matrix = Matrix::null(); unsafe { ffi::cairo_get_font_matrix(self.0, matrix.mut_ptr()); } matrix } pub fn set_font_options(&self, options: &FontOptions) { unsafe { ffi::cairo_set_font_options(self.0, options.to_raw_none()) } } pub fn get_font_options(&self) -> FontOptions { let out = FontOptions::new(); unsafe { ffi::cairo_get_font_options(self.0, out.to_raw_none()); } out } pub fn set_font_face(&self, font_face: &FontFace) { unsafe { ffi::cairo_set_font_face(self.0, font_face.to_raw_none()) } } pub fn get_font_face(&self) -> FontFace { unsafe { FontFace::from_raw_none(ffi::cairo_get_font_face(self.0)) } } pub fn set_scaled_font(&self, scaled_font: &ScaledFont) { unsafe { ffi::cairo_set_scaled_font(self.0, scaled_font.to_raw_none()) } } pub fn get_scaled_font(&self) -> ScaledFont { unsafe { ScaledFont::from_raw_none(ffi::cairo_get_scaled_font(self.0)) } } pub fn show_text(&self, text: &str) { unsafe { let text = CString::new(text).unwrap(); ffi::cairo_show_text(self.0, text.as_ptr()) } } pub fn show_glyphs(&self, glyphs: &[Glyph]) { unsafe { ffi::cairo_show_glyphs(self.0, glyphs.as_ptr(), glyphs.len() as c_int) } } pub fn show_text_glyphs( &self, text: &str, glyphs: &[Glyph], clusters: &[TextCluster], cluster_flags: TextClusterFlags, ) { unsafe { let text = CString::new(text).unwrap(); ffi::cairo_show_text_glyphs( self.0, text.as_ptr(), -1 as c_int, //NULL terminated glyphs.as_ptr(), glyphs.len() as c_int, clusters.as_ptr(), clusters.len() as c_int, cluster_flags.into(), ) } } pub fn font_extents(&self) -> FontExtents { let mut extents = FontExtents { ascent: 0.0, descent: 0.0, height: 0.0, max_x_advance: 0.0, max_y_advance: 0.0, }; unsafe { ffi::cairo_font_extents(self.0, &mut extents); } extents } pub fn text_extents(&self, text: &str) -> TextExtents { let mut extents = TextExtents { x_bearing: 0.0, y_bearing: 0.0, width: 0.0, height: 0.0, x_advance: 0.0, y_advance: 0.0, }; unsafe { let text = CString::new(text).unwrap(); ffi::cairo_text_extents(self.0, text.as_ptr(), &mut extents); } extents } pub fn glyph_extents(&self, glyphs: &[Glyph]) -> TextExtents { let mut extents = TextExtents { x_bearing: 0.0, y_bearing: 0.0, width: 0.0, height: 0.0, x_advance: 0.0, y_advance: 0.0, }; unsafe { ffi::cairo_glyph_extents(self.0, glyphs.as_ptr(), glyphs.len() as c_int, &mut extents); } extents } // paths stuff pub fn copy_path(&self) -> Path { unsafe { Path::from_raw_full(ffi::cairo_copy_path(self.0)) } } pub fn copy_path_flat(&self) -> Path { unsafe { Path::from_raw_full(ffi::cairo_copy_path_flat(self.0)) } } pub fn append_path(&self, path: &Path) { unsafe { ffi::cairo_append_path(self.0, path.as_ptr()) } } pub fn has_current_point(&self) -> bool { unsafe { ffi::cairo_has_current_point(self.0).as_bool() } } pub fn get_current_point(&self) -> (f64, f64) { unsafe { let mut x = 0.0; let mut y = 0.0; ffi::cairo_get_current_point(self.0, &mut x, &mut y); (x, y) } } pub fn new_path(&self) { unsafe { ffi::cairo_new_path(self.0) } } pub fn new_sub_path(&self) { unsafe { ffi::cairo_new_sub_path(self.0) } } pub fn close_path(&self) { unsafe { ffi::cairo_close_path(self.0) } } pub fn arc(&self, xc: f64, yc: f64, radius: f64, angle1: f64, angle2: f64) { unsafe { ffi::cairo_arc(self.0, xc, yc, radius, angle1, angle2) } } pub fn arc_negative(&self, xc: f64, yc: f64, radius: f64, angle1: f64, angle2: f64) { unsafe { ffi::cairo_arc_negative(self.0, xc, yc, radius, angle1, angle2) } } pub fn curve_to(&self, x1: f64, y1: f64, x2: f64, y2: f64, x3: f64, y3: f64) { unsafe { ffi::cairo_curve_to(self.0, x1, y1, x2, y2, x3, y3) } } pub fn line_to(&self, x: f64, y: f64) { unsafe { ffi::cairo_line_to(self.0, x, y) } } pub fn move_to(&self, x: f64, y: f64) { unsafe { ffi::cairo_move_to(self.0, x, y) } } pub fn rectangle(&self, x: f64, y: f64, width: f64, height: f64) { unsafe { ffi::cairo_rectangle(self.0, x, y, width, height) } } pub fn text_path(&self, str_: &str) { unsafe { let str_ = CString::new(str_).unwrap(); ffi::cairo_text_path(self.0, str_.as_ptr()) } } pub fn glyph_path(&self, glyphs: &[Glyph]) { unsafe { ffi::cairo_glyph_path(self.0, glyphs.as_ptr(), glyphs.len() as i32) } } pub fn rel_curve_to(&self, dx1: f64, dy1: f64, dx2: f64, dy2: f64, dx3: f64, dy3: f64) { unsafe { ffi::cairo_rel_curve_to(self.0, dx1, dy1, dx2, dy2, dx3, dy3) } } pub fn rel_line_to(&self, dx: f64, dy: f64) { unsafe { ffi::cairo_rel_line_to(self.0, dx, dy) } } pub fn rel_move_to(&self, dx: f64, dy: f64) { unsafe { ffi::cairo_rel_move_to(self.0, dx, dy) } } pub fn path_extents(&self) -> (f64, f64, f64, f64) { let mut x1: f64 = 0.0; let mut y1: f64 = 0.0; let mut x2: f64 = 0.0; let mut y2: f64 = 0.0; unsafe { ffi::cairo_path_extents(self.0, &mut x1, &mut y1, &mut x2, &mut y2); } (x1, y1, x2, y2) } #[cfg(any(feature = "v1_16", feature = "dox"))] pub fn tag_begin(&self, tag_name: &str, attributes: &str) { unsafe { let tag_name = CString::new(tag_name).unwrap(); let attributes = CString::new(attributes).unwrap(); ffi::cairo_tag_begin(self.0, tag_name.as_ptr(), attributes.as_ptr()) } } #[cfg(any(feature = "v1_16", feature = "dox"))] pub fn tag_end(&self, tag_name: &str) { unsafe { let tag_name = CString::new(tag_name).unwrap(); ffi::cairo_tag_end(self.0, tag_name.as_ptr()) } } } impl fmt::Display for Context { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Context") } } #[cfg(test)] mod tests { use super::*; use enums::Format; use image_surface::ImageSurface; use patterns::LinearGradient; fn create_ctx() -> Context { let surface = ImageSurface::create(Format::ARgb32, 10, 10).unwrap(); Context::new(&surface) } #[test] fn drop_non_reference_pattern_from_ctx() { let ctx = create_ctx(); ctx.get_source(); } #[test] fn drop_non_reference_pattern() { let ctx = create_ctx(); let pattern = LinearGradient::new(1.0f64, 2.0f64, 3.0f64, 4.0f64); ctx.set_source(&pattern); } } cairo-rs-0.7.1/src/device.rs010066400017500001750000000233141350734563600140740ustar0000000000000000// Copyright 2015-2016, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use std::ffi::CString; use std::path::Path; use enums::{Content, DeviceType, ScriptMode, Status}; use ffi; #[cfg(feature = "use_glib")] use glib::translate::*; use recording_surface::RecordingSurface; use std::fmt; use surface::Surface; #[derive(Debug)] pub struct Device(*mut ffi::cairo_device_t, bool); impl Device { pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_device_t) -> Device { assert!(!ptr.is_null()); ffi::cairo_device_reference(ptr); Device(ptr, false) } pub unsafe fn from_raw_borrow(ptr: *mut ffi::cairo_device_t) -> Device { assert!(!ptr.is_null()); Device(ptr, true) } pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_device_t) -> Device { assert!(!ptr.is_null()); Device(ptr, false) } pub fn to_raw_none(&self) -> *mut ffi::cairo_device_t { self.0 } pub fn create>(filename: P) -> Option { unsafe { let filename = filename.as_ref().to_string_lossy().into_owned(); let filename = CString::new(filename).unwrap(); let p = ffi::cairo_script_create(filename.as_ptr()); if p.is_null() { None } else { Some(Self::from_raw_full(p)) } } } pub fn from_recording_surface(&self, surface: &RecordingSurface) -> Status { unsafe { Status::from(ffi::cairo_script_from_recording_surface( self.to_raw_none(), surface.to_raw_none(), )) } } pub fn get_mode(&self) -> ScriptMode { unsafe { ScriptMode::from(ffi::cairo_script_get_mode(self.to_raw_none())) } } pub fn set_mode(&self, mode: ScriptMode) { unsafe { ffi::cairo_script_set_mode(self.to_raw_none(), mode.into()) } } pub fn surface_create(&self, content: Content, width: f64, height: f64) -> Option { unsafe { let p = ffi::cairo_script_surface_create(self.to_raw_none(), content.into(), width, height); if p.is_null() { None } else { Some(Surface::from_raw_full(p)) } } } pub fn surface_create_for_target(&self, target: &Surface) -> Option { unsafe { let p = ffi::cairo_script_surface_create_for_target( self.to_raw_none(), target.to_raw_none(), ); if p.is_null() { None } else { Some(Surface::from_raw_full(p)) } } } pub fn write_comment(&self, comment: &str) { unsafe { let len = comment.len(); let comment = CString::new(comment).unwrap(); ffi::cairo_script_write_comment(self.to_raw_none(), comment.as_ptr(), len as i32) } } pub fn status(&self) -> Status { unsafe { Status::from(ffi::cairo_device_status(self.to_raw_none())) } } pub fn finish(&self) { unsafe { ffi::cairo_device_finish(self.to_raw_none()) } } pub fn flush(&self) { unsafe { ffi::cairo_device_flush(self.to_raw_none()) } } pub fn get_type(&self) -> DeviceType { unsafe { DeviceType::from(ffi::cairo_device_get_type(self.to_raw_none())) } } // Maybe improve this API? pub fn acquire(&self) -> Status { unsafe { Status::from(ffi::cairo_device_acquire(self.to_raw_none())) } } // Maybe improve this API? pub fn release(&self) { unsafe { ffi::cairo_device_release(self.to_raw_none()) } } pub fn observer_elapsed(&self) -> f64 { unsafe { ffi::cairo_device_observer_elapsed(self.to_raw_none()) } } pub fn observer_fill_elapsed(&self) -> f64 { unsafe { ffi::cairo_device_observer_fill_elapsed(self.to_raw_none()) } } pub fn observer_glyphs_elapsed(&self) -> f64 { unsafe { ffi::cairo_device_observer_glyphs_elapsed(self.to_raw_none()) } } pub fn observer_mask_elapsed(&self) -> f64 { unsafe { ffi::cairo_device_observer_mask_elapsed(self.to_raw_none()) } } pub fn observer_paint_elapsed(&self) -> f64 { unsafe { ffi::cairo_device_observer_paint_elapsed(self.to_raw_none()) } } pub fn observer_stroke_elapsed(&self) -> f64 { unsafe { ffi::cairo_device_observer_stroke_elapsed(self.to_raw_none()) } } #[cfg(any(feature = "xlib", feature = "xcb", feature = "dox"))] pub fn debug_cap_xrender_version(&self, major_version: i32, minor_version: i32) { unsafe { match self.get_type() { DeviceType::Xlib => { #[cfg(feature = "xlib")] { ffi::cairo_xlib_device_debug_cap_xrender_version( self.to_raw_none(), major_version, minor_version, ) } #[cfg(not(feature = "xlib"))] { panic!("you need to enable \"xlib\" feature") } } DeviceType::Xcb => { #[cfg(feature = "xcb")] { ffi::cairo_xcb_device_debug_cap_xrender_version( self.to_raw_none(), major_version, minor_version, ) } #[cfg(not(feature = "xcb"))] { panic!("you need to enable \"xcb\" feature") } } d => panic!("invalid device type: {}", d), } } } #[cfg(any(feature = "xlib", feature = "xcb", feature = "dox"))] pub fn debug_get_precision(&self) -> i32 { unsafe { match self.get_type() { DeviceType::Xlib => { #[cfg(feature = "xlib")] { ffi::cairo_xlib_device_debug_get_precision(self.to_raw_none()) } #[cfg(not(feature = "xlib"))] { panic!("you need to enable \"xlib\" feature") } } DeviceType::Xcb => { #[cfg(feature = "xcb")] { ffi::cairo_xcb_device_debug_get_precision(self.to_raw_none()) } #[cfg(not(feature = "xcb"))] { panic!("you need to enable \"xcb\" feature") } } d => panic!("invalid device type: {}", d), } } } #[cfg(any(feature = "xlib", feature = "xcb", feature = "dox"))] pub fn debug_set_precision(&self, precision: i32) { unsafe { match self.get_type() { DeviceType::Xlib => { #[cfg(feature = "xlib")] { ffi::cairo_xlib_device_debug_set_precision(self.to_raw_none(), precision) } #[cfg(not(feature = "xlib"))] { panic!("you need to enable \"xlib\" feature") } } DeviceType::Xcb => { #[cfg(feature = "xcb")] { ffi::cairo_xcb_device_debug_set_precision(self.to_raw_none(), precision) } #[cfg(not(feature = "xcb"))] { panic!("you need to enable \"xcb\" feature") } } d => panic!("invalid device type: {}", d), } } } user_data_methods! { ffi::cairo_device_get_user_data, ffi::cairo_device_set_user_data, } } #[cfg(feature = "use_glib")] impl<'a> ToGlibPtr<'a, *mut ffi::cairo_device_t> for Device { type Storage = &'a Device; #[inline] fn to_glib_none(&'a self) -> Stash<'a, *mut ffi::cairo_device_t, Self> { Stash(self.to_raw_none(), self) } #[inline] fn to_glib_full(&self) -> *mut ffi::cairo_device_t { unsafe { ffi::cairo_device_reference(self.to_raw_none()) } } } #[cfg(feature = "use_glib")] impl FromGlibPtrNone<*mut ffi::cairo_device_t> for Device { #[inline] unsafe fn from_glib_none(ptr: *mut ffi::cairo_device_t) -> Device { Self::from_raw_none(ptr) } } #[cfg(feature = "use_glib")] impl FromGlibPtrBorrow<*mut ffi::cairo_device_t> for Device { #[inline] unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_device_t) -> Device { Self::from_raw_borrow(ptr) } } #[cfg(feature = "use_glib")] impl FromGlibPtrFull<*mut ffi::cairo_device_t> for Device { #[inline] unsafe fn from_glib_full(ptr: *mut ffi::cairo_device_t) -> Device { Self::from_raw_full(ptr) } } #[cfg(feature = "use_glib")] gvalue_impl!( Device, ffi::cairo_device_t, ffi::gobject::cairo_gobject_device_get_type ); impl Clone for Device { fn clone(&self) -> Device { unsafe { Self::from_raw_none(ffi::cairo_device_reference(self.0)) } } } impl Drop for Device { fn drop(&mut self) { if !self.1 { unsafe { ffi::cairo_device_destroy(self.0); } } } } impl fmt::Display for Device { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Device") } } cairo-rs-0.7.1/src/enums.rs010066400017500001750000002050021350734563600137600ustar0000000000000000// Copyright 2013-2019, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use std::ffi::CStr; use std::fmt::{self, Debug, Error}; use std::i32; use std::u32; use ffi; #[cfg(feature = "use_glib")] use glib; #[cfg(feature = "use_glib")] use glib::translate::*; #[cfg(feature = "use_glib")] use gobject_ffi; // Helper macro for our GValue related trait impls #[cfg(feature = "use_glib")] macro_rules! gvalue_impl { ($name:ty, $get_type:expr) => { impl glib::types::StaticType for $name { fn static_type() -> glib::Type { unsafe { from_glib($get_type()) } } } impl<'a> glib::value::FromValueOptional<'a> for $name { unsafe fn from_value_optional(value: &glib::value::Value) -> Option { Some(glib::value::FromValue::from_value(value)) } } impl<'a> glib::value::FromValue<'a> for $name { unsafe fn from_value(value: &glib::value::Value) -> Self { Self::from(gobject_ffi::g_value_get_enum(value.to_glib_none().0)) } } impl glib::value::SetValue for $name { unsafe fn set_value(value: &mut glib::value::Value, this: &Self) { gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, (*this).into()) } } }; } #[derive(Clone, Copy, PartialEq, Eq)] pub enum Status { Success, NoMemory, InvalidRestore, InvalidPopGroup, NoCurrentPoint, InvalidMatrix, InvalidStatus, NullPointer, InvalidString, InvalidPathData, ReadError, WriteError, SurfaceFinished, SurfaceTypeMismatch, PatternTypeMismatch, InvalidContent, InvalidFormat, InvalidVisual, FileNotFound, InvalidDash, InvalidDscComment, InvalidIndex, ClipNotRepresentable, TempFileError, InvalidStride, FontTypeMismatch, UserFontImmutable, UserFontError, NegativeCount, InvalidClusters, InvalidSlant, InvalidWeight, InvalidSize, UserFontNotImplemented, DeviceTypeMismatch, DeviceError, InvalidMeshConstruction, DeviceFinished, // CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID has been used on at least one image but no // image provided `JBig2Global` (Since 1.14) JBig2GlobalMissing, PngError, FreetypeError, Win32GdiError, LastStatus, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for Status { fn into(self) -> ffi::cairo_status_t { match self { Status::Success => ffi::STATUS_SUCCESS, Status::NoMemory => ffi::STATUS_NO_MEMORY, Status::InvalidRestore => ffi::STATUS_INVALID_RESTORE, Status::InvalidPopGroup => ffi::STATUS_INVALID_POP_GROUP, Status::NoCurrentPoint => ffi::STATUS_NO_CURRENT_POINT, Status::InvalidMatrix => ffi::STATUS_INVALID_MATRIX, Status::InvalidStatus => ffi::STATUS_INVALID_STATUS, Status::NullPointer => ffi::STATUS_NULL_POINTER, Status::InvalidString => ffi::STATUS_INVALID_STRING, Status::InvalidPathData => ffi::STATUS_INVALID_PATH_DATA, Status::ReadError => ffi::STATUS_READ_ERROR, Status::WriteError => ffi::STATUS_WRITE_ERROR, Status::SurfaceFinished => ffi::STATUS_SURFACE_FINISHED, Status::SurfaceTypeMismatch => ffi::STATUS_SURFACE_TYPE_MISMATCH, Status::PatternTypeMismatch => ffi::STATUS_PATTERN_TYPE_MISMATCH, Status::InvalidContent => ffi::STATUS_INVALID_CONTENT, Status::InvalidFormat => ffi::STATUS_INVALID_FORMAT, Status::InvalidVisual => ffi::STATUS_INVALID_VISUAL, Status::FileNotFound => ffi::STATUS_FILE_NOT_FOUND, Status::InvalidDash => ffi::STATUS_INVALID_DASH, Status::InvalidDscComment => ffi::STATUS_INVALID_DSC_COMMENT, Status::InvalidIndex => ffi::STATUS_INVALID_INDEX, Status::ClipNotRepresentable => ffi::STATUS_CLIP_NOT_REPRESENTABLE, Status::TempFileError => ffi::STATUS_TEMP_FILE_ERROR, Status::InvalidStride => ffi::STATUS_INVALID_STRIDE, Status::FontTypeMismatch => ffi::STATUS_FONT_TYPE_MISMATCH, Status::UserFontImmutable => ffi::STATUS_USER_FONT_IMMUTABLE, Status::UserFontError => ffi::STATUS_USER_FONT_ERROR, Status::NegativeCount => ffi::STATUS_NEGATIVE_COUNT, Status::InvalidClusters => ffi::STATUS_INVALID_CLUSTERS, Status::InvalidSlant => ffi::STATUS_INVALID_SLANT, Status::InvalidWeight => ffi::STATUS_INVALID_WEIGHT, Status::InvalidSize => ffi::STATUS_INVALID_SIZE, Status::UserFontNotImplemented => ffi::STATUS_USER_FONT_NOT_IMPLEMENTED, Status::DeviceTypeMismatch => ffi::STATUS_DEVICE_TYPE_MISMATCH, Status::DeviceError => ffi::STATUS_DEVICE_ERROR, Status::InvalidMeshConstruction => ffi::STATUS_INVALID_MESH_CONSTRUCTION, Status::DeviceFinished => ffi::STATUS_DEVICE_FINISHED, Status::JBig2GlobalMissing => ffi::STATUS_J_BIG2_GLOBAL_MISSING, Status::PngError => ffi::STATUS_PNG_ERROR, Status::FreetypeError => ffi::STATUS_FREETYPE_ERROR, Status::Win32GdiError => ffi::STATUS_WIN32_GDI_ERROR, Status::LastStatus => ffi::STATUS_LAST_STATUS, Status::__Unknown(value) => value, } } } #[doc(hidden)] impl From for Status { fn from(value: ffi::cairo_status_t) -> Self { match value { ffi::STATUS_SUCCESS => Status::Success, ffi::STATUS_NO_MEMORY => Status::NoMemory, ffi::STATUS_INVALID_RESTORE => Status::InvalidRestore, ffi::STATUS_INVALID_POP_GROUP => Status::InvalidPopGroup, ffi::STATUS_NO_CURRENT_POINT => Status::NoCurrentPoint, ffi::STATUS_INVALID_MATRIX => Status::InvalidMatrix, ffi::STATUS_INVALID_STATUS => Status::InvalidStatus, ffi::STATUS_NULL_POINTER => Status::NullPointer, ffi::STATUS_INVALID_STRING => Status::InvalidString, ffi::STATUS_INVALID_PATH_DATA => Status::InvalidPathData, ffi::STATUS_READ_ERROR => Status::ReadError, ffi::STATUS_WRITE_ERROR => Status::WriteError, ffi::STATUS_SURFACE_FINISHED => Status::SurfaceFinished, ffi::STATUS_SURFACE_TYPE_MISMATCH => Status::SurfaceTypeMismatch, ffi::STATUS_PATTERN_TYPE_MISMATCH => Status::PatternTypeMismatch, ffi::STATUS_INVALID_CONTENT => Status::InvalidContent, ffi::STATUS_INVALID_FORMAT => Status::InvalidFormat, ffi::STATUS_INVALID_VISUAL => Status::InvalidVisual, ffi::STATUS_FILE_NOT_FOUND => Status::FileNotFound, ffi::STATUS_INVALID_DASH => Status::InvalidDash, ffi::STATUS_INVALID_DSC_COMMENT => Status::InvalidDscComment, ffi::STATUS_INVALID_INDEX => Status::InvalidIndex, ffi::STATUS_CLIP_NOT_REPRESENTABLE => Status::ClipNotRepresentable, ffi::STATUS_TEMP_FILE_ERROR => Status::TempFileError, ffi::STATUS_INVALID_STRIDE => Status::InvalidStride, ffi::STATUS_FONT_TYPE_MISMATCH => Status::FontTypeMismatch, ffi::STATUS_USER_FONT_IMMUTABLE => Status::UserFontImmutable, ffi::STATUS_USER_FONT_ERROR => Status::UserFontError, ffi::STATUS_NEGATIVE_COUNT => Status::NegativeCount, ffi::STATUS_INVALID_CLUSTERS => Status::InvalidClusters, ffi::STATUS_INVALID_SLANT => Status::InvalidSlant, ffi::STATUS_INVALID_WEIGHT => Status::InvalidWeight, ffi::STATUS_INVALID_SIZE => Status::InvalidSize, ffi::STATUS_USER_FONT_NOT_IMPLEMENTED => Status::UserFontNotImplemented, ffi::STATUS_DEVICE_TYPE_MISMATCH => Status::DeviceTypeMismatch, ffi::STATUS_DEVICE_ERROR => Status::DeviceError, ffi::STATUS_INVALID_MESH_CONSTRUCTION => Status::InvalidMeshConstruction, ffi::STATUS_DEVICE_FINISHED => Status::DeviceFinished, ffi::STATUS_J_BIG2_GLOBAL_MISSING => Status::JBig2GlobalMissing, ffi::STATUS_PNG_ERROR => Status::PngError, ffi::STATUS_FREETYPE_ERROR => Status::FreetypeError, ffi::STATUS_WIN32_GDI_ERROR => Status::Win32GdiError, ffi::STATUS_LAST_STATUS => Status::LastStatus, value => Status::__Unknown(value), } } } impl Debug for Status { fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> Result<(), Error> { unsafe { let char_ptr = ffi::cairo_status_to_string((*self).into()); let tmp = String::from_utf8_lossy(CStr::from_ptr(char_ptr).to_bytes()).into_owned(); tmp.fmt(formatter) } } } impl fmt::Display for Status { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "Status::{}", match *self { Status::Success => "Success", Status::NoMemory => "NoMemory", Status::InvalidRestore => "InvalidRestore", Status::InvalidPopGroup => "InvalidPopGroup", Status::NoCurrentPoint => "NoCurrentPoint", Status::InvalidMatrix => "InvalidMatrix", Status::InvalidStatus => "InvalidStatus", Status::NullPointer => "NullPointer", Status::InvalidString => "InvalidString", Status::InvalidPathData => "InvalidPathData", Status::ReadError => "ReadError", Status::WriteError => "WriteError", Status::SurfaceFinished => "SurfaceFinished", Status::SurfaceTypeMismatch => "SurfaceTypeMismatch", Status::PatternTypeMismatch => "PatternTypeMismatch", Status::InvalidContent => "InvalidContent", Status::InvalidFormat => "InvalidFormat", Status::InvalidVisual => "InvalidVisual", Status::FileNotFound => "FileNotFound", Status::InvalidDash => "InvalidDash", Status::InvalidDscComment => "InvalidDscComment", Status::InvalidIndex => "InvalidIndex", Status::ClipNotRepresentable => "ClipNotRepresentable", Status::TempFileError => "TempFileError", Status::InvalidStride => "InvalidStride", Status::FontTypeMismatch => "FontTypeMismatch", Status::UserFontImmutable => "UserFontImmutable", Status::UserFontError => "UserFontError", Status::NegativeCount => "NegativeCount", Status::InvalidClusters => "InvalidClusters", Status::InvalidSlant => "InvalidSlant", Status::InvalidWeight => "InvalidWeight", Status::InvalidSize => "InvalidSize", Status::UserFontNotImplemented => "UserFontNotImplemented", Status::DeviceTypeMismatch => "DeviceTypeMismatch", Status::DeviceError => "DeviceError", Status::InvalidMeshConstruction => "InvalidMeshConstruction", Status::DeviceFinished => "DeviceFinished", Status::JBig2GlobalMissing => "JBig2GlobalMissing", Status::PngError => "PngError", Status::FreetypeError => "FreetypeError", Status::Win32GdiError => "Win32GdiError", Status::LastStatus => "LastStatus", _ => "Unknown", } ) } } impl Status { pub fn ensure_valid(self) { if self != Status::Success { panic!("Cairo error {:?}", self) } } } #[cfg(feature = "use_glib")] gvalue_impl!(Status, ffi::gobject::cairo_gobject_status_get_type); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum Antialias { Default, /* method */ None, Gray, Subpixel, /* hints */ Fast, Good, Best, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for Antialias { fn into(self) -> ffi::cairo_antialias_t { match self { Antialias::Default => ffi::ANTIALIAS_DEFAULT, Antialias::None => ffi::ANTIALIAS_NONE, Antialias::Gray => ffi::ANTIALIAS_GRAY, Antialias::Subpixel => ffi::ANTIALIAS_SUBPIXEL, Antialias::Fast => ffi::ANTIALIAS_FAST, Antialias::Good => ffi::ANTIALIAS_GOOD, Antialias::Best => ffi::ANTIALIAS_BEST, Antialias::__Unknown(value) => value, } } } #[doc(hidden)] impl From for Antialias { fn from(value: ffi::cairo_antialias_t) -> Self { match value { ffi::ANTIALIAS_DEFAULT => Antialias::Default, ffi::ANTIALIAS_NONE => Antialias::None, ffi::ANTIALIAS_GRAY => Antialias::Gray, ffi::ANTIALIAS_SUBPIXEL => Antialias::Subpixel, ffi::ANTIALIAS_FAST => Antialias::Fast, ffi::ANTIALIAS_GOOD => Antialias::Good, ffi::ANTIALIAS_BEST => Antialias::Best, value => Antialias::__Unknown(value), } } } impl fmt::Display for Antialias { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "Antialias::{}", match *self { Antialias::Default => "Default", Antialias::None => "None", Antialias::Gray => "Gray", Antialias::Subpixel => "Subpixel", Antialias::Fast => "Fast", Antialias::Good => "Good", Antialias::Best => "Best", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!(Antialias, ffi::gobject::cairo_gobject_antialias_get_type); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum FillRule { Winding, EvenOdd, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for FillRule { fn into(self) -> ffi::cairo_fill_rule_t { match self { FillRule::Winding => ffi::FILL_RULE_WINDING, FillRule::EvenOdd => ffi::FILL_RULE_EVEN_ODD, FillRule::__Unknown(value) => value, } } } #[doc(hidden)] impl From for FillRule { fn from(value: ffi::cairo_fill_rule_t) -> Self { match value { ffi::FILL_RULE_WINDING => FillRule::Winding, ffi::FILL_RULE_EVEN_ODD => FillRule::EvenOdd, value => FillRule::__Unknown(value), } } } impl fmt::Display for FillRule { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "FillRule::{}", match *self { FillRule::Winding => "Winding", FillRule::EvenOdd => "EvenOdd", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!(FillRule, ffi::gobject::cairo_gobject_fill_rule_get_type); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum LineCap { Butt, Round, Square, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for LineCap { fn into(self) -> ffi::cairo_line_cap_t { match self { LineCap::Butt => ffi::LINE_CAP_BUTT, LineCap::Round => ffi::LINE_CAP_ROUND, LineCap::Square => ffi::LINE_CAP_SQUARE, LineCap::__Unknown(value) => value, } } } #[doc(hidden)] impl From for LineCap { fn from(value: ffi::cairo_line_cap_t) -> Self { match value { ffi::LINE_CAP_BUTT => LineCap::Butt, ffi::LINE_CAP_ROUND => LineCap::Round, ffi::LINE_CAP_SQUARE => LineCap::Square, value => LineCap::__Unknown(value), } } } impl fmt::Display for LineCap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "LineCap::{}", match *self { LineCap::Butt => "Butt", LineCap::Round => "Round", LineCap::Square => "Square", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!(LineCap, ffi::gobject::cairo_gobject_line_cap_get_type); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum LineJoin { Miter, Round, Bevel, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for LineJoin { fn into(self) -> ffi::cairo_line_join_t { match self { LineJoin::Miter => ffi::LINE_JOIN_MITER, LineJoin::Round => ffi::LINE_JOIN_ROUND, LineJoin::Bevel => ffi::LINE_JOIN_BEVEL, LineJoin::__Unknown(value) => value, } } } #[doc(hidden)] impl From for LineJoin { fn from(value: ffi::cairo_line_join_t) -> Self { match value { ffi::LINE_JOIN_MITER => LineJoin::Miter, ffi::LINE_JOIN_ROUND => LineJoin::Round, ffi::LINE_JOIN_BEVEL => LineJoin::Bevel, value => LineJoin::__Unknown(value), } } } impl fmt::Display for LineJoin { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "LineJoin::{}", match *self { LineJoin::Miter => "Miter", LineJoin::Round => "Round", LineJoin::Bevel => "Bevel", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!(LineJoin, ffi::gobject::cairo_gobject_line_join_get_type); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum Operator { Clear, Source, Over, In, Out, Atop, Dest, DestOver, DestIn, DestOut, DestAtop, Xor, Add, Saturate, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, HardLight, SoftLight, Difference, Exclusion, HslHue, HslSaturation, HslColor, HslLuminosity, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for Operator { fn into(self) -> ffi::cairo_operator_t { match self { Operator::Clear => ffi::OPERATOR_CLEAR, Operator::Source => ffi::OPERATOR_SOURCE, Operator::Over => ffi::OPERATOR_OVER, Operator::In => ffi::OPERATOR_IN, Operator::Out => ffi::OPERATOR_OUT, Operator::Atop => ffi::OPERATOR_ATOP, Operator::Dest => ffi::OPERATOR_DEST, Operator::DestOver => ffi::OPERATOR_DEST_OVER, Operator::DestIn => ffi::OPERATOR_DEST_IN, Operator::DestOut => ffi::OPERATOR_DEST_OUT, Operator::DestAtop => ffi::OPERATOR_DEST_ATOP, Operator::Xor => ffi::OPERATOR_XOR, Operator::Add => ffi::OPERATOR_ADD, Operator::Saturate => ffi::OPERATOR_SATURATE, Operator::Multiply => ffi::OPERATOR_MULTIPLY, Operator::Screen => ffi::OPERATOR_SCREEN, Operator::Overlay => ffi::OPERATOR_OVERLAY, Operator::Darken => ffi::OPERATOR_DARKEN, Operator::Lighten => ffi::OPERATOR_LIGHTEN, Operator::ColorDodge => ffi::OPERATOR_COLOR_DODGE, Operator::ColorBurn => ffi::OPERATOR_COLOR_BURN, Operator::HardLight => ffi::OPERATOR_HARD_LIGHT, Operator::SoftLight => ffi::OPERATOR_SOFT_LIGHT, Operator::Difference => ffi::OPERATOR_DIFFERENCE, Operator::Exclusion => ffi::OPERATOR_EXCLUSION, Operator::HslHue => ffi::OPERATOR_HSL_HUE, Operator::HslSaturation => ffi::OPERATOR_HSL_SATURATION, Operator::HslColor => ffi::OPERATOR_HSL_COLOR, Operator::HslLuminosity => ffi::OPERATOR_HSL_LUMINOSITY, Operator::__Unknown(value) => value, } } } #[doc(hidden)] impl From for Operator { fn from(value: ffi::cairo_operator_t) -> Self { match value { ffi::OPERATOR_CLEAR => Operator::Clear, ffi::OPERATOR_SOURCE => Operator::Source, ffi::OPERATOR_OVER => Operator::Over, ffi::OPERATOR_IN => Operator::In, ffi::OPERATOR_OUT => Operator::Out, ffi::OPERATOR_ATOP => Operator::Atop, ffi::OPERATOR_DEST => Operator::Dest, ffi::OPERATOR_DEST_OVER => Operator::DestOver, ffi::OPERATOR_DEST_IN => Operator::DestIn, ffi::OPERATOR_DEST_OUT => Operator::DestOut, ffi::OPERATOR_DEST_ATOP => Operator::DestAtop, ffi::OPERATOR_XOR => Operator::Xor, ffi::OPERATOR_ADD => Operator::Add, ffi::OPERATOR_SATURATE => Operator::Saturate, ffi::OPERATOR_MULTIPLY => Operator::Multiply, ffi::OPERATOR_SCREEN => Operator::Screen, ffi::OPERATOR_OVERLAY => Operator::Overlay, ffi::OPERATOR_DARKEN => Operator::Darken, ffi::OPERATOR_LIGHTEN => Operator::Lighten, ffi::OPERATOR_COLOR_DODGE => Operator::ColorDodge, ffi::OPERATOR_COLOR_BURN => Operator::ColorBurn, ffi::OPERATOR_HARD_LIGHT => Operator::HardLight, ffi::OPERATOR_SOFT_LIGHT => Operator::SoftLight, ffi::OPERATOR_DIFFERENCE => Operator::Difference, ffi::OPERATOR_EXCLUSION => Operator::Exclusion, ffi::OPERATOR_HSL_HUE => Operator::HslHue, ffi::OPERATOR_HSL_SATURATION => Operator::HslSaturation, ffi::OPERATOR_HSL_COLOR => Operator::HslColor, ffi::OPERATOR_HSL_LUMINOSITY => Operator::HslLuminosity, value => Operator::__Unknown(value), } } } impl fmt::Display for Operator { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "Operator::{}", match *self { Operator::Clear => "Clear", Operator::Source => "Source", Operator::Over => "Over", Operator::In => "In", Operator::Out => "Out", Operator::Atop => "Atop", Operator::Dest => "Dest", Operator::DestOver => "DestOver", Operator::DestIn => "DestIn", Operator::DestOut => "DestOut", Operator::DestAtop => "DestAtop", Operator::Xor => "Xor", Operator::Add => "Add", Operator::Saturate => "Saturate", Operator::Multiply => "Multiply", Operator::Screen => "Screen", Operator::Overlay => "Overlay", Operator::Darken => "Darken", Operator::Lighten => "Lighten", Operator::ColorDodge => "ColorDodge", Operator::ColorBurn => "ColorBurn", Operator::HardLight => "HardLight", Operator::SoftLight => "SoftLight", Operator::Difference => "Difference", Operator::Exclusion => "Exclusion", Operator::HslHue => "HslHue", Operator::HslSaturation => "HslSaturation", Operator::HslColor => "HslColor", Operator::HslLuminosity => "HslLuminosity", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!(Operator, ffi::gobject::cairo_gobject_operator_get_type); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum PathDataType { MoveTo, LineTo, CurveTo, ClosePath, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for PathDataType { fn into(self) -> ffi::cairo_path_data_type_t { match self { PathDataType::MoveTo => ffi::PATH_DATA_TYPE_MOVE_TO, PathDataType::LineTo => ffi::PATH_DATA_TYPE_LINE_TO, PathDataType::CurveTo => ffi::PATH_DATA_TYPE_CURVE_TO, PathDataType::ClosePath => ffi::PATH_DATA_TYPE_CLOSE_PATH, PathDataType::__Unknown(value) => value, } } } #[doc(hidden)] impl From for PathDataType { fn from(value: ffi::cairo_path_data_type_t) -> Self { match value { ffi::PATH_DATA_TYPE_MOVE_TO => PathDataType::MoveTo, ffi::PATH_DATA_TYPE_LINE_TO => PathDataType::LineTo, ffi::PATH_DATA_TYPE_CURVE_TO => PathDataType::CurveTo, ffi::PATH_DATA_TYPE_CLOSE_PATH => PathDataType::ClosePath, value => PathDataType::__Unknown(value), } } } impl fmt::Display for PathDataType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "PathDataType::{}", match *self { PathDataType::MoveTo => "MoveTo", PathDataType::LineTo => "LineTo", PathDataType::CurveTo => "CurveTo", PathDataType::ClosePath => "ClosePath", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!( PathDataType, ffi::gobject::cairo_gobject_path_data_type_get_type ); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum Content { Color, Alpha, ColorAlpha, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for Content { fn into(self) -> ffi::cairo_content_t { match self { Content::Color => ffi::CONTENT_COLOR, Content::Alpha => ffi::CONTENT_ALPHA, Content::ColorAlpha => ffi::CONTENT_COLOR_ALPHA, Content::__Unknown(value) => value, } } } #[doc(hidden)] impl From for Content { fn from(value: ffi::cairo_content_t) -> Self { match value { ffi::CONTENT_COLOR => Content::Color, ffi::CONTENT_ALPHA => Content::Alpha, ffi::CONTENT_COLOR_ALPHA => Content::ColorAlpha, value => Content::__Unknown(value), } } } impl fmt::Display for Content { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "Content::{}", match *self { Content::Color => "Color", Content::Alpha => "Alpha", Content::ColorAlpha => "ColorAlpha", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!(Content, ffi::gobject::cairo_gobject_content_get_type); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum Extend { None, Repeat, Reflect, Pad, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for Extend { fn into(self) -> ffi::cairo_extend_t { match self { Extend::None => ffi::EXTEND_NONE, Extend::Repeat => ffi::EXTEND_REPEAT, Extend::Reflect => ffi::EXTEND_REFLECT, Extend::Pad => ffi::EXTEND_PAD, Extend::__Unknown(value) => value, } } } #[doc(hidden)] impl From for Extend { fn from(value: ffi::cairo_extend_t) -> Self { match value { ffi::EXTEND_NONE => Extend::None, ffi::EXTEND_REPEAT => Extend::Repeat, ffi::EXTEND_REFLECT => Extend::Reflect, ffi::EXTEND_PAD => Extend::Pad, value => Extend::__Unknown(value), } } } impl fmt::Display for Extend { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "Extend::{}", match *self { Extend::None => "None", Extend::Repeat => "Repeat", Extend::Reflect => "Reflect", Extend::Pad => "Pad", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!(Extend, ffi::gobject::cairo_gobject_extend_get_type); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum Filter { Fast, Good, Best, Nearest, Bilinear, Gaussian, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for Filter { fn into(self) -> ffi::cairo_filter_t { match self { Filter::Fast => ffi::FILTER_FAST, Filter::Good => ffi::FILTER_GOOD, Filter::Best => ffi::FILTER_BEST, Filter::Nearest => ffi::FILTER_NEAREST, Filter::Bilinear => ffi::FILTER_BILINEAR, Filter::Gaussian => ffi::FILTER_GAUSSIAN, Filter::__Unknown(value) => value, } } } #[doc(hidden)] impl From for Filter { fn from(value: ffi::cairo_filter_t) -> Self { match value { ffi::FILTER_FAST => Filter::Fast, ffi::FILTER_GOOD => Filter::Good, ffi::FILTER_BEST => Filter::Best, ffi::FILTER_NEAREST => Filter::Nearest, ffi::FILTER_BILINEAR => Filter::Bilinear, ffi::FILTER_GAUSSIAN => Filter::Gaussian, value => Filter::__Unknown(value), } } } impl fmt::Display for Filter { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "Filter::{}", match *self { Filter::Fast => "Fast", Filter::Good => "Good", Filter::Best => "Best", Filter::Nearest => "Nearest", Filter::Bilinear => "Bilinear", Filter::Gaussian => "Gaussian", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!(Filter, ffi::gobject::cairo_gobject_filter_get_type); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum PatternType { Solid, Surface, LinearGradient, RadialGradient, Mesh, RasterSource, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for PatternType { fn into(self) -> ffi::cairo_pattern_type_t { match self { PatternType::Solid => ffi::PATTERN_TYPE_SOLID, PatternType::Surface => ffi::PATTERN_TYPE_SURFACE, PatternType::LinearGradient => ffi::PATTERN_TYPE_LINEAR_GRADIENT, PatternType::RadialGradient => ffi::PATTERN_TYPE_RADIAL_GRADIENT, PatternType::Mesh => ffi::PATTERN_TYPE_MESH, PatternType::RasterSource => ffi::PATTERN_TYPE_RASTER_SOURCE, PatternType::__Unknown(value) => value, } } } #[doc(hidden)] impl From for PatternType { fn from(value: ffi::cairo_pattern_type_t) -> Self { match value { ffi::PATTERN_TYPE_SOLID => PatternType::Solid, ffi::PATTERN_TYPE_SURFACE => PatternType::Surface, ffi::PATTERN_TYPE_LINEAR_GRADIENT => PatternType::LinearGradient, ffi::PATTERN_TYPE_RADIAL_GRADIENT => PatternType::RadialGradient, ffi::PATTERN_TYPE_MESH => PatternType::Mesh, ffi::PATTERN_TYPE_RASTER_SOURCE => PatternType::RasterSource, value => PatternType::__Unknown(value), } } } impl fmt::Display for PatternType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "PatternType::{}", match *self { PatternType::Solid => "Solid", PatternType::Surface => "Surface", PatternType::LinearGradient => "LinearGradient", PatternType::RadialGradient => "RadialGradient", PatternType::Mesh => "Mesh", PatternType::RasterSource => "RasterSource", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!( PatternType, ffi::gobject::cairo_gobject_pattern_type_get_type ); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum FontSlant { Normal, Italic, Oblique, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for FontSlant { fn into(self) -> ffi::cairo_font_slant_t { match self { FontSlant::Normal => ffi::FONT_SLANT_NORMAL, FontSlant::Italic => ffi::FONT_SLANT_ITALIC, FontSlant::Oblique => ffi::FONT_SLANT_OBLIQUE, FontSlant::__Unknown(value) => value, } } } #[doc(hidden)] impl From for FontSlant { fn from(value: ffi::cairo_font_slant_t) -> Self { match value { ffi::FONT_SLANT_NORMAL => FontSlant::Normal, ffi::FONT_SLANT_ITALIC => FontSlant::Italic, ffi::FONT_SLANT_OBLIQUE => FontSlant::Oblique, value => FontSlant::__Unknown(value), } } } impl fmt::Display for FontSlant { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "FontSlant::{}", match *self { FontSlant::Normal => "Normal", FontSlant::Italic => "Italic", FontSlant::Oblique => "Oblique", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!(FontSlant, ffi::gobject::cairo_gobject_font_slant_get_type); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum FontWeight { Normal, Bold, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for FontWeight { fn into(self) -> ffi::cairo_font_weight_t { match self { FontWeight::Normal => ffi::FONT_WEIGHT_NORMAL, FontWeight::Bold => ffi::FONT_WEIGHT_BOLD, FontWeight::__Unknown(value) => value, } } } #[doc(hidden)] impl From for FontWeight { fn from(value: ffi::cairo_font_weight_t) -> Self { match value { ffi::FONT_WEIGHT_NORMAL => FontWeight::Normal, ffi::FONT_WEIGHT_BOLD => FontWeight::Bold, value => FontWeight::__Unknown(value), } } } impl fmt::Display for FontWeight { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "FontWeight::{}", match *self { FontWeight::Normal => "Normal", FontWeight::Bold => "Bold", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!(FontWeight, ffi::gobject::cairo_gobject_font_weight_get_type); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum TextClusterFlags { None, Backward, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for TextClusterFlags { fn into(self) -> ffi::cairo_text_cluster_flags_t { match self { TextClusterFlags::None => ffi::TEXT_CLUSTER_FLAGS_NONE, TextClusterFlags::Backward => ffi::TEXT_CLUSTER_FLAGS_BACKWARD, TextClusterFlags::__Unknown(value) => value, } } } #[doc(hidden)] impl From for TextClusterFlags { fn from(value: ffi::cairo_text_cluster_flags_t) -> Self { match value { ffi::TEXT_CLUSTER_FLAGS_NONE => TextClusterFlags::None, ffi::TEXT_CLUSTER_FLAGS_BACKWARD => TextClusterFlags::Backward, value => TextClusterFlags::__Unknown(value), } } } impl fmt::Display for TextClusterFlags { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "TextClusterFlags::{}", match *self { TextClusterFlags::None => "None", TextClusterFlags::Backward => "Backward", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!( TextClusterFlags, ffi::gobject::cairo_gobject_text_cluster_flags_get_type ); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum FontType { FontTypeToy, FontTypeFt, FontTypeWin32, FontTypeQuartz, FontTypeUser, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for FontType { fn into(self) -> ffi::cairo_font_type_t { match self { FontType::FontTypeToy => ffi::FONT_TYPE_FONT_TYPE_TOY, FontType::FontTypeFt => ffi::FONT_TYPE_FONT_TYPE_FT, FontType::FontTypeWin32 => ffi::FONT_TYPE_FONT_TYPE_WIN32, FontType::FontTypeQuartz => ffi::FONT_TYPE_FONT_TYPE_QUARTZ, FontType::FontTypeUser => ffi::FONT_TYPE_FONT_TYPE_USER, FontType::__Unknown(value) => value, } } } #[doc(hidden)] impl From for FontType { fn from(value: ffi::cairo_font_type_t) -> Self { match value { ffi::FONT_TYPE_FONT_TYPE_TOY => FontType::FontTypeToy, ffi::FONT_TYPE_FONT_TYPE_FT => FontType::FontTypeFt, ffi::FONT_TYPE_FONT_TYPE_WIN32 => FontType::FontTypeWin32, ffi::FONT_TYPE_FONT_TYPE_QUARTZ => FontType::FontTypeQuartz, ffi::FONT_TYPE_FONT_TYPE_USER => FontType::FontTypeUser, value => FontType::__Unknown(value), } } } impl fmt::Display for FontType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "FontType::{}", match *self { FontType::FontTypeToy => "FontTypeToy", FontType::FontTypeFt => "FontTypeFt", FontType::FontTypeWin32 => "FontTypeWin32", FontType::FontTypeQuartz => "FontTypeQuartz", FontType::FontTypeUser => "FontTypeUser", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!(FontType, ffi::gobject::cairo_gobject_font_type_get_type); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum SubpixelOrder { Default, Rgb, Bgr, Vrgb, Vbgr, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for SubpixelOrder { fn into(self) -> ffi::cairo_subpixel_order_t { match self { SubpixelOrder::Default => ffi::SUBPIXEL_ORDER_DEFAULT, SubpixelOrder::Rgb => ffi::SUBPIXEL_ORDER_RGB, SubpixelOrder::Bgr => ffi::SUBPIXEL_ORDER_BGR, SubpixelOrder::Vrgb => ffi::SUBPIXEL_ORDER_VRGB, SubpixelOrder::Vbgr => ffi::SUBPIXEL_ORDER_VBGR, SubpixelOrder::__Unknown(value) => value, } } } #[doc(hidden)] impl From for SubpixelOrder { fn from(value: ffi::cairo_subpixel_order_t) -> Self { match value { ffi::SUBPIXEL_ORDER_DEFAULT => SubpixelOrder::Default, ffi::SUBPIXEL_ORDER_RGB => SubpixelOrder::Rgb, ffi::SUBPIXEL_ORDER_BGR => SubpixelOrder::Bgr, ffi::SUBPIXEL_ORDER_VRGB => SubpixelOrder::Vrgb, ffi::SUBPIXEL_ORDER_VBGR => SubpixelOrder::Vbgr, value => SubpixelOrder::__Unknown(value), } } } impl fmt::Display for SubpixelOrder { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "SubpixelOrder::{}", match *self { SubpixelOrder::Default => "Default", SubpixelOrder::Rgb => "Rgb", SubpixelOrder::Bgr => "Bgr", SubpixelOrder::Vrgb => "Vrgb", SubpixelOrder::Vbgr => "Vbgr", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!( SubpixelOrder, ffi::gobject::cairo_gobject_subpixel_order_get_type ); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum HintStyle { Default, None, Slight, Medium, Full, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for HintStyle { fn into(self) -> ffi::cairo_hint_style_t { match self { HintStyle::Default => ffi::HINT_STYLE_DEFAULT, HintStyle::None => ffi::HINT_STYLE_NONE, HintStyle::Slight => ffi::HINT_STYLE_SLIGHT, HintStyle::Medium => ffi::HINT_STYLE_MEDIUM, HintStyle::Full => ffi::HINT_STYLE_FULL, HintStyle::__Unknown(value) => value, } } } #[doc(hidden)] impl From for HintStyle { fn from(value: ffi::cairo_hint_style_t) -> Self { match value { ffi::HINT_STYLE_DEFAULT => HintStyle::Default, ffi::HINT_STYLE_NONE => HintStyle::None, ffi::HINT_STYLE_SLIGHT => HintStyle::Slight, ffi::HINT_STYLE_MEDIUM => HintStyle::Medium, ffi::HINT_STYLE_FULL => HintStyle::Full, value => HintStyle::__Unknown(value), } } } impl fmt::Display for HintStyle { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "HintStyle::{}", match *self { HintStyle::Default => "Default", HintStyle::None => "None", HintStyle::Slight => "Slight", HintStyle::Medium => "Medium", HintStyle::Full => "Full", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!(HintStyle, ffi::gobject::cairo_gobject_hint_style_get_type); #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum HintMetrics { Default, Off, On, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for HintMetrics { fn into(self) -> ffi::cairo_hint_metrics_t { match self { HintMetrics::Default => ffi::HINT_METRICS_DEFAULT, HintMetrics::Off => ffi::HINT_METRICS_OFF, HintMetrics::On => ffi::HINT_METRICS_ON, HintMetrics::__Unknown(value) => value, } } } #[doc(hidden)] impl From for HintMetrics { fn from(value: ffi::cairo_hint_metrics_t) -> Self { match value { ffi::HINT_METRICS_DEFAULT => HintMetrics::Default, ffi::HINT_METRICS_OFF => HintMetrics::Off, ffi::HINT_METRICS_ON => HintMetrics::On, value => HintMetrics::__Unknown(value), } } } impl fmt::Display for HintMetrics { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "HintMetrics::{}", match *self { HintMetrics::Default => "Default", HintMetrics::Off => "Off", HintMetrics::On => "On", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!( HintMetrics, ffi::gobject::cairo_gobject_hint_metrics_get_type ); #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum SurfaceType { Image, Pdf, Ps, Xlib, Xcb, Glitz, Quartz, Win32, BeOs, DirectFb, Svg, Os2, Win32Printing, QuartzImage, Script, Qt, Recording, Vg, Gl, Drm, Tee, Xml, Skia, Subsurface, Cogl, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for SurfaceType { fn into(self) -> ffi::cairo_surface_type_t { match self { SurfaceType::Image => ffi::SURFACE_TYPE_IMAGE, SurfaceType::Pdf => ffi::SURFACE_TYPE_PDF, SurfaceType::Ps => ffi::SURFACE_TYPE_PS, SurfaceType::Xlib => ffi::SURFACE_TYPE_XLIB, SurfaceType::Xcb => ffi::SURFACE_TYPE_XCB, SurfaceType::Glitz => ffi::SURFACE_TYPE_GLITZ, SurfaceType::Quartz => ffi::SURFACE_TYPE_QUARTZ, SurfaceType::Win32 => ffi::SURFACE_TYPE_WIN32, SurfaceType::BeOs => ffi::SURFACE_TYPE_BE_OS, SurfaceType::DirectFb => ffi::SURFACE_TYPE_DIRECT_FB, SurfaceType::Svg => ffi::SURFACE_TYPE_SVG, SurfaceType::Os2 => ffi::SURFACE_TYPE_OS2, SurfaceType::Win32Printing => ffi::SURFACE_TYPE_WIN32_PRINTING, SurfaceType::QuartzImage => ffi::SURFACE_TYPE_QUARTZ_IMAGE, SurfaceType::Script => ffi::SURFACE_TYPE_SCRIPT, SurfaceType::Qt => ffi::SURFACE_TYPE_QT, SurfaceType::Recording => ffi::SURFACE_TYPE_RECORDING, SurfaceType::Vg => ffi::SURFACE_TYPE_VG, SurfaceType::Gl => ffi::SURFACE_TYPE_GL, SurfaceType::Drm => ffi::SURFACE_TYPE_DRM, SurfaceType::Tee => ffi::SURFACE_TYPE_TEE, SurfaceType::Xml => ffi::SURFACE_TYPE_XML, SurfaceType::Skia => ffi::SURFACE_TYPE_SKIA, SurfaceType::Subsurface => ffi::SURFACE_TYPE_SUBSURFACE, SurfaceType::Cogl => ffi::SURFACE_TYPE_COGL, SurfaceType::__Unknown(value) => value, } } } #[doc(hidden)] impl From for SurfaceType { fn from(value: ffi::cairo_surface_type_t) -> Self { match value { ffi::SURFACE_TYPE_IMAGE => SurfaceType::Image, ffi::SURFACE_TYPE_PDF => SurfaceType::Pdf, ffi::SURFACE_TYPE_PS => SurfaceType::Ps, ffi::SURFACE_TYPE_XLIB => SurfaceType::Xlib, ffi::SURFACE_TYPE_XCB => SurfaceType::Xcb, ffi::SURFACE_TYPE_GLITZ => SurfaceType::Glitz, ffi::SURFACE_TYPE_QUARTZ => SurfaceType::Quartz, ffi::SURFACE_TYPE_WIN32 => SurfaceType::Win32, ffi::SURFACE_TYPE_BE_OS => SurfaceType::BeOs, ffi::SURFACE_TYPE_DIRECT_FB => SurfaceType::DirectFb, ffi::SURFACE_TYPE_SVG => SurfaceType::Svg, ffi::SURFACE_TYPE_OS2 => SurfaceType::Os2, ffi::SURFACE_TYPE_WIN32_PRINTING => SurfaceType::Win32Printing, ffi::SURFACE_TYPE_QUARTZ_IMAGE => SurfaceType::QuartzImage, ffi::SURFACE_TYPE_SCRIPT => SurfaceType::Script, ffi::SURFACE_TYPE_QT => SurfaceType::Qt, ffi::SURFACE_TYPE_RECORDING => SurfaceType::Recording, ffi::SURFACE_TYPE_VG => SurfaceType::Vg, ffi::SURFACE_TYPE_GL => SurfaceType::Gl, ffi::SURFACE_TYPE_DRM => SurfaceType::Drm, ffi::SURFACE_TYPE_TEE => SurfaceType::Tee, ffi::SURFACE_TYPE_XML => SurfaceType::Xml, ffi::SURFACE_TYPE_SKIA => SurfaceType::Skia, ffi::SURFACE_TYPE_SUBSURFACE => SurfaceType::Subsurface, ffi::SURFACE_TYPE_COGL => SurfaceType::Cogl, value => SurfaceType::__Unknown(value), } } } impl fmt::Display for SurfaceType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "SurfaceType::{}", match *self { SurfaceType::Image => "Image", SurfaceType::Pdf => "Pdf", SurfaceType::Ps => "Ps", SurfaceType::Xlib => "Xlib", SurfaceType::Xcb => "Xcb", SurfaceType::Glitz => "Glitz", SurfaceType::Quartz => "Quartz", SurfaceType::Win32 => "Win32", SurfaceType::BeOs => "BeOs", SurfaceType::DirectFb => "DirectFb", SurfaceType::Svg => "Svg", SurfaceType::Os2 => "Os2", SurfaceType::Win32Printing => "Win32Printing", SurfaceType::QuartzImage => "QuartzImage", SurfaceType::Script => "Script", SurfaceType::Qt => "Qt", SurfaceType::Recording => "Recording", SurfaceType::Vg => "Vg", SurfaceType::Gl => "Gl", SurfaceType::Drm => "Drm", SurfaceType::Tee => "Tee", SurfaceType::Xml => "Xml", SurfaceType::Skia => "Skia", SurfaceType::Subsurface => "Subsurface", SurfaceType::Cogl => "Cogl", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!( SurfaceType, ffi::gobject::cairo_gobject_surface_type_get_type ); #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[cfg(any(all(feature = "svg", feature = "v1_16"), feature = "dox"))] pub enum SvgUnit { User, Em, Ex, Px, In, Cm, Mm, Pt, Pc, Percent, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] #[cfg(any(all(feature = "svg", feature = "v1_16"), feature = "dox"))] impl Into for SvgUnit { fn into(self) -> ffi::cairo_svg_unit_t { match self { SvgUnit::User => ffi::SVG_UNIT_USER, SvgUnit::Em => ffi::SVG_UNIT_EM, SvgUnit::Ex => ffi::SVG_UNIT_EX, SvgUnit::Px => ffi::SVG_UNIT_PX, SvgUnit::In => ffi::SVG_UNIT_IN, SvgUnit::Cm => ffi::SVG_UNIT_CM, SvgUnit::Mm => ffi::SVG_UNIT_MM, SvgUnit::Pt => ffi::SVG_UNIT_PT, SvgUnit::Pc => ffi::SVG_UNIT_PC, SvgUnit::Percent => ffi::SVG_UNIT_PERCENT, SvgUnit::__Unknown(value) => value, } } } #[doc(hidden)] #[cfg(any(all(feature = "svg", feature = "v1_16"), feature = "dox"))] impl From for SvgUnit { fn from(value: ffi::cairo_svg_unit_t) -> Self { match value { ffi::SVG_UNIT_USER => SvgUnit::User, ffi::SVG_UNIT_EM => SvgUnit::Em, ffi::SVG_UNIT_EX => SvgUnit::Ex, ffi::SVG_UNIT_PX => SvgUnit::Px, ffi::SVG_UNIT_IN => SvgUnit::In, ffi::SVG_UNIT_CM => SvgUnit::Cm, ffi::SVG_UNIT_MM => SvgUnit::Mm, ffi::SVG_UNIT_PT => SvgUnit::Pt, ffi::SVG_UNIT_PC => SvgUnit::Pc, ffi::SVG_UNIT_PERCENT => SvgUnit::Percent, value => SvgUnit::__Unknown(value), } } } #[cfg(any(all(feature = "svg", feature = "v1_16"), feature = "dox"))] impl fmt::Display for SvgUnit { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "SvgUnit::{}", match *self { SvgUnit::User => "User", SvgUnit::Em => "Em", SvgUnit::Ex => "Ex", SvgUnit::Px => "Px", SvgUnit::In => "In", SvgUnit::Cm => "Cm", SvgUnit::Mm => "Mm", SvgUnit::Pt => "Pt", SvgUnit::Pc => "Pc", SvgUnit::Percent => "Percent", _ => "Unknown", } ) } } #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Format { Invalid, ARgb32, Rgb24, A8, A1, Rgb16_565, Rgb30, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for Format { fn into(self) -> ffi::cairo_format_t { match self { Format::Invalid => ffi::FORMAT_INVALID, Format::ARgb32 => ffi::FORMAT_A_RGB32, Format::Rgb24 => ffi::FORMAT_RGB24, Format::A8 => ffi::FORMAT_A8, Format::A1 => ffi::FORMAT_A1, Format::Rgb16_565 => ffi::FORMAT_RGB16_565, Format::Rgb30 => ffi::FORMAT_RGB30, Format::__Unknown(value) => value, } } } #[doc(hidden)] impl From for Format { fn from(value: ffi::cairo_format_t) -> Self { match value { ffi::FORMAT_INVALID => Format::Invalid, ffi::FORMAT_A_RGB32 => Format::ARgb32, ffi::FORMAT_RGB24 => Format::Rgb24, ffi::FORMAT_A8 => Format::A8, ffi::FORMAT_A1 => Format::A1, ffi::FORMAT_RGB16_565 => Format::Rgb16_565, ffi::FORMAT_RGB30 => Format::Rgb30, value => Format::__Unknown(value), } } } impl fmt::Display for Format { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "Format::{}", match *self { Format::Invalid => "Invalid", Format::ARgb32 => "ARgb32", Format::Rgb24 => "Rgb24", Format::A8 => "A8", Format::A1 => "A1", Format::Rgb16_565 => "Rgb16_565", Format::Rgb30 => "Rgb30", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!(Format, ffi::gobject::cairo_gobject_format_get_type); impl Format { pub fn stride_for_width(self, width: u32) -> Result { assert!(width <= i32::MAX as u32); let width = width as i32; let stride = unsafe { ffi::cairo_format_stride_for_width(self.into(), width) }; if stride == -1 { Err(()) } else { Ok(stride) } } } #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum RegionOverlap { In, Out, Part, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for RegionOverlap { fn into(self) -> ffi::cairo_region_overlap_t { match self { RegionOverlap::In => ffi::REGION_OVERLAP_IN, RegionOverlap::Out => ffi::REGION_OVERLAP_OUT, RegionOverlap::Part => ffi::REGION_OVERLAP_PART, RegionOverlap::__Unknown(value) => value, } } } #[doc(hidden)] impl From for RegionOverlap { fn from(value: ffi::cairo_region_overlap_t) -> Self { match value { ffi::REGION_OVERLAP_IN => RegionOverlap::In, ffi::REGION_OVERLAP_OUT => RegionOverlap::Out, ffi::REGION_OVERLAP_PART => RegionOverlap::Part, value => RegionOverlap::__Unknown(value), } } } impl fmt::Display for RegionOverlap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "RegionOverlap::{}", match *self { RegionOverlap::In => "In", RegionOverlap::Out => "Out", RegionOverlap::Part => "Part", _ => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!( RegionOverlap, ffi::gobject::cairo_gobject_region_overlap_get_type ); bitflags! { pub struct PdfOutline: i32 { const OPEN = ffi::PDF_OUTLINE_FLAG_OPEN; const BOLD = ffi::PDF_OUTLINE_FLAG_BOLD; const ITALIC = ffi::PDF_OUTLINE_FLAG_ITALIC; } } #[cfg(any(feature = "pdf", feature = "dox"))] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum PdfMetadata { Title, Author, Subject, Keywords, Creator, CreateDate, ModDate, #[doc(hidden)] __Unknown(i32), } #[cfg(any(all(feature = "pdf", feature = "v1_16"), feature = "dox"))] #[doc(hidden)] impl Into for PdfMetadata { fn into(self) -> ffi::cairo_pdf_metadata_t { match self { PdfMetadata::Title => ffi::PDF_METADATA_TITLE, PdfMetadata::Author => ffi::PDF_METADATA_AUTHOR, PdfMetadata::Subject => ffi::PDF_METADATA_SUBJECT, PdfMetadata::Keywords => ffi::PDF_METADATA_KEYWORDS, PdfMetadata::Creator => ffi::PDF_METADATA_CREATOR, PdfMetadata::CreateDate => ffi::PDF_METADATA_CREATE_DATE, PdfMetadata::ModDate => ffi::PDF_METADATA_MOD_DATE, PdfMetadata::__Unknown(value) => value, } } } #[cfg(any(all(feature = "pdf", feature = "v1_16"), feature = "dox"))] #[doc(hidden)] impl From for PdfMetadata { fn from(value: ffi::cairo_pdf_metadata_t) -> Self { match value { ffi::PDF_METADATA_TITLE => PdfMetadata::Title, ffi::PDF_METADATA_AUTHOR => PdfMetadata::Author, ffi::PDF_METADATA_SUBJECT => PdfMetadata::Subject, ffi::PDF_METADATA_KEYWORDS => PdfMetadata::Keywords, ffi::PDF_METADATA_CREATOR => PdfMetadata::Creator, ffi::PDF_METADATA_CREATE_DATE => PdfMetadata::CreateDate, ffi::PDF_METADATA_MOD_DATE => PdfMetadata::ModDate, value => PdfMetadata::__Unknown(value), } } } #[cfg(any(all(feature = "pdf", feature = "v1_16"), feature = "dox"))] impl fmt::Display for PdfMetadata { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "PdfMetadata::{}", match *self { PdfMetadata::Title => "Title", PdfMetadata::Author => "Author", PdfMetadata::Subject => "Subject", PdfMetadata::Keywords => "Keywords", PdfMetadata::Creator => "Creator", PdfMetadata::CreateDate => "CreateDate", PdfMetadata::ModDate => "ModDate", _ => "Unknown", } ) } } #[cfg(any(feature = "pdf", feature = "dox"))] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum PdfVersion { _1_4, _1_5, #[doc(hidden)] __Unknown(i32), } #[cfg(any(feature = "pdf", feature = "dox"))] #[doc(hidden)] impl Into for PdfVersion { fn into(self) -> ffi::cairo_pdf_version_t { match self { PdfVersion::_1_4 => ffi::PDF_VERSION__1_4, PdfVersion::_1_5 => ffi::PDF_VERSION__1_5, PdfVersion::__Unknown(value) => value, } } } #[cfg(any(feature = "pdf", feature = "dox"))] #[doc(hidden)] impl From for PdfVersion { fn from(value: ffi::cairo_pdf_version_t) -> Self { match value { ffi::PDF_VERSION__1_4 => PdfVersion::_1_4, ffi::PDF_VERSION__1_5 => PdfVersion::_1_5, value => PdfVersion::__Unknown(value), } } } #[cfg(any(feature = "pdf", feature = "dox"))] impl fmt::Display for PdfVersion { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "PdfVersion::{}", match *self { PdfVersion::_1_4 => "1_4", PdfVersion::_1_5 => "1_5", _ => "Unknown", } ) } } #[cfg(any(feature = "svg", feature = "dox"))] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum SvgVersion { _1_1, _1_2, #[doc(hidden)] __Unknown(i32), } #[cfg(any(feature = "svg", feature = "dox"))] #[doc(hidden)] impl Into for SvgVersion { fn into(self) -> ffi::cairo_svg_version_t { match self { SvgVersion::_1_1 => ffi::SVG_VERSION__1_1, SvgVersion::_1_2 => ffi::SVG_VERSION__1_2, SvgVersion::__Unknown(value) => value, } } } #[cfg(any(feature = "svg", feature = "dox"))] #[doc(hidden)] impl From for SvgVersion { fn from(value: ffi::cairo_svg_version_t) -> Self { match value { ffi::SVG_VERSION__1_1 => SvgVersion::_1_1, ffi::SVG_VERSION__1_2 => SvgVersion::_1_2, value => SvgVersion::__Unknown(value), } } } #[cfg(any(feature = "svg", feature = "dox"))] impl fmt::Display for SvgVersion { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "SvgVersion::{}", match *self { SvgVersion::_1_1 => "1_1", SvgVersion::_1_2 => "1_2", _ => "Unknown", } ) } } #[cfg(any(feature = "ps", feature = "dox"))] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum PsLevel { _2, _3, #[doc(hidden)] __Unknown(i32), } #[cfg(any(feature = "ps", feature = "dox"))] #[doc(hidden)] impl Into for PsLevel { fn into(self) -> ffi::cairo_ps_level_t { match self { PsLevel::_2 => ffi::PS_LEVEL__2, PsLevel::_3 => ffi::PS_LEVEL__3, PsLevel::__Unknown(value) => value, } } } #[cfg(any(feature = "ps", feature = "dox"))] #[doc(hidden)] impl From for PsLevel { fn from(value: ffi::cairo_ps_level_t) -> Self { match value { ffi::PS_LEVEL__2 => PsLevel::_2, ffi::PS_LEVEL__3 => PsLevel::_3, value => PsLevel::__Unknown(value), } } } #[cfg(any(feature = "ps", feature = "dox"))] impl fmt::Display for PsLevel { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "PsLevel::{}", match *self { PsLevel::_2 => "_2", PsLevel::_3 => "_3", _ => "Unknown", } ) } } #[derive(Clone, PartialEq, PartialOrd, Copy, Debug)] pub enum MeshCorner { MeshCorner0, MeshCorner1, MeshCorner2, MeshCorner3, #[doc(hidden)] __Unknown(u32), } #[doc(hidden)] impl Into for MeshCorner { fn into(self) -> ffi::cairo_mesh_corner_t { match self { MeshCorner::MeshCorner0 => ffi::MESH_CORNER_MESH_CORNER0, MeshCorner::MeshCorner1 => ffi::MESH_CORNER_MESH_CORNER1, MeshCorner::MeshCorner2 => ffi::MESH_CORNER_MESH_CORNER2, MeshCorner::MeshCorner3 => ffi::MESH_CORNER_MESH_CORNER3, MeshCorner::__Unknown(value) => value, } } } #[doc(hidden)] impl From for MeshCorner { fn from(value: ffi::cairo_mesh_corner_t) -> Self { match value { ffi::MESH_CORNER_MESH_CORNER0 => MeshCorner::MeshCorner0, ffi::MESH_CORNER_MESH_CORNER1 => MeshCorner::MeshCorner1, ffi::MESH_CORNER_MESH_CORNER2 => MeshCorner::MeshCorner2, ffi::MESH_CORNER_MESH_CORNER3 => MeshCorner::MeshCorner3, value => MeshCorner::__Unknown(value), } } } impl fmt::Display for MeshCorner { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "MeshCorner::{}", match *self { MeshCorner::MeshCorner0 => "MeshCorner0", MeshCorner::MeshCorner1 => "MeshCorner1", MeshCorner::MeshCorner2 => "MeshCorner2", MeshCorner::MeshCorner3 => "MeshCorner3", _ => "Unknown", } ) } } #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum FtSynthesize { Bold, Oblique, #[doc(hidden)] __Unknown(u32), } #[doc(hidden)] impl Into for FtSynthesize { fn into(self) -> ffi::cairo_ft_synthesize_t { match self { FtSynthesize::Bold => ffi::CAIRO_FT_SYNTHESIZE_BOLD, FtSynthesize::Oblique => ffi::CAIRO_FT_SYNTHESIZE_OBLIQUE, FtSynthesize::__Unknown(value) => value, } } } #[doc(hidden)] impl From for FtSynthesize { fn from(value: ffi::cairo_ft_synthesize_t) -> Self { match value { ffi::CAIRO_FT_SYNTHESIZE_BOLD => FtSynthesize::Bold, ffi::CAIRO_FT_SYNTHESIZE_OBLIQUE => FtSynthesize::Oblique, value => FtSynthesize::__Unknown(value), } } } impl fmt::Display for FtSynthesize { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "FtSynthesize::{}", match *self { FtSynthesize::Bold => "Bold", FtSynthesize::Oblique => "Oblique", FtSynthesize::__Unknown(_) => "Unknown", } ) } } #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum ScriptMode { Ascii, Binary, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for ScriptMode { fn into(self) -> ffi::cairo_script_mode_t { match self { ScriptMode::Ascii => ffi::CAIRO_SCRIPT_MODE_ASCII, ScriptMode::Binary => ffi::CAIRO_SCRIPT_MODE_BINARY, ScriptMode::__Unknown(value) => value, } } } #[doc(hidden)] impl From for ScriptMode { fn from(value: ffi::cairo_script_mode_t) -> Self { match value { ffi::CAIRO_SCRIPT_MODE_ASCII => ScriptMode::Ascii, ffi::CAIRO_SCRIPT_MODE_BINARY => ScriptMode::Binary, value => ScriptMode::__Unknown(value), } } } impl fmt::Display for ScriptMode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "ScriptMode::{}", match *self { ScriptMode::Ascii => "Ascii", ScriptMode::Binary => "Binary", ScriptMode::__Unknown(_) => "Unknown", } ) } } #[derive(Clone, PartialEq, PartialOrd, Debug, Copy)] pub enum DeviceType { Ascii, Binary, Script, Xcb, Xlib, Xml, Cogl, Win32, Invalid, #[doc(hidden)] __Unknown(i32), } #[doc(hidden)] impl Into for DeviceType { fn into(self) -> ffi::cairo_device_type_t { match self { DeviceType::Ascii => ffi::CAIRO_DEVICE_TYPE_DRM, DeviceType::Binary => ffi::CAIRO_DEVICE_TYPE_GL, DeviceType::Script => ffi::CAIRO_DEVICE_TYPE_SCRIPT, DeviceType::Xcb => ffi::CAIRO_DEVICE_TYPE_XCB, DeviceType::Xlib => ffi::CAIRO_DEVICE_TYPE_XLIB, DeviceType::Xml => ffi::CAIRO_DEVICE_TYPE_XML, DeviceType::Cogl => ffi::CAIRO_DEVICE_TYPE_COGL, DeviceType::Win32 => ffi::CAIRO_DEVICE_TYPE_WIN32, DeviceType::Invalid => ffi::CAIRO_DEVICE_TYPE_INVALID, DeviceType::__Unknown(value) => value, } } } #[doc(hidden)] impl From for DeviceType { fn from(value: ffi::cairo_device_type_t) -> Self { match value { ffi::CAIRO_DEVICE_TYPE_DRM => DeviceType::Ascii, ffi::CAIRO_DEVICE_TYPE_GL => DeviceType::Binary, ffi::CAIRO_DEVICE_TYPE_SCRIPT => DeviceType::Script, ffi::CAIRO_DEVICE_TYPE_XCB => DeviceType::Xcb, ffi::CAIRO_DEVICE_TYPE_XLIB => DeviceType::Xlib, ffi::CAIRO_DEVICE_TYPE_XML => DeviceType::Xml, ffi::CAIRO_DEVICE_TYPE_COGL => DeviceType::Cogl, ffi::CAIRO_DEVICE_TYPE_WIN32 => DeviceType::Win32, ffi::CAIRO_DEVICE_TYPE_INVALID => DeviceType::Invalid, value => DeviceType::__Unknown(value), } } } impl fmt::Display for DeviceType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "DeviceType::{}", match *self { DeviceType::Ascii => "Ascii", DeviceType::Binary => "Binary", DeviceType::Script => "Script", DeviceType::Xcb => "Xcb", DeviceType::Xlib => "Xlib", DeviceType::Xml => "Xml", DeviceType::Cogl => "Cogl", DeviceType::Win32 => "Win32", DeviceType::Invalid => "Invalid", DeviceType::__Unknown(_) => "Unknown", } ) } } #[cfg(feature = "use_glib")] gvalue_impl!(DeviceType, ffi::gobject::cairo_gobject_device_type_get_type); #[cfg(test)] mod tests { use super::*; #[test] #[should_panic] fn stride_panics_on_bad_value() { let _ = Format::Rgb24.stride_for_width(u32::MAX); } #[test] fn stride_errors_on_large_width() { assert!(Format::Rgb24.stride_for_width(i32::MAX as u32).is_err()); } #[test] fn stride_works() { assert!(Format::Rgb24.stride_for_width(1).unwrap() == 4); } } cairo-rs-0.7.1/src/error.rs010066400017500001750000000036061350734563600137700ustar0000000000000000// Copyright 2016, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use enums::Status; use std::error::Error; use std::fmt; use std::io; #[derive(Debug)] pub enum BorrowError { Cairo(Status), NonExclusive, } impl From for BorrowError { fn from(status: Status) -> Self { BorrowError::Cairo(status) } } impl fmt::Display for BorrowError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { BorrowError::Cairo(status) => write!(f, "BorrowError::Cairo({})", status), BorrowError::NonExclusive => write!(f, "BorrowError::NonExclusive"), } } } impl Error for BorrowError { fn description(&self) -> &str { match *self { BorrowError::Cairo(_) => "BorrowError::Cairo", BorrowError::NonExclusive => "BorrowError::NonExclusive", } } fn cause(&self) -> Option<&dyn Error> { None } } #[derive(Debug)] pub enum IoError { Cairo(Status), Io(io::Error), } impl From for IoError { fn from(status: Status) -> Self { IoError::Cairo(status) } } impl fmt::Display for IoError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { IoError::Cairo(status) => write!(f, "IoError::Cairo({})", status), IoError::Io(ref e) => write!(f, "IoError::Io({})", e), } } } impl Error for IoError { fn description(&self) -> &str { match *self { IoError::Cairo(_) => "IoError::Cairo", IoError::Io(ref e) => e.description(), } } fn cause(&self) -> Option<&dyn Error> { match *self { IoError::Cairo(_) => None, IoError::Io(ref e) => Some(e), } } } cairo-rs-0.7.1/src/font/font_face.rs010066400017500001750000000077351350734563600155400ustar0000000000000000use ffi; #[cfg(feature = "use_glib")] use glib::translate::*; use libc::c_char; use std::ffi::{CStr, CString}; use enums::{FontSlant, FontType, FontWeight, FtSynthesize, Status}; #[cfg(feature = "use_glib")] glib_wrapper! { #[derive(Debug)] pub struct FontFace(Shared); match fn { ref => |ptr| ffi::cairo_font_face_reference(ptr), unref => |ptr| ffi::cairo_font_face_destroy(ptr), get_type => || ffi::gobject::cairo_gobject_font_face_get_type(), } } #[cfg(not(feature = "use_glib"))] #[derive(Debug)] pub struct FontFace(*mut ffi::cairo_font_face_t); impl FontFace { pub fn toy_create(family: &str, slant: FontSlant, weight: FontWeight) -> FontFace { let font_face: FontFace = unsafe { let family = CString::new(family).unwrap(); FontFace::from_raw_full(ffi::cairo_toy_font_face_create( family.as_ptr(), slant.into(), weight.into(), )) }; font_face.ensure_status(); font_face } #[cfg(feature = "use_glib")] pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_font_face_t) -> FontFace { from_glib_full(ptr) } #[cfg(not(feature = "use_glib"))] pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_font_face_t) -> FontFace { assert!(!ptr.is_null()); FontFace(ptr) } #[cfg(feature = "use_glib")] pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_font_face_t) -> FontFace { from_glib_none(ptr) } #[cfg(not(feature = "use_glib"))] pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_font_face_t) -> FontFace { assert!(!ptr.is_null()); FontFace(ptr) } #[cfg(feature = "use_glib")] pub fn to_raw_none(&self) -> *mut ffi::cairo_font_face_t { self.to_glib_none().0 } #[cfg(not(feature = "use_glib"))] pub fn to_raw_none(&self) -> *mut ffi::cairo_font_face_t { self.0 } pub fn toy_get_family(&self) -> Option { unsafe { to_optional_string(ffi::cairo_toy_font_face_get_family(self.to_raw_none())) } } pub fn toy_get_slant(&self) -> FontSlant { unsafe { FontSlant::from(ffi::cairo_toy_font_face_get_slant(self.to_raw_none())) } } pub fn toy_get_weight(&self) -> FontWeight { unsafe { FontWeight::from(ffi::cairo_toy_font_face_get_weight(self.to_raw_none())) } } pub fn ensure_status(&self) { let status = unsafe { ffi::cairo_font_face_status(self.to_raw_none()) }; Status::from(status).ensure_valid() } pub fn get_type(&self) -> FontType { unsafe { FontType::from(ffi::cairo_font_face_get_type(self.to_raw_none())) } } pub fn get_reference_count(&self) -> usize { unsafe { ffi::cairo_font_face_get_reference_count(self.to_raw_none()) as usize } } pub fn get_synthesize(&self) -> FtSynthesize { unsafe { FtSynthesize::from(ffi::cairo_ft_font_face_get_synthesize(self.to_raw_none())) } } pub fn set_synthesize(&self, synth_flags: FtSynthesize) { unsafe { ffi::cairo_ft_font_face_set_synthesize(self.to_raw_none(), synth_flags.into()) } } pub fn unset_synthesize(&self, synth_flags: FtSynthesize) { unsafe { ffi::cairo_ft_font_face_unset_synthesize(self.to_raw_none(), synth_flags.into()) } } user_data_methods! { ffi::cairo_font_face_get_user_data, ffi::cairo_font_face_set_user_data, } } #[cfg(not(feature = "use_glib"))] impl Drop for FontFace { fn drop(&mut self) { unsafe { ffi::cairo_font_face_destroy(self.to_raw_none()); } } } #[cfg(not(feature = "use_glib"))] impl Clone for FontFace { fn clone(&self) -> FontFace { unsafe { FontFace::from_raw_none(self.to_raw_none()) } } } pub(crate) unsafe fn to_optional_string(str: *const c_char) -> Option { if str.is_null() { None } else { Some(String::from_utf8_lossy(CStr::from_ptr(str).to_bytes()).into_owned()) } } cairo-rs-0.7.1/src/font/font_options.rs010066400017500001750000000120441350734563600163220ustar0000000000000000use ffi; #[cfg(feature = "use_glib")] use glib::translate::*; use std::cmp::PartialEq; use std::hash; #[cfg(any(feature = "v1_16", feature = "dox"))] use font::font_face::to_optional_string; #[cfg(any(feature = "v1_16", feature = "dox"))] use std::ffi::CString; use enums::{Antialias, HintMetrics, HintStyle, Status, SubpixelOrder}; #[cfg(feature = "use_glib")] glib_wrapper! { #[derive(Debug)] pub struct FontOptions(Boxed); match fn { copy => |ptr| { let ptr = ffi::cairo_font_options_copy(ptr); let status = ffi::cairo_font_options_status(ptr); Status::from(status).ensure_valid(); ptr }, free => |ptr| ffi::cairo_font_options_destroy(ptr), get_type => || ffi::gobject::cairo_gobject_font_options_get_type(), } } #[cfg(not(feature = "use_glib"))] #[derive(Debug)] pub struct FontOptions(*mut ffi::cairo_font_options_t); impl FontOptions { pub fn new() -> FontOptions { let font_options: FontOptions = unsafe { FontOptions::from_raw_full(ffi::cairo_font_options_create()) }; font_options.ensure_status(); font_options } #[cfg(feature = "use_glib")] pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_font_options_t) -> FontOptions { from_glib_full(ptr) } #[cfg(not(feature = "use_glib"))] pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_font_options_t) -> FontOptions { assert!(!ptr.is_null()); FontOptions(ptr) } #[cfg(feature = "use_glib")] pub fn to_raw_none(&self) -> *mut ffi::cairo_font_options_t { mut_override(self.to_glib_none().0) } #[cfg(not(feature = "use_glib"))] pub fn to_raw_none(&self) -> *mut ffi::cairo_font_options_t { self.0 } pub fn ensure_status(&self) { let status = unsafe { ffi::cairo_font_options_status(self.to_raw_none()) }; Status::from(status).ensure_valid() } pub fn merge(&mut self, other: &FontOptions) { unsafe { ffi::cairo_font_options_merge(self.to_raw_none(), other.to_raw_none()) } } pub fn set_antialias(&mut self, antialias: Antialias) { unsafe { ffi::cairo_font_options_set_antialias(self.to_raw_none(), antialias.into()) } } pub fn get_antialias(&self) -> Antialias { unsafe { Antialias::from(ffi::cairo_font_options_get_antialias(self.to_raw_none())) } } pub fn set_subpixel_order(&mut self, order: SubpixelOrder) { unsafe { ffi::cairo_font_options_set_subpixel_order(self.to_raw_none(), order.into()) } } pub fn get_subpixel_order(&self) -> SubpixelOrder { unsafe { SubpixelOrder::from(ffi::cairo_font_options_get_subpixel_order( self.to_raw_none(), )) } } pub fn set_hint_style(&mut self, hint_style: HintStyle) { unsafe { ffi::cairo_font_options_set_hint_style(self.to_raw_none(), hint_style.into()) } } pub fn get_hint_style(&self) -> HintStyle { unsafe { HintStyle::from(ffi::cairo_font_options_get_hint_style(self.to_raw_none())) } } pub fn set_hint_metrics(&mut self, hint_metrics: HintMetrics) { unsafe { ffi::cairo_font_options_set_hint_metrics(self.to_raw_none(), hint_metrics.into()) } } pub fn get_hint_metrics(&self) -> HintMetrics { unsafe { HintMetrics::from(ffi::cairo_font_options_get_hint_metrics(self.to_raw_none())) } } #[cfg(any(feature = "v1_16", feature = "dox"))] pub fn get_variations(&self) -> Option { unsafe { to_optional_string(ffi::cairo_font_options_get_variations(self.to_raw_none())) } } #[cfg(any(feature = "v1_16", feature = "dox"))] pub fn set_variations<'a, T: Into>>(&self, variations: T) { unsafe { let variations = variations.into(); match variations { Some(ref v) => { let v = CString::new(*v).unwrap(); ffi::cairo_font_options_set_variations(self.to_raw_none(), v.as_ptr()) } None => ffi::cairo_font_options_set_variations(self.to_raw_none(), 0 as *const _), } } } } impl PartialEq for FontOptions { fn eq(&self, other: &FontOptions) -> bool { unsafe { ffi::cairo_font_options_equal(self.to_raw_none(), other.to_raw_none()).as_bool() } } } impl Eq for FontOptions {} impl hash::Hash for FontOptions { fn hash(&self, state: &mut H) where H: hash::Hasher, { unsafe { hash::Hash::hash(&ffi::cairo_font_options_hash(self.to_raw_none()), state) } } } impl Default for FontOptions { fn default() -> Self { Self::new() } } #[cfg(not(feature = "use_glib"))] impl Drop for FontOptions { fn drop(&mut self) { unsafe { ffi::cairo_font_options_destroy(self.to_raw_none()); } } } #[cfg(not(feature = "use_glib"))] impl Clone for FontOptions { fn clone(&self) -> FontOptions { unsafe { FontOptions::from_raw_full(ffi::cairo_font_options_copy(self.to_raw_none())) } } } cairo-rs-0.7.1/src/font/mod.rs010066400017500001750000000026701350734563600143640ustar0000000000000000// Copyright 2013-2015, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or mod font_face; mod font_options; mod scaled_font; pub use enums::{ Antialias, FontSlant, FontType, FontWeight, HintMetrics, HintStyle, SubpixelOrder, TextClusterFlags, }; pub use ffi::{FontExtents, Glyph, TextCluster, TextExtents}; /* TODO Allocates an array of cairo_glyph_t's. This function is only useful in implementations of cairo_user_scaled_font_text_to_glyphs_func_t where the user needs to allocate an array of glyphs that cairo will free. For all other uses, user can use their own allocation method for glyphs. impl Glyph { //pub fn cairo_glyph_allocate(num_glyphs: c_int) -> *Glyph; //pub fn cairo_glyph_free(glyphs: *Glyph); } Allocates an array of cairo_glyph_t's. This function is only useful in implementations of cairo_user_scaled_font_text_to_glyphs_func_t where the user needs to allocate an array of glyphs that cairo will free. For all other uses, user can use their own allocation method for glyphs. impl TextCluster { //pub fn cairo_text_cluster_allocate(num_clusters: c_int) -> *TextCluster; //pub fn cairo_text_cluster_free(clusters: *TextCluster); } */ pub use self::font_face::FontFace; pub use self::font_options::FontOptions; pub use self::scaled_font::ScaledFont; cairo-rs-0.7.1/src/font/scaled_font.rs010066400017500001750000000164441350734563600160720ustar0000000000000000use ffi; #[cfg(feature = "use_glib")] use glib::translate::*; use std::ffi::CString; use std::ptr; use enums::{FontType, Status}; use ffi::{FontExtents, Glyph, TextCluster, TextExtents}; use matrices::Matrix; use super::{FontFace, FontOptions}; #[cfg(feature = "use_glib")] glib_wrapper! { #[derive(Debug)] pub struct ScaledFont(Shared); match fn { ref => |ptr| ffi::cairo_scaled_font_reference(ptr), unref => |ptr| ffi::cairo_scaled_font_destroy(ptr), get_type => || ffi::gobject::cairo_gobject_scaled_font_get_type(), } } #[cfg(not(feature = "use_glib"))] #[derive(Debug)] pub struct ScaledFont(*mut ffi::cairo_scaled_font_t); impl ScaledFont { pub fn new( font_face: &FontFace, font_matrix: &Matrix, ctm: &Matrix, options: &FontOptions, ) -> ScaledFont { let scaled_font: ScaledFont = unsafe { ScaledFont::from_raw_full(ffi::cairo_scaled_font_create( font_face.to_raw_none(), font_matrix.ptr(), ctm.ptr(), options.to_raw_none(), )) }; scaled_font.ensure_status(); scaled_font } #[cfg(feature = "use_glib")] pub fn to_raw_none(&self) -> *mut ffi::cairo_scaled_font_t { self.to_glib_none().0 } #[cfg(not(feature = "use_glib"))] pub fn to_raw_none(&self) -> *mut ffi::cairo_scaled_font_t { self.0 } #[cfg(not(feature = "use_glib"))] pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_scaled_font_t) -> ScaledFont { assert!(!ptr.is_null()); ScaledFont(ptr) } #[cfg(feature = "use_glib")] pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_scaled_font_t) -> ScaledFont { from_glib_full(ptr) } #[cfg(feature = "use_glib")] pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_scaled_font_t) -> ScaledFont { from_glib_none(ptr) } #[cfg(not(feature = "use_glib"))] pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_scaled_font_t) -> ScaledFont { assert!(!ptr.is_null()); ffi::cairo_scaled_font_reference(ptr); ScaledFont(ptr) } pub fn ensure_status(&self) { let status = unsafe { ffi::cairo_scaled_font_status(self.to_raw_none()) }; Status::from(status).ensure_valid() } pub fn get_type(&self) -> FontType { unsafe { FontType::from(ffi::cairo_scaled_font_get_type(self.to_raw_none())) } } pub fn get_reference_count(&self) -> usize { unsafe { ffi::cairo_scaled_font_get_reference_count(self.to_raw_none()) as usize } } pub fn extents(&self) -> FontExtents { let mut extents = FontExtents { ascent: 0.0, descent: 0.0, height: 0.0, max_x_advance: 0.0, max_y_advance: 0.0, }; unsafe { ffi::cairo_scaled_font_extents(self.to_raw_none(), &mut extents) } extents } pub fn text_extents(&self, text: &str) -> TextExtents { let mut extents = TextExtents { x_bearing: 0.0, y_bearing: 0.0, width: 0.0, height: 0.0, x_advance: 0.0, y_advance: 0.0, }; let text = CString::new(text).unwrap(); unsafe { ffi::cairo_scaled_font_text_extents(self.to_raw_none(), text.as_ptr(), &mut extents) } extents } pub fn glyph_extents(&self, glyphs: &[Glyph]) -> TextExtents { let mut extents = TextExtents { x_bearing: 0.0, y_bearing: 0.0, width: 0.0, height: 0.0, x_advance: 0.0, y_advance: 0.0, }; unsafe { ffi::cairo_scaled_font_glyph_extents( self.to_raw_none(), glyphs.as_ptr(), glyphs.len() as i32, &mut extents, ) } extents } pub fn text_to_glyphs(&self, x: f64, y: f64, text: &str) -> (Vec, Vec) { // This large unsafe block is due to the FFI function returning two specially allocated // (cairo_{glyph,text_cluster}_allocate) pointers that need to be copied into Vec // types before they're of any use to Rust code. unsafe { let mut glyphs_ptr: *mut Glyph = ptr::null_mut(); let mut glyph_count = 0i32; let mut clusters_ptr: *mut TextCluster = ptr::null_mut(); let mut cluster_count = 0i32; let mut cluster_flags = 0i32; let text_length = text.len() as i32; let text = CString::new(text).unwrap(); let status = ffi::cairo_scaled_font_text_to_glyphs( self.to_raw_none(), x, y, text.as_ptr(), text_length, &mut glyphs_ptr, &mut glyph_count, &mut clusters_ptr, &mut cluster_count, &mut cluster_flags, ); Status::from(status).ensure_valid(); let glyph_count = glyph_count as usize; let glyphs: Vec = { let mut glyphs: Vec = Vec::with_capacity(glyph_count); glyphs.set_len(glyph_count); ptr::copy(glyphs_ptr, glyphs.as_mut_ptr(), glyph_count); glyphs }; let cluster_count = cluster_count as usize; let clusters: Vec = { let mut clusters = Vec::with_capacity(cluster_count); clusters.set_len(cluster_count); ptr::copy(clusters_ptr, clusters.as_mut_ptr(), cluster_count); clusters }; ffi::cairo_glyph_free(glyphs_ptr); ffi::cairo_text_cluster_free(clusters_ptr); (glyphs, clusters) } } pub fn get_font_face(&self) -> FontFace { unsafe { FontFace::from_raw_none(ffi::cairo_scaled_font_get_font_face(self.to_raw_none())) } } pub fn get_font_options(&self) -> FontOptions { let options = FontOptions::new(); unsafe { ffi::cairo_scaled_font_get_font_options(self.to_raw_none(), options.to_raw_none()) } options } pub fn get_font_matrix(&self) -> Matrix { let mut matrix = Matrix::null(); unsafe { ffi::cairo_scaled_font_get_font_matrix(self.to_raw_none(), matrix.mut_ptr()) } matrix } pub fn get_ctm(&self) -> Matrix { let mut matrix = Matrix::null(); unsafe { ffi::cairo_scaled_font_get_ctm(self.to_raw_none(), matrix.mut_ptr()) } matrix } pub fn get_scale_matrix(&self) -> Matrix { let mut matrix = Matrix::null(); unsafe { ffi::cairo_scaled_font_get_scale_matrix(self.to_raw_none(), matrix.mut_ptr()) } matrix } user_data_methods! { ffi::cairo_scaled_font_get_user_data, ffi::cairo_scaled_font_set_user_data, } } #[cfg(not(feature = "use_glib"))] impl Drop for ScaledFont { fn drop(&mut self) { unsafe { ffi::cairo_scaled_font_destroy(self.to_raw_none()); } } } #[cfg(not(feature = "use_glib"))] impl Clone for ScaledFont { fn clone(&self) -> ScaledFont { unsafe { ScaledFont::from_raw_none(self.to_raw_none()) } } } cairo-rs-0.7.1/src/image_surface.rs010066400017500001750000000162041350734563600154270ustar0000000000000000// Copyright 2015, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use std::convert::TryFrom; use std::ops::{Deref, DerefMut}; use std::rc::Rc; use std::slice; use enums::{Format, SurfaceType}; use ffi; #[cfg(feature = "use_glib")] use glib::translate::*; use std::fmt; use surface::Surface; use BorrowError; use Status; #[derive(Debug)] pub struct ImageSurface(Surface); impl TryFrom for ImageSurface { type Error = Surface; fn try_from(surface: Surface) -> Result { if surface.get_type() == SurfaceType::Image { Ok(ImageSurface(surface)) } else { Err(surface) } } } impl ImageSurface { pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_surface_t) -> Result { let surface = Self::try_from(Surface::from_raw_full(ptr)).unwrap(); let status = surface.status(); match status { Status::Success => Ok(surface), _ => Err(status), } } pub fn create(format: Format, width: i32, height: i32) -> Result { unsafe { Self::from_raw_full(ffi::cairo_image_surface_create( format.into(), width, height, )) } } pub fn create_for_data + 'static>( data: D, format: Format, width: i32, height: i32, stride: i32, ) -> Result { let mut data: Box> = Box::new(data); let (ptr, len) = { let data: &mut [u8] = (*data).as_mut(); (data.as_mut_ptr(), data.len()) }; assert!(len >= (height * stride) as usize); let result = unsafe { ImageSurface::from_raw_full(ffi::cairo_image_surface_create_for_data( ptr, format.into(), width, height, stride, )) }; if let Ok(surface) = &result { static IMAGE_SURFACE_DATA: crate::UserDataKey>> = crate::UserDataKey::new(); surface.set_user_data(&IMAGE_SURFACE_DATA, Rc::new(data)) } result } pub fn get_data(&mut self) -> Result { unsafe { if ffi::cairo_surface_get_reference_count(self.to_raw_none()) > 1 { return Err(BorrowError::NonExclusive); } self.flush(); match self.status() { Status::Success => (), status => return Err(BorrowError::from(status)), } if ffi::cairo_image_surface_get_data(self.to_raw_none()).is_null() { return Err(BorrowError::from(Status::SurfaceFinished)); } Ok(ImageSurfaceData::new(self)) } } pub fn get_format(&self) -> Format { unsafe { Format::from(ffi::cairo_image_surface_get_format(self.to_raw_none())) } } pub fn get_height(&self) -> i32 { unsafe { ffi::cairo_image_surface_get_height(self.to_raw_none()) } } pub fn get_stride(&self) -> i32 { unsafe { ffi::cairo_image_surface_get_stride(self.to_raw_none()) } } pub fn get_width(&self) -> i32 { unsafe { ffi::cairo_image_surface_get_width(self.to_raw_none()) } } } #[cfg(feature = "use_glib")] impl<'a> ToGlibPtr<'a, *mut ffi::cairo_surface_t> for ImageSurface { type Storage = &'a Surface; #[inline] fn to_glib_none(&'a self) -> Stash<'a, *mut ffi::cairo_surface_t, Self> { let stash = self.0.to_glib_none(); Stash(stash.0, stash.1) } #[inline] fn to_glib_full(&self) -> *mut ffi::cairo_surface_t { unsafe { ffi::cairo_surface_reference(self.0.to_glib_none().0) } } } #[cfg(feature = "use_glib")] impl FromGlibPtrNone<*mut ffi::cairo_surface_t> for ImageSurface { #[inline] unsafe fn from_glib_none(ptr: *mut ffi::cairo_surface_t) -> ImageSurface { Self::try_from(from_glib_none::<_, Surface>(ptr)).unwrap() } } #[cfg(feature = "use_glib")] impl FromGlibPtrBorrow<*mut ffi::cairo_surface_t> for ImageSurface { #[inline] unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_surface_t) -> ImageSurface { Self::try_from(from_glib_borrow::<_, Surface>(ptr)).unwrap() } } #[cfg(feature = "use_glib")] impl FromGlibPtrFull<*mut ffi::cairo_surface_t> for ImageSurface { #[inline] unsafe fn from_glib_full(ptr: *mut ffi::cairo_surface_t) -> ImageSurface { Self::from_raw_full(ptr).unwrap() } } #[cfg(feature = "use_glib")] gvalue_impl!( ImageSurface, ffi::cairo_surface_t, ffi::gobject::cairo_gobject_surface_get_type ); impl Deref for ImageSurface { type Target = Surface; fn deref(&self) -> &Surface { &self.0 } } impl Clone for ImageSurface { fn clone(&self) -> ImageSurface { ImageSurface(self.0.clone()) } } impl fmt::Display for ImageSurface { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "ImageSurface") } } #[derive(Debug)] pub struct ImageSurfaceData<'a> { surface: &'a mut ImageSurface, slice: &'a mut [u8], dirty: bool, } impl<'a> ImageSurfaceData<'a> { fn new(surface: &'a mut ImageSurface) -> ImageSurfaceData<'a> { unsafe { let ptr = ffi::cairo_image_surface_get_data(surface.to_raw_none()); debug_assert!(!ptr.is_null()); let len = (surface.get_stride() as usize) * (surface.get_height() as usize); ImageSurfaceData { surface, slice: slice::from_raw_parts_mut(ptr, len), dirty: false, } } } } impl<'a> Drop for ImageSurfaceData<'a> { fn drop(&mut self) { if self.dirty { unsafe { ffi::cairo_surface_mark_dirty(self.surface.to_raw_none()) } } } } impl<'a> Deref for ImageSurfaceData<'a> { type Target = [u8]; fn deref(&self) -> &[u8] { self.slice } } impl<'a> DerefMut for ImageSurfaceData<'a> { fn deref_mut(&mut self) -> &mut [u8] { self.dirty = true; self.slice } } impl<'a> fmt::Display for ImageSurfaceData<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "ImageSurfaceData") } } #[cfg(test)] mod tests { use super::*; #[test] fn create_with_invalid_size_yields_error() { let result = ImageSurface::create(Format::ARgb32, 50000, 50000); assert!(result.is_err()); } #[test] fn create_for_data_with_invalid_stride_yields_error() { let result = ImageSurface::create_for_data(vec![0u8; 10], Format::ARgb32, 1, 2, 5); // unaligned stride assert!(result.is_err()); } #[test] fn create_with_valid_size() { let result = ImageSurface::create(Format::ARgb32, 10, 10); assert!(result.is_ok()); let result = ImageSurface::create_for_data(vec![0u8; 40 * 10], Format::ARgb32, 10, 10, 40); assert!(result.is_ok()); } } cairo-rs-0.7.1/src/image_surface_png.rs010066400017500001750000000151001350734563600162650ustar0000000000000000// Copyright 2016, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use std::any::Any; use std::io::{Error, Read, Write}; use std::panic::AssertUnwindSafe; use std::slice; use libc::{c_uint, c_void}; use enums::Status; use error::IoError; use ffi::{self, cairo_status_t}; use ImageSurface; struct ReadEnv<'a, R: 'a + Read> { reader: &'a mut R, io_error: Option, unwind_payload: Option>, } unsafe extern "C" fn read_func( closure: *mut c_void, data: *mut u8, len: c_uint, ) -> cairo_status_t { let read_env: &mut ReadEnv = &mut *(closure as *mut ReadEnv); // Don’t attempt another read if a previous one errored or panicked: if read_env.io_error.is_some() || read_env.unwind_payload.is_some() { return Status::ReadError.into(); } let buffer = slice::from_raw_parts_mut(data, len as usize); let result = std::panic::catch_unwind(AssertUnwindSafe(|| read_env.reader.read_exact(buffer))); match result { Ok(Ok(())) => Status::Success, Ok(Err(error)) => { read_env.io_error = Some(error); Status::ReadError } Err(payload) => { read_env.unwind_payload = Some(payload); Status::ReadError } } .into() } struct WriteEnv<'a, W: 'a + Write> { writer: &'a mut W, io_error: Option, unwind_payload: Option>, } unsafe extern "C" fn write_func( closure: *mut c_void, data: *mut u8, len: c_uint, ) -> cairo_status_t { let write_env: &mut WriteEnv = &mut *(closure as *mut WriteEnv); // Don’t attempt another write if a previous one errored or panicked: if write_env.io_error.is_some() || write_env.unwind_payload.is_some() { return Status::WriteError.into(); } let buffer = slice::from_raw_parts(data, len as usize); let result = std::panic::catch_unwind(AssertUnwindSafe(|| write_env.writer.write_all(buffer))); match result { Ok(Ok(())) => Status::Success, Ok(Err(error)) => { write_env.io_error = Some(error); Status::WriteError } Err(payload) => { write_env.unwind_payload = Some(payload); Status::WriteError } } .into() } impl ImageSurface { pub fn create_from_png(stream: &mut R) -> Result { let mut env = ReadEnv { reader: stream, io_error: None, unwind_payload: None, }; unsafe { let raw_surface = ffi::cairo_image_surface_create_from_png_stream( Some(read_func::), &mut env as *mut ReadEnv as *mut c_void, ); let surface = ImageSurface::from_raw_full(raw_surface)?; if let Some(payload) = env.unwind_payload { std::panic::resume_unwind(payload) } match env.io_error { None => Ok(surface), Some(err) => Err(IoError::Io(err)), } } } pub fn write_to_png(&self, stream: &mut W) -> Result<(), IoError> { let mut env = WriteEnv { writer: stream, io_error: None, unwind_payload: None, }; let status = unsafe { ffi::cairo_surface_write_to_png_stream( self.to_raw_none(), Some(write_func::), &mut env as *mut WriteEnv as *mut c_void, ) }; if let Some(payload) = env.unwind_payload { std::panic::resume_unwind(payload) } match env.io_error { None => match Status::from(status) { Status::Success => Ok(()), st => Err(IoError::Cairo(st.into())), }, Some(err) => Err(IoError::Io(err)), } } } #[cfg(test)] mod tests { use super::*; use enums::Format; use std::io::ErrorKind; struct IoErrorReader; // A reader that always returns an error impl Read for IoErrorReader { fn read(&mut self, _: &mut [u8]) -> Result { Err(Error::new(ErrorKind::Other, "yikes!")) } } #[test] fn valid_png_reads_correctly() { // A 1x1 PNG, RGB, no alpha, with a single pixel with (42, 42, 42) values let png_data: Vec = vec![ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53, 0xde, 0x00, 0x00, 0x00, 0x0c, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0xd0, 0xd2, 0xd2, 0x02, 0x00, 0x01, 0x00, 0x00, 0x7f, 0x09, 0xa9, 0x5a, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, ]; let r = ImageSurface::create_from_png(&mut &png_data[..]); assert!(r.is_ok()); let mut surface = r.unwrap(); assert!(surface.get_width() == 1); assert!(surface.get_height() == 1); assert!(surface.get_format() == Format::Rgb24); let data = surface.get_data().unwrap(); assert!(data.len() >= 3); let slice = &data[0..3]; assert!(slice[0] == 42); assert!(slice[1] == 42); assert!(slice[2] == 42); } #[cfg(not(target_os = "macos"))] #[test] fn invalid_png_yields_error() { let png_data: Vec = vec![ // v--- this byte is modified 0x89, 0x40, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53, 0xde, 0x00, 0x00, 0x00, 0x0c, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0xd0, 0xd2, 0xd2, 0x02, 0x00, 0x01, 0x00, 0x00, 0x7f, 0x09, 0xa9, 0x5a, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, ]; match ImageSurface::create_from_png(&mut &png_data[..]) { Err(IoError::Cairo(_)) => (), _ => unreachable!(), } } #[cfg(not(target_os = "macos"))] #[test] fn io_error_yields_cairo_read_error() { let mut r = IoErrorReader; match ImageSurface::create_from_png(&mut r) { Err(IoError::Cairo(Status::ReadError)) => (), _ => unreachable!(), } } } cairo-rs-0.7.1/src/lib.rs010066400017500001750000000106021350734573200133740ustar0000000000000000// Copyright 2013-2016, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or extern crate cairo_sys as ffi; extern crate libc; #[macro_use] extern crate bitflags; #[cfg(feature = "use_glib")] #[macro_use] extern crate glib; #[cfg(feature = "use_glib")] extern crate glib_sys as glib_ffi; #[cfg(feature = "use_glib")] extern crate gobject_sys as gobject_ffi; #[cfg(test)] extern crate tempfile; // Helper macro for our GValue related trait impls #[cfg(feature = "use_glib")] macro_rules! gvalue_impl { ($name:ty, $ffi_name:ty, $get_type:expr) => { use glib; #[allow(unused_imports)] use glib::translate::*; use glib_ffi; use gobject_ffi; impl glib::types::StaticType for $name { fn static_type() -> glib::types::Type { unsafe { from_glib($get_type()) } } } impl<'a> glib::value::FromValueOptional<'a> for $name { unsafe fn from_value_optional(v: &'a glib::value::Value) -> Option { let ptr = gobject_ffi::g_value_get_boxed(v.to_glib_none().0); assert!(!ptr.is_null()); from_glib_none(ptr as *mut $ffi_name) } } impl glib::value::SetValue for $name { unsafe fn set_value(v: &mut glib::value::Value, s: &Self) { gobject_ffi::g_value_set_boxed( v.to_glib_none_mut().0, s.to_glib_none().0 as glib_ffi::gpointer, ); } } impl glib::value::SetValueOptional for $name { unsafe fn set_value_optional(v: &mut glib::value::Value, s: Option<&Self>) { if let Some(s) = s { gobject_ffi::g_value_set_boxed( v.to_glib_none_mut().0, s.to_glib_none().0 as glib_ffi::gpointer, ); } else { gobject_ffi::g_value_set_boxed(v.to_glib_none_mut().0, ::std::ptr::null_mut()); } } } }; } pub use user_data::UserDataKey; pub use context::{Context, RectangleList}; pub use paths::{Path, PathSegment, PathSegments}; pub use device::Device; pub use enums::*; pub use error::{BorrowError, IoError}; pub use patterns::{ Gradient, LinearGradient, Mesh, Pattern, RadialGradient, SolidPattern, SurfacePattern }; pub use font::{ FontExtents, FontFace, FontOptions, FontSlant, FontType, FontWeight, Glyph, ScaledFont, TextCluster, TextExtents, }; pub use matrices::Matrix; pub use recording_surface::RecordingSurface; pub use rectangle::Rectangle; pub use rectangle_int::RectangleInt; pub use region::Region; pub use surface::{MappedImageSurface, Surface}; pub use image_surface::{ImageSurface, ImageSurfaceData}; #[cfg(any(feature = "pdf", feature = "svg", feature = "ps", feature = "dox"))] pub use stream::StreamWithError; #[cfg(any(feature = "pdf", feature = "dox"))] pub use pdf::PdfSurface; #[cfg(any(feature = "ps", feature = "dox"))] pub use ps::PsSurface; #[cfg(any(feature = "svg", feature = "dox"))] pub use svg::SvgSurface; #[cfg(any(feature = "xcb", feature = "dox"))] pub use xcb::{ XCBConnection, XCBDrawable, XCBPixmap, XCBRenderPictFormInfo, XCBScreen, XCBSurface, XCBVisualType, }; #[macro_use] mod user_data; mod constants; pub use constants::*; mod utils; pub use utils::*; mod context; mod device; mod enums; mod error; mod font; mod image_surface; #[cfg(any(feature = "png", feature = "dox"))] mod image_surface_png; mod matrices; mod paths; mod patterns; mod recording_surface; mod rectangle; mod rectangle_int; mod region; mod surface; #[cfg(any(feature = "xcb", feature = "dox"))] mod xcb; #[cfg(any(feature = "pdf", feature = "svg", feature = "ps", feature = "dox"))] #[macro_use] mod stream; #[cfg(any(feature = "pdf", feature = "dox"))] mod pdf; #[cfg(any(feature = "ps", feature = "dox"))] mod ps; #[cfg(any(feature = "svg", feature = "dox"))] mod svg; #[cfg(any(target_os = "macos", target_os = "ios", feature = "dox"))] mod quartz_surface; #[cfg(any(target_os = "macos", target_os = "ios", feature = "dox"))] pub use quartz_surface::QuartzSurface; #[cfg(any(windows, feature = "dox"))] mod win32_surface; #[cfg(any(windows, feature = "dox"))] pub use win32_surface::Win32Surface; cairo-rs-0.7.1/src/matrices.rs010066400017500001750000000101121350734563600144340ustar0000000000000000// Copyright 2013-2015, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use enums::Status; use ffi; use libc::c_double; #[repr(C)] #[derive(Debug, Clone, Copy, PartialEq)] pub struct Matrix { pub xx: c_double, pub yx: c_double, pub xy: c_double, pub yy: c_double, pub x0: c_double, pub y0: c_double, } impl Default for Matrix { fn default() -> Matrix { Matrix::identity() } } impl Matrix { pub(crate) fn ptr(&self) -> *const ffi::Matrix { self as *const Matrix as _ } pub(crate) fn mut_ptr(&mut self) -> *mut ffi::Matrix { self as *mut Matrix as _ } pub(crate) fn null() -> Matrix { Matrix { xx: 0.0, yx: 0.0, xy: 0.0, yy: 0.0, x0: 0.0, y0: 0.0, } } pub fn identity() -> Matrix { Matrix { xx: 1.0, yx: 0.0, xy: 0.0, yy: 1.0, x0: 0.0, y0: 0.0, } } pub fn new(xx: f64, yx: f64, xy: f64, yy: f64, x0: f64, y0: f64) -> Matrix { Matrix { xx, yx, xy, yy, x0, y0, } } pub fn multiply(left: &Matrix, right: &Matrix) -> Matrix { let mut matrix = Matrix::null(); unsafe { ffi::cairo_matrix_multiply(matrix.mut_ptr(), left.ptr(), right.ptr()); } matrix } pub fn translate(&mut self, tx: f64, ty: f64) { unsafe { ffi::cairo_matrix_translate(self.mut_ptr(), tx, ty) } } pub fn scale(&mut self, sx: f64, sy: f64) { unsafe { ffi::cairo_matrix_scale(self.mut_ptr(), sx, sy) } } pub fn rotate(&mut self, angle: f64) { unsafe { ffi::cairo_matrix_rotate(self.mut_ptr(), angle) } } pub fn invert(&mut self) { let result = unsafe { ffi::cairo_matrix_invert(self.mut_ptr()) }; Status::from(result).ensure_valid(); } pub fn try_invert(&self) -> Result { let mut matrix = *self; let result = unsafe { Status::from(ffi::cairo_matrix_invert(matrix.mut_ptr())) }; match result { Status::Success => Ok(matrix), _ => Err(result), } } pub fn transform_distance(&self, _dx: f64, _dy: f64) -> (f64, f64) { let mut dx = _dx; let mut dy = _dy; unsafe { ffi::cairo_matrix_transform_distance(self.ptr(), &mut dx, &mut dy); } (dx, dy) } pub fn transform_point(&self, _x: f64, _y: f64) -> (f64, f64) { let mut x = _x; let mut y = _y; unsafe { ffi::cairo_matrix_transform_point(self.ptr(), &mut x, &mut y); } (x, y) } } #[cfg(test)] mod tests { use super::*; #[test] fn memory_layout_is_ffi_equivalent() { macro_rules! dummy_values { ($Matrix: ident) => { $Matrix { xx: 1.0, yx: 2.0, xy: 3.0, yy: 4.0, x0: 5.0, y0: 6.0, } }; } use ffi::Matrix as FfiMatrix; let transmuted: Matrix = unsafe { std::mem::transmute(dummy_values!(FfiMatrix)) }; assert_eq!(transmuted, dummy_values!(Matrix)); } #[test] fn invalid_matrix_does_not_invert() { let matrix = Matrix::null(); assert!(matrix.try_invert().is_err()); } #[test] #[should_panic] fn inverting_invalid_matrix_panics() { let mut matrix = Matrix::null(); matrix.invert(); } #[test] fn valid_matrix_try_invert() { let matrix = Matrix::identity(); assert!(matrix.try_invert().unwrap() == Matrix::identity()); } #[test] fn valid_matrix_invert() { let mut matrix = Matrix::identity(); matrix.invert(); assert!(matrix == Matrix::identity()); } } cairo-rs-0.7.1/src/paths.rs010066400017500001750000000143641350734563600137610ustar0000000000000000// Copyright 2013-2015, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use enums::{PathDataType, Status}; use ffi; use ffi::cairo_path_t; use std::fmt; use std::iter::Iterator; #[derive(Debug)] pub struct Path(*mut cairo_path_t); impl Path { pub fn as_ptr(&self) -> *mut cairo_path_t { self.0 } pub fn ensure_status(&self) { unsafe { let ptr: *mut cairo_path_t = self.as_ptr(); Status::from((*ptr).status).ensure_valid() } } pub unsafe fn from_raw_full(pointer: *mut cairo_path_t) -> Path { Path(pointer) } pub fn iter(&self) -> PathSegments { use std::slice; unsafe { let ptr: *mut cairo_path_t = self.as_ptr(); let length = (*ptr).num_data as usize; let data_ptr = (*ptr).data; let data_vec = if length != 0 && !data_ptr.is_null() { slice::from_raw_parts(data_ptr, length) } else { &[] }; PathSegments { data: data_vec, i: 0, num_data: length, } } } } impl Drop for Path { fn drop(&mut self) { unsafe { ffi::cairo_path_destroy(self.as_ptr()); } } } impl fmt::Display for Path { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Path") } } #[derive(Debug, Clone, Copy, PartialEq)] pub enum PathSegment { MoveTo((f64, f64)), LineTo((f64, f64)), CurveTo((f64, f64), (f64, f64), (f64, f64)), ClosePath, } impl fmt::Display for PathSegment { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "PathSegment::{}", match *self { PathSegment::MoveTo(_) => "MoveTo", PathSegment::LineTo(_) => "LineTo", PathSegment::CurveTo(_, _, _) => "CurveTo", PathSegment::ClosePath => "ClosePath", } ) } } pub struct PathSegments<'a> { data: &'a [ffi::cairo_path_data], i: usize, num_data: usize, } impl<'a> Iterator for PathSegments<'a> { type Item = PathSegment; fn next(&mut self) -> Option { if self.i >= self.num_data { return None; } unsafe { let res = match PathDataType::from(self.data[self.i].header.data_type) { PathDataType::MoveTo => PathSegment::MoveTo(to_tuple(&self.data[self.i + 1].point)), PathDataType::LineTo => PathSegment::LineTo(to_tuple(&self.data[self.i + 1].point)), PathDataType::CurveTo => PathSegment::CurveTo( to_tuple(&self.data[self.i + 1].point), to_tuple(&self.data[self.i + 2].point), to_tuple(&self.data[self.i + 3].point), ), PathDataType::ClosePath => PathSegment::ClosePath, PathDataType::__Unknown(x) => panic!("Unknown value: {}", x), }; self.i += self.data[self.i].header.length as usize; Some(res) } } } impl<'a> fmt::Display for PathSegments<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "PathSegments") } } fn to_tuple(pair: &[f64; 2]) -> (f64, f64) { (pair[0], pair[1]) } #[cfg(test)] mod tests { use super::*; use context::*; use enums::Format; use image_surface::*; fn make_cr() -> Context { let surface = ImageSurface::create(Format::Rgb24, 1, 1).unwrap(); Context::new(&surface) } fn assert_path_equals_segments(expected: &Path, actual: &Vec) { // First ensure the lengths are equal let expected_iter = expected.iter(); let actual_iter = actual.iter(); assert_eq!(expected_iter.count(), actual_iter.count()); // Then actually compare the contents let expected_iter = expected.iter(); let actual_iter = actual.iter(); let mut iter = expected_iter.zip(actual_iter); while let Some((e, a)) = iter.next() { assert_eq!(e, *a); } } #[test] fn empty_path_doesnt_iter() { let cr = make_cr(); let path = cr.copy_path(); assert!(path.iter().next().is_none()); } #[test] fn moveto() { let cr = make_cr(); cr.move_to(1.0, 2.0); let path = cr.copy_path(); assert_path_equals_segments(&path, &vec![PathSegment::MoveTo((1.0, 2.0))]); } #[test] fn moveto_lineto_moveto() { let cr = make_cr(); cr.move_to(1.0, 2.0); cr.line_to(3.0, 4.0); cr.move_to(5.0, 6.0); let path = cr.copy_path(); assert_path_equals_segments( &path, &vec![ PathSegment::MoveTo((1.0, 2.0)), PathSegment::LineTo((3.0, 4.0)), PathSegment::MoveTo((5.0, 6.0)), ], ); } #[test] fn moveto_closepath() { let cr = make_cr(); cr.move_to(1.0, 2.0); cr.close_path(); let path = cr.copy_path(); // Note that Cairo represents a close_path as closepath+moveto, // so that the next subpath will have a starting point, // from the extra moveto. assert_path_equals_segments( &path, &vec![ PathSegment::MoveTo((1.0, 2.0)), PathSegment::ClosePath, PathSegment::MoveTo((1.0, 2.0)), ], ); } #[test] fn curveto_closed_subpath_lineto() { let cr = make_cr(); cr.move_to(1.0, 2.0); cr.curve_to(3.0, 4.0, 5.0, 6.0, 7.0, 8.0); cr.close_path(); cr.line_to(9.0, 10.0); let path = cr.copy_path(); assert_path_equals_segments( &path, &vec![ PathSegment::MoveTo((1.0, 2.0)), PathSegment::CurveTo((3.0, 4.0), (5.0, 6.0), (7.0, 8.0)), PathSegment::ClosePath, PathSegment::MoveTo((1.0, 2.0)), PathSegment::LineTo((9.0, 10.0)), ], ); } } cairo-rs-0.7.1/src/patterns.rs010066400017500001750000000326731350734563600145050ustar0000000000000000// Copyright 2013-2015, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use enums::MeshCorner; use enums::{Extend, Filter, PatternType, Status}; use ffi; use ffi::{cairo_pattern_t, cairo_surface_t}; use libc::{c_double, c_int, c_uint}; use std::convert::TryFrom; use std::fmt; use std::ops::Deref; use std::ptr; use {Matrix, Path, Surface}; // See http://cairographics.org/manual/bindings-patterns.html for more info #[derive(Debug)] pub struct Pattern { pointer: *mut cairo_pattern_t, } impl fmt::Display for Pattern { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Pattern") } } impl Pattern { user_data_methods! { ffi::cairo_pattern_get_user_data, ffi::cairo_pattern_set_user_data, } pub fn to_raw_none(&self) -> *mut cairo_pattern_t { self.pointer } pub unsafe fn from_raw_none(pointer: *mut cairo_pattern_t) -> Pattern { ffi::cairo_pattern_reference(pointer); Self::from_raw_full(pointer) } pub unsafe fn from_raw_full(pointer: *mut cairo_pattern_t) -> Pattern { Pattern { pointer } } pub fn get_type(&self) -> PatternType { unsafe { ffi::cairo_pattern_get_type(self.pointer).into() } } pub fn ensure_status(&self) { self.status().ensure_valid(); } pub fn status(&self) -> Status { unsafe { Status::from(ffi::cairo_pattern_status(self.pointer)) } } pub fn get_reference_count(&self) -> isize { unsafe { ffi::cairo_pattern_get_reference_count(self.pointer) as isize } } pub fn set_extend(&self, extend: Extend) { unsafe { ffi::cairo_pattern_set_extend(self.pointer, extend.into()) } } pub fn get_extend(&self) -> Extend { unsafe { Extend::from(ffi::cairo_pattern_get_extend(self.pointer)) } } pub fn set_filter(&self, filter: Filter) { unsafe { ffi::cairo_pattern_set_filter(self.pointer, filter.into()) } } pub fn get_filter(&self) -> Filter { unsafe { Filter::from(ffi::cairo_pattern_get_filter(self.pointer)) } } pub fn set_matrix(&self, matrix: Matrix) { unsafe { ffi::cairo_pattern_set_matrix(self.pointer, matrix.ptr()) } } pub fn get_matrix(&self) -> Matrix { let mut matrix = Matrix::null(); unsafe { ffi::cairo_pattern_get_matrix(self.pointer, matrix.mut_ptr()); } matrix } } impl Clone for Pattern { fn clone(&self) -> Self { Pattern { pointer: unsafe { ffi::cairo_pattern_reference(self.pointer) }, } } } impl Drop for Pattern { fn drop(&mut self) { unsafe { ffi::cairo_pattern_destroy(self.pointer) } } } macro_rules! convert { ($source: ident => $dest: ident = $( $variant: ident )|+ $( ($intermediate: ident) )*) => { impl TryFrom<$source> for $dest { type Error = $source; fn try_from(pattern: $source) -> Result { if $( pattern.get_type() == PatternType::$variant )||+ { $( let pattern = $intermediate(pattern); )* Ok($dest(pattern)) } else { Err(pattern) } } } }; } macro_rules! pattern_type( //Signals without arguments ($pattern_type:ident $( = $variant: ident)*) => ( #[derive(Debug, Clone)] pub struct $pattern_type(Pattern); impl Deref for $pattern_type { type Target = Pattern; fn deref(&self) -> &Pattern { &self.0 } } impl fmt::Display for $pattern_type { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, stringify!($pattern_type)) } } $( convert!(Pattern => $pattern_type = $variant); )* ); ); pattern_type!(SolidPattern = Solid); impl SolidPattern { pub fn from_rgb(red: f64, green: f64, blue: f64) -> SolidPattern { unsafe { SolidPattern(Pattern::from_raw_full(ffi::cairo_pattern_create_rgb( red, green, blue, ))) } } pub fn from_rgba(red: f64, green: f64, blue: f64, alpha: f64) -> SolidPattern { unsafe { SolidPattern(Pattern::from_raw_full(ffi::cairo_pattern_create_rgba( red, green, blue, alpha, ))) } } pub fn get_rgba(&self) -> (f64, f64, f64, f64) { unsafe { let mut red = 0.0; let mut green = 0.0; let mut blue = 0.0; let mut alpha = 0.0; Status::from(ffi::cairo_pattern_get_rgba( self.pointer, &mut red, &mut green, &mut blue, &mut alpha, )) .ensure_valid(); (red, green, blue, alpha) } } } pattern_type!(Gradient); convert!(Pattern => Gradient = LinearGradient | RadialGradient); impl Gradient { pub fn add_color_stop_rgb(&self, offset: f64, red: f64, green: f64, blue: f64) { unsafe { ffi::cairo_pattern_add_color_stop_rgb(self.pointer, offset, red, green, blue) } } pub fn add_color_stop_rgba(&self, offset: f64, red: f64, green: f64, blue: f64, alpha: f64) { unsafe { ffi::cairo_pattern_add_color_stop_rgba(self.pointer, offset, red, green, blue, alpha) } } pub fn get_color_stop_count(&self) -> isize { unsafe { let mut count = 0; let result = ffi::cairo_pattern_get_color_stop_count(self.pointer, &mut count); Status::from(result).ensure_valid(); // Not sure if these are needed count as isize } } pub fn get_color_stop_rgba(&self, index: isize) -> (f64, f64, f64, f64, f64) { unsafe { let mut offset = 0.0; let mut red = 0.0; let mut green = 0.0; let mut blue = 0.0; let mut alpha = 0.0; Status::from(ffi::cairo_pattern_get_color_stop_rgba( self.pointer, index as c_int, &mut offset, &mut red, &mut green, &mut blue, &mut alpha, )) .ensure_valid(); (offset, red, green, blue, alpha) } } } macro_rules! gradient_type { ($gradient_type: ident) => { #[derive(Debug, Clone)] pub struct $gradient_type(Gradient); impl Deref for $gradient_type { type Target = Gradient; fn deref(&self) -> &Gradient { &self.0 } } impl fmt::Display for $gradient_type { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, stringify!($gradient_type)) } } convert!(Pattern => $gradient_type = $gradient_type (Gradient)); convert!(Gradient => $gradient_type = $gradient_type); } } gradient_type!(LinearGradient); impl LinearGradient { pub fn new(x0: f64, y0: f64, x1: f64, y1: f64) -> LinearGradient { unsafe { LinearGradient(Gradient(Pattern::from_raw_full( ffi::cairo_pattern_create_linear(x0, y0, x1, y1), ))) } } pub fn get_linear_points(&self) -> (f64, f64, f64, f64) { unsafe { let mut x0 = 0.0; let mut y0 = 0.0; let mut x1 = 0.0; let mut y1 = 0.0; Status::from(ffi::cairo_pattern_get_linear_points( self.pointer, &mut x0, &mut y0, &mut x1, &mut y1, )) .ensure_valid(); (x0, y0, x1, y1) } } } gradient_type!(RadialGradient); impl RadialGradient { pub fn new(x0: f64, y0: f64, r0: f64, x1: f64, y1: f64, r1: f64) -> RadialGradient { unsafe { RadialGradient(Gradient(Pattern::from_raw_full( ffi::cairo_pattern_create_radial(x0, y0, r0, x1, y1, r1), ))) } } pub fn get_radial_circles(&self) -> (f64, f64, f64, f64, f64, f64) { unsafe { let mut x0 = 0.0; let mut y0 = 0.0; let mut r0 = 0.0; let mut x1 = 0.0; let mut y1 = 0.0; let mut r1 = 0.0; Status::from(ffi::cairo_pattern_get_radial_circles( self.pointer, &mut x0, &mut y0, &mut r0, &mut x1, &mut y1, &mut r1, )) .ensure_valid(); (x0, y0, r0, x1, y1, r1) } } } pattern_type!(SurfacePattern = Surface); impl SurfacePattern { pub fn create(surface: &Surface) -> SurfacePattern { unsafe { SurfacePattern(Pattern::from_raw_full( ffi::cairo_pattern_create_for_surface(surface.to_raw_none()), )) } } pub fn get_surface(&self) -> Surface { unsafe { let mut surface_ptr: *mut cairo_surface_t = ptr::null_mut(); Status::from(ffi::cairo_pattern_get_surface( self.pointer, &mut surface_ptr, )) .ensure_valid(); Surface::from_raw_none(surface_ptr) } } } pattern_type!(Mesh = Mesh); impl Mesh { pub fn new() -> Mesh { unsafe { Mesh(Pattern::from_raw_full(ffi::cairo_pattern_create_mesh())) } } pub fn begin_patch(&self) { unsafe { ffi::cairo_mesh_pattern_begin_patch(self.pointer) } self.ensure_status(); } pub fn end_patch(&self) { unsafe { ffi::cairo_mesh_pattern_end_patch(self.pointer) } self.ensure_status(); } pub fn move_to(&self, x: f64, y: f64) { unsafe { ffi::cairo_mesh_pattern_move_to(self.pointer, x, y) } self.ensure_status(); } pub fn line_to(&self, x: f64, y: f64) { unsafe { ffi::cairo_mesh_pattern_line_to(self.pointer, x, y) } self.ensure_status(); } pub fn curve_to(&self, x1: f64, y1: f64, x2: f64, y2: f64, x3: f64, y3: f64) { unsafe { ffi::cairo_mesh_pattern_curve_to(self.pointer, x1, y1, x2, y2, x3, y3) } self.ensure_status(); } pub fn set_control_point(&self, corner: MeshCorner, x: f64, y: f64) { unsafe { ffi::cairo_mesh_pattern_set_control_point(self.pointer, corner.into(), x, y) } self.ensure_status(); } pub fn get_control_point(&self, patch_num: usize, corner: MeshCorner) -> (f64, f64) { let mut x: c_double = 0.0; let mut y: c_double = 0.0; let status = unsafe { ffi::cairo_mesh_pattern_get_control_point( self.pointer, patch_num as c_uint, corner.into(), &mut x, &mut y, ) }; Status::from(status).ensure_valid(); (x, y) } pub fn set_corner_color_rgb(&self, corner: MeshCorner, red: f64, green: f64, blue: f64) { unsafe { ffi::cairo_mesh_pattern_set_corner_color_rgb( self.pointer, corner.into(), red, green, blue, ) } self.ensure_status(); } pub fn set_corner_color_rgba( &self, corner: MeshCorner, red: f64, green: f64, blue: f64, alpha: f64, ) { unsafe { ffi::cairo_mesh_pattern_set_corner_color_rgba( self.pointer, corner.into(), red, green, blue, alpha, ) } self.ensure_status(); } pub fn get_corner_color_rgba( &self, patch_num: usize, corner: MeshCorner, ) -> (f64, f64, f64, f64) { let mut red: c_double = 0.0; let mut green: c_double = 0.0; let mut blue: c_double = 0.0; let mut alpha: c_double = 0.0; let status = unsafe { ffi::cairo_mesh_pattern_get_corner_color_rgba( self.pointer, patch_num as c_uint, corner.into(), &mut red, &mut green, &mut blue, &mut alpha, ) }; Status::from(status).ensure_valid(); (red, green, blue, alpha) } pub fn get_patch_count(&self) -> usize { let mut count: c_uint = 0; unsafe { Status::from(ffi::cairo_mesh_pattern_get_patch_count( self.pointer, &mut count, )) .ensure_valid(); } count as usize } pub fn get_path(&self, patch_num: usize) -> Path { let path: Path = unsafe { Path::from_raw_full(ffi::cairo_mesh_pattern_get_path( self.pointer, patch_num as c_uint, )) }; path.ensure_status(); path } } #[test] fn try_from() { let linear = LinearGradient::new(0., 0., 1., 1.); let gradient = Gradient::clone(&linear); let pattern = Pattern::clone(&linear); assert!(Gradient::try_from(pattern.clone()).is_ok()); assert!(LinearGradient::try_from(gradient).is_ok()); assert!(LinearGradient::try_from(pattern).is_ok()); } cairo-rs-0.7.1/src/pdf.rs010066400017500001750000000206241350734563600134070ustar0000000000000000// Copyright 2018-2019, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use std::ffi::{CStr, CString}; use std::fmt; use std::io; use std::mem; use std::ops::Deref; use std::path::Path; use enums::PdfVersion; #[cfg(any(all(feature = "pdf", feature = "v1_16"), feature = "dox"))] use enums::{PdfMetadata, PdfOutline}; use ffi; use surface::Surface; #[cfg(feature = "use_glib")] use glib::translate::*; impl PdfVersion { pub fn as_str(self) -> Option<&'static str> { unsafe { let res = ffi::cairo_pdf_version_to_string(self.into()); res.as_ref() .and_then(|cstr| CStr::from_ptr(cstr as _).to_str().ok()) } } } #[derive(Debug)] pub struct PdfSurface { inner: Surface, } impl PdfSurface { pub fn new>(width: f64, height: f64, path: P) -> Self { let path = path.as_ref().to_string_lossy().into_owned(); let path = CString::new(path).unwrap(); unsafe { let raw = ffi::cairo_pdf_surface_create(path.as_ptr(), width, height); Self { inner: Surface::from_raw_full(raw), } } } for_stream_constructors!(cairo_pdf_surface_create_for_stream); pub fn get_versions() -> impl Iterator { let vers_slice = unsafe { let mut vers_ptr: *mut ffi::cairo_pdf_version_t = mem::uninitialized(); let mut num_vers = 0; ffi::cairo_pdf_get_versions(&mut vers_ptr as _, &mut num_vers as _); std::slice::from_raw_parts(vers_ptr, num_vers as _) }; vers_slice.iter().map(|v| PdfVersion::from(*v)) } pub fn restrict(&self, version: PdfVersion) { unsafe { ffi::cairo_pdf_surface_restrict_to_version(self.inner.to_raw_none(), version.into()); } } pub fn set_size(&self, width: f64, height: f64) { unsafe { ffi::cairo_pdf_surface_set_size(self.inner.to_raw_none(), width, height); } } #[cfg(any(all(feature = "pdf", feature = "v1_16"), feature = "dox"))] pub fn set_metadata(&self, metadata: PdfMetadata, value: &str) { let value = CString::new(value).unwrap(); unsafe { ffi::cairo_pdf_surface_set_metadata( self.inner.to_raw_none(), metadata.into(), value.as_ptr(), ); } } #[cfg(any(all(feature = "pdf", feature = "v1_16"), feature = "dox"))] pub fn set_page_label(&self, label: &str) { let label = CString::new(label).unwrap(); unsafe { ffi::cairo_pdf_surface_set_page_label(self.inner.to_raw_none(), label.as_ptr()); } } #[cfg(any(all(feature = "pdf", feature = "v1_16"), feature = "dox"))] pub fn set_thumbnail_size(&self, width: i32, height: i32) { unsafe { ffi::cairo_pdf_surface_set_thumbnail_size( self.inner.to_raw_none(), width as _, height as _, ); } } #[cfg(any(all(feature = "pdf", feature = "v1_16"), feature = "dox"))] pub fn add_outline( &self, parent_id: i32, name: &str, link_attribs: &str, flags: PdfOutline, ) -> i32 { let name = CString::new(name).unwrap(); let link_attribs = CString::new(link_attribs).unwrap(); unsafe { ffi::cairo_pdf_surface_add_outline( self.inner.to_raw_none(), parent_id, name.as_ptr(), link_attribs.as_ptr(), flags.bits() as _, ) as _ } } } impl Deref for PdfSurface { type Target = Surface; fn deref(&self) -> &Surface { &self.inner } } #[cfg(feature = "use_glib")] impl<'a> ToGlibPtr<'a, *mut ffi::cairo_surface_t> for PdfSurface { type Storage = &'a Surface; #[inline] fn to_glib_none(&'a self) -> Stash<'a, *mut ffi::cairo_surface_t, Self> { let stash = self.inner.to_glib_none(); Stash(stash.0, stash.1) } } #[cfg(feature = "use_glib")] impl FromGlibPtrNone<*mut ffi::cairo_surface_t> for PdfSurface { #[inline] unsafe fn from_glib_none(ptr: *mut ffi::cairo_surface_t) -> PdfSurface { PdfSurface { inner: from_glib_none(ptr), } } } #[cfg(feature = "use_glib")] impl FromGlibPtrBorrow<*mut ffi::cairo_surface_t> for PdfSurface { #[inline] unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_surface_t) -> PdfSurface { PdfSurface { inner: from_glib_borrow(ptr), } } } #[cfg(feature = "use_glib")] impl FromGlibPtrFull<*mut ffi::cairo_surface_t> for PdfSurface { #[inline] unsafe fn from_glib_full(ptr: *mut ffi::cairo_surface_t) -> PdfSurface { Self { inner: Surface::from_raw_full(ptr), } } } impl fmt::Display for PdfSurface { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "PdfSurface") } } #[cfg(test)] mod test { use super::*; use context::*; use tempfile::tempfile; fn draw(surface: &Surface) { let cr = Context::new(surface); cr.set_line_width(25.0); cr.set_source_rgba(1.0, 0.0, 0.0, 0.5); cr.line_to(0., 0.); cr.line_to(100., 100.); cr.stroke(); cr.set_source_rgba(0.0, 0.0, 1.0, 0.5); cr.line_to(0., 100.); cr.line_to(100., 0.); cr.stroke(); } fn draw_in_buffer() -> Vec { let buffer: Vec = vec![]; let surface = PdfSurface::for_stream(100., 100., buffer); draw(&surface); *surface.finish_output_stream().unwrap().downcast().unwrap() } #[test] fn versions() { assert!(PdfSurface::get_versions().any(|v| v == PdfVersion::_1_4)); } #[test] fn version_string() { let ver_str = PdfVersion::_1_4.as_str().unwrap(); assert_eq!(ver_str, "PDF 1.4"); } #[test] #[cfg(unix)] fn file() { let surface = PdfSurface::new(100., 100., "/dev/null"); draw(&surface); surface.finish(); } #[test] fn writer() { let file = tempfile().expect("tempfile failed"); let surface = PdfSurface::for_stream(100., 100., file); draw(&surface); let stream = surface.finish_output_stream().unwrap(); let file = stream.downcast::().unwrap(); let buffer = draw_in_buffer(); let file_size = file.metadata().unwrap().len(); assert_eq!(file_size, buffer.len() as u64); } #[test] fn ref_writer() { let mut file = tempfile().expect("tempfile failed"); let surface = unsafe { PdfSurface::for_raw_stream(100., 100., &mut file) }; draw(&surface); surface.finish_output_stream().unwrap(); drop(file); } #[test] fn buffer() { let buffer = draw_in_buffer(); let header = b"%PDF-1.5"; assert_eq!(&buffer[..header.len()], header); } #[test] fn custom_writer() { struct CustomWriter(usize); impl io::Write for CustomWriter { fn write(&mut self, buf: &[u8]) -> io::Result { self.0 += buf.len(); Ok(buf.len()) } fn flush(&mut self) -> io::Result<()> { Ok(()) } } let custom_writer = CustomWriter(0); let surface = PdfSurface::for_stream(20., 20., custom_writer); surface.set_size(100., 100.); draw(&surface); let stream = surface.finish_output_stream().unwrap(); let custom_writer = stream.downcast::().unwrap(); let buffer = draw_in_buffer(); assert_eq!(custom_writer.0, buffer.len()); } fn with_panicky_stream() -> PdfSurface { struct PanicWriter; impl io::Write for PanicWriter { fn write(&mut self, _buf: &[u8]) -> io::Result { panic!("panic in writer"); } fn flush(&mut self) -> io::Result<()> { Ok(()) } } let surface = PdfSurface::for_stream(20., 20., PanicWriter); surface.finish(); surface } #[test] #[should_panic] fn finish_stream_propagates_panic() { let _ = with_panicky_stream().finish_output_stream(); } } cairo-rs-0.7.1/src/ps.rs010066400017500001750000000175151350734563600132650ustar0000000000000000// Copyright 2018-2019, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use std::ffi::{CStr, CString}; use std::fmt; use std::io; use std::mem; use std::ops::Deref; use std::path::Path; use enums::PsLevel; use ffi; use surface::Surface; #[cfg(feature = "use_glib")] use glib::translate::*; impl PsLevel { pub fn as_str(self) -> Option<&'static str> { unsafe { let res = ffi::cairo_ps_level_to_string(self.into()); res.as_ref() .and_then(|cstr| CStr::from_ptr(cstr as _).to_str().ok()) } } } #[derive(Debug)] pub struct PsSurface { inner: Surface, } #[cfg(feature = "use_glib")] impl<'a> ToGlibPtr<'a, *mut ffi::cairo_surface_t> for PsSurface { type Storage = &'a Surface; #[inline] fn to_glib_none(&'a self) -> Stash<'a, *mut ffi::cairo_surface_t, Self> { let stash = self.inner.to_glib_none(); Stash(stash.0, stash.1) } } #[cfg(feature = "use_glib")] impl FromGlibPtrNone<*mut ffi::cairo_surface_t> for PsSurface { #[inline] unsafe fn from_glib_none(ptr: *mut ffi::cairo_surface_t) -> PsSurface { PsSurface { inner: from_glib_none(ptr), } } } #[cfg(feature = "use_glib")] impl FromGlibPtrBorrow<*mut ffi::cairo_surface_t> for PsSurface { #[inline] unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_surface_t) -> PsSurface { PsSurface { inner: from_glib_borrow(ptr), } } } #[cfg(feature = "use_glib")] impl FromGlibPtrFull<*mut ffi::cairo_surface_t> for PsSurface { #[inline] unsafe fn from_glib_full(ptr: *mut ffi::cairo_surface_t) -> PsSurface { PsSurface { inner: Surface::from_raw_full(ptr), } } } impl PsSurface { pub fn new>(width: f64, height: f64, path: P) -> Self { let path = path.as_ref().to_string_lossy().into_owned(); let path = CString::new(path).unwrap(); unsafe { Self { inner: Surface::from_raw_full(ffi::cairo_ps_surface_create( path.as_ptr(), width, height, )), } } } for_stream_constructors!(cairo_ps_surface_create_for_stream); pub fn get_levels() -> impl Iterator { let lvls_slice = unsafe { let mut vers_ptr: *mut ffi::cairo_ps_level_t = mem::uninitialized(); let mut num_vers = 0; ffi::cairo_ps_get_levels(&mut vers_ptr as _, &mut num_vers as _); std::slice::from_raw_parts(vers_ptr, num_vers as _) }; lvls_slice.iter().map(|v| PsLevel::from(*v)) } pub fn restrict(&self, level: PsLevel) { unsafe { ffi::cairo_ps_surface_restrict_to_level(self.inner.to_raw_none(), level.into()); } } pub fn get_eps(&self) -> bool { unsafe { ffi::cairo_ps_surface_get_eps(self.inner.to_raw_none()).as_bool() } } pub fn set_eps(&self, eps: bool) { unsafe { ffi::cairo_ps_surface_set_eps(self.inner.to_raw_none(), eps.into()); } } pub fn set_size(&self, width: f64, height: f64) { unsafe { ffi::cairo_ps_surface_set_size(self.inner.to_raw_none(), width, height); } } pub fn cairo_ps_surface_dsc_begin_setup(&self) { unsafe { ffi::cairo_ps_surface_dsc_begin_setup(self.inner.to_raw_none()); } } pub fn cairo_ps_surface_dsc_begin_page_setup(&self) { unsafe { ffi::cairo_ps_surface_dsc_begin_page_setup(self.inner.to_raw_none()); } } pub fn cairo_ps_surface_dsc_comment(&self, comment: &str) { let comment = CString::new(comment).unwrap(); unsafe { ffi::cairo_ps_surface_dsc_comment(self.inner.to_raw_none(), comment.as_ptr()); } } } impl Deref for PsSurface { type Target = Surface; fn deref(&self) -> &Surface { &self.inner } } impl fmt::Display for PsSurface { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "PsSurface") } } #[cfg(test)] mod test { use super::*; use context::*; use tempfile::tempfile; fn draw(surface: &Surface) { let cr = Context::new(surface); // Note: Not using RGBA here as PS doesn't natively support // semi-transparency and Cairo would then embed a rasterized bitmap cr.set_line_width(25.0); cr.set_source_rgb(1.0, 0.0, 0.0); cr.line_to(0., 0.); cr.line_to(100., 100.); cr.stroke(); cr.set_source_rgb(0.0, 0.0, 1.0); cr.line_to(0., 100.); cr.line_to(100., 0.); cr.stroke(); } fn draw_in_buffer() -> Vec { let buffer: Vec = vec![]; let surface = PsSurface::for_stream(100., 100., buffer); draw(&surface); *surface.finish_output_stream().unwrap().downcast().unwrap() } #[test] fn levels() { assert!(PsSurface::get_levels().any(|v| v == PsLevel::_2)); } #[test] fn level_string() { let ver_str = PsLevel::_2.as_str().unwrap(); assert_eq!(ver_str, "PS Level 2"); } #[test] fn eps() { let buffer: Vec = vec![]; let surface = PsSurface::for_stream(100., 100., buffer); surface.set_eps(true); assert_eq!(surface.get_eps(), true); } #[test] #[cfg(unix)] fn file() { let surface = PsSurface::new(100., 100., "/dev/null"); draw(&surface); surface.finish(); } #[test] fn writer() { let file = tempfile().expect("tempfile failed"); let surface = PsSurface::for_stream(100., 100., file); draw(&surface); let stream = surface.finish_output_stream().unwrap(); let file = stream.downcast::().unwrap(); let buffer = draw_in_buffer(); let file_size = file.metadata().unwrap().len(); assert_eq!(file_size, buffer.len() as u64); } #[test] fn ref_writer() { let mut file = tempfile().expect("tempfile failed"); let surface = unsafe { PsSurface::for_raw_stream(100., 100., &mut file) }; draw(&surface); surface.finish_output_stream().unwrap(); } #[test] fn buffer() { let buffer = draw_in_buffer(); let header = b"%!PS-Adobe"; assert_eq!(&buffer[..header.len()], header); } #[test] fn custom_writer() { struct CustomWriter(usize); impl io::Write for CustomWriter { fn write(&mut self, buf: &[u8]) -> io::Result { self.0 += buf.len(); Ok(buf.len()) } fn flush(&mut self) -> io::Result<()> { Ok(()) } } let custom_writer = CustomWriter(0); let surface = PsSurface::for_stream(20., 20., custom_writer); surface.set_size(100., 100.); draw(&surface); let stream = surface.finish_output_stream().unwrap(); let custom_writer = stream.downcast::().unwrap(); let buffer = draw_in_buffer(); assert_eq!(custom_writer.0, buffer.len()); } fn with_panicky_stream() -> PsSurface { struct PanicWriter; impl io::Write for PanicWriter { fn write(&mut self, _buf: &[u8]) -> io::Result { panic!("panic in writer"); } fn flush(&mut self) -> io::Result<()> { Ok(()) } } let surface = PsSurface::for_stream(20., 20., PanicWriter); surface.finish(); surface } #[test] #[should_panic] fn finish_stream_propagates_panic() { let _ = with_panicky_stream().finish_output_stream(); } } cairo-rs-0.7.1/src/quartz_surface.rs010066400017500001750000000071231350734563600156730ustar0000000000000000// Copyright 2017, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use std::convert::TryFrom; use std::fmt; use std::ops::Deref; use enums::{Format, SurfaceType}; use ffi; #[cfg(feature = "use_glib")] use glib::translate::*; use surface::Surface; use Status; use ffi::CGContextRef; #[derive(Debug)] pub struct QuartzSurface(Surface); impl TryFrom for QuartzSurface { type Error = Surface; fn try_from(surface: Surface) -> Result { if surface.get_type() == SurfaceType::Quartz { Ok(QuartzSurface(surface)) } else { Err(surface) } } } impl QuartzSurface { pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_surface_t) -> Result { let surface = Self::try_from(Surface::from_raw_full(ptr)).unwrap(); let status = surface.status(); match status { Status::Success => Ok(surface), _ => Err(status), } } pub fn create(format: Format, width: u32, height: u32) -> Result { unsafe { Self::from_raw_full(ffi::cairo_quartz_surface_create( format.into(), width, height, )) } } pub fn create_for_cg_context( cg_context: CGContextRef, width: u32, height: u32, ) -> Result { unsafe { Self::from_raw_full(ffi::cairo_quartz_surface_create_for_cg_context( cg_context, width, height, )) } } pub fn get_cg_context(&self) -> CGContextRef { unsafe { ffi::cairo_quartz_surface_get_cg_context(self.to_raw_none()) } } } #[cfg(feature = "use_glib")] impl<'a> ToGlibPtr<'a, *mut ffi::cairo_surface_t> for QuartzSurface { type Storage = &'a Surface; #[inline] fn to_glib_none(&'a self) -> Stash<'a, *mut ffi::cairo_surface_t, Self> { let stash = self.0.to_glib_none(); Stash(stash.0, stash.1) } #[inline] fn to_glib_full(&self) -> *mut ffi::cairo_surface_t { unsafe { ffi::cairo_surface_reference(self.to_glib_none().0) } } } #[cfg(feature = "use_glib")] impl FromGlibPtrNone<*mut ffi::cairo_surface_t> for QuartzSurface { #[inline] unsafe fn from_glib_none(ptr: *mut ffi::cairo_surface_t) -> QuartzSurface { Self::try_from(from_glib_none::<_, Surface>(ptr)).unwrap() } } #[cfg(feature = "use_glib")] impl FromGlibPtrBorrow<*mut ffi::cairo_surface_t> for QuartzSurface { #[inline] unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_surface_t) -> QuartzSurface { Self::try_from(from_glib_borrow::<_, Surface>(ptr)).unwrap() } } #[cfg(feature = "use_glib")] impl FromGlibPtrFull<*mut ffi::cairo_surface_t> for QuartzSurface { #[inline] unsafe fn from_glib_full(ptr: *mut ffi::cairo_surface_t) -> QuartzSurface { Self::try_from(from_glib_full::<_, Surface>(ptr)).unwrap() } } #[cfg(feature = "use_glib")] gvalue_impl!( QuartzSurface, ffi::cairo_surface_t, ffi::gobject::cairo_gobject_surface_get_type ); impl Deref for QuartzSurface { type Target = Surface; fn deref(&self) -> &Surface { &self.0 } } impl Clone for QuartzSurface { fn clone(&self) -> QuartzSurface { QuartzSurface(self.0.clone()) } } impl fmt::Display for QuartzSurface { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "QuartzSurface") } } cairo-rs-0.7.1/src/recording_surface.rs010066400017500001750000000067341350734563600163300ustar0000000000000000// Copyright 2019, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use std::convert::TryFrom; use std::fmt; use std::ops::Deref; use enums::{Content, SurfaceType}; use ffi; #[cfg(feature = "use_glib")] use glib::translate::*; use rectangle::Rectangle; use surface::Surface; #[derive(Debug)] pub struct RecordingSurface(Surface); impl TryFrom for RecordingSurface { type Error = Surface; fn try_from(surface: Surface) -> Result { if surface.get_type() == SurfaceType::Recording { Ok(RecordingSurface(surface)) } else { Err(surface) } } } impl RecordingSurface { pub fn create>>( content: Content, extends: T, ) -> Option { unsafe { let extends = extends.into(); let extends = match extends { Some(c) => c.to_raw_none(), None => ::std::ptr::null(), }; let p = ffi::cairo_recording_surface_create(content.into(), extends); if p.is_null() { None } else { Some(RecordingSurface(Surface::from_raw_full(p))) } } } pub fn get_extents(&self) -> Option { unsafe { let rectangle: Rectangle = ::std::mem::zeroed(); if ffi::cairo_recording_surface_get_extents(self.to_raw_none(), rectangle.to_raw_none()) .as_bool() { Some(rectangle) } else { None } } } pub fn ink_extents(&self) -> (f64, f64, f64, f64) { let mut x0 = 0.; let mut y0 = 0.; let mut width = 0.; let mut height = 0.; unsafe { ffi::cairo_recording_surface_ink_extents( self.to_raw_none(), &mut x0, &mut y0, &mut width, &mut height, ); } (x0, y0, width, height) } } #[cfg(feature = "use_glib")] impl FromGlibPtrNone<*mut ffi::cairo_surface_t> for RecordingSurface { #[inline] unsafe fn from_glib_none(ptr: *mut ffi::cairo_surface_t) -> RecordingSurface { RecordingSurface(Surface::from_glib_none(ptr)) } } #[cfg(feature = "use_glib")] impl FromGlibPtrBorrow<*mut ffi::cairo_surface_t> for RecordingSurface { #[inline] unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_surface_t) -> RecordingSurface { RecordingSurface(Surface::from_glib_borrow(ptr)) } } #[cfg(feature = "use_glib")] impl FromGlibPtrFull<*mut ffi::cairo_surface_t> for RecordingSurface { #[inline] unsafe fn from_glib_full(ptr: *mut ffi::cairo_surface_t) -> RecordingSurface { RecordingSurface(Surface::from_raw_full(ptr)) } } #[cfg(feature = "use_glib")] gvalue_impl!( RecordingSurface, ffi::cairo_surface_t, ffi::gobject::cairo_gobject_surface_get_type ); impl Deref for RecordingSurface { type Target = Surface; fn deref(&self) -> &Surface { &self.0 } } impl Clone for RecordingSurface { fn clone(&self) -> RecordingSurface { RecordingSurface(self.0.clone()) } } impl fmt::Display for RecordingSurface { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "RecordingSurface") } } cairo-rs-0.7.1/src/rectangle.rs010066400017500001750000000044021350734563600145760ustar0000000000000000use ffi; #[cfg(feature = "use_glib")] use glib::translate::*; use std::fmt; #[cfg(feature = "use_glib")] use std::mem; #[derive(Clone, Copy, Debug, PartialEq)] #[repr(C)] pub struct Rectangle { pub x: f64, pub y: f64, pub width: f64, pub height: f64, } #[cfg(feature = "use_glib")] #[doc(hidden)] impl Uninitialized for Rectangle { #[inline] unsafe fn uninitialized() -> Self { mem::uninitialized() } } #[cfg(feature = "use_glib")] #[doc(hidden)] impl<'a> ToGlibPtr<'a, *const ffi::cairo_rectangle_t> for Rectangle { type Storage = &'a Self; #[inline] fn to_glib_none(&'a self) -> Stash<'a, *const ffi::cairo_rectangle_t, Self> { let ptr: *const Rectangle = &*self; Stash(ptr as *const ffi::cairo_rectangle_t, self) } } #[cfg(feature = "use_glib")] #[doc(hidden)] impl<'a> ToGlibPtrMut<'a, *mut ffi::cairo_rectangle_t> for Rectangle { type Storage = &'a mut Self; #[inline] fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut ffi::cairo_rectangle_t, Self> { let ptr: *mut Rectangle = &mut *self; StashMut(ptr as *mut ffi::cairo_rectangle_t, self) } } #[cfg(feature = "use_glib")] #[doc(hidden)] impl FromGlibPtrNone<*const ffi::cairo_rectangle_t> for Rectangle { unsafe fn from_glib_none(ptr: *const ffi::cairo_rectangle_t) -> Self { *(ptr as *const Rectangle) } } #[cfg(feature = "use_glib")] #[doc(hidden)] impl FromGlibPtrBorrow<*mut ffi::cairo_rectangle_t> for Rectangle { unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_rectangle_t) -> Self { *(ptr as *mut Rectangle) } } #[cfg(feature = "use_glib")] #[doc(hidden)] impl FromGlibPtrNone<*mut ffi::cairo_rectangle_t> for Rectangle { unsafe fn from_glib_none(ptr: *mut ffi::cairo_rectangle_t) -> Self { *(ptr as *mut Rectangle) } } #[cfg(feature = "use_glib")] gvalue_impl!( Rectangle, ffi::cairo_rectangle_t, ffi::gobject::cairo_gobject_rectangle_get_type ); impl Rectangle { pub fn to_raw_none(&self) -> *mut ffi::cairo_rectangle_t { let ptr = &*self as *const Rectangle as usize; ptr as *mut ffi::cairo_rectangle_t } } impl fmt::Display for Rectangle { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Rectangle") } } cairo-rs-0.7.1/src/rectangle_int.rs010066400017500001750000000045771350734563600154650ustar0000000000000000use ffi; #[cfg(feature = "use_glib")] use glib::translate::*; use std::fmt; #[cfg(feature = "use_glib")] use std::mem; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[repr(C)] pub struct RectangleInt { pub x: i32, pub y: i32, pub width: i32, pub height: i32, } #[cfg(feature = "use_glib")] #[doc(hidden)] impl Uninitialized for RectangleInt { #[inline] unsafe fn uninitialized() -> Self { mem::uninitialized() } } #[cfg(feature = "use_glib")] #[doc(hidden)] impl<'a> ToGlibPtr<'a, *const ffi::cairo_rectangle_int_t> for RectangleInt { type Storage = &'a Self; #[inline] fn to_glib_none(&'a self) -> Stash<'a, *const ffi::cairo_rectangle_int_t, Self> { let ptr: *const RectangleInt = &*self; Stash(ptr as *const ffi::cairo_rectangle_int_t, self) } } #[cfg(feature = "use_glib")] #[doc(hidden)] impl<'a> ToGlibPtrMut<'a, *mut ffi::cairo_rectangle_int_t> for RectangleInt { type Storage = &'a mut Self; #[inline] fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut ffi::cairo_rectangle_int_t, Self> { let ptr: *mut RectangleInt = &mut *self; StashMut(ptr as *mut ffi::cairo_rectangle_int_t, self) } } #[cfg(feature = "use_glib")] #[doc(hidden)] impl FromGlibPtrNone<*const ffi::cairo_rectangle_int_t> for RectangleInt { unsafe fn from_glib_none(ptr: *const ffi::cairo_rectangle_int_t) -> Self { *(ptr as *const RectangleInt) } } #[cfg(feature = "use_glib")] #[doc(hidden)] impl FromGlibPtrBorrow<*mut ffi::cairo_rectangle_int_t> for RectangleInt { unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_rectangle_int_t) -> Self { *(ptr as *mut RectangleInt) } } #[cfg(feature = "use_glib")] #[doc(hidden)] impl FromGlibPtrNone<*mut ffi::cairo_rectangle_int_t> for RectangleInt { unsafe fn from_glib_none(ptr: *mut ffi::cairo_rectangle_int_t) -> Self { *(ptr as *mut RectangleInt) } } #[cfg(feature = "use_glib")] gvalue_impl!( RectangleInt, ffi::cairo_rectangle_int_t, ffi::gobject::cairo_gobject_rectangle_int_get_type ); impl RectangleInt { pub fn to_raw_none(&self) -> *mut ffi::cairo_rectangle_int_t { let ptr = &*self as *const RectangleInt as usize; ptr as *mut ffi::cairo_rectangle_int_t } } impl fmt::Display for RectangleInt { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "RectangleInt") } } cairo-rs-0.7.1/src/region.rs010066400017500001750000000152101350734563600141140ustar0000000000000000// Copyright 2013-2017, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use enums::{RegionOverlap, Status}; use ffi; #[cfg(feature = "use_glib")] use glib::translate::*; use std::fmt; use RectangleInt; use ffi::cairo_region_t; #[derive(Debug)] pub struct Region(*mut cairo_region_t, bool); #[cfg(feature = "use_glib")] #[doc(hidden)] impl<'a> ToGlibPtr<'a, *mut ffi::cairo_region_t> for &'a Region { type Storage = &'a Region; #[inline] fn to_glib_none(&self) -> Stash<'a, *mut ffi::cairo_region_t, &'a Region> { Stash(self.0, *self) } #[inline] fn to_glib_full(&self) -> *mut ffi::cairo_region_t { unsafe { ffi::cairo_region_reference(self.0) } } } #[cfg(feature = "use_glib")] #[doc(hidden)] impl<'a> ToGlibPtrMut<'a, *mut ffi::cairo_region_t> for Region { type Storage = &'a mut Self; // FIXME: This is unsafe: regions are reference counted so we could get multiple mutable // references here #[inline] fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut ffi::cairo_region_t, Self> { StashMut(self.0, self) } } #[cfg(feature = "use_glib")] #[doc(hidden)] impl FromGlibPtrNone<*mut ffi::cairo_region_t> for Region { #[inline] unsafe fn from_glib_none(ptr: *mut ffi::cairo_region_t) -> Region { Self::from_raw_none(ptr) } } #[cfg(feature = "use_glib")] #[doc(hidden)] impl FromGlibPtrBorrow<*mut ffi::cairo_region_t> for Region { #[inline] unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_region_t) -> Region { Self::from_raw_borrow(ptr) } } #[cfg(feature = "use_glib")] #[doc(hidden)] impl FromGlibPtrFull<*mut ffi::cairo_region_t> for Region { #[inline] unsafe fn from_glib_full(ptr: *mut ffi::cairo_region_t) -> Region { Self::from_raw_full(ptr) } } #[cfg(feature = "use_glib")] gvalue_impl!( Region, ffi::cairo_region_t, ffi::gobject::cairo_gobject_region_get_type ); impl Clone for Region { fn clone(&self) -> Region { unsafe { Self::from_raw_none(self.to_raw_none()) } } } impl Drop for Region { fn drop(&mut self) { if !self.1 { unsafe { ffi::cairo_region_destroy(self.0); } } } } impl PartialEq for Region { fn eq(&self, other: &Region) -> bool { unsafe { ffi::cairo_region_equal(self.0, other.0).as_bool() } } } impl Eq for Region {} impl Region { #[inline] pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_region_t) -> Region { assert!(!ptr.is_null()); ffi::cairo_region_reference(ptr); Region(ptr, false) } #[inline] pub unsafe fn from_raw_borrow(ptr: *mut ffi::cairo_region_t) -> Region { assert!(!ptr.is_null()); Region(ptr, true) } #[inline] pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_region_t) -> Region { assert!(!ptr.is_null()); Region(ptr, false) } pub fn to_raw_none(&self) -> *mut ffi::cairo_region_t { self.0 } pub fn create() -> Region { unsafe { Self::from_raw_full(ffi::cairo_region_create()) } } pub fn create_rectangle(rectangle: &RectangleInt) -> Region { unsafe { Self::from_raw_full(ffi::cairo_region_create_rectangle(rectangle.to_raw_none())) } } pub fn create_rectangles(rectangles: &[RectangleInt]) -> Region { unsafe { Self::from_raw_full(ffi::cairo_region_create_rectangles( rectangles.as_ptr() as *mut ffi::cairo_rectangle_int_t, rectangles.len() as i32, )) } } pub fn copy(&self) -> Region { unsafe { Self::from_raw_full(ffi::cairo_region_copy(self.0)) } } pub fn status(&self) -> Status { unsafe { Status::from(ffi::cairo_region_status(self.0)) } } pub fn get_extents(&self, rectangle: &mut RectangleInt) { unsafe { ffi::cairo_region_get_extents(self.0, rectangle.to_raw_none()) } } pub fn num_rectangles(&self) -> i32 { unsafe { ffi::cairo_region_num_rectangles(self.0) } } pub fn get_rectangle(&self, nth: i32) -> RectangleInt { unsafe { let rectangle: RectangleInt = ::std::mem::zeroed(); ffi::cairo_region_get_rectangle(self.0, nth, rectangle.to_raw_none()); rectangle } } pub fn is_empty(&self) -> bool { unsafe { ffi::cairo_region_is_empty(self.0).as_bool() } } pub fn contains_point(&self, x: i32, y: i32) -> bool { unsafe { ffi::cairo_region_contains_point(self.0, x, y).as_bool() } } pub fn contains_rectangle(&self, rectangle: &RectangleInt) -> RegionOverlap { unsafe { RegionOverlap::from(ffi::cairo_region_contains_rectangle( self.0, rectangle.to_raw_none(), )) } } pub fn translate(&self, dx: i32, dy: i32) { unsafe { ffi::cairo_region_translate(self.0, dx, dy) } } pub fn intersect(&self, other: &Region) -> Status { unsafe { Status::from(ffi::cairo_region_intersect(self.0, other.0)) } } pub fn intersect_rectangle(&self, rectangle: &RectangleInt) -> Status { unsafe { Status::from(ffi::cairo_region_intersect_rectangle( self.0, rectangle.to_raw_none(), )) } } pub fn subtract(&self, other: &Region) -> Status { unsafe { Status::from(ffi::cairo_region_subtract(self.0, other.0)) } } pub fn subtract_rectangle(&self, rectangle: &RectangleInt) -> Status { unsafe { Status::from(ffi::cairo_region_subtract_rectangle( self.0, rectangle.to_raw_none(), )) } } pub fn union(&self, other: &Region) -> Status { unsafe { Status::from(ffi::cairo_region_union(self.0, other.0)) } } pub fn union_rectangle(&self, rectangle: &RectangleInt) -> Status { unsafe { Status::from(ffi::cairo_region_union_rectangle( self.0, rectangle.to_raw_none(), )) } } pub fn xor(&self, other: &Region) -> Status { unsafe { Status::from(ffi::cairo_region_xor(self.0, other.0)) } } pub fn xor_rectangle(&self, rectangle: &RectangleInt) -> Status { unsafe { Status::from(ffi::cairo_region_xor_rectangle( self.0, rectangle.to_raw_none(), )) } } } impl fmt::Display for Region { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Region") } } cairo-rs-0.7.1/src/stream.rs010066400017500001750000000217471350734563600141400ustar0000000000000000// Copyright 2019, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use ffi::{self, cairo_status_t}; use {Status, Surface, UserDataKey}; use libc::{c_double, c_uchar, c_uint, c_void}; use std::any::Any; use std::cell::{Cell, RefCell}; use std::io; use std::panic::AssertUnwindSafe; use std::rc::Rc; macro_rules! for_stream_constructors { ($constructor_ffi: ident) => { /// Takes full ownership of the output stream, /// which is not allowed to borrow any lifetime shorter than `'static`. /// /// Because the underlying `cairo_surface_t` is reference-counted, /// a lifetime parameter in a Rust wrapper type would not be enough to track /// how long it can keep writing to the stream. pub fn for_stream(width: f64, height: f64, stream: W) -> Self { Self { inner: Surface::_for_stream(ffi::$constructor_ffi, width, height, stream), } } /// Allows writing to a borrowed stream. The lifetime of the borrow is not tracked. /// /// # Safety /// /// The value that `stream` points to must live at least until the underlying `cairo_surface_t` /// (which maybe be longer then the Rust `PdfSurface` wrapper, because of reference-counting), /// or until the output stream is removed from the surface with [`Surface::take_output_stream`]. /// /// Since the former is hard to track for sure, the latter is strongly recommended. /// The concrete type behind the `Box` value returned by `take_output_stream` /// is private, so you won’t be able to downcast it. /// But removing it anyway ensures that later writes do no go through a dangling pointer. pub unsafe fn for_raw_stream( width: f64, height: f64, stream: *mut W, ) -> Self { Self { inner: Surface::_for_raw_stream(ffi::$constructor_ffi, width, height, stream), } } }; } impl Surface { pub(crate) fn _for_stream( constructor: Constructor, width: f64, height: f64, stream: W, ) -> Self { let env_rc = Rc::new(CallbackEnvironment { mutable: RefCell::new(MutableCallbackEnvironment { stream: Some((Box::new(stream), None)), unwind_payload: None, }), saw_already_borrowed: Cell::new(false), }); let env: *const CallbackEnvironment = &*env_rc; unsafe { let ptr = constructor(Some(write_callback::), env as *mut c_void, width, height); let surface = Surface::from_raw_full(ptr); surface.set_user_data(&STREAM_CALLBACK_ENVIRONMENT, env_rc); surface } } pub(crate) unsafe fn _for_raw_stream( constructor: Constructor, width: f64, height: f64, stream: *mut W, ) -> Self { Self::_for_stream(constructor, width, height, RawStream(stream)) } /// Finish the surface, then remove and return the output stream if any. /// /// This calls [`Surface::finish`], to make sure pending writes are done. /// /// This is relevant for surfaces created for example with [`PdfSurface::for_stream`]. /// /// Use [`Box::downcast`] to recover the concrete stream type. /// /// # Panics /// /// This method panics if: /// /// * This method was already called for this surface, or /// * This surface was not created with an output stream in the first place, or /// * A previous write to this surface panicked, or /// * A previous write happened while another write was ongoing, or /// * A write is ongoing now. /// /// The latter two cases can only occur with a pathological output stream type /// that accesses the same surface again from `Write::write_all`. pub fn finish_output_stream(&self) -> Result, StreamWithError> { self.finish(); let env = self .get_user_data_ptr(&STREAM_CALLBACK_ENVIRONMENT) .expect("surface without an output stream"); // Safety: since `STREAM_CALLBACK_ENVIRONMENT` is private and we never // call `set_user_data` again or `remove_user_data` with it, // the contract of `get_user_data_ptr` says that the user data entry // lives as long as the underlying `cairo_surface_t` // which is at least as long as `self`. let env = unsafe { &*env.as_ptr() }; if env.saw_already_borrowed.get() { panic!( "The output stream’s RefCell was already borrowed when cairo attempted a write" ) } let mut mutable = env.mutable.borrow_mut(); if let Some(payload) = mutable.unwind_payload.take() { std::panic::resume_unwind(payload) } let (stream, io_error) = mutable .stream .take() .expect("output stream was already taken"); if let Some(error) = io_error { Err(StreamWithError { stream, error }) } else { Ok(stream) } } } pub struct StreamWithError { pub stream: Box, pub error: io::Error, } impl std::fmt::Debug for StreamWithError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { self.error.fmt(f) } } impl std::fmt::Display for StreamWithError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { self.error.fmt(f) } } impl From for io::Error { fn from(e: StreamWithError) -> Self { e.error } } pub(crate) type Constructor = unsafe extern "C" fn( ffi::cairo_write_func_t, *mut c_void, c_double, c_double, ) -> *mut ffi::cairo_surface_t; static STREAM_CALLBACK_ENVIRONMENT: UserDataKey = UserDataKey::new(); struct CallbackEnvironment { mutable: RefCell, saw_already_borrowed: Cell, } struct MutableCallbackEnvironment { stream: Option<(Box, Option)>, unwind_payload: Option>, } // Safety: unwinding into C is undefined behavior (https://github.com/rust-lang/rust/issues/58794) // so code outside of the `catch_unwind` call must never panic. extern "C" fn write_callback( env: *mut c_void, data: *mut c_uchar, length: c_uint, ) -> cairo_status_t { // This is consistent with the type of `env` in `Surface::_for_stream`. let env: *const CallbackEnvironment = env as _; // Safety: the user data entry keeps `Rc` alive // until the surface is destroyed. // If this is called by cairo, the surface is still alive. let env: &CallbackEnvironment = unsafe { &*env }; if let Ok(mut mutable) = env.mutable.try_borrow_mut() { if let MutableCallbackEnvironment { stream: Some(( stream, // Don’t attempt another write if a previous one errored or panicked: io_error @ None, )), unwind_payload: unwind_payload @ None, } = &mut *mutable { // Safety: `write_callback` was instanciated in `Surface::_for_stream` // with a W parameter consistent with the box that was unsized to `Box`. let stream = unsafe { stream.downcast_mut_unchecked::() }; // Safety: this is the callback contract from cairo’s API let data = unsafe { std::slice::from_raw_parts(data, length as usize) }; // Because `::write_all` is a generic, // we must conservatively assume that it can panic. let result = std::panic::catch_unwind(AssertUnwindSafe(|| stream.write_all(data))); match result { Ok(Ok(())) => return Status::Success.into(), Ok(Err(error)) => { *io_error = Some(error); } Err(payload) => { *unwind_payload = Some(payload); } } } } else { env.saw_already_borrowed.set(true) } Status::WriteError.into() } struct RawStream(*mut W); impl io::Write for RawStream { fn write(&mut self, buf: &[u8]) -> io::Result { unsafe { (*self.0).write(buf) } } fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { unsafe { (*self.0).write_all(buf) } } fn flush(&mut self) -> io::Result<()> { unsafe { (*self.0).flush() } } } trait AnyExt { /// Any::downcast_mut, but YOLO unsafe fn downcast_mut_unchecked(&mut self) -> &mut T { let ptr = self as *mut Self as *mut T; &mut *ptr } } impl AnyExt for dyn Any {} cairo-rs-0.7.1/src/surface.rs010066400017500001750000000237551350734563600142760ustar0000000000000000// Copyright 2015-2016, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use libc::{c_ulong, c_void}; use std::ffi::CString; use std::fmt; use std::ops::Deref; use std::ptr; use std::slice; use enums::{Content, Format, Status, SurfaceType}; use ffi; #[cfg(feature = "use_glib")] use glib::translate::*; use image_surface::ImageSurface; use rectangle_int::RectangleInt; #[derive(Debug)] pub struct Surface(*mut ffi::cairo_surface_t, bool); impl Surface { pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_surface_t) -> Surface { assert!(!ptr.is_null()); ffi::cairo_surface_reference(ptr); Surface(ptr, false) } pub unsafe fn from_raw_borrow(ptr: *mut ffi::cairo_surface_t) -> Surface { assert!(!ptr.is_null()); Surface(ptr, true) } pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_surface_t) -> Surface { assert!(!ptr.is_null()); Surface(ptr, false) } pub fn to_raw_none(&self) -> *mut ffi::cairo_surface_t { self.0 } pub fn create_similar(&self, content: Content, width: i32, height: i32) -> Surface { unsafe { Self::from_raw_full(ffi::cairo_surface_create_similar( self.0, content.into(), width, height, )) } } pub fn get_mime_data(&self, mime_type: &str) -> Option> { let data_ptr: *mut u8 = ptr::null_mut(); let mut length: c_ulong = 0; unsafe { let mime_type = CString::new(mime_type).unwrap(); ffi::cairo_surface_get_mime_data( self.to_raw_none(), mime_type.as_ptr(), &data_ptr, &mut length, ); if !data_ptr.is_null() && length != 0 { Some(slice::from_raw_parts(data_ptr as *const u8, length as usize).to_vec()) } else { None } } } pub unsafe fn get_mime_data_raw(&self, mime_type: &str) -> Option<&[u8]> { let data_ptr: *mut u8 = ptr::null_mut(); let mut length: c_ulong = 0; let mime_type = CString::new(mime_type).unwrap(); ffi::cairo_surface_get_mime_data( self.to_raw_none(), mime_type.as_ptr(), &data_ptr, &mut length, ); if !data_ptr.is_null() && length != 0 { Some(slice::from_raw_parts( data_ptr as *const u8, length as usize, )) } else { None } } pub fn set_mime_data + 'static>( &self, mime_type: &str, slice: T, ) -> Result<(), Status> { let b = Box::new(slice); let (size, data) = { let slice = (*b).as_ref(); (slice.len(), slice.as_ptr()) }; let user_data = Box::into_raw(b); unsafe extern "C" fn unbox(data: *mut c_void) { let data: Box = Box::from_raw(data as *mut T); drop(data); } let status = unsafe { let mime_type = CString::new(mime_type).unwrap(); ffi::cairo_surface_set_mime_data( self.to_raw_none(), mime_type.as_ptr(), data, size as c_ulong, Some(unbox::), user_data as *mut _, ) }; match Status::from(status) { Status::Success => Ok(()), x => Err(x), } } pub fn supports_mime_type(&self, mime_type: &str) -> bool { unsafe { let mime_type = CString::new(mime_type).unwrap(); ffi::cairo_surface_supports_mime_type(self.0, mime_type.as_ptr()).as_bool() } } pub fn set_device_offset(&self, x_offset: f64, y_offset: f64) { unsafe { ffi::cairo_surface_set_device_offset(self.to_raw_none(), x_offset, y_offset) } } pub fn get_device_offset(&self) -> (f64, f64) { let mut x_offset = 0.0f64; let mut y_offset = 0.0f64; unsafe { ffi::cairo_surface_get_device_offset(self.to_raw_none(), &mut x_offset, &mut y_offset); } (x_offset, y_offset) } #[cfg(any(feature = "v1_14", feature = "dox"))] pub fn set_device_scale(&self, x_scale: f64, y_scale: f64) { unsafe { ffi::cairo_surface_set_device_scale(self.to_raw_none(), x_scale, y_scale) } } #[cfg(any(feature = "v1_14", feature = "dox"))] pub fn get_device_scale(&self) -> (f64, f64) { let mut x_scale = 0.0f64; let mut y_scale = 0.0f64; unsafe { ffi::cairo_surface_get_device_scale(self.to_raw_none(), &mut x_scale, &mut y_scale); } (x_scale, y_scale) } pub fn set_fallback_resolution(&self, x_pixels_per_inch: f64, y_pixels_per_inch: f64) { unsafe { ffi::cairo_surface_set_fallback_resolution( self.to_raw_none(), x_pixels_per_inch, y_pixels_per_inch, ) } } pub fn get_fallback_resolution(&self) -> (f64, f64) { let mut x_pixels_per_inch = 0.0f64; let mut y_pixels_per_inch = 0.0f64; unsafe { ffi::cairo_surface_get_fallback_resolution( self.to_raw_none(), &mut x_pixels_per_inch, &mut y_pixels_per_inch, ); } (x_pixels_per_inch, y_pixels_per_inch) } pub fn create_similar_image(&self, format: Format, width: i32, height: i32) -> Option { unsafe { let p = ffi::cairo_surface_create_similar_image( self.to_raw_none(), format.into(), width, height, ); if p.is_null() { None } else { Some(Self::from_raw_full(p)) } } } pub fn map_to_image( &self, extents: Option, ) -> Result { unsafe { ImageSurface::from_raw_full(match extents { Some(ref e) => ffi::cairo_surface_map_to_image(self.to_raw_none(), e.to_raw_none()), None => ffi::cairo_surface_map_to_image(self.to_raw_none(), 0 as *const _), }) .map(|s| MappedImageSurface { original_surface: self.clone(), image_surface: s, }) } } user_data_methods! { ffi::cairo_surface_get_user_data, ffi::cairo_surface_set_user_data, } } #[cfg(feature = "use_glib")] impl<'a> ToGlibPtr<'a, *mut ffi::cairo_surface_t> for Surface { type Storage = &'a Surface; #[inline] fn to_glib_none(&'a self) -> Stash<'a, *mut ffi::cairo_surface_t, Self> { Stash(self.to_raw_none(), self) } #[inline] fn to_glib_full(&self) -> *mut ffi::cairo_surface_t { unsafe { ffi::cairo_surface_reference(self.to_raw_none()) } } } #[cfg(feature = "use_glib")] impl FromGlibPtrNone<*mut ffi::cairo_surface_t> for Surface { #[inline] unsafe fn from_glib_none(ptr: *mut ffi::cairo_surface_t) -> Surface { Self::from_raw_none(ptr) } } #[cfg(feature = "use_glib")] impl FromGlibPtrBorrow<*mut ffi::cairo_surface_t> for Surface { #[inline] unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_surface_t) -> Surface { Self::from_raw_borrow(ptr) } } #[cfg(feature = "use_glib")] impl FromGlibPtrFull<*mut ffi::cairo_surface_t> for Surface { #[inline] unsafe fn from_glib_full(ptr: *mut ffi::cairo_surface_t) -> Surface { Self::from_raw_full(ptr) } } #[cfg(feature = "use_glib")] gvalue_impl!( Surface, ffi::cairo_surface_t, ffi::gobject::cairo_gobject_surface_get_type ); impl Clone for Surface { fn clone(&self) -> Surface { unsafe { Self::from_raw_none(self.0) } } } impl Drop for Surface { fn drop(&mut self) { if !self.1 { unsafe { ffi::cairo_surface_destroy(self.0); } } } } impl fmt::Display for Surface { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Surface") } } impl Surface { pub fn flush(&self) { unsafe { ffi::cairo_surface_flush(self.0); } } pub fn finish(&self) { unsafe { ffi::cairo_surface_finish(self.0); } } pub fn get_type(&self) -> SurfaceType { unsafe { SurfaceType::from(ffi::cairo_surface_get_type(self.0)) } } pub fn status(&self) -> Status { unsafe { Status::from(ffi::cairo_surface_status(self.0)) } } } #[derive(Debug)] pub struct MappedImageSurface { original_surface: Surface, image_surface: ImageSurface, } impl Deref for MappedImageSurface { type Target = ImageSurface; fn deref(&self) -> &ImageSurface { &self.image_surface } } impl Drop for MappedImageSurface { fn drop(&mut self) { unsafe { ffi::cairo_surface_unmap_image( self.original_surface.to_raw_none(), self.image_surface.to_raw_none(), ); ffi::cairo_surface_reference(self.image_surface.to_raw_none()); } } } impl fmt::Display for MappedImageSurface { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "MappedImageSurface") } } #[cfg(test)] mod tests { use constants::MIME_TYPE_PNG; use Format; use ImageSurface; #[test] fn mime_data() { let surface = ImageSurface::create(Format::ARgb32, 500, 500).unwrap(); let data = surface.get_mime_data(MIME_TYPE_PNG); /* Initially the data for any mime type has to be none */ assert!(data.is_none()); assert!(surface.set_mime_data(MIME_TYPE_PNG, &[1u8, 10u8]).is_ok()); let data = surface.get_mime_data(MIME_TYPE_PNG).unwrap(); assert_eq!(data, &[1u8, 10u8]); } } cairo-rs-0.7.1/src/svg.rs010066400017500001750000000171771350734563600134460ustar0000000000000000// Copyright 2018-2019, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use std::ffi::{CStr, CString}; use std::fmt; use std::io; use std::mem; use std::ops::Deref; use std::path::Path; #[cfg(any(all(feature = "svg", feature = "v1_16"), feature = "dox"))] use enums::SvgUnit; use enums::SvgVersion; use ffi; use surface::Surface; #[cfg(feature = "use_glib")] use glib::translate::*; impl SvgVersion { pub fn as_str(self) -> Option<&'static str> { unsafe { let res = ffi::cairo_svg_version_to_string(self.into()); res.as_ref() .and_then(|cstr| CStr::from_ptr(cstr as _).to_str().ok()) } } } #[derive(Debug)] pub struct SvgSurface { inner: Surface, } impl SvgSurface { pub fn new>(width: f64, height: f64, path: P) -> SvgSurface { let path = path.as_ref().to_string_lossy().into_owned(); let path = CString::new(path).unwrap(); unsafe { Self { inner: Surface::from_raw_full(ffi::cairo_svg_surface_create( path.as_ptr(), width, height, )), } } } for_stream_constructors!(cairo_svg_surface_create_for_stream); pub fn get_versions() -> impl Iterator { let vers_slice = unsafe { let mut vers_ptr: *mut ffi::cairo_svg_version_t = mem::uninitialized(); let mut num_vers = 0; ffi::cairo_svg_get_versions(&mut vers_ptr as _, &mut num_vers as _); std::slice::from_raw_parts(vers_ptr, num_vers as _) }; vers_slice.iter().map(|v| SvgVersion::from(*v)) } pub fn restrict(&self, version: SvgVersion) { unsafe { ffi::cairo_svg_surface_restrict_to_version(self.inner.to_raw_none(), version.into()); } } #[cfg(any(all(feature = "svg", feature = "v1_16"), feature = "dox"))] pub fn set_document_unit(&mut self, unit: SvgUnit) { unsafe { ffi::cairo_svg_surface_set_document_unit(self.inner.to_raw_none(), unit.into()); } } #[cfg(any(all(feature = "svg", feature = "v1_16"), feature = "dox"))] pub fn get_document_unit(&self) -> SvgUnit { unsafe { SvgUnit::from(ffi::cairo_svg_surface_get_document_unit( self.inner.to_raw_none(), )) } } } impl Deref for SvgSurface { type Target = Surface; fn deref(&self) -> &Surface { &self.inner } } #[cfg(feature = "use_glib")] impl<'a> ToGlibPtr<'a, *mut ffi::cairo_surface_t> for SvgSurface { type Storage = &'a Surface; #[inline] fn to_glib_none(&'a self) -> Stash<'a, *mut ffi::cairo_surface_t, Self> { let stash = self.inner.to_glib_none(); Stash(stash.0, stash.1) } } #[cfg(feature = "use_glib")] impl FromGlibPtrNone<*mut ffi::cairo_surface_t> for SvgSurface { #[inline] unsafe fn from_glib_none(ptr: *mut ffi::cairo_surface_t) -> SvgSurface { SvgSurface { inner: from_glib_borrow(ptr), } } } #[cfg(feature = "use_glib")] impl FromGlibPtrBorrow<*mut ffi::cairo_surface_t> for SvgSurface { #[inline] unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_surface_t) -> SvgSurface { SvgSurface { inner: from_glib_borrow(ptr), } } } #[cfg(feature = "use_glib")] impl FromGlibPtrFull<*mut ffi::cairo_surface_t> for SvgSurface { #[inline] unsafe fn from_glib_full(ptr: *mut ffi::cairo_surface_t) -> SvgSurface { Self { inner: Surface::from_raw_full(ptr), } } } impl fmt::Display for SvgSurface { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "SvgSurface") } } #[cfg(test)] mod test { use super::*; use context::*; use tempfile::tempfile; fn draw(surface: &Surface) { let cr = Context::new(surface); cr.set_line_width(25.0); cr.set_source_rgba(1.0, 0.0, 0.0, 0.5); cr.line_to(0., 0.); cr.line_to(100., 100.); cr.stroke(); cr.set_source_rgba(0.0, 0.0, 1.0, 0.5); cr.line_to(0., 100.); cr.line_to(100., 0.); cr.stroke(); } fn draw_in_buffer() -> Vec { let buffer: Vec = vec![]; let surface = SvgSurface::for_stream(100., 100., buffer); draw(&surface); *surface.finish_output_stream().unwrap().downcast().unwrap() } fn assert_len_close_enough(len_a: usize, len_b: usize) { // It seems cairo randomizies some element IDs which might make one svg slightly // larger than the other. Here we make sure the difference is within ~10%. let len_diff = (len_a as isize - len_b as isize).abs() as usize; assert!(len_diff < len_b / 10); } #[test] fn versions() { assert!(SvgSurface::get_versions().any(|v| v == SvgVersion::_1_1)); } #[test] fn version_string() { let ver_str = SvgVersion::_1_1.as_str().unwrap(); assert_eq!(ver_str, "SVG 1.1"); } #[test] #[cfg(unix)] fn file() { let surface = SvgSurface::new(100., 100., "/dev/null"); draw(&surface); surface.finish(); } #[test] fn writer() { let file = tempfile().expect("tempfile failed"); let surface = SvgSurface::for_stream(100., 100., file); draw(&surface); let stream = surface.finish_output_stream().unwrap(); let file = stream.downcast::().unwrap(); let buffer = draw_in_buffer(); let file_size = file.metadata().unwrap().len(); assert_len_close_enough(file_size as usize, buffer.len()); } #[test] fn ref_writer() { let mut file = tempfile().expect("tempfile failed"); let surface = unsafe { SvgSurface::for_raw_stream(100., 100., &mut file) }; draw(&surface); surface.finish_output_stream().unwrap(); } #[test] fn buffer() { let buffer = draw_in_buffer(); let header = b" io::Result { self.1.write(buf)?; self.0 += buf.len(); Ok(buf.len()) } fn flush(&mut self) -> io::Result<()> { Ok(()) } } let file = tempfile().expect("tempfile failed"); let custom_writer = CustomWriter(0, file); let surface = SvgSurface::for_stream(100., 100., custom_writer); draw(&surface); let stream = surface.finish_output_stream().unwrap(); let custom_writer = stream.downcast::().unwrap(); let buffer = draw_in_buffer(); assert_len_close_enough(custom_writer.0, buffer.len()); } fn with_panicky_stream() -> SvgSurface { struct PanicWriter; impl io::Write for PanicWriter { fn write(&mut self, _buf: &[u8]) -> io::Result { panic!("panic in writer"); } fn flush(&mut self) -> io::Result<()> { Ok(()) } } let surface = SvgSurface::for_stream(20., 20., PanicWriter); surface.finish(); surface } #[test] #[should_panic] fn finish_stream_propagates_panic() { let _ = with_panicky_stream().finish_output_stream(); } } cairo-rs-0.7.1/src/user_data.rs010066400017500001750000000131571350734563600146100ustar0000000000000000use std::marker::PhantomData; use ffi::cairo_user_data_key_t; pub struct UserDataKey { pub(crate) ffi: cairo_user_data_key_t, marker: PhantomData<*const T>, } unsafe impl Sync for UserDataKey {} impl UserDataKey { pub const fn new() -> Self { UserDataKey { ffi: cairo_user_data_key_t { unused: 0 }, marker: PhantomData, } } } // In a safe API for user data we can’t make `get_user_data` // transfer full ownership of the value to the caller (e.g. by returning `Box`) // because `self` still has a pointer to that value // and `get_user_data` could be called again with the same key. // // We also can’t return a `&T` reference that borrows from `self` // because the value could be removed with `remove_user_data` or replaced with `set_user_data` // while the borrow still needs to be valid. // (Borrowing with `&mut self` would not help as `Self` can be itself reference-counted.) // // Therefore the value must be reference-counted. // // We use `Rc` over `Arc` because the types implementing these methods are `!Send` and `!Sync`. // See macro_rules! user_data_methods { ($ffi_get_user_data: path, $ffi_set_user_data: path,) => { /// Attach user data to `self` for the given `key`. pub fn set_user_data(&self, key: &'static crate::UserDataKey, value: std::rc::Rc) { unsafe extern "C" fn destructor(ptr: *mut libc::c_void) { let ptr: *const T = ptr as _; drop(std::rc::Rc::from_raw(ptr)) } // Safety: // // The destructor’s cast and `from_raw` are symetric // with the `into_raw` and cast below. // They both transfer ownership of one strong reference: // neither of them touches the reference count. let ptr: *const T = std::rc::Rc::into_raw(value); let ptr = ptr as *mut T as *mut libc::c_void; let result = unsafe { $ffi_set_user_data(self.to_raw_none(), &key.ffi, ptr, Some(destructor::)) }; Status::from(result).ensure_valid() } /// Return the user data previously attached to `self` with the given `key`, if any. pub fn get_user_data(&self, key: &'static crate::UserDataKey) -> Option> { let ptr = self.get_user_data_ptr(key)?.as_ptr(); // Safety: // // `Rc::from_raw` would normally take ownership of a strong reference for this pointer. // But `self` still has a copy of that pointer and `get_user_data` can be called again // with the same key. // We use `ManuallyDrop` to avoid running the destructor of that first `Rc`, // and return a cloned one (which increments the reference count). unsafe { let rc = std::mem::ManuallyDrop::new(std::rc::Rc::from_raw(ptr)); Some(std::rc::Rc::clone(&rc)) } } /// Return the user data previously attached to `self` with the given `key`, if any, /// without incrementing the reference count. /// /// The pointer is valid when it is returned from this method, /// until the cairo object that `self` represents is destroyed /// or `remove_user_data` or `set_user_data` is called with the same key. pub fn get_user_data_ptr(&self, key: &'static crate::UserDataKey) -> Option> { // Safety: // // If `ffi_get_user_data` returns a non-null pointer, // there was a previous call to `ffi_set_user_data` with a key with the same address. // Either: // // * This was a call to a Rust `Self::set_user_data` method. // Because that method takes a `&'static` reference, // the key used then must live at that address until the end of the process. // Because `UserDataKey` has a non-zero size regardless of `T`, // no other `UserDataKey` value can have the same address. // Therefore the `T` type was the same then at it is now and `cast` is type-safe. // // * Or, it is technically possible that the `set` call was to the C function directly, // with a `cairo_user_data_key_t` in heap-allocated memory that was then freed, // then `Box::new(UserDataKey::new()).leak()` was used to create a `&'static` // that happens to have the same address because the allocator for `Box` // reused that memory region. // Since this involves a C (or FFI) call *and* is so far out of “typical” use // of the user data functionality, we consider this a misuse of an unsafe API. unsafe { let ptr = $ffi_get_user_data(self.to_raw_none(), &key.ffi); Some(std::ptr::NonNull::new(ptr)?.cast()) } } /// Unattach from `self` the user data associated with `key`, if any. /// If there is no other `Rc` strong reference, the data is destroyed. pub fn remove_user_data(&self, key: &'static crate::UserDataKey) { let result = unsafe { $ffi_set_user_data(self.to_raw_none(), &key.ffi, std::ptr::null_mut(), None) }; Status::from(result).ensure_valid() } }; } cairo-rs-0.7.1/src/utils.rs010066400017500001750000000024601350734563600137740ustar0000000000000000// Copyright 2013-2018, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use ffi; use std::ffi::CStr; use std::fmt; pub unsafe fn debug_reset_static_data() { ffi::cairo_debug_reset_static_data() } pub fn get_version_string() -> &'static str { unsafe { let ptr = ffi::cairo_version_string(); CStr::from_ptr(ptr) .to_str() .expect("invalid version string") } } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] pub struct Version { pub major: u8, pub minor: u8, pub micro: u8, } impl Version { pub fn get_version() -> Version { let version = unsafe { ffi::cairo_version() }; Version { major: (version / 10_000 % 100) as _, minor: (version / 100 % 100) as _, micro: (version % 100) as _, } } } impl fmt::Display for Version { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}.{}.{}", self.major, self.minor, self.micro) } } #[cfg(test)] mod tests { use super::*; #[test] fn check_versions() { assert_eq!(get_version_string(), Version::get_version().to_string()); } } cairo-rs-0.7.1/src/win32_surface.rs010066400017500001750000000102771350734563600153130ustar0000000000000000// Copyright 2017, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or pub use ffi::winapi; use std::convert::TryFrom; use std::fmt; use std::ops::Deref; use enums::{Format, SurfaceType}; use ffi; #[cfg(feature = "use_glib")] use glib::translate::*; use surface::Surface; use Status; #[derive(Debug)] pub struct Win32Surface(Surface); impl TryFrom for Win32Surface { type Error = Surface; fn try_from(surface: Surface) -> Result { if surface.get_type() == SurfaceType::Win32 { Ok(Win32Surface(surface)) } else { Err(surface) } } } impl Win32Surface { pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_surface_t) -> Result { let surface = Self::try_from(Surface::from_raw_full(ptr)).unwrap(); let status = surface.status(); match status { Status::Success => Ok(surface), _ => Err(status), } } pub fn create(hdc: winapi::HDC) -> Result { unsafe { Self::from_raw_full(ffi::cairo_win32_surface_create(hdc)) } } #[cfg(any(all(windows, feature = "v1_14"), feature = "dox"))] pub fn create_with_format(hdc: winapi::HDC, format: Format) -> Result { unsafe { Self::from_raw_full(ffi::cairo_win32_surface_create_with_format( hdc, format.into(), )) } } pub fn create_with_dib( format: Format, width: i32, height: i32, ) -> Result { unsafe { Self::from_raw_full(ffi::cairo_win32_surface_create_with_dib( format.into(), width, height, )) } } pub fn create_with_ddb( hdc: winapi::HDC, format: Format, width: i32, height: i32, ) -> Result { unsafe { Self::from_raw_full(ffi::cairo_win32_surface_create_with_ddb( hdc, format.into(), width, height, )) } } pub fn printing_surface_create(hdc: winapi::HDC) -> Result { unsafe { Self::from_raw_full(ffi::cairo_win32_printing_surface_create(hdc)) } } } #[cfg(feature = "use_glib")] impl<'a> ToGlibPtr<'a, *mut ffi::cairo_surface_t> for Win32Surface { type Storage = &'a Surface; #[inline] fn to_glib_none(&'a self) -> Stash<'a, *mut ffi::cairo_surface_t, Self> { let stash = self.0.to_glib_none(); Stash(stash.0, stash.1) } #[inline] fn to_glib_full(&self) -> *mut ffi::cairo_surface_t { unsafe { ffi::cairo_surface_reference(self.to_glib_none().0) } } } #[cfg(feature = "use_glib")] impl FromGlibPtrNone<*mut ffi::cairo_surface_t> for Win32Surface { #[inline] unsafe fn from_glib_none(ptr: *mut ffi::cairo_surface_t) -> Win32Surface { Self::try_from(from_glib_none::<_, Surface>(ptr)).unwrap() } } #[cfg(feature = "use_glib")] impl FromGlibPtrBorrow<*mut ffi::cairo_surface_t> for Win32Surface { #[inline] unsafe fn from_glib_borrow(ptr: *mut ffi::cairo_surface_t) -> Win32Surface { Self::try_from(from_glib_borrow::<_, Surface>(ptr)).unwrap() } } #[cfg(feature = "use_glib")] impl FromGlibPtrFull<*mut ffi::cairo_surface_t> for Win32Surface { #[inline] unsafe fn from_glib_full(ptr: *mut ffi::cairo_surface_t) -> Win32Surface { Self::try_from(from_glib_full::<_, Surface>(ptr)).unwrap() } } #[cfg(feature = "use_glib")] gvalue_impl!( Win32Surface, ffi::cairo_surface_t, ffi::gobject::cairo_gobject_surface_get_type ); impl Deref for Win32Surface { type Target = Surface; fn deref(&self) -> &Surface { &self.0 } } impl Clone for Win32Surface { fn clone(&self) -> Win32Surface { Win32Surface(self.0.clone()) } } impl fmt::Display for Win32Surface { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Win32Surface") } } cairo-rs-0.7.1/src/xcb.rs010066400017500001750000000270101350734563600134060ustar0000000000000000// Copyright 2013-2015, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use enums::SurfaceType; use ffi; #[cfg(feature = "use_glib")] use glib::translate::*; use std::fmt; use surface::Surface; #[derive(Debug)] pub struct XCBDrawable(pub u32); impl XCBDrawable { fn to_raw_none(&self) -> u32 { self.0 } } impl fmt::Display for XCBDrawable { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "XCBDrawable") } } #[derive(Debug)] pub struct XCBPixmap(pub u32); impl XCBPixmap { fn to_raw_none(&self) -> u32 { self.0 } } impl fmt::Display for XCBPixmap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "XCBPixmap") } } #[derive(Debug)] pub struct XCBConnection(pub *mut ffi::xcb_connection_t); impl XCBConnection { pub fn to_raw_none(&self) -> *mut ffi::xcb_connection_t { self.0 } pub unsafe fn from_raw_none(ptr: *mut ffi::xcb_connection_t) -> XCBConnection { assert!(!ptr.is_null()); XCBConnection(ptr) } pub unsafe fn from_raw_borrow(ptr: *mut ffi::xcb_connection_t) -> XCBConnection { assert!(!ptr.is_null()); XCBConnection(ptr) } pub unsafe fn from_raw_full(ptr: *mut ffi::xcb_connection_t) -> XCBConnection { assert!(!ptr.is_null()); XCBConnection(ptr) } } #[cfg(feature = "use_glib")] impl<'a> ToGlibPtr<'a, *mut ffi::xcb_connection_t> for &'a XCBConnection { type Storage = &'a XCBConnection; #[inline] fn to_glib_none(&self) -> Stash<'a, *mut ffi::xcb_connection_t, &'a XCBConnection> { Stash(self.to_raw_none(), *self) } } #[cfg(feature = "use_glib")] impl FromGlibPtrNone<*mut ffi::xcb_connection_t> for XCBConnection { #[inline] unsafe fn from_glib_none(ptr: *mut ffi::xcb_connection_t) -> XCBConnection { Self::from_raw_none(ptr) } } #[cfg(feature = "use_glib")] impl FromGlibPtrBorrow<*mut ffi::xcb_connection_t> for XCBConnection { #[inline] unsafe fn from_glib_borrow(ptr: *mut ffi::xcb_connection_t) -> XCBConnection { Self::from_raw_borrow(ptr) } } #[cfg(feature = "use_glib")] impl FromGlibPtrFull<*mut ffi::xcb_connection_t> for XCBConnection { #[inline] unsafe fn from_glib_full(ptr: *mut ffi::xcb_connection_t) -> XCBConnection { Self::from_raw_full(ptr) } } impl Clone for XCBConnection { fn clone(&self) -> XCBConnection { unsafe { Self::from_raw_none(self.to_raw_none()) } } } impl fmt::Display for XCBConnection { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "XCBConnection") } } #[derive(Debug)] pub struct XCBRenderPictFormInfo(pub *mut ffi::xcb_render_pictforminfo_t); impl XCBRenderPictFormInfo { pub fn to_raw_none(&self) -> *mut ffi::xcb_render_pictforminfo_t { self.0 } pub unsafe fn from_raw_none(ptr: *mut ffi::xcb_render_pictforminfo_t) -> XCBRenderPictFormInfo { assert!(!ptr.is_null()); XCBRenderPictFormInfo(ptr) } pub unsafe fn from_raw_borrow( ptr: *mut ffi::xcb_render_pictforminfo_t, ) -> XCBRenderPictFormInfo { assert!(!ptr.is_null()); XCBRenderPictFormInfo(ptr) } pub unsafe fn from_raw_full(ptr: *mut ffi::xcb_render_pictforminfo_t) -> XCBRenderPictFormInfo { assert!(!ptr.is_null()); XCBRenderPictFormInfo(ptr) } } #[cfg(feature = "use_glib")] impl<'a> ToGlibPtr<'a, *mut ffi::xcb_render_pictforminfo_t> for &'a XCBRenderPictFormInfo { type Storage = &'a XCBRenderPictFormInfo; #[inline] fn to_glib_none( &self, ) -> Stash<'a, *mut ffi::xcb_render_pictforminfo_t, &'a XCBRenderPictFormInfo> { Stash(self.to_raw_none(), *self) } } #[cfg(feature = "use_glib")] impl FromGlibPtrNone<*mut ffi::xcb_render_pictforminfo_t> for XCBRenderPictFormInfo { #[inline] unsafe fn from_glib_none(ptr: *mut ffi::xcb_render_pictforminfo_t) -> XCBRenderPictFormInfo { Self::from_raw_none(ptr) } } #[cfg(feature = "use_glib")] impl FromGlibPtrBorrow<*mut ffi::xcb_render_pictforminfo_t> for XCBRenderPictFormInfo { #[inline] unsafe fn from_glib_borrow(ptr: *mut ffi::xcb_render_pictforminfo_t) -> XCBRenderPictFormInfo { Self::from_raw_borrow(ptr) } } #[cfg(feature = "use_glib")] impl FromGlibPtrFull<*mut ffi::xcb_render_pictforminfo_t> for XCBRenderPictFormInfo { #[inline] unsafe fn from_glib_full(ptr: *mut ffi::xcb_render_pictforminfo_t) -> XCBRenderPictFormInfo { Self::from_raw_full(ptr) } } impl Clone for XCBRenderPictFormInfo { fn clone(&self) -> XCBRenderPictFormInfo { unsafe { Self::from_raw_none(self.to_raw_none()) } } } impl fmt::Display for XCBRenderPictFormInfo { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "XCBRenderPictFormInfo") } } #[derive(Debug)] pub struct XCBScreen(pub *mut ffi::xcb_screen_t); impl XCBScreen { pub fn to_raw_none(&self) -> *mut ffi::xcb_screen_t { self.0 } pub unsafe fn from_raw_none(ptr: *mut ffi::xcb_screen_t) -> XCBScreen { assert!(!ptr.is_null()); XCBScreen(ptr) } pub unsafe fn from_raw_borrow(ptr: *mut ffi::xcb_screen_t) -> XCBScreen { assert!(!ptr.is_null()); XCBScreen(ptr) } pub unsafe fn from_raw_full(ptr: *mut ffi::xcb_screen_t) -> XCBScreen { assert!(!ptr.is_null()); XCBScreen(ptr) } } #[cfg(feature = "use_glib")] impl<'a> ToGlibPtr<'a, *mut ffi::xcb_screen_t> for &'a XCBScreen { type Storage = &'a XCBScreen; #[inline] fn to_glib_none(&self) -> Stash<'a, *mut ffi::xcb_screen_t, &'a XCBScreen> { Stash(self.to_raw_none(), *self) } } #[cfg(feature = "use_glib")] impl FromGlibPtrNone<*mut ffi::xcb_screen_t> for XCBScreen { #[inline] unsafe fn from_glib_none(ptr: *mut ffi::xcb_screen_t) -> XCBScreen { Self::from_raw_none(ptr) } } #[cfg(feature = "use_glib")] impl FromGlibPtrBorrow<*mut ffi::xcb_screen_t> for XCBScreen { #[inline] unsafe fn from_glib_borrow(ptr: *mut ffi::xcb_screen_t) -> XCBScreen { Self::from_raw_borrow(ptr) } } #[cfg(feature = "use_glib")] impl FromGlibPtrFull<*mut ffi::xcb_screen_t> for XCBScreen { #[inline] unsafe fn from_glib_full(ptr: *mut ffi::xcb_screen_t) -> XCBScreen { Self::from_raw_full(ptr) } } impl Clone for XCBScreen { fn clone(&self) -> XCBScreen { unsafe { Self::from_raw_none(self.to_raw_none()) } } } impl fmt::Display for XCBScreen { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "XCBScreen") } } pub struct XCBSurface(Surface); impl std::ops::Deref for XCBSurface { type Target = Surface; fn deref(&self) -> &Surface { &self.0 } } impl std::convert::TryFrom for XCBSurface { type Error = Surface; fn try_from(surface: Surface) -> Result { if surface.get_type() == SurfaceType::Xcb { Ok(Self(surface)) } else { Err(surface) } } } impl XCBSurface { pub fn create( connection: &XCBConnection, drawable: &XCBDrawable, visual: &XCBVisualType, width: i32, height: i32, ) -> Self { unsafe { Self(Surface::from_raw_full(ffi::cairo_xcb_surface_create( connection.to_raw_none(), drawable.to_raw_none(), visual.to_raw_none(), width, height, ))) } } pub fn create_for_bitmap( connection: &XCBConnection, screen: &XCBScreen, bitmap: &XCBPixmap, width: i32, height: i32, ) -> Self { unsafe { Self(Surface::from_raw_full( ffi::cairo_xcb_surface_create_for_bitmap( connection.to_raw_none(), screen.to_raw_none(), bitmap.to_raw_none(), width, height, ), )) } } pub fn create_with_xrender_format( connection: &XCBConnection, screen: &XCBScreen, bitmap: &XCBPixmap, format: &XCBRenderPictFormInfo, width: i32, height: i32, ) -> Self { unsafe { Self(Surface::from_raw_full( ffi::cairo_xcb_surface_create_with_xrender_format( connection.to_raw_none(), screen.to_raw_none(), bitmap.to_raw_none(), format.to_raw_none(), width, height, ), )) } } pub fn set_size(&self, width: i32, height: i32) { unsafe { ffi::cairo_xcb_surface_set_size(self.to_raw_none(), width, height) } } pub fn set_drawable(&self, drawable: &XCBDrawable, width: i32, height: i32) { unsafe { ffi::cairo_xcb_surface_set_drawable( self.to_raw_none(), drawable.to_raw_none(), width, height, ) } } } #[derive(Debug)] pub struct XCBVisualType(pub *mut ffi::xcb_visualtype_t); impl XCBVisualType { pub fn to_raw_none(&self) -> *mut ffi::xcb_visualtype_t { self.0 } pub unsafe fn from_raw_none(ptr: *mut ffi::xcb_visualtype_t) -> XCBVisualType { assert!(!ptr.is_null()); XCBVisualType(ptr) } pub unsafe fn from_raw_borrow(ptr: *mut ffi::xcb_visualtype_t) -> XCBVisualType { assert!(!ptr.is_null()); XCBVisualType(ptr) } pub unsafe fn from_raw_full(ptr: *mut ffi::xcb_visualtype_t) -> XCBVisualType { assert!(!ptr.is_null()); XCBVisualType(ptr) } } #[cfg(feature = "use_glib")] impl<'a> ToGlibPtr<'a, *mut ffi::xcb_visualtype_t> for &'a XCBVisualType { type Storage = &'a XCBVisualType; #[inline] fn to_glib_none(&self) -> Stash<'a, *mut ffi::xcb_visualtype_t, &'a XCBVisualType> { Stash(self.to_raw_none(), *self) } } #[cfg(feature = "use_glib")] impl FromGlibPtrNone<*mut ffi::xcb_visualtype_t> for XCBVisualType { #[inline] unsafe fn from_glib_none(ptr: *mut ffi::xcb_visualtype_t) -> XCBVisualType { Self::from_raw_none(ptr) } } #[cfg(feature = "use_glib")] impl FromGlibPtrBorrow<*mut ffi::xcb_visualtype_t> for XCBVisualType { #[inline] unsafe fn from_glib_borrow(ptr: *mut ffi::xcb_visualtype_t) -> XCBVisualType { Self::from_raw_borrow(ptr) } } #[cfg(feature = "use_glib")] impl FromGlibPtrFull<*mut ffi::xcb_visualtype_t> for XCBVisualType { #[inline] unsafe fn from_glib_full(ptr: *mut ffi::xcb_visualtype_t) -> XCBVisualType { Self::from_raw_full(ptr) } } impl Clone for XCBVisualType { fn clone(&self) -> XCBVisualType { unsafe { Self::from_raw_none(self.to_raw_none()) } } } impl fmt::Display for XCBVisualType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "XCBVisualType") } } impl ::device::Device { pub fn get_connection(&self) -> XCBConnection { unsafe { XCBConnection::from_raw_full(ffi::cairo_xcb_device_get_connection(self.to_raw_none())) } } pub fn debug_cap_xshm_version(&self, major_version: i32, minor_version: i32) { unsafe { ffi::cairo_xcb_device_debug_cap_xshm_version( self.to_raw_none(), major_version, minor_version, ) } } } cairo-rs-0.7.1/.cargo_vcs_info.json0000644000000001120000000000000126110ustar00{ "git": { "sha1": "ca312b34f49ee616220e0a07439386148a286b3c" } }