summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@gnome.org>2018-02-27 09:44:16 -0600
committerFederico Mena Quintero <federico@gnome.org>2018-02-27 09:44:16 -0600
commitc7f57a38a9b6cf88c6f842f6d16173a6b51b0993 (patch)
tree40e1c5234e21158331b091b2472f923444334d42
parentd453061d60720832e42ed80e8d55cf29c78916fd (diff)
parent3f098e50a32df183fb1b2bd11008577abaeac3e9 (diff)
downloadlibrsvg-import-rsvg-rs.tar.gz
Merge branch 'import-rebased'import-rsvg-rs
-rw-r--r--.gitmodules3
-rw-r--r--Makefile.am82
-rw-r--r--configure.ac8
m---------gir0
-rw-r--r--rsvg-rs/.gitignore5
-rw-r--r--rsvg-rs/CHANGELOG.md15
-rw-r--r--rsvg-rs/Cargo.toml34
-rw-r--r--rsvg-rs/Gir.toml38
-rw-r--r--rsvg-rs/Makefile32
-rw-r--r--rsvg-rs/README.md17
-rw-r--r--rsvg-rs/rsvg-sys/Cargo.toml30
-rw-r--r--rsvg-rs/rsvg-sys/Gir.toml12
-rw-r--r--rsvg-rs/rsvg-sys/build.rs61
-rw-r--r--rsvg-rs/rsvg-sys/src/lib.rs160
-rw-r--r--rsvg-rs/src/auto/enums.rs6
-rw-r--r--rsvg-rs/src/auto/flags.rs58
-rw-r--r--rsvg-rs/src/auto/handle.rs574
-rw-r--r--rsvg-rs/src/auto/mod.rs14
-rw-r--r--rsvg-rs/src/dimension_data.rs67
-rw-r--r--rsvg-rs/src/handle.rs16
-rw-r--r--rsvg-rs/src/lib.rs125
-rw-r--r--rsvg-rs/src/position_data.rs67
22 files changed, 1405 insertions, 19 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..c21670ff
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "gir"]
+ path = gir
+ url = git@github.com:gtk-rs/gir.git
diff --git a/Makefile.am b/Makefile.am
index a5a16220..1f6dcc9a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,13 +3,19 @@ SUBDIRS = . gdk-pixbuf-loader tests tools doc win32
NULL =
BUILT_SOURCES =
+# ---------- Products of the build, to be installed ----------
+
+# the main library
lib_LTLIBRARIES = librsvg-@RSVG_API_MAJOR_VERSION@.la
+# programs
bin_PROGRAMS = rsvg-convert
if HAVE_GTK_3
bin_PROGRAMS += rsvg-view-3
endif
+# ---------- librsvg library ----------
+
headers = \
librsvg/rsvg.h \
librsvg/rsvg-cairo.h
@@ -123,8 +129,9 @@ cargo_verbose_ = $(cargo_verbose_$(AM_DEFAULT_VERBOSITY))
cargo_verbose_0 =
cargo_verbose_1 = --verbose
-RUST_LIB=@abs_top_builddir@/target/@RUST_TARGET_SUBDIR@/librsvg_internals.a
CARGO_TARGET_DIR=@abs_top_builddir@/target
+RUST_BINARIES_DIR=$(CARGO_TARGET_DIR)/@RUST_TARGET_SUBDIR@
+RUST_LIB=$(RUST_BINARIES_DIR)/librsvg_internals.a
check-local:
cd $(srcdir) && \
@@ -298,10 +305,11 @@ librsvg/s-enum-types-c: $(headers) Makefile
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
-if HAVE_INTROSPECTION
+# ---------- GObject Introspection ----------
+
-include $(INTROSPECTION_MAKEFILE)
-INTROSPECTION_GIRS = Rsvg-@RSVG_API_VERSION@.gir
+INTROSPECTION_GIR = Rsvg-@RSVG_API_VERSION@.gir
INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) --symbol-prefix=rsvg --symbol-prefix=librsvg
INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir)
@@ -329,13 +337,15 @@ Rsvg_@RSVG_API_VERSION_U@_gir_LIBS = librsvg-@RSVG_API_MAJOR_VERSION@.la
Rsvg_@RSVG_API_VERSION_U@_gir_SCANNERFLAGS = --c-include="librsvg/rsvg.h"
girdir = $(datadir)/gir-1.0
-nodist_gir_DATA = $(INTROSPECTION_GIRS)
+nodist_gir_DATA = $(INTROSPECTION_GIR)
typelibsdir = $(libdir)/girepository-1.0
-nodist_typelibs_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
+nodist_typelibs_DATA = $(INTROSPECTION_GIR:.gir=.typelib)
CLEANFILES += $(nodist_gir_DATA) $(nodist_typelibs_DATA)
+# ---------- Vala binding ----------
+
if ENABLE_VAPIGEN
include $(VAPIGEN_MAKEFILE)
@@ -354,8 +364,6 @@ CLEANFILES += $(VAPIGEN_VAPIS)
endif # ENABLE_VAPIGEN
-endif # HAVE_INTROSPECTION
-
# ------------------- MSVC Build Items ----------------
MSVCPROJS = rsvg rsvg-convert
@@ -377,9 +385,7 @@ MSVCPROJ_GENERATED = \
$(top_builddir)/win32/vs12/rsvg.vcxproj \
$(top_builddir)/win32/vs12/rsvg-convert.vcxproj
-if HAVE_INTROSPECTION
-
-MSVC_INTROSPECT_GIRS = $(INTROSPECTION_GIRS)
+MSVC_INTROSPECT_GIRS = $(INTROSPECTION_GIR)
INTROSPECTION_INTERMEDIATE_ITEMS = \
$(top_builddir)/win32/Rsvg-@RSVG_API_VERSION@.gir.msvc.introspect \
@@ -396,13 +402,65 @@ Rsvg_@RSVG_API_VERSION_U@_gir_MSVC_SCANNERFLAGS = $(Rsvg_@RSVG_API_VERSION_U@_gi
MSVCPROJ_GENERATED += $(INTROSPECTION_INTERMEDIATE_ITEMS)
include $(top_srcdir)/win32/Makefile.msvc-introspection
-endif # HAVE_INTROSPECTION
$(MSVCPROJ_GENERATED): $(top_builddir)/win32/vs12/rsvg.vs12.headers
EXTRA_DIST += $(MSVCPROJ_GENERATED)
-# ChangeLog generation
+# ---------- gir tool from gtk-rs ----------
+
+GIR_SRC= \
+ gir/LICENSE \
+ gir/build.rs \
+ gir/Cargo.toml \
+ gir/Gir_Gio.toml \
+ gir/README.md \
+ gir/Gir_Gtk.toml \
+ gir/Cargo.lock \
+ $(shell find gir/src -name '*.rs')
+# do we need to run find(1) in gir/tests as well?
+
+EXTRA_DIST += $(GIR_SRC)
+
+GIR = $(RUST_BINARIES_DIR)/gir
+
+# $(GIR_SRC):
+# git submodule update --init
+
+$(GIR): $(GIR_SRC)
+ +cd $(top_srcdir)/gir && \
+ PKG_CONFIG_ALLOW_CROSS=1 \
+ PKG_CONFIG='$(PKG_CONFIG)' \
+ CARGO_TARGET_DIR=$(CARGO_TARGET_DIR) \
+ cargo build $(CARGO_VERBOSE) $(CARGO_TARGET_ARGS) $(CARGO_RELEASE_ARGS)
+
+# ---------- rsvg-rs binding ----------
+
+RS_BINDING_LIB=$(RUST_BINARIES_DIR)/librsvg_rs.rlib
+
+RS_BINDING_GIR=rsvg-rs/$(INTROSPECTION_GIR)
+
+# Copy the generated .gir into rsvg-rs so it can be used as a standalone crate
+$(RS_BINDING_GIR): $(INTROSPECTION_GIR)
+ cp $(INTROSPECTION_GIR) $(RS_BINDING_GIR)
+
+RS_BINDING_SOURCES= \
+ rsvg-rs/Cargo.toml \
+ rsvg-rs/Gir.toml \
+ rsvg-rs/src/dimension_data.rs \
+ rsvg-rs/src/handle.rs \
+ rsvg-rs/src/lib.rs \
+ rsvg-rs/src/position_data.rs
+
+# Build the binding
+$(RS_BINDING_LIB): $(RS_BINDING_GIR) $(RS_BINDING_SOURCES) $(GIR)
+ +cd $(top_srcdir)/rsvg-rs && \
+ PKG_CONFIG_ALLOW_CROSS=1 \
+ PKG_CONFIG='$(PKG_CONFIG)' \
+ CARGO_TARGET_DIR=$(CARGO_TARGET_DIR) \
+ cargo build $(CARGO_VERBOSE) $(CARGO_TARGET_ARGS) $(CARGO_RELEASE_ARGS)
+
+# ---------- ChangeLog generation ----------
ChangeLog:
$(AM_V_GEN) if test -d $(top_srcdir)/.git; then \
diff --git a/configure.ac b/configure.ac
index 9f8dce29..40a06a6f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -289,12 +289,7 @@ AC_SUBST([RUST_TARGET_SUBDIR])
dnl ===========================================================================
dnl Build introspectable bindings
-# No automagic please!
-if test -z "$enable_introspection"; then
- enable_introspection=yes
-fi
-
-GOBJECT_INTROSPECTION_CHECK([0.10.8])
+GOBJECT_INTROSPECTION_REQUIRE([0.10.8])
# Vala bindings
VAPIGEN_CHECK([0.17.1.26],,,[no])
@@ -378,7 +373,6 @@ librsvg-$VERSION
Debugging information for Rust: ${debug_release}
- Build introspectable bindings: ${found_introspection}
Build Vala bindings: ${enable_vala}
Build GdkPixbuf loader: ${enable_pixbuf_loader}
GTK+ $GTK3_REQUIRED or later: ${have_gtk_3}
diff --git a/gir b/gir
new file mode 160000
+Subproject 6114d1c7e248c982fb67c73fbf1b4318675a88e
diff --git a/rsvg-rs/.gitignore b/rsvg-rs/.gitignore
new file mode 100644
index 00000000..5141448e
--- /dev/null
+++ b/rsvg-rs/.gitignore
@@ -0,0 +1,5 @@
+.idea
+target/
+**/*.rs.bk
+Cargo.lock
+vendor.md \ No newline at end of file
diff --git a/rsvg-rs/CHANGELOG.md b/rsvg-rs/CHANGELOG.md
new file mode 100644
index 00000000..bcc0e694
--- /dev/null
+++ b/rsvg-rs/CHANGELOG.md
@@ -0,0 +1,15 @@
+# Changelog
+
+### 0.3.0
+
+- Works with `gtk = "0.3.0"`
+
+### 0.2.0
+
+- Works with `gtk = "0.2.0"`
+- Regenerated API (`HandleExt` trait introduced)
+
+### 0.1.3
+
+- Initial commit
+- Works with `gtk = "0.1.3"`
diff --git a/rsvg-rs/Cargo.toml b/rsvg-rs/Cargo.toml
new file mode 100644
index 00000000..24cf5d96
--- /dev/null
+++ b/rsvg-rs/Cargo.toml
@@ -0,0 +1,34 @@
+[package]
+name = "rsvg"
+version = "0.3.0"
+authors = ["selaux"]
+description = "Rust bindings for the Rsvg library"
+repository = "https://github.com/selaux/rsvg-rs"
+license = "MIT"
+
+keywords = ["rsvg", "svg", "gtk-rs"]
+include = ["src/**/*", "Cargo.toml"]
+
+[lib]
+name = "rsvg"
+
+[dependencies]
+libc = "0.2"
+bitflags = "0.9"
+glib = "0.4.0"
+glib-sys = "0.5.0"
+gobject-sys = "0.5.0"
+gdk-pixbuf = "0.3.0"
+
+[dev-dependencies]
+# image = "0.13.0"
+# imageproc = "0.8.0"
+gtk = "0.3.0"
+
+[dependencies.cairo-rs]
+version = "0.3.0"
+features = ["png"]
+
+[dependencies.rsvg-sys]
+version = "0.5.0"
+path = "./rsvg-sys"
diff --git a/rsvg-rs/Gir.toml b/rsvg-rs/Gir.toml
new file mode 100644
index 00000000..d71fafa2
--- /dev/null
+++ b/rsvg-rs/Gir.toml
@@ -0,0 +1,38 @@
+[options]
+girs_dir = "gir-files"
+library = "Rsvg"
+version = "2.0"
+min_cfg_version = "2.36"
+target_path = "."
+work_mode = "normal"
+generate_safety_asserts = false
+deprecate_by_min_version = true
+
+generate = [
+ "Rsvg.HandleFlags"
+]
+
+manual = [
+ "Rsvg.DimensionData",
+ "Rsvg.PositionData",
+ "cairo.Context",
+ "GdkPixbuf.Pixbuf",
+ "GLib.Error"
+]
+
+[[object]]
+name = "Rsvg.Handle"
+status = "generate"
+ [[object.function]]
+ pattern = "render_cairo(_sub)?"
+ [[object.function.parameter]]
+ name = "cr"
+ const = true
+
+ [[object.function]]
+ name = "get_base_uri"
+ ignore = true
+
+ [[object.property]]
+ name = "base-uri"
+ ignore = true \ No newline at end of file
diff --git a/rsvg-rs/Makefile b/rsvg-rs/Makefile
new file mode 100644
index 00000000..56558613
--- /dev/null
+++ b/rsvg-rs/Makefile
@@ -0,0 +1,32 @@
+RUSTDOC_STRIPPER = target/rustdoc-stripper/bin/rustdoc-stripper
+GIR = target/gir/bin/gir
+GIR_FILES = $(shell pkg-config --variable girdir gobject-introspection-1.0)
+SYS_FILES = rsvg-sys/src/lib.rs
+DOCS = vendor.md
+
+src/auto/mod.rs : Gir.toml $(GIR) $(RUSTDOC_STRIPPER) $(GIR_FILES) $(SYS_FILES) $(DOCS)
+ $(GIR) -c Gir.toml -d $(GIR_FILES)
+ $(RUSTDOC_STRIPPER) -g -o $(DOCS) -d src/auto
+
+$(DOCS): Gir.toml $(GIR) $(GIR_FILES)
+ $(GIR) -c $< -d $(GIR_FILES) -m doc
+
+.PHONY: clean
+clean:
+ rm -rf src/auto $(SYS_FILES) $(DOCS)
+
+$(SYS_FILES): rsvg-sys/Gir.toml $(GIR) $(GIR_FILES)
+ $(GIR) -c $< -o $(abspath rsvg-sys) -d $(GIR_FILES)
+
+$(RUSTDOC_STRIPPER) :
+ cargo install --root target/rustdoc-stripper rustdoc-stripper --version "0.1.5"
+
+$(GIR) :
+ cargo install --root target/gir --git https://github.com/gtk-rs/gir --rev d50d839ceaed9cc5eabac729dbc161c295306270 gir
+
+.PHONY: gir
+gir : src/auto/mod.rs
+
+.PHONY: gir-sys
+gir-sys : $(SYS_FILES)
+
diff --git a/rsvg-rs/README.md b/rsvg-rs/README.md
new file mode 100644
index 00000000..ae9f76e4
--- /dev/null
+++ b/rsvg-rs/README.md
@@ -0,0 +1,17 @@
+# rsvg-rs
+
+[![Version](https://img.shields.io/crates/v/rsvg.svg)](https://crates.io/crates/rsvg)
+[![Documentation](https://docs.rs/rsvg/badge.svg)](https://docs.rs/crate/rsvg)
+[![Build Status](https://travis-ci.org/selaux/rsvg-rs.svg?branch=master)](https://travis-ci.org/selaux/rsvg-rs)
+
+[libRSVG](https://wiki.gnome.org/action/show/Projects/LibRsvg?action=show&redirect=LibRsvg) bindings for Rust.
+
+Based on [Gtk-rs project](http://gtk-rs.org/) bindings.
+
+## Example
+
+See [examples folder](/examples)
+
+## License
+
+MIT
diff --git a/rsvg-rs/rsvg-sys/Cargo.toml b/rsvg-rs/rsvg-sys/Cargo.toml
new file mode 100644
index 00000000..b0d01985
--- /dev/null
+++ b/rsvg-rs/rsvg-sys/Cargo.toml
@@ -0,0 +1,30 @@
+[build-dependencies]
+pkg-config = "0.3.7"
+
+[dependencies]
+atk-sys = "0.5.0"
+bitflags = "1.0"
+cairo-sys-rs = "0.5.0"
+gdk-pixbuf-sys = "0.5.0"
+gdk-sys = "0.5.0"
+gio-sys = "0.5.0"
+glib-sys = "0.5.0"
+gobject-sys = "0.5.0"
+libc = "0.2"
+pango-sys = "0.5.0"
+
+[features]
+dox = []
+
+[lib]
+name = "rsvg_sys"
+
+[package]
+authors = ["selaux"]
+build = "build.rs"
+description = "Rust bindings for the Rsvg library (ffi)"
+license = "MIT"
+links = "rsvg"
+name = "rsvg-sys"
+repository = "https://github.com/selaux/rsvg-rs"
+version = "0.5.0"
diff --git a/rsvg-rs/rsvg-sys/Gir.toml b/rsvg-rs/rsvg-sys/Gir.toml
new file mode 100644
index 00000000..980c87a8
--- /dev/null
+++ b/rsvg-rs/rsvg-sys/Gir.toml
@@ -0,0 +1,12 @@
+[options]
+work_mode = "sys"
+library = "Rsvg"
+version = "2.0"
+min_cfg_version = "2.36"
+external_libraries = [
+ "GLib",
+ "GObject",
+ "Gio",
+ "GdkPixbuf",
+ "Cairo",
+]
diff --git a/rsvg-rs/rsvg-sys/build.rs b/rsvg-rs/rsvg-sys/build.rs
new file mode 100644
index 00000000..405c80f8
--- /dev/null
+++ b/rsvg-rs/rsvg-sys/build.rs
@@ -0,0 +1,61 @@
+extern crate pkg_config;
+
+use pkg_config::{Config, Error};
+use std::env;
+use std::io::prelude::*;
+use std::io;
+use std::process;
+
+fn main() {
+ if let Err(s) = find() {
+ let _ = writeln!(io::stderr(), "{}", s);
+ process::exit(1);
+ }
+}
+
+fn find() -> Result<(), Error> {
+ let package_name = "librsvg-2.0";
+ let shared_libs = ["rsvg-2"];
+ let version = {
+ "2.36"
+ };
+
+ if let Ok(lib_dir) = env::var("GTK_LIB_DIR") {
+ for lib_ in shared_libs.iter() {
+ println!("cargo:rustc-link-lib=dylib={}", lib_);
+ }
+ println!("cargo:rustc-link-search=native={}", lib_dir);
+ return Ok(())
+ }
+
+ let target = env::var("TARGET").expect("TARGET environment variable doesn't exist");
+ let hardcode_shared_libs = target.contains("windows");
+
+ let mut config = Config::new();
+ config.atleast_version(version);
+ if hardcode_shared_libs {
+ config.cargo_metadata(false);
+ }
+ match config.probe(package_name) {
+ Ok(library) => {
+ if hardcode_shared_libs {
+ for lib_ in shared_libs.iter() {
+ println!("cargo:rustc-link-lib=dylib={}", lib_);
+ }
+ for path in library.link_paths.iter() {
+ println!("cargo:rustc-link-search=native={}",
+ path.to_str().expect("library path doesn't exist"));
+ }
+ }
+ Ok(())
+ }
+ Err(Error::EnvNoPkgConfig(_)) | Err(Error::Command { .. }) => {
+ for lib_ in shared_libs.iter() {
+ println!("cargo:rustc-link-lib=dylib={}", lib_);
+ }
+ Ok(())
+ }
+ Err(err) => Err(err),
+ }
+}
+
diff --git a/rsvg-rs/rsvg-sys/src/lib.rs b/rsvg-rs/rsvg-sys/src/lib.rs
new file mode 100644
index 00000000..7fe0ea91
--- /dev/null
+++ b/rsvg-rs/rsvg-sys/src/lib.rs
@@ -0,0 +1,160 @@
+// This file was generated by gir (d50d839) from gir-files (???)
+// DO NOT EDIT
+
+#![allow(non_camel_case_types, non_upper_case_globals)]
+
+extern crate libc;
+#[macro_use] extern crate bitflags;
+extern crate glib_sys as glib;
+extern crate gobject_sys as gobject;
+extern crate gio_sys as gio;
+extern crate gdk_pixbuf_sys as gdk_pixbuf;
+extern crate cairo_sys as cairo;
+
+#[allow(unused_imports)]
+use libc::{c_int, c_char, c_uchar, c_float, c_uint, c_double,
+ c_short, c_ushort, c_long, c_ulong,
+ c_void, size_t, ssize_t, intptr_t, uintptr_t, time_t, FILE};
+
+#[allow(unused_imports)]
+use glib::{gboolean, gconstpointer, gpointer, GType, Volatile};
+
+// Enums
+pub type Error = c_int;
+pub const RSVG_ERROR_FAILED: Error = 0;
+pub type RsvgError = Error;
+
+// Constants
+pub const LIBRSVG_MAJOR_VERSION: c_int = 2;
+pub const LIBRSVG_MICRO_VERSION: c_int = 2;
+pub const LIBRSVG_MINOR_VERSION: c_int = 42;
+pub const LIBRSVG_VERSION: *const c_char = b"2.42.2\0" as *const u8 as *const c_char;
+
+// Flags
+bitflags! {
+ #[repr(C)]
+ pub struct RsvgHandleFlags: c_uint {
+ const FLAGS_NONE = 0;
+ const FLAG_UNLIMITED = 1;
+ const FLAG_KEEP_IMAGE_DATA = 2;
+ }
+}
+pub const RSVG_HANDLE_FLAGS_NONE: RsvgHandleFlags = RsvgHandleFlags::FLAGS_NONE;
+pub const RSVG_HANDLE_FLAG_UNLIMITED: RsvgHandleFlags = RsvgHandleFlags::FLAG_UNLIMITED;
+pub const RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA: RsvgHandleFlags = RsvgHandleFlags::FLAG_KEEP_IMAGE_DATA;
+
+// Records
+#[repr(C)]
+pub struct RsvgDimensionData {
+ pub width: c_int,
+ pub height: c_int,
+ pub em: c_double,
+ pub ex: c_double,
+}
+
+impl ::std::fmt::Debug for RsvgDimensionData {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ write!(f, "RsvgDimensionData @ {:?}", self as *const _)
+ }
+}
+
+#[repr(C)]
+pub struct RsvgHandleClass {
+ pub parent: gobject::GObjectClass,
+ pub _abi_padding: [gpointer; 15],
+}
+
+impl ::std::fmt::Debug for RsvgHandleClass {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ write!(f, "RsvgHandleClass @ {:?}", self as *const _)
+ }
+}
+
+#[repr(C)]
+pub struct RsvgHandlePrivate(c_void);
+
+impl ::std::fmt::Debug for RsvgHandlePrivate {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ write!(f, "RsvgHandlePrivate @ {:?}", self as *const _)
+ }
+}
+
+#[repr(C)]
+pub struct RsvgPositionData {
+ pub x: c_int,
+ pub y: c_int,
+}
+
+impl ::std::fmt::Debug for RsvgPositionData {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ write!(f, "RsvgPositionData @ {:?}", self as *const _)
+ }
+}
+
+// Classes
+#[repr(C)]
+pub struct RsvgHandle {
+ pub parent: gobject::GObject,
+ pub priv_: *mut RsvgHandlePrivate,
+ pub _abi_padding: [gpointer; 15],
+}
+
+impl ::std::fmt::Debug for RsvgHandle {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ f.debug_struct(&format!("RsvgHandle @ {:?}", self as *const _))
+ .field("parent", &self.parent)
+ .field("priv_", &self.priv_)
+ .field("_abi_padding", &self._abi_padding)
+ .finish()
+ }
+}
+
+extern "C" {
+
+ //=========================================================================
+ // RsvgError
+ //=========================================================================
+ pub fn rsvg_error_get_type() -> GType;
+ pub fn rsvg_error_quark() -> glib::GQuark;
+
+ //=========================================================================
+ // RsvgHandleFlags
+ //=========================================================================
+ pub fn rsvg_handle_flags_get_type() -> GType;
+
+ //=========================================================================
+ // RsvgHandle
+ //=========================================================================
+ pub fn rsvg_handle_get_type() -> GType;
+ pub fn rsvg_handle_new() -> *mut RsvgHandle;
+ pub fn rsvg_handle_new_from_data(data: *mut u8, data_len: size_t, error: *mut *mut glib::GError) -> *mut RsvgHandle;
+ pub fn rsvg_handle_new_from_file(file_name: *const c_char, error: *mut *mut glib::GError) -> *mut RsvgHandle;
+ pub fn rsvg_handle_new_from_gfile_sync(file: *mut gio::GFile, flags: RsvgHandleFlags, cancellable: *mut gio::GCancellable, error: *mut *mut glib::GError) -> *mut RsvgHandle;
+ pub fn rsvg_handle_new_from_stream_sync(input_stream: *mut gio::GInputStream, base_file: *mut gio::GFile, flags: RsvgHandleFlags, cancellable: *mut gio::GCancellable, error: *mut *mut glib::GError) -> *mut RsvgHandle;
+ pub fn rsvg_handle_new_with_flags(flags: RsvgHandleFlags) -> *mut RsvgHandle;
+ pub fn rsvg_handle_close(handle: *mut RsvgHandle, error: *mut *mut glib::GError) -> gboolean;
+ pub fn rsvg_handle_get_base_uri(handle: *mut RsvgHandle) -> *const c_char;
+ pub fn rsvg_handle_get_dimensions(handle: *mut RsvgHandle, dimension_data: *mut RsvgDimensionData);
+ pub fn rsvg_handle_get_dimensions_sub(handle: *mut RsvgHandle, dimension_data: *mut RsvgDimensionData, id: *const c_char) -> gboolean;
+ pub fn rsvg_handle_get_pixbuf(handle: *mut RsvgHandle) -> *mut gdk_pixbuf::GdkPixbuf;
+ pub fn rsvg_handle_get_pixbuf_sub(handle: *mut RsvgHandle, id: *const c_char) -> *mut gdk_pixbuf::GdkPixbuf;
+ pub fn rsvg_handle_get_position_sub(handle: *mut RsvgHandle, position_data: *mut RsvgPositionData, id: *const c_char) -> gboolean;
+ pub fn rsvg_handle_has_sub(handle: *mut RsvgHandle, id: *const c_char) -> gboolean;
+ pub fn rsvg_handle_internal_set_testing(handle: *mut RsvgHandle, testing: gboolean);
+ pub fn rsvg_handle_read_stream_sync(handle: *mut RsvgHandle, stream: *mut gio::GInputStream, cancellable: *mut gio::GCancellable, error: *mut *mut glib::GError) -> gboolean;
+ pub fn rsvg_handle_render_cairo(handle: *mut RsvgHandle, cr: *mut cairo::cairo_t) -> gboolean;
+ pub fn rsvg_handle_render_cairo_sub(handle: *mut RsvgHandle, cr: *mut cairo::cairo_t, id: *const c_char) -> gboolean;
+ pub fn rsvg_handle_set_base_gfile(handle: *mut RsvgHandle, base_file: *mut gio::GFile);
+ pub fn rsvg_handle_set_base_uri(handle: *mut RsvgHandle, base_uri: *const c_char);
+ pub fn rsvg_handle_set_dpi(handle: *mut RsvgHandle, dpi: c_double);
+ pub fn rsvg_handle_set_dpi_x_y(handle: *mut RsvgHandle, dpi_x: c_double, dpi_y: c_double);
+ pub fn rsvg_handle_write(handle: *mut RsvgHandle, buf: *mut u8, count: size_t, error: *mut *mut glib::GError) -> gboolean;
+
+ //=========================================================================
+ // Other functions
+ //=========================================================================
+ pub fn rsvg_cleanup();
+ pub fn rsvg_set_default_dpi(dpi: c_double);
+ pub fn rsvg_set_default_dpi_x_y(dpi_x: c_double, dpi_y: c_double);
+
+}
diff --git a/rsvg-rs/src/auto/enums.rs b/rsvg-rs/src/auto/enums.rs
new file mode 100644
index 00000000..956a81a1
--- /dev/null
+++ b/rsvg-rs/src/auto/enums.rs
@@ -0,0 +1,6 @@
+// This file was generated by gir (d50d839) from gir-files (???)
+// DO NOT EDIT
+
+use ffi;
+use glib::translate::*;
+
diff --git a/rsvg-rs/src/auto/flags.rs b/rsvg-rs/src/auto/flags.rs
new file mode 100644
index 00000000..b53bd76b
--- /dev/null
+++ b/rsvg-rs/src/auto/flags.rs
@@ -0,0 +1,58 @@
+// This file was generated by gir (d50d839) from gir-files (???)
+// DO NOT EDIT
+
+use ffi;
+use glib::Type;
+use glib::StaticType;
+use glib::value::{Value, SetValue, FromValue, FromValueOptional};
+use gobject_ffi;
+use glib::translate::*;
+
+bitflags! {
+ pub struct HandleFlags: u32 {
+ const FLAGS_NONE = 0;
+ const FLAG_UNLIMITED = 1;
+ const FLAG_KEEP_IMAGE_DATA = 2;
+ }
+}
+
+#[doc(hidden)]
+impl ToGlib for HandleFlags {
+ type GlibType = ffi::RsvgHandleFlags;
+
+ fn to_glib(&self) -> ffi::RsvgHandleFlags {
+ ffi::RsvgHandleFlags::from_bits_truncate(self.bits())
+ }
+}
+
+#[doc(hidden)]
+impl FromGlib<ffi::RsvgHandleFlags> for HandleFlags {
+ fn from_glib(value: ffi::RsvgHandleFlags) -> HandleFlags {
+ HandleFlags::from_bits_truncate(value.bits())
+ }
+}
+
+impl StaticType for HandleFlags {
+ fn static_type() -> Type {
+ unsafe { from_glib(ffi::rsvg_handle_flags_get_type()) }
+ }
+}
+
+impl<'a> FromValueOptional<'a> for HandleFlags {
+ unsafe fn from_value_optional(value: &Value) -> Option<Self> {
+ Some(FromValue::from_value(value))
+ }
+}
+
+impl<'a> FromValue<'a> for HandleFlags {
+ unsafe fn from_value(value: &Value) -> Self {
+ from_glib(ffi::RsvgHandleFlags::from_bits_truncate(gobject_ffi::g_value_get_flags(value.to_glib_none().0)))
+ }
+}
+
+impl SetValue for HandleFlags {
+ unsafe fn set_value(value: &mut Value, this: &Self) {
+ gobject_ffi::g_value_set_flags(value.to_glib_none_mut().0, this.to_glib().bits())
+ }
+}
+
diff --git a/rsvg-rs/src/auto/handle.rs b/rsvg-rs/src/auto/handle.rs
new file mode 100644
index 00000000..9f7a342c
--- /dev/null
+++ b/rsvg-rs/src/auto/handle.rs
@@ -0,0 +1,574 @@
+// This file was generated by gir (d50d839) from gir-files (???)
+// DO NOT EDIT
+
+use DimensionData;
+use Error;
+use HandleFlags;
+use PositionData;
+use cairo;
+use ffi;
+use gdk_pixbuf;
+use glib;
+use glib::StaticType;
+use glib::Value;
+use glib::object::Downcast;
+use glib::object::IsA;
+use glib::signal::SignalHandlerId;
+use glib::signal::connect;
+use glib::translate::*;
+use glib_ffi;
+use gobject_ffi;
+use std::boxed::Box as Box_;
+use std::mem;
+use std::mem::transmute;
+use std::ptr;
+
+glib_wrapper! {
+ pub struct Handle(Object<ffi::RsvgHandle, ffi::RsvgHandleClass>);
+
+ match fn {
+ get_type => || ffi::rsvg_handle_get_type(),
+ }
+}
+
+impl Handle {
+ /// Returns a new rsvg handle. Must be freed with `gobject::Object::unref`. This
+ /// handle can be used for dynamically loading an image. You need to feed it
+ /// data using `HandleExt::write`, then call `HandleExt::close` when done.
+ /// Afterwords, you can render it using Cairo or get a `gdk_pixbuf::Pixbuf` from it. When
+ /// finished, free with `gobject::Object::unref`. No more than one image can be loaded
+ /// with one handle.
+ ///
+ /// # Returns
+ ///
+ /// A new `Handle`
+ pub fn new() -> Handle {
+ unsafe {
+ from_glib_full(ffi::rsvg_handle_new())
+ }
+ }
+
+ /// Loads the SVG specified by `data`.
+ /// ## `data`
+ /// The SVG data
+ /// ## `data_len`
+ /// The length of `data`, in bytes
+ ///
+ /// # Returns
+ ///
+ /// A `Handle` or `None` if an error occurs.
+ pub fn new_from_data(data: &[u8]) -> Result<Handle, Error> {
+ let data_len = data.len() as usize;
+ unsafe {
+ let mut error = ptr::null_mut();
+ let ret = ffi::rsvg_handle_new_from_data(data.to_glib_none().0, data_len, &mut error);
+ if error.is_null() { Ok(from_glib_full(ret)) } else { Err(from_glib_full(error)) }
+ }
+ }
+
+ /// Loads the SVG specified by `file_name`.
+ /// ## `file_name`
+ /// The file name to load. If built with gnome-vfs, can be a URI.
+ ///
+ /// # Returns
+ ///
+ /// A `Handle` or `None` if an error occurs.
+ pub fn new_from_file(file_name: &str) -> Result<Handle, Error> {
+ unsafe {
+ let mut error = ptr::null_mut();
+ let ret = ffi::rsvg_handle_new_from_file(file_name.to_glib_none().0, &mut error);
+ if error.is_null() { Ok(from_glib_full(ret)) } else { Err(from_glib_full(error)) }
+ }
+ }
+
+ //pub fn new_from_gfile_sync<'a, P: IsA</*Ignored*/gio::File>, Q: Into<Option<&'a /*Ignored*/gio::Cancellable>>>(file: &P, flags: HandleFlags, cancellable: Q) -> Result<Handle, Error> {
+ // unsafe { TODO: call ffi::rsvg_handle_new_from_gfile_sync() }
+ //}
+
+ //pub fn new_from_stream_sync<'a, 'b, P: IsA</*Ignored*/gio::InputStream>, Q: IsA</*Ignored*/gio::File> + 'a, R: Into<Option<&'a Q>>, S: Into<Option<&'b /*Ignored*/gio::Cancellable>>>(input_stream: &P, base_file: R, flags: HandleFlags, cancellable: S) -> Result<Handle, Error> {
+ // unsafe { TODO: call ffi::rsvg_handle_new_from_stream_sync() }
+ //}
+
+ /// Creates a new `Handle` with flags `flags`.
+ /// ## `flags`
+ /// flags from `HandleFlags`
+ ///
+ /// # Returns
+ ///
+ /// a new `Handle`
+ pub fn new_with_flags(flags: HandleFlags) -> Handle {
+ unsafe {
+ from_glib_full(ffi::rsvg_handle_new_with_flags(flags.to_glib()))
+ }
+ }
+}
+
+impl Default for Handle {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+/// Trait containing all `Handle` methods.
+///
+/// # Implementors
+///
+/// [`Handle`](struct.Handle.html)
+pub trait HandleExt {
+ /// Closes `self`, to indicate that loading the image is complete. This will
+ /// return `true` if the loader closed successfully. Note that `self` isn't
+ /// freed until `gobject::Object::unref` is called.
+ ///
+ /// # Returns
+ ///
+ /// `true` on success, or `false` on error
+ fn close(&self) -> Result<(), Error>;
+
+ /// Get the SVG's size. Do not call from within the size_func callback, because an infinite loop will occur.
+ /// ## `dimension_data`
+ /// A place to store the SVG's size
+ fn get_dimensions(&self) -> DimensionData;
+
+ /// Get the size of a subelement of the SVG file. Do not call from within the
+ /// size_func callback, because an infinite loop will occur.
+ /// ## `dimension_data`
+ /// A place to store the SVG's size
+ /// ## `id`
+ /// An element's id within the SVG, starting with "##", for
+ /// example, "#`layer1`"; or `None` to use the whole SVG.
+ fn get_dimensions_sub<'a, P: Into<Option<&'a str>>>(&self, id: P) -> Option<DimensionData>;
+
+ /// Returns the pixbuf loaded by `self`. The pixbuf returned will be reffed, so
+ /// the caller of this function must assume that ref. If insufficient data has
+ /// been read to create the pixbuf, or an error occurred in loading, then `None`
+ /// will be returned. Note that the pixbuf may not be complete until
+ /// `HandleExt::close` has been called.
+ ///
+ /// # Returns
+ ///
+ /// the pixbuf loaded by `self`, or `None`.
+ fn get_pixbuf(&self) -> Option<gdk_pixbuf::Pixbuf>;
+
+ /// Returns the pixbuf loaded by `self`. The pixbuf returned will be reffed, so
+ /// the caller of this function must assume that ref. If insufficient data has
+ /// been read to create the pixbuf, or an error occurred in loading, then `None`
+ /// will be returned. Note that the pixbuf may not be complete until
+ /// `HandleExt::close` has been called.
+ /// ## `id`
+ /// An element's id within the SVG, starting with "##", for
+ /// example, "#`layer1`"; or `None` to use the whole SVG.
+ ///
+ /// # Returns
+ ///
+ /// the pixbuf loaded by `self`, or `None`.
+ fn get_pixbuf_sub<'a, P: Into<Option<&'a str>>>(&self, id: P) -> Option<gdk_pixbuf::Pixbuf>;
+
+ /// Get the position of a subelement of the SVG file. Do not call from within
+ /// the size_func callback, because an infinite loop will occur.
+ /// ## `position_data`
+ /// A place to store the SVG fragment's position.
+ /// ## `id`
+ /// An element's id within the SVG, starting with "##", for
+ /// example, "#`layer1`"; or `None` to use the whole SVG.
+ fn get_position_sub<'a, P: Into<Option<&'a str>>>(&self, id: P) -> Option<PositionData>;
+
+ /// Checks whether the element `id` exists in the SVG document.
+ /// ## `id`
+ /// an element's id within the SVG, starting with "##", for example, "#`layer1`".
+ ///
+ /// # Returns
+ ///
+ /// `true` if `id` exists in the SVG document
+ fn has_sub(&self, id: &str) -> bool;
+
+ fn internal_set_testing(&self, testing: bool);
+
+ //fn read_stream_sync<'a, P: IsA</*Ignored*/gio::InputStream>, Q: Into<Option<&'a /*Ignored*/gio::Cancellable>>>(&self, stream: &P, cancellable: Q) -> Result<(), Error>;
+
+ /// Draws a SVG to a Cairo surface
+ /// ## `cr`
+ /// A Cairo renderer
+ ///
+ /// # Returns
+ ///
+ /// `true` if drawing succeeded.
+ fn render_cairo(&self, cr: &cairo::Context) -> bool;
+
+ /// Draws a subset of a SVG to a Cairo surface
+ /// ## `cr`
+ /// A Cairo renderer
+ /// ## `id`
+ /// An element's id within the SVG, or `None` to render
+ /// the whole SVG. For example, if you have a layer called "layer1"
+ /// that you wish to render, pass "#`layer1`" as the id.
+ ///
+ /// # Returns
+ ///
+ /// `true` if drawing succeeded.
+ fn render_cairo_sub<'a, P: Into<Option<&'a str>>>(&self, cr: &cairo::Context, id: P) -> bool;
+
+ //fn set_base_gfile<P: IsA</*Ignored*/gio::File>>(&self, base_file: &P);
+
+ /// Set the base URI for this SVG. This can only be called before `HandleExt::write`
+ /// has been called.
+ /// ## `base_uri`
+ /// The base uri
+ fn set_base_uri(&self, base_uri: &str);
+
+ /// Sets the DPI for the outgoing pixbuf. Common values are
+ /// 75, 90, and 300 DPI. Passing a number <= 0 to `dpi` will
+ /// reset the DPI to whatever the default value happens to be.
+ /// ## `dpi`
+ /// Dots Per Inch (aka Pixels Per Inch)
+ fn set_dpi(&self, dpi: f64);
+
+ /// Sets the DPI for the outgoing pixbuf. Common values are
+ /// 75, 90, and 300 DPI. Passing a number <= 0 to `dpi_x` or `dpi_y` will
+ /// reset the DPI to whatever the default value happens to be.
+ /// ## `dpi_x`
+ /// Dots Per Inch (aka Pixels Per Inch)
+ /// ## `dpi_y`
+ /// Dots Per Inch (aka Pixels Per Inch)
+ fn set_dpi_x_y(&self, dpi_x: f64, dpi_y: f64);
+
+ /// Loads the next `count` bytes of the image. This will return `true` if the data
+ /// was loaded successful, and `false` if an error occurred. In the latter case,
+ /// the loader will be closed, and will not accept further writes. If `false` is
+ /// returned, `error` will be set to an error from the `Error` domain. Errors
+ /// from `gio::IOErrorEnum` are also possible.
+ /// ## `buf`
+ /// pointer to svg data
+ /// ## `count`
+ /// length of the `buf` buffer in bytes
+ ///
+ /// # Returns
+ ///
+ /// `true` on success, or `false` on error
+ fn write(&self, buf: &[u8]) -> Result<(), Error>;
+
+ fn get_property_dpi_x(&self) -> f64;
+
+ fn set_property_dpi_x(&self, dpi_x: f64);
+
+ fn get_property_dpi_y(&self) -> f64;
+
+ fn set_property_dpi_y(&self, dpi_y: f64);
+
+ fn get_property_em(&self) -> f64;
+
+ fn get_property_ex(&self) -> f64;
+
+ /// Flags from `HandleFlags`.
+ fn get_property_flags(&self) -> HandleFlags;
+
+ fn get_property_height(&self) -> i32;
+
+ fn get_property_width(&self) -> i32;
+
+ fn connect_property_dpi_x_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
+
+ fn connect_property_dpi_y_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
+
+ fn connect_property_em_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
+
+ fn connect_property_ex_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
+
+ fn connect_property_flags_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
+
+ fn connect_property_height_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
+
+ fn connect_property_width_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
+}
+
+impl<O: IsA<Handle> + IsA<glib::object::Object>> HandleExt for O {
+ fn close(&self) -> Result<(), Error> {
+ unsafe {
+ let mut error = ptr::null_mut();
+ let _ = ffi::rsvg_handle_close(self.to_glib_none().0, &mut error);
+ if error.is_null() { Ok(()) } else { Err(from_glib_full(error)) }
+ }
+ }
+
+ fn get_dimensions(&self) -> DimensionData {
+ unsafe {
+ let mut dimension_data = DimensionData::uninitialized();
+ ffi::rsvg_handle_get_dimensions(self.to_glib_none().0, dimension_data.to_glib_none_mut().0);
+ dimension_data
+ }
+ }
+
+ fn get_dimensions_sub<'a, P: Into<Option<&'a str>>>(&self, id: P) -> Option<DimensionData> {
+ let id = id.into();
+ let id = id.to_glib_none();
+ unsafe {
+ let mut dimension_data = DimensionData::uninitialized();
+ let ret = from_glib(ffi::rsvg_handle_get_dimensions_sub(self.to_glib_none().0, dimension_data.to_glib_none_mut().0, id.0));
+ if ret { Some(dimension_data) } else { None }
+ }
+ }
+
+ fn get_pixbuf(&self) -> Option<gdk_pixbuf::Pixbuf> {
+ unsafe {
+ from_glib_full(ffi::rsvg_handle_get_pixbuf(self.to_glib_none().0))
+ }
+ }
+
+ fn get_pixbuf_sub<'a, P: Into<Option<&'a str>>>(&self, id: P) -> Option<gdk_pixbuf::Pixbuf> {
+ let id = id.into();
+ let id = id.to_glib_none();
+ unsafe {
+ from_glib_full(ffi::rsvg_handle_get_pixbuf_sub(self.to_glib_none().0, id.0))
+ }
+ }
+
+ fn get_position_sub<'a, P: Into<Option<&'a str>>>(&self, id: P) -> Option<PositionData> {
+ let id = id.into();
+ let id = id.to_glib_none();
+ unsafe {
+ let mut position_data = PositionData::uninitialized();
+ let ret = from_glib(ffi::rsvg_handle_get_position_sub(self.to_glib_none().0, position_data.to_glib_none_mut().0, id.0));
+ if ret { Some(position_data) } else { None }
+ }
+ }
+
+ fn has_sub(&self, id: &str) -> bool {
+ unsafe {
+ from_glib(ffi::rsvg_handle_has_sub(self.to_glib_none().0, id.to_glib_none().0))
+ }
+ }
+
+ fn internal_set_testing(&self, testing: bool) {
+ unsafe {
+ ffi::rsvg_handle_internal_set_testing(self.to_glib_none().0, testing.to_glib());
+ }
+ }
+
+ //fn read_stream_sync<'a, P: IsA</*Ignored*/gio::InputStream>, Q: Into<Option<&'a /*Ignored*/gio::Cancellable>>>(&self, stream: &P, cancellable: Q) -> Result<(), Error> {
+ // unsafe { TODO: call ffi::rsvg_handle_read_stream_sync() }
+ //}
+
+ fn render_cairo(&self, cr: &cairo::Context) -> bool {
+ unsafe {
+ from_glib(ffi::rsvg_handle_render_cairo(self.to_glib_none().0, mut_override(cr.to_glib_none().0)))
+ }
+ }
+
+ fn render_cairo_sub<'a, P: Into<Option<&'a str>>>(&self, cr: &cairo::Context, id: P) -> bool {
+ let id = id.into();
+ let id = id.to_glib_none();
+ unsafe {
+ from_glib(ffi::rsvg_handle_render_cairo_sub(self.to_glib_none().0, mut_override(cr.to_glib_none().0), id.0))
+ }
+ }
+
+ //fn set_base_gfile<P: IsA</*Ignored*/gio::File>>(&self, base_file: &P) {
+ // unsafe { TODO: call ffi::rsvg_handle_set_base_gfile() }
+ //}
+
+ fn set_base_uri(&self, base_uri: &str) {
+ unsafe {
+ ffi::rsvg_handle_set_base_uri(self.to_glib_none().0, base_uri.to_glib_none().0);
+ }
+ }
+
+ fn set_dpi(&self, dpi: f64) {
+ unsafe {
+ ffi::rsvg_handle_set_dpi(self.to_glib_none().0, dpi);
+ }
+ }
+
+ fn set_dpi_x_y(&self, dpi_x: f64, dpi_y: f64) {
+ unsafe {
+ ffi::rsvg_handle_set_dpi_x_y(self.to_glib_none().0, dpi_x, dpi_y);
+ }
+ }
+
+ fn write(&self, buf: &[u8]) -> Result<(), Error> {
+ let count = buf.len() as usize;
+ unsafe {
+ let mut error = ptr::null_mut();
+ let _ = ffi::rsvg_handle_write(self.to_glib_none().0, buf.to_glib_none().0, count, &mut error);
+ if error.is_null() { Ok(()) } else { Err(from_glib_full(error)) }
+ }
+ }
+
+ fn get_property_dpi_x(&self) -> f64 {
+ unsafe {
+ let mut value = Value::uninitialized();
+ gobject_ffi::g_value_init(value.to_glib_none_mut().0, <f64 as StaticType>::static_type().to_glib());
+ gobject_ffi::g_object_get_property(self.to_glib_none().0, "dpi-x".to_glib_none().0, value.to_glib_none_mut().0);
+ value.get().unwrap()
+ }
+ }
+
+ fn set_property_dpi_x(&self, dpi_x: f64) {
+ unsafe {
+ gobject_ffi::g_object_set_property(self.to_glib_none().0, "dpi-x".to_glib_none().0, Value::from(&dpi_x).to_glib_none().0);
+ }
+ }
+
+ fn get_property_dpi_y(&self) -> f64 {
+ unsafe {
+ let mut value = Value::uninitialized();
+ gobject_ffi::g_value_init(value.to_glib_none_mut().0, <f64 as StaticType>::static_type().to_glib());
+ gobject_ffi::g_object_get_property(self.to_glib_none().0, "dpi-y".to_glib_none().0, value.to_glib_none_mut().0);
+ value.get().unwrap()
+ }
+ }
+
+ fn set_property_dpi_y(&self, dpi_y: f64) {
+ unsafe {
+ gobject_ffi::g_object_set_property(self.to_glib_none().0, "dpi-y".to_glib_none().0, Value::from(&dpi_y).to_glib_none().0);
+ }
+ }
+
+ fn get_property_em(&self) -> f64 {
+ unsafe {
+ let mut value = Value::uninitialized();
+ gobject_ffi::g_value_init(value.to_glib_none_mut().0, <f64 as StaticType>::static_type().to_glib());
+ gobject_ffi::g_object_get_property(self.to_glib_none().0, "em".to_glib_none().0, value.to_glib_none_mut().0);
+ value.get().unwrap()
+ }
+ }
+
+ fn get_property_ex(&self) -> f64 {
+ unsafe {
+ let mut value = Value::uninitialized();
+ gobject_ffi::g_value_init(value.to_glib_none_mut().0, <f64 as StaticType>::static_type().to_glib());
+ gobject_ffi::g_object_get_property(self.to_glib_none().0, "ex".to_glib_none().0, value.to_glib_none_mut().0);
+ value.get().unwrap()
+ }
+ }
+
+ fn get_property_flags(&self) -> HandleFlags {
+ unsafe {
+ let mut value = Value::uninitialized();
+ gobject_ffi::g_value_init(value.to_glib_none_mut().0, <HandleFlags as StaticType>::static_type().to_glib());
+ gobject_ffi::g_object_get_property(self.to_glib_none().0, "flags".to_glib_none().0, value.to_glib_none_mut().0);
+ value.get().unwrap()
+ }
+ }
+
+ fn get_property_height(&self) -> i32 {
+ unsafe {
+ let mut value = Value::uninitialized();
+ gobject_ffi::g_value_init(value.to_glib_none_mut().0, <i32 as StaticType>::static_type().to_glib());
+ gobject_ffi::g_object_get_property(self.to_glib_none().0, "height".to_glib_none().0, value.to_glib_none_mut().0);
+ value.get().unwrap()
+ }
+ }
+
+ fn get_property_width(&self) -> i32 {
+ unsafe {
+ let mut value = Value::uninitialized();
+ gobject_ffi::g_value_init(value.to_glib_none_mut().0, <i32 as StaticType>::static_type().to_glib());
+ gobject_ffi::g_object_get_property(self.to_glib_none().0, "width".to_glib_none().0, value.to_glib_none_mut().0);
+ value.get().unwrap()
+ }
+ }
+
+ fn connect_property_dpi_x_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
+ unsafe {
+ let f: Box_<Box_<Fn(&Self) + 'static>> = Box_::new(Box_::new(f));
+ connect(self.to_glib_none().0, "notify::dpi-x",
+ transmute(notify_dpi_x_trampoline::<Self> as usize), Box_::into_raw(f) as *mut _)
+ }
+ }
+
+ fn connect_property_dpi_y_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
+ unsafe {
+ let f: Box_<Box_<Fn(&Self) + 'static>> = Box_::new(Box_::new(f));
+ connect(self.to_glib_none().0, "notify::dpi-y",
+ transmute(notify_dpi_y_trampoline::<Self> as usize), Box_::into_raw(f) as *mut _)
+ }
+ }
+
+ fn connect_property_em_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
+ unsafe {
+ let f: Box_<Box_<Fn(&Self) + 'static>> = Box_::new(Box_::new(f));
+ connect(self.to_glib_none().0, "notify::em",
+ transmute(notify_em_trampoline::<Self> as usize), Box_::into_raw(f) as *mut _)
+ }
+ }
+
+ fn connect_property_ex_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
+ unsafe {
+ let f: Box_<Box_<Fn(&Self) + 'static>> = Box_::new(Box_::new(f));
+ connect(self.to_glib_none().0, "notify::ex",
+ transmute(notify_ex_trampoline::<Self> as usize), Box_::into_raw(f) as *mut _)
+ }
+ }
+
+ fn connect_property_flags_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
+ unsafe {
+ let f: Box_<Box_<Fn(&Self) + 'static>> = Box_::new(Box_::new(f));
+ connect(self.to_glib_none().0, "notify::flags",
+ transmute(notify_flags_trampoline::<Self> as usize), Box_::into_raw(f) as *mut _)
+ }
+ }
+
+ fn connect_property_height_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
+ unsafe {
+ let f: Box_<Box_<Fn(&Self) + 'static>> = Box_::new(Box_::new(f));
+ connect(self.to_glib_none().0, "notify::height",
+ transmute(notify_height_trampoline::<Self> as usize), Box_::into_raw(f) as *mut _)
+ }
+ }
+
+ fn connect_property_width_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
+ unsafe {
+ let f: Box_<Box_<Fn(&Self) + 'static>> = Box_::new(Box_::new(f));
+ connect(self.to_glib_none().0, "notify::width",
+ transmute(notify_width_trampoline::<Self> as usize), Box_::into_raw(f) as *mut _)
+ }
+ }
+}
+
+unsafe extern "C" fn notify_dpi_x_trampoline<P>(this: *mut ffi::RsvgHandle, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer)
+where P: IsA<Handle> {
+ callback_guard!();
+ let f: &&(Fn(&P) + 'static) = transmute(f);
+ f(&Handle::from_glib_borrow(this).downcast_unchecked())
+}
+
+unsafe extern "C" fn notify_dpi_y_trampoline<P>(this: *mut ffi::RsvgHandle, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer)
+where P: IsA<Handle> {
+ callback_guard!();
+ let f: &&(Fn(&P) + 'static) = transmute(f);
+ f(&Handle::from_glib_borrow(this).downcast_unchecked())
+}
+
+unsafe extern "C" fn notify_em_trampoline<P>(this: *mut ffi::RsvgHandle, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer)
+where P: IsA<Handle> {
+ callback_guard!();
+ let f: &&(Fn(&P) + 'static) = transmute(f);
+ f(&Handle::from_glib_borrow(this).downcast_unchecked())
+}
+
+unsafe extern "C" fn notify_ex_trampoline<P>(this: *mut ffi::RsvgHandle, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer)
+where P: IsA<Handle> {
+ callback_guard!();
+ let f: &&(Fn(&P) + 'static) = transmute(f);
+ f(&Handle::from_glib_borrow(this).downcast_unchecked())
+}
+
+unsafe extern "C" fn notify_flags_trampoline<P>(this: *mut ffi::RsvgHandle, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer)
+where P: IsA<Handle> {
+ callback_guard!();
+ let f: &&(Fn(&P) + 'static) = transmute(f);
+ f(&Handle::from_glib_borrow(this).downcast_unchecked())
+}
+
+unsafe extern "C" fn notify_height_trampoline<P>(this: *mut ffi::RsvgHandle, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer)
+where P: IsA<Handle> {
+ callback_guard!();
+ let f: &&(Fn(&P) + 'static) = transmute(f);
+ f(&Handle::from_glib_borrow(this).downcast_unchecked())
+}
+
+unsafe extern "C" fn notify_width_trampoline<P>(this: *mut ffi::RsvgHandle, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer)
+where P: IsA<Handle> {
+ callback_guard!();
+ let f: &&(Fn(&P) + 'static) = transmute(f);
+ f(&Handle::from_glib_borrow(this).downcast_unchecked())
+}
diff --git a/rsvg-rs/src/auto/mod.rs b/rsvg-rs/src/auto/mod.rs
new file mode 100644
index 00000000..4ddf345a
--- /dev/null
+++ b/rsvg-rs/src/auto/mod.rs
@@ -0,0 +1,14 @@
+// This file was generated by gir (d50d839) from gir-files (???)
+// DO NOT EDIT
+
+mod handle;
+pub use self::handle::Handle;
+pub use self::handle::HandleExt;
+
+mod flags;
+pub use self::flags::HandleFlags;
+
+#[doc(hidden)]
+pub mod traits {
+ pub use super::HandleExt;
+}
diff --git a/rsvg-rs/src/dimension_data.rs b/rsvg-rs/src/dimension_data.rs
new file mode 100644
index 00000000..37dc22c4
--- /dev/null
+++ b/rsvg-rs/src/dimension_data.rs
@@ -0,0 +1,67 @@
+use std::mem;
+use glib::translate::*;
+use ffi;
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[repr(C)]
+pub struct DimensionData {
+ pub width: i32,
+ pub height: i32,
+ pub em: f64,
+ pub ex: f64,
+}
+
+impl DimensionData {
+ pub fn new(width: i32, height: i32, em: f64, ex: f64) -> DimensionData {
+ DimensionData {
+ width: width,
+ height: height,
+ em: em,
+ ex: ex,
+ }
+ }
+}
+
+#[doc(hidden)]
+impl Uninitialized for DimensionData {
+ #[inline]
+ unsafe fn uninitialized() -> Self {
+ mem::uninitialized()
+ }
+}
+
+#[doc(hidden)]
+impl<'a> ToGlibPtr<'a, *const ffi::RsvgDimensionData> for DimensionData {
+ type Storage = &'a Self;
+
+ #[inline]
+ fn to_glib_none(&'a self) -> Stash<'a, *const ffi::RsvgDimensionData, Self> {
+ let ptr: *const DimensionData = &*self;
+ Stash(ptr as *const ffi::RsvgDimensionData, self)
+ }
+}
+
+#[doc(hidden)]
+impl<'a> ToGlibPtrMut<'a, *mut ffi::RsvgDimensionData> for DimensionData {
+ type Storage = &'a mut Self;
+
+ #[inline]
+ fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut ffi::RsvgDimensionData, Self> {
+ let ptr: *mut DimensionData = &mut *self;
+ StashMut(ptr as *mut ffi::RsvgDimensionData, self)
+ }
+}
+
+#[doc(hidden)]
+impl FromGlibPtrNone<*const ffi::RsvgDimensionData> for DimensionData {
+ unsafe fn from_glib_none(ptr: *const ffi::RsvgDimensionData) -> Self {
+ *(ptr as *const DimensionData)
+ }
+}
+
+#[doc(hidden)]
+impl FromGlibPtrNone<*mut ffi::RsvgDimensionData> for DimensionData {
+ unsafe fn from_glib_none(ptr: *mut ffi::RsvgDimensionData) -> Self {
+ *(ptr as *mut DimensionData)
+ }
+} \ No newline at end of file
diff --git a/rsvg-rs/src/handle.rs b/rsvg-rs/src/handle.rs
new file mode 100644
index 00000000..0e02e472
--- /dev/null
+++ b/rsvg-rs/src/handle.rs
@@ -0,0 +1,16 @@
+use ffi;
+use std::ptr;
+
+use glib::Error;
+use glib::translate::*;
+use auto::Handle;
+
+impl Handle {
+ pub fn new_from_str(data: &str) -> Result<Handle, Error> {
+ unsafe {
+ let mut error = ptr::null_mut();
+ let handle = ffi::rsvg_handle_new_from_data(data.as_ptr() as *mut _, data.len() as _, &mut error);
+ if error.is_null() { Ok(from_glib_full(handle)) } else { Err(from_glib_full(error)) }
+ }
+ }
+} \ No newline at end of file
diff --git a/rsvg-rs/src/lib.rs b/rsvg-rs/src/lib.rs
new file mode 100644
index 00000000..158eef54
--- /dev/null
+++ b/rsvg-rs/src/lib.rs
@@ -0,0 +1,125 @@
+extern crate rsvg_sys as ffi;
+extern crate glib_sys as glib_ffi;
+extern crate gobject_sys as gobject_ffi;
+
+#[macro_use]
+extern crate glib;
+extern crate cairo;
+extern crate gdk_pixbuf;
+#[macro_use]
+extern crate bitflags;
+extern crate libc;
+
+macro_rules! callback_guard {
+ () => ()
+}
+
+pub use glib::Error;
+
+mod auto;
+pub use auto::*;
+
+mod handle;
+mod position_data;
+mod dimension_data;
+pub use position_data::PositionData;
+pub use dimension_data::DimensionData;
+
+#[cfg(test)]
+#[macro_use]
+extern crate imageproc;
+
+#[cfg(test)]
+mod tests {
+ extern crate image;
+
+ use super::HandleExt;
+ use self::image::GenericImage;
+
+ fn get_fixture_path(fixture: &str) -> String {
+ return format!("./test-fixtures/{}", fixture);
+ }
+
+ #[test]
+ fn it_should_be_possible_to_create_new_handle_and_write_manually_to_it() {
+ let handle = super::Handle::new();
+
+ handle.write(r#"<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="50" height="50"></svg>"#.as_bytes()).unwrap();
+ handle.close().unwrap();
+
+ assert_eq!(handle.get_dimensions(), super::DimensionData { width: 50, height: 50, em: 50.0, ex: 50.0 });
+ assert_eq!(handle.get_position_sub("#unknownid"), None);
+ }
+
+ #[test]
+ fn it_should_be_possible_to_load_svg_from_string() {
+ let svg = r#"<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="50" height="50"></svg>"#;
+ let handle = super::Handle::new_from_str(svg).unwrap();
+
+ assert_eq!(handle.get_dimensions(), super::DimensionData { width: 50, height: 50, em: 50.0, ex: 50.0 });
+ assert_eq!(handle.get_position_sub("#unknownid"), None);
+ }
+
+ #[test]
+ fn it_should_be_possible_to_load_svg_from_slice() {
+ let svg = r#"<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="50" height="50"></svg>"#;
+ let handle = super::Handle::new_from_data(svg.as_bytes()).unwrap();
+
+ assert_eq!(handle.get_dimensions(), super::DimensionData { width: 50, height: 50, em: 50.0, ex: 50.0 });
+ assert_eq!(handle.get_position_sub("#unknownid"), None);
+ }
+
+ #[test]
+ #[ignore]
+ fn it_should_be_possible_to_load_svg_from_file() {
+ let svg_path = get_fixture_path("mysvg.svg");
+ let handle = super::Handle::new_from_file(&svg_path).unwrap();
+
+ assert_eq!(handle.get_dimensions(), super::DimensionData { width: 100, height: 100, em: 100.0, ex: 100.0 });
+ assert_eq!(handle.get_position_sub("#unknownid"), None);
+ }
+
+ #[test]
+ #[ignore]
+ fn it_should_be_possible_to_render_to_cairo_context() {
+ let svg_path = get_fixture_path("mysvg.svg");
+ let expected = image::open(get_fixture_path("mysvg.svg.png")).unwrap();
+ let handle = super::Handle::new_from_file(&svg_path).unwrap();
+ let dimensions = handle.get_dimensions();
+ let surface = super::cairo::ImageSurface::create(super::cairo::Format::ARgb32, dimensions.width, dimensions.height).unwrap();
+ let context = super::cairo::Context::new(&surface);
+ let mut png_data: Vec<u8> = vec!();
+
+ context.paint_with_alpha(0.0);
+ handle.render_cairo(&context);
+ surface.write_to_png(&mut png_data).unwrap();
+
+ let result = image::load_from_memory_with_format(&png_data, image::ImageFormat::PNG).unwrap();
+ assert_dimensions_match!(result, expected);
+ assert_pixels_eq!(result, expected);
+ }
+
+ #[test]
+ #[ignore]
+ fn it_should_be_possible_to_render_to_gdk_pixbuf_without_throwing() {
+ let svg_path = get_fixture_path("mysvg.svg");
+ let expected = image::open(get_fixture_path("mysvg.svg.png")).unwrap();
+ let handle = super::Handle::new_from_file(&svg_path).unwrap();
+ let pixbuf = handle.get_pixbuf().unwrap();
+ let pixels = (unsafe { pixbuf.get_pixels() }).to_vec();
+ let dimensions = handle.get_dimensions();
+ let result = image::ImageBuffer::from_raw(dimensions.width as u32, dimensions.height as u32, pixels)
+ .map(|v| image::DynamicImage::ImageRgba8(v))
+ .unwrap();
+
+ assert_dimensions_match!(result, expected);
+ assert_pixels_eq!(result, expected);
+ }
+
+ #[test]
+ fn it_should_return_an_error_when_loading_non_existing_file() {
+ let handle = super::Handle::new_from_file("unknown.svg");
+
+ assert!(handle.is_err());
+ }
+}
diff --git a/rsvg-rs/src/position_data.rs b/rsvg-rs/src/position_data.rs
new file mode 100644
index 00000000..10837ddd
--- /dev/null
+++ b/rsvg-rs/src/position_data.rs
@@ -0,0 +1,67 @@
+use std::mem;
+use glib::translate::*;
+use ffi;
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[repr(C)]
+pub struct PositionData {
+ pub x: i32,
+ pub y: i32,
+ pub em: f64,
+ pub ex: f64,
+}
+
+impl PositionData {
+ pub fn new(x: i32, y: i32, em: f64, ex: f64) -> PositionData {
+ PositionData {
+ x: x,
+ y: y,
+ em: em,
+ ex: ex,
+ }
+ }
+}
+
+#[doc(hidden)]
+impl Uninitialized for PositionData {
+ #[inline]
+ unsafe fn uninitialized() -> Self {
+ mem::uninitialized()
+ }
+}
+
+#[doc(hidden)]
+impl<'a> ToGlibPtr<'a, *const ffi::RsvgPositionData> for PositionData {
+ type Storage = &'a Self;
+
+ #[inline]
+ fn to_glib_none(&'a self) -> Stash<'a, *const ffi::RsvgPositionData, Self> {
+ let ptr: *const PositionData = &*self;
+ Stash(ptr as *const ffi::RsvgPositionData, self)
+ }
+}
+
+#[doc(hidden)]
+impl<'a> ToGlibPtrMut<'a, *mut ffi::RsvgPositionData> for PositionData {
+ type Storage = &'a mut Self;
+
+ #[inline]
+ fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut ffi::RsvgPositionData, Self> {
+ let ptr: *mut PositionData = &mut *self;
+ StashMut(ptr as *mut ffi::RsvgPositionData, self)
+ }
+}
+
+#[doc(hidden)]
+impl FromGlibPtrNone<*const ffi::RsvgPositionData> for PositionData {
+ unsafe fn from_glib_none(ptr: *const ffi::RsvgPositionData) -> Self {
+ *(ptr as *const PositionData)
+ }
+}
+
+#[doc(hidden)]
+impl FromGlibPtrNone<*mut ffi::RsvgPositionData> for PositionData {
+ unsafe fn from_glib_none(ptr: *mut ffi::RsvgPositionData) -> Self {
+ *(ptr as *mut PositionData)
+ }
+} \ No newline at end of file