Skip to content
This repository has been archived by the owner on Jun 8, 2021. It is now read-only.

Commit

Permalink
PDF, SVG, PS: Add bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
vojtechkral committed Feb 6, 2019
1 parent 2ae5561 commit fbe7bac
Show file tree
Hide file tree
Showing 6 changed files with 279 additions and 4 deletions.
54 changes: 54 additions & 0 deletions cairo-sys-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ pub type cairo_surface_type_t = c_int;
pub type cairo_svg_unit_t = c_int;
pub type cairo_text_cluster_flags_t = c_int;

#[cfg(any(feature = "pdf", feature = "dox"))]
pub type cairo_pdf_outline_flags_t = c_int;
#[cfg(any(feature = "pdf", feature = "dox"))]
pub type cairo_pdf_metadata_t = c_int;
#[cfg(any(feature = "pdf", feature = "dox"))]
pub type cairo_pdf_version_t = c_int;
#[cfg(any(feature = "svg", feature = "dox"))]
Expand Down Expand Up @@ -261,6 +265,12 @@ impl cairo_bool_t {
}
}

impl From<bool> for cairo_bool_t {
fn from(b: bool) -> cairo_bool_t {
cairo_bool_t { value: b as _ }
}
}

pub type CGContextRef = *mut c_void;

pub type cairo_destroy_func_t = Option<unsafe extern fn (*mut c_void)>;
Expand Down Expand Up @@ -593,9 +603,31 @@ extern "C" {
#[cfg(any(feature = "pdf", feature = "dox"))]
pub fn cairo_pdf_surface_restrict_to_version (surface: *mut cairo_surface_t, version: cairo_pdf_version_t);
#[cfg(any(feature = "pdf", feature = "dox"))]
pub fn cairo_pdf_get_versions (versions: *mut *mut cairo_pdf_version_t,
num_versions: *mut c_int);
#[cfg(any(feature = "pdf", feature = "dox"))]
pub fn cairo_pdf_version_to_string (version: cairo_pdf_version_t) -> *const c_char;
#[cfg(any(feature = "pdf", feature = "dox"))]
pub fn cairo_pdf_surface_set_size (surface: *mut cairo_surface_t,
width_in_points: f64,
height_in_points: f64);
#[cfg(any(feature = "pdf", feature = "dox"))]
pub fn cairo_pdf_surface_add_outline (surface: *mut cairo_surface_t,
parent_id: c_int,
utf8: *const c_char,
link_attribs: *const c_char,
flags: cairo_pdf_outline_flags_t) -> c_int;
#[cfg(any(feature = "pdf", feature = "dox"))]
pub fn cairo_pdf_surface_set_metadata (surface: *mut cairo_surface_t,
metadata: cairo_pdf_metadata_t,
utf8: *const c_char);
#[cfg(any(feature = "pdf", feature = "dox"))]
pub fn cairo_pdf_surface_set_page_label (surface: *mut cairo_surface_t,
utf8: *const c_char);
#[cfg(any(feature = "pdf", feature = "dox"))]
pub fn cairo_pdf_surface_set_thumbnail_size (surface: *mut cairo_surface_t,
width: c_int,
height: c_int);

// CAIRO SVG
#[cfg(any(feature = "svg", feature = "dox"))]
Expand All @@ -613,6 +645,12 @@ extern "C" {
pub fn cairo_svg_surface_get_document_unit(surface: *const cairo_surface_t) -> cairo_svg_unit_t;
#[cfg(any(feature = "svg", feature = "dox"))]
pub fn cairo_svg_surface_set_document_unit(surface: *mut cairo_surface_t, unit: cairo_svg_unit_t);
#[cfg(any(feature = "svg", feature = "dox"))]
pub fn cairo_svg_get_versions (versions: *mut *mut cairo_svg_version_t,
num_versions: *mut c_int);
#[cfg(any(feature = "svg", feature = "dox"))]
pub fn cairo_svg_version_to_string (version: cairo_svg_version_t) -> *const c_char;

// CAIRO PS
#[cfg(any(feature = "ps", feature = "dox"))]
pub fn cairo_ps_surface_create (filename: *const c_char,
Expand All @@ -626,6 +664,11 @@ extern "C" {
#[cfg(any(feature = "ps", feature = "dox"))]
pub fn cairo_ps_surface_restrict_to_level (surface: *mut cairo_surface_t, version: cairo_ps_level_t);
#[cfg(any(feature = "ps", feature = "dox"))]
pub fn cairo_ps_get_levels (levels: *mut *mut cairo_ps_level_t,
num_levels: *mut c_int);
#[cfg(any(feature = "ps", feature = "dox"))]
pub fn cairo_ps_level_to_string (level: cairo_ps_level_t) -> *const c_char;
#[cfg(any(feature = "ps", feature = "dox"))]
pub fn cairo_ps_surface_set_eps (surface: *mut cairo_surface_t, eps: cairo_bool_t);
#[cfg(any(feature = "ps", feature = "dox"))]
pub fn cairo_ps_surface_get_eps (surface: *mut cairo_surface_t) -> cairo_bool_t;
Expand Down Expand Up @@ -949,6 +992,17 @@ pub const FORMAT_RGB30: i32 = 5;
pub const REGION_OVERLAP_IN: i32 = 0;
pub const REGION_OVERLAP_OUT: i32 = 1;
pub const REGION_OVERLAP_PART: i32 = 2;
pub const PDF_OUTLINE_FLAG_OPEN: i32 = 0x1;
pub const PDF_OUTLINE_FLAG_BOLD: i32 = 0x2;
pub const PDF_OUTLINE_FLAG_ITALIC: i32 = 0x4;
pub const PDF_OUTLINE_FLAG__ALL: i32 = PDF_OUTLINE_FLAG_OPEN|PDF_OUTLINE_FLAG_BOLD|PDF_OUTLINE_FLAG_ITALIC;
pub const PDF_METADATA_TITLE: i32 = 0;
pub const PDF_METADATA_AUTHOR: i32 = 1;
pub const PDF_METADATA_SUBJECT: i32 = 2;
pub const PDF_METADATA_KEYWORDS: i32 = 3;
pub const PDF_METADATA_CREATOR: i32 = 4;
pub const PDF_METADATA_CREATE_DATE: i32 = 5;
pub const PDF_METADATA_MOD_DATE: i32 = 6;
pub const PDF_VERSION__1_4: i32 = 0;
pub const PDF_VERSION__1_5: i32 = 1;
pub const SVG_VERSION__1_1: i32 = 0;
Expand Down
8 changes: 8 additions & 0 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use ffi;


pub const MIME_TYPE_JPEG: &str = "image/jpeg";
pub const MIME_TYPE_PNG: &str = "image/png";
pub const MIME_TYPE_JP2: &str = "image/jp2";
Expand All @@ -14,3 +17,8 @@ pub const MIME_TYPE_CCITT_FAX: &str = "image/g3fax";
pub const MIME_TYPE_CCITT_FAX_PARAMS: &str = "application/x-cairo.ccitt.params";
pub const MIME_TYPE_EPS: &str = "application/postscript";
pub const MIME_TYPE_EPS_PARAMS: &str = "application/x-cairo.eps.params";

pub const PDF_OUTLINE_ROOT: i32 = 0;
pub const PDF_OUTLINE_OPEN: i32 = ffi::PDF_OUTLINE_FLAG_OPEN;
pub const PDF_OUTLINE_BOLD: i32 = ffi::PDF_OUTLINE_FLAG_BOLD;
pub const PDF_OUTLINE_ITALIC: i32 = ffi::PDF_OUTLINE_FLAG_ITALIC;
48 changes: 48 additions & 0 deletions src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1227,6 +1227,54 @@ impl From<ffi::cairo_region_overlap_t> for RegionOverlap {
#[cfg(feature = "use_glib")]
gvalue_impl!(RegionOverlap, ffi::gobject::cairo_gobject_region_overlap_get_type);

#[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(feature = "pdf", feature = "dox"))]
#[doc(hidden)]
impl Into<ffi::cairo_pdf_metadata_t> 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(feature = "pdf", feature = "dox"))]
#[doc(hidden)]
impl From<ffi::cairo_pdf_metadata_t> 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(feature = "pdf", feature = "dox"))]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum PdfVersion {
Expand Down
66 changes: 64 additions & 2 deletions src/pdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,40 @@
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use std::ffi::CString;
use std::mem;
use std::ffi::{CStr, CString};
use std::ops::Deref;
use std::path::Path;
use std::io;

use ffi;
use ::enums::PdfVersion;
use ::enums::{PdfVersion, PdfMetadata};
use surface::Surface;
use support::{self, FromRawSurface};

#[cfg(feature = "use_glib")]
use glib::translate::*;


pub fn get_versions() -> Vec<PdfVersion> {
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)).collect()
}

pub fn version_to_string(version: PdfVersion) -> Option<String> {
unsafe {
let res = ffi::cairo_pdf_version_to_string(version.into());
res.as_ref().and_then(|cstr| CStr::from_ptr(cstr as _).to_str().ok()).map(String::from)
}
}

pub struct File {
inner: Surface,
}
Expand Down Expand Up @@ -48,6 +68,36 @@ impl File {
ffi::cairo_pdf_surface_set_size(self.inner.to_raw_none(), width, height);
}
}

pub fn set_metadata(&self, metadata: PdfMetadata, value: &str) {
unsafe {
ffi::cairo_pdf_surface_set_metadata(self.inner.to_raw_none(), metadata.into(), value.as_ptr() as _);
}
}

pub fn set_page_label(&self, label: &str) {
unsafe {
ffi::cairo_pdf_surface_set_page_label(self.inner.to_raw_none(), label.as_ptr() as _);
}
}

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 _);
}
}

pub fn add_outline(&self, parent_id: i32, name: &str, link_attribs: &str, flags: i32) -> i32 {
unsafe {
ffi::cairo_pdf_surface_add_outline(
self.inner.to_raw_none(),
parent_id,
name.as_ptr() as _,
link_attribs.as_ptr() as _,
flags as _
) as _
}
}
}

impl AsRef<Surface> for File {
Expand Down Expand Up @@ -231,6 +281,18 @@ mod test {
surface.finish()
}

#[test]
fn versions() {
let vers = get_versions();
assert!(vers.iter().any(|v| *v == PdfVersion::_1_4));
}

#[test]
fn version_string() {
let ver_str = version_to_string(PdfVersion::_1_4).unwrap();
assert_eq!(ver_str, "PDF 1.4");
}

#[test]
#[cfg(unix)]
fn file() {
Expand Down
73 changes: 72 additions & 1 deletion src/ps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use std::ffi::CString;
use std::mem;
use std::ffi::{CStr, CString};
use std::ops::Deref;
use std::path::Path;
use std::io;
Expand All @@ -16,6 +17,25 @@ use support::{self, FromRawSurface};
use glib::translate::*;


pub fn get_levels() -> Vec<PsLevel> {
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)).collect()
}

pub fn level_to_string(level: PsLevel) -> Option<String> {
unsafe {
let res = ffi::cairo_ps_level_to_string(level.into());
res.as_ref().and_then(|cstr| CStr::from_ptr(cstr as _).to_str().ok()).map(String::from)
}
}

pub struct File {
inner: Surface,
}
Expand Down Expand Up @@ -77,11 +97,42 @@ impl File {
}
}

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) {
unsafe {
ffi::cairo_ps_surface_dsc_comment(self.inner.to_raw_none(), comment.as_ptr() as _);
}
}

}

impl AsRef<Surface> for File {
Expand Down Expand Up @@ -232,6 +283,26 @@ mod test {
surface.finish()
}

#[test]
fn levels() {
let vers = get_levels();
assert!(vers.iter().any(|v| *v == PsLevel::_2));
}

#[test]
fn level_string() {
let ver_str = level_to_string(PsLevel::_2).unwrap();
assert_eq!(ver_str, "PS Level 2");
}

#[test]
fn eps() {
let buffer: Vec<u8> = vec![];
let surface = Writer::new(100., 100., buffer);
surface.set_eps(true);
assert_eq!(surface.get_eps(), true);
}

#[test]
#[cfg(unix)]
fn file() {
Expand Down

0 comments on commit fbe7bac

Please sign in to comment.