[librsvg] Revert "Revert the subclass branch temporarily"



commit d448231decfbefb129359ee6b66c07353bf89b3c
Author: Federico Mena Quintero <federico gnome org>
Date:   Fri Feb 22 09:21:47 2019 -0600

    Revert "Revert the subclass branch temporarily"
    
    Now that gtk-rs had a release, we can re-merge the subclass branch.
    
    This reverts commit 21efded1ac00f8adb39e3bd2e239acc20ce2e0a5.

 Cargo.lock                                         | 180 ++++++------
 librsvg/rsvg-handle.c                              | 248 +---------------
 librsvg_crate/Cargo.toml                           |   8 +-
 librsvg_crate/src/lib.rs                           |  10 +-
 rsvg_internals/Cargo.toml                          |  25 +-
 rsvg_internals/src/c_api.rs                        | 294 +++++++++++++++++++
 rsvg_internals/src/error.rs                        |   5 +-
 rsvg_internals/src/gradient.rs                     |  12 +-
 rsvg_internals/src/handle.rs                       | 316 +++++++++++----------
 rsvg_internals/src/io.rs                           |   2 +-
 rsvg_internals/src/lib.rs                          |   7 +-
 rsvg_internals/src/pixbuf_utils.rs                 |   5 +-
 rsvg_internals/src/surface_utils/shared_surface.rs |   2 +-
 rsvg_internals/src/svg.rs                          |  10 +-
 rsvg_internals/src/text.rs                         |   4 +-
 tests/api.c                                        | 128 +++++++++
 16 files changed, 732 insertions(+), 524 deletions(-)
---
diff --git a/Cargo.lock b/Cargo.lock
index 32a086a6..4aa88794 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -62,24 +62,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index";
 
 [[package]]
 name = "cairo-rs"
-version = "0.5.0"
+version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 dependencies = [
- "cairo-sys-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cairo-sys-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cairo-sys-rs"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 dependencies = [
- "glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -252,7 +251,7 @@ dependencies = [
 
 [[package]]
 name = "either"
-version = "1.5.0"
+version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 
 [[package]]
@@ -332,26 +331,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index";
 
 [[package]]
 name = "gdk-pixbuf"
-version = "0.5.0"
+version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 dependencies = [
- "gdk-pixbuf-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "gio-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gdk-pixbuf-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gio 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gio-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "gdk-pixbuf-sys"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 dependencies = [
- "gio-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gio-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -366,45 +365,45 @@ dependencies = [
 
 [[package]]
 name = "gio"
-version = "0.5.1"
+version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "fragile 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gio-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gio-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "gio-sys"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 dependencies = [
- "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "glib"
-version = "0.6.1"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "glib-sys"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 dependencies = [
  "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -413,10 +412,10 @@ dependencies = [
 
 [[package]]
 name = "gobject-sys"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 dependencies = [
- "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -436,7 +435,7 @@ name = "itertools"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 dependencies = [
- "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "either 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -482,9 +481,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index";
 name = "librsvg"
 version = "0.0.1"
 dependencies = [
- "cairo-rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cairo-rs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gio 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "rsvg_internals 0.0.1",
  "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -529,7 +528,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index";
 
 [[package]]
 name = "nalgebra"
-version = "0.17.1"
+version = "0.17.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 dependencies = [
  "alga 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -578,55 +577,55 @@ dependencies = [
 
 [[package]]
 name = "pango"
-version = "0.5.0"
+version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
- "pango-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pango-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "pango-sys"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 dependencies = [
- "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "pangocairo"
-version = "0.6.0"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "cairo-rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cairo-sys-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cairo-rs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cairo-sys-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
- "pango 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "pango-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "pangocairo-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pango 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pango-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pangocairo-sys 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "pangocairo-sys"
-version = "0.8.0"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 dependencies = [
- "cairo-sys-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cairo-sys-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
- "pango-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pango-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -811,7 +810,7 @@ version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 dependencies = [
  "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "either 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -891,32 +890,33 @@ dependencies = [
 name = "rsvg_internals"
 version = "0.0.1"
 dependencies = [
- "cairo-rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cairo-sys-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cairo-rs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cairo-sys-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "criterion 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.25.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "data-url 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "downcast-rs 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gdk-pixbuf 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gdk-pixbuf-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "gio-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gdk-pixbuf 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gdk-pixbuf-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gio 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gio-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
  "locale_config 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "nalgebra 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nalgebra 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "pango 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "pango-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "pangocairo 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pango 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pango-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pangocairo 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1161,8 +1161,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index";
 "checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = 
"a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
 "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = 
"228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
 "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
-"checksum cairo-rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"dd940f0d609699e343ef71c4af5f66423afbf30d666f796dabd8fd15229cf5b6"
-"checksum cairo-sys-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"d25596627380be4381247dba06c69ad05ca21b3b065bd9827e416882ac41dcd2"
+"checksum cairo-rs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"9e09d8a818b2ccc8983f04d95a9350c3cf8d24cc456cedca3b88fa3a81fdc0e2"
+"checksum cairo-sys-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"b3fa13914fdc013387afa771f554f2f71d6ae931f4e5be9246c337d60c3dc484"
 "checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = 
"926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"
 "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = 
"082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
 "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
@@ -1180,7 +1180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index";
 "checksum downcast-rs 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = 
"18df8ce4470c189d18aa926022da57544f31e154631eb4cfe796aea97051fe6c"
 "checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = 
"6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd"
 "checksum dtoa-short 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = 
"59020b8513b76630c49d918c33db9f4c91638e7d3404a28084083b87e33f76f2"
-"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
+"checksum either 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"c67353c641dc847124ea1902d69bd753dee9bb3beff9aa3662ecf86c971d1fac"
 "checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = 
"6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec"
 "checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = 
"04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91"
 "checksum encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = 
"4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81"
@@ -1191,14 +1191,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index";
 "checksum float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"134a8fa843d80a51a5b77d36d42bc2def9edcb0262c914861d08129fd1926600"
 "checksum fragile 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"05f8140122fa0d5dcb9fc8627cfce2b37cc1500f752636d46ea28bc26785c2f9"
 "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
-"checksum gdk-pixbuf 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"bc3aa730cb4df3de5d9fed59f43afdf9e5fb2d3d10bfcbd04cec031435ce87f5"
-"checksum gdk-pixbuf-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"08284f16ce4d909b10d785a763ba190e222d2c1557b29908bf0a661e27a8ac3b"
+"checksum gdk-pixbuf 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"9a1bcb11b461ff5638f6bf03c9f173d3dc250eabc8e57a60644b6f529d3a7c91"
+"checksum gdk-pixbuf-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"10e1115ca451907b6d775fc0392641d14c89277662d98828412fb68555e7e8c8"
 "checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592"
-"checksum gio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"29a44b051990573448edc80b1995237f8b97b5734d2aec05105b9242aa10af11"
-"checksum gio-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"6975ada29f7924dc1c90b30ed3b32d777805a275556c05e420da4fbdc22eb250"
-"checksum glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"7a333edf5b9f1411c246ef14e7881b087255f04c56dbef48c64a0cb039b4b340"
-"checksum glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"3573351e846caed9f11207b275cd67bc07f0c2c94fb628e5d7c92ca056c7882d"
-"checksum gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"08475e4a08f27e6e2287005950114735ed61cec2cb8c1187682a5aec8c69b715"
+"checksum gio 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"ff120a666f4a0f41cca7554fbac82defc2562e90eccf3b26a30e6461fa1bbde8"
+"checksum gio-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"04957c40df00dd72f7c9ec8e382b01ff8ed4a904fcd2fa608b7ae7fbaccfda8f"
+"checksum glib 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"ff186a0d7c1057652b96b51ee21bde4e7255812bdff62a83debf873be7d80d5c"
+"checksum glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"5bda542f3caee39a027638e9644ff89204101ad916fd7370b585ad2c5fc97e61"
+"checksum gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"23e05a14290d3dc255223cba51db4b0f3da438d5250657996fa99b2a30faf43e"
 "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = 
"38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
 "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
 "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = 
"1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
@@ -1213,16 +1213,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index";
 "checksum matrixmultiply 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = 
"dcfed72d871629daa12b25af198f110e8095d7650f5f4c61c5bac28364604f9b"
 "checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
 "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
-"checksum nalgebra 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"ad7190397e73f47014191c4758b2666e616354e36f33f39da9311842db9eca56"
+"checksum nalgebra 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)" = 
"f76a29833cbba252d6799bcfd8e603610a2165a18b62c7f4307495d851c3d337"
 "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = 
"2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
 "checksum num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"107b9be86cd2481930688277b675b0114578227f034674726605b8a482d8baf8"
 "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = 
"0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
 "checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
 "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
-"checksum pango 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"4c2cb169402a3eb1ba034a7cc7d95b8b1c106e9be5ba4be79a5a93dc1a2795f4"
-"checksum pango-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"d6eb49268e69dd0c1da5d3001a61aac08e2e9d2bfbe4ae4b19b9963c998f6453"
-"checksum pangocairo 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"4325b65f44487564a18d6402bed48c1bc4642167bfe972a753d039d1ac938c21"
-"checksum pangocairo-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"9e79ffb01eae5bc130b44fde529fa493ad6308c340da1358eaa2435ed3580e4f"
+"checksum pango 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"4e36b55d7cd522bd183efeb3dfabc547bda1f26eadf8a1241dac09ab3fd3242c"
+"checksum pango-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"747ab9cd4d537e6dc5ef0e4308c10dde8b706673b0237fed4e056b8d2c0b23c8"
+"checksum pangocairo 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"706e885b46a16ba96f46f3c8d880ca6082c2c62693b75f3d167bd3aa4e34b0d4"
+"checksum pangocairo-sys 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"868310e83da5269323c28bd47b641557d032426f396cddfa45e247ff44da9a12"
 "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
 "checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = 
"b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18"
 "checksum phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = 
"b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e"
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index ac36a64a..c1d4d976 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -275,18 +275,10 @@
 
 #include "rsvg.h"
 
-/* Defined in rsvg_internals/src/handle.rs */
-typedef struct RsvgHandleRust RsvgHandleRust;
-
 /* Implemented in rsvg_internals/src/xml.rs */
 typedef struct RsvgXmlState RsvgXmlState;
 
-G_GNUC_INTERNAL
-RsvgHandleRust *rsvg_handle_get_rust (RsvgHandle *handle);
-
 /* Implemented in rsvg_internals/src/handle.rs */
-extern RsvgHandleRust *rsvg_handle_rust_new (void);
-extern void rsvg_handle_rust_free (RsvgHandleRust *raw_handle);
 extern double rsvg_handle_rust_get_dpi_x (RsvgHandle *raw_handle);
 extern double rsvg_handle_rust_get_dpi_y (RsvgHandle *raw_handle);
 extern void rsvg_handle_rust_set_dpi_x (RsvgHandle *raw_handle, double dpi_x);
@@ -352,236 +344,13 @@ extern void rsvg_handle_rust_get_intrinsic_dimensions (RsvgHandle *handle,
 extern GType rsvg_rust_error_get_type (void);
 extern GType rsvg_rust_handle_flags_get_type (void);
 
-typedef struct {
-    RsvgHandleRust *rust_handle;
-} RsvgHandlePrivate;
-
-enum {
-    PROP_0,
-    PROP_FLAGS,
-    PROP_DPI_X,
-    PROP_DPI_Y,
-    PROP_BASE_URI,
-    PROP_WIDTH,
-    PROP_HEIGHT,
-    PROP_EM,
-    PROP_EX,
-    PROP_TITLE,
-    PROP_DESC,
-    PROP_METADATA,
-    NUM_PROPS
-};
-
-G_DEFINE_TYPE_WITH_CODE (RsvgHandle, rsvg_handle, G_TYPE_OBJECT,
-                         G_ADD_PRIVATE (RsvgHandle))
-
-static void
-rsvg_handle_init (RsvgHandle *self)
-{
-    RsvgHandlePrivate *priv = rsvg_handle_get_instance_private (self);
-    priv->rust_handle = rsvg_handle_rust_new();
-}
-
-static void
-rsvg_handle_dispose (GObject *instance)
-{
-    RsvgHandle *self = (RsvgHandle *) instance;
-    RsvgHandlePrivate *priv = rsvg_handle_get_instance_private (self);
-
-    g_clear_pointer (&priv->rust_handle, rsvg_handle_rust_free);
-
-    G_OBJECT_CLASS (rsvg_handle_parent_class)->dispose (instance);
-}
-
-static void
-rsvg_handle_set_property (GObject * instance, guint prop_id, GValue const *value, GParamSpec * pspec)
-{
-    RsvgHandle *self = RSVG_HANDLE (instance);
-
-    switch (prop_id) {
-    case PROP_FLAGS:
-        rsvg_handle_rust_set_flags (self, g_value_get_flags (value));
-        break;
-    case PROP_DPI_X:
-        rsvg_handle_rust_set_dpi_x (self, g_value_get_double (value));
-        break;
-    case PROP_DPI_Y:
-        rsvg_handle_rust_set_dpi_y (self, g_value_get_double (value));
-        break;
-    case PROP_BASE_URI: {
-        const char *str = g_value_get_string (value);
-
-        if (str) {
-            rsvg_handle_set_base_uri (self, str);
-        }
-
-        break;
-    }
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (instance, prop_id, pspec);
-    }
-}
-
-static void
-rsvg_handle_get_property (GObject * instance, guint prop_id, GValue * value, GParamSpec * pspec)
-{
-    RsvgHandle *self = RSVG_HANDLE (instance);
-    RsvgDimensionData dim;
-
-    switch (prop_id) {
-    case PROP_FLAGS:
-        g_value_set_flags (value, rsvg_handle_rust_get_flags (self));
-        break;
-    case PROP_DPI_X:
-        g_value_set_double (value, rsvg_handle_rust_get_dpi_x (self));
-        break;
-    case PROP_DPI_Y:
-        g_value_set_double (value, rsvg_handle_rust_get_dpi_y (self));
-        break;
-    case PROP_BASE_URI:
-        g_value_set_string (value, rsvg_handle_get_base_uri (self));
-        break;
-    case PROP_WIDTH:
-        rsvg_handle_get_dimensions (self, &dim);
-        g_value_set_int (value, dim.width);
-        break;
-    case PROP_HEIGHT:
-        rsvg_handle_get_dimensions (self, &dim);
-        g_value_set_int (value, dim.height);
-        break;
-    case PROP_EM:
-        rsvg_handle_get_dimensions (self, &dim);
-        g_value_set_double (value, dim.em);
-        break;
-    case PROP_EX:
-        rsvg_handle_get_dimensions (self, &dim);
-        g_value_set_double (value, dim.ex);
-        break;
-    case PROP_TITLE:
-        /* deprecated */
-        break;
-    case PROP_DESC:
-        /* deprecated */
-        break;
-    case PROP_METADATA:
-        g_value_set_string (value, rsvg_handle_get_metadata (self));
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (instance, prop_id, pspec);
-    }
-}
+/* Implemented in rsvg_internals/src/c_api.rs */
+extern GType rsvg_handle_rust_get_type (void);
 
-static void
-rsvg_handle_class_init (RsvgHandleClass * klass)
+GType
+rsvg_handle_get_type (void)
 {
-    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
-    gobject_class->dispose = rsvg_handle_dispose;
-    gobject_class->set_property = rsvg_handle_set_property;
-    gobject_class->get_property = rsvg_handle_get_property;
-
-    /**
-     * RsvgHandle:flags:
-     *
-     * Flags from #RsvgHandleFlags.
-     *
-     * Since: 2.36
-     */
-    g_object_class_install_property (gobject_class,
-                                     PROP_FLAGS,
-                                     g_param_spec_flags ("flags", NULL, NULL,
-                                                         RSVG_TYPE_HANDLE_FLAGS,
-                                                         RSVG_HANDLE_FLAGS_NONE,
-                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
-    /**
-     * dpi-x:
-     */
-    g_object_class_install_property (gobject_class,
-                                     PROP_DPI_X,
-                                     g_param_spec_double ("dpi-x", _("Horizontal resolution"),
-                                                          _("Horizontal resolution"),
-                                                          0., G_MAXDOUBLE, 0.,
-                                                          (GParamFlags) (G_PARAM_READWRITE |
-                                                                         G_PARAM_CONSTRUCT)));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_DPI_Y,
-                                     g_param_spec_double ("dpi-y", _("Vertical resolution"),
-                                                          _("Vertical resolution"),
-                                                          0., G_MAXDOUBLE, 0.,
-                                                          (GParamFlags) (G_PARAM_READWRITE |
-                                                                         G_PARAM_CONSTRUCT)));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_BASE_URI,
-                                     g_param_spec_string ("base-uri", _("Base URI"),
-                                                          _("Base URI"), NULL,
-                                                          (GParamFlags) (G_PARAM_READWRITE |
-                                                                         G_PARAM_CONSTRUCT)));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_WIDTH,
-                                     g_param_spec_int ("width", _("Image width"),
-                                                       _("Image width"), 0, G_MAXINT, 0,
-                                                       (GParamFlags) (G_PARAM_READABLE)));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_HEIGHT,
-                                     g_param_spec_int ("height", _("Image height"),
-                                                       _("Image height"), 0, G_MAXINT, 0,
-                                                       (GParamFlags) (G_PARAM_READABLE)));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_EM,
-                                     g_param_spec_double ("em", _("em"),
-                                                          _("em"), 0, G_MAXDOUBLE, 0,
-                                                          (GParamFlags) (G_PARAM_READABLE)));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_EX,
-                                     g_param_spec_double ("ex", _("ex"),
-                                                          _("ex"), 0, G_MAXDOUBLE, 0,
-                                                          (GParamFlags) (G_PARAM_READABLE)));
-
-    /**
-     * RsvgHandle:title:
-     *
-     * SVG's description
-     *
-     * Deprecated: 2.36
-     */
-    g_object_class_install_property (gobject_class,
-                                     PROP_TITLE,
-                                     g_param_spec_string ("title", _("Title"),
-                                                          _("SVG file title"), NULL,
-                                                          (GParamFlags) (G_PARAM_READABLE)));
-
-    /**
-     * RsvgHandle:desc:
-     *
-     * SVG's description
-     *
-     * Deprecated: 2.36
-     */
-    g_object_class_install_property (gobject_class,
-                                     PROP_DESC,
-                                     g_param_spec_string ("desc", _("Description"),
-                                                          _("SVG file description"), NULL,
-                                                          (GParamFlags) (G_PARAM_READABLE)));
-
-    /**
-     * RsvgHandle:metadata:
-     *
-     * SVG's description
-     *
-     * Deprecated: 2.36
-     */
-    g_object_class_install_property (gobject_class,
-                                     PROP_METADATA,
-                                     g_param_spec_string ("metadata", _("Metadata"),
-                                                          _("SVG file metadata"), NULL,
-                                                          (GParamFlags) (G_PARAM_READABLE)));
+    return rsvg_handle_rust_get_type ();
 }
 
 /**
@@ -958,13 +727,6 @@ rsvg_handle_get_desc (RsvgHandle *handle)
     return NULL;
 }
 
-RsvgHandleRust *
-rsvg_handle_get_rust (RsvgHandle *handle)
-{
-    RsvgHandlePrivate *priv = rsvg_handle_get_instance_private (handle);
-    return priv->rust_handle;
-}
-
 /**
  * rsvg_handle_render_cairo_sub:
  * @handle: A #RsvgHandle
diff --git a/librsvg_crate/Cargo.toml b/librsvg_crate/Cargo.toml
index d361501e..c4a9aa2b 100644
--- a/librsvg_crate/Cargo.toml
+++ b/librsvg_crate/Cargo.toml
@@ -9,14 +9,14 @@ build = "build.rs"
 name = "librsvg"
 
 [dependencies]
-cairo-rs = "0.5.0"
-glib = "0.6.0"
-gio = { version="0.5.1", features=["v2_48"] } # per configure.ac
+cairo-rs = "0.6.0"
+glib = "0.7.0"
+gio = { version="0.6.0", features=["v2_48"] } # per configure.ac
 rsvg_internals = { path = "../rsvg_internals" }
 url = "1.7.2"
 
 [dev-dependencies]
-cairo-rs = { version = "0.5.0", features = ["png"] }
+cairo-rs = { version = "0.6.0", features = ["png"] }
 
 [build-dependencies]
 pkg-config = "0.3.14"
diff --git a/librsvg_crate/src/lib.rs b/librsvg_crate/src/lib.rs
index f5bb489e..9f5bb09a 100644
--- a/librsvg_crate/src/lib.rs
+++ b/librsvg_crate/src/lib.rs
@@ -274,9 +274,13 @@ impl LoadOptions {
         file: &gio::File,
         cancellable: P,
     ) -> Result<SvgHandle, LoadingError> {
-        let stream = file.read(None)?;
+        let cancellable = cancellable.into();
 
-        self.read_stream(&stream.upcast(), Some(&file), cancellable.into())
+        let cancellable_clone = cancellable.clone();
+
+        let stream = file.read(cancellable)?;
+
+        self.read_stream(&stream.upcast(), Some(&file), cancellable_clone)
     }
 
     /// Reads an SVG stream from a `gio::InputStream`.
@@ -297,7 +301,7 @@ impl LoadOptions {
         base_file: Option<&gio::File>,
         cancellable: P,
     ) -> Result<SvgHandle, LoadingError> {
-        let mut handle = Handle::new_with_flags(self.load_flags());
+        let handle = Handle::new_with_flags(self.load_flags());
         handle.construct_read_stream_sync(stream, base_file, cancellable.into())?;
 
         Ok(SvgHandle(handle))
diff --git a/rsvg_internals/Cargo.toml b/rsvg_internals/Cargo.toml
index 03770e8f..f2b53ba9 100644
--- a/rsvg_internals/Cargo.toml
+++ b/rsvg_internals/Cargo.toml
@@ -20,20 +20,21 @@ build = "build.rs"
 phf_codegen = "0.7.21"
 
 [dependencies]
-cairo-rs = "0.5.0"
-cairo-sys-rs = "0.7.0"
+bitflags = "1.0"
+cairo-rs = "0.6.0"
+cairo-sys-rs = "0.8.0"
 cssparser = "0.25.1"
 data-url = "0.1"
 downcast-rs = "^1.0.0"
 encoding = "0.2.33"
 float-cmp = "0.4.0"
-gdk-pixbuf = "0.5.0"
-gdk-pixbuf-sys = "0.7.0"
-gio = { version="0.5.1", features=["v2_48"] } # per configure.ac
-gio-sys = "0.7.0"
-glib = "0.6.0"
-glib-sys = "0.7.0"
-gobject-sys = "0.7.0"
+gdk-pixbuf = "0.6.0"
+gdk-pixbuf-sys = "0.8.0"
+gio = { version="0.6.0", features=["v2_48"] } # per configure.ac
+gio-sys = "0.8.0"
+glib = { version="0.7.0", features=["subclassing"] }
+glib-sys = "0.8.0"
+gobject-sys = "0.8.0"
 itertools = "0.8"
 language-tags = "0.2.2"
 lazy_static = "1.0.0"
@@ -42,9 +43,9 @@ locale_config = "*" # recommended explicitly by locale_config's README.md
 nalgebra = "0.17"
 num-traits = "0.2"
 owning_ref = "0.4.0"
-pango = "0.5.0"
-pango-sys = "0.7.0"
-pangocairo = "0.6.0"
+pango = "0.6.0"
+pango-sys = "0.8.0"
+pangocairo = "0.7.0"
 phf = "0.7.21"
 rayon = "1"
 regex = "1"
diff --git a/rsvg_internals/src/c_api.rs b/rsvg_internals/src/c_api.rs
index 83314050..f699871b 100644
--- a/rsvg_internals/src/c_api.rs
+++ b/rsvg_internals/src/c_api.rs
@@ -1,9 +1,303 @@
+use std::ops;
 use std::sync::Once;
+use std::{f64, i32};
+
+use libc;
+
+use glib::object::ObjectClass;
+use glib::subclass;
+use glib::subclass::object::ObjectClassSubclassExt;
+use glib::subclass::prelude::*;
+use glib::translate::*;
+use glib::value::{FromValue, FromValueOptional, SetValue};
+use glib::{ParamFlags, ParamSpec, StaticType, ToValue, Type, Value};
 
 use glib_sys;
 use gobject_sys::{self, GEnumValue, GFlagsValue};
 
 use error::RSVG_ERROR_FAILED;
+use handle::Handle;
+
+mod handle_flags {
+    // The following is entirely stolen from the auto-generated code
+    // for GBindingFlags, from gtk-rs/glib/src/gobject/auto/flags.rs
+
+    use super::*;
+
+    // Keep these in sync with rsvg.h:RsvgHandleFlags
+    #[cfg_attr(rustfmt, rustfmt_skip)]
+    bitflags! {
+        pub struct HandleFlags: u32 {
+            const NONE            = 0;
+            const UNLIMITED       = 1 << 0;
+            const KEEP_IMAGE_DATA = 1 << 1;
+        }
+    }
+
+    pub type RsvgHandleFlags = libc::c_uint;
+
+    impl ToGlib for HandleFlags {
+        type GlibType = RsvgHandleFlags;
+
+        fn to_glib(&self) -> RsvgHandleFlags {
+            self.bits()
+        }
+    }
+
+    impl FromGlib<RsvgHandleFlags> for HandleFlags {
+        fn from_glib(value: RsvgHandleFlags) -> HandleFlags {
+            HandleFlags::from_bits_truncate(value)
+        }
+    }
+
+    impl StaticType for HandleFlags {
+        fn static_type() -> Type {
+            unsafe { from_glib(rsvg_rust_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(gobject_sys::g_value_get_flags(value.to_glib_none().0))
+        }
+    }
+
+    impl SetValue for HandleFlags {
+        unsafe fn set_value(value: &mut Value, this: &Self) {
+            gobject_sys::g_value_set_flags(value.to_glib_none_mut().0, this.to_glib())
+        }
+    }
+}
+
+pub use self::handle_flags::*;
+
+// Keep this in sync with rsvg.h:RsvgHandleClass
+#[repr(C)]
+pub struct RsvgHandleClass {
+    parent: gobject_sys::GObjectClass,
+
+    _abi_padding: [glib_sys::gpointer; 15],
+}
+
+// Keep this in sync with rsvg.h:RsvgHandle
+#[repr(C)]
+pub struct RsvgHandle {
+    parent: gobject_sys::GObject,
+
+    _abi_padding: [glib_sys::gpointer; 16],
+}
+
+unsafe impl ClassStruct for RsvgHandleClass {
+    type Type = Handle;
+}
+
+unsafe impl InstanceStruct for RsvgHandle {
+    type Type = Handle;
+}
+
+impl ops::Deref for RsvgHandleClass {
+    type Target = ObjectClass;
+
+    fn deref(&self) -> &Self::Target {
+        unsafe { &*(self as *const _ as *const Self::Target) }
+    }
+}
+
+impl ops::DerefMut for RsvgHandleClass {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        unsafe { &mut *(self as *mut _ as *mut Self::Target) }
+    }
+}
+
+static PROPERTIES: [subclass::Property; 11] = [
+    subclass::Property("flags", |name| {
+        ParamSpec::flags(
+            name,
+            "Flags",
+            "Loading flags",
+            HandleFlags::static_type(),
+            0,
+            ParamFlags::READWRITE | ParamFlags::CONSTRUCT_ONLY,
+        )
+    }),
+    subclass::Property("dpi-x", |name| {
+        ParamSpec::double(
+            name,
+            "Horizontal DPI",
+            "Horizontal resolution in dots per inch",
+            0.0,
+            f64::MAX,
+            0.0,
+            ParamFlags::READWRITE | ParamFlags::CONSTRUCT,
+        )
+    }),
+    subclass::Property("dpi-y", |name| {
+        ParamSpec::double(
+            name,
+            "Vertical DPI",
+            "Vertical resolution in dots per inch",
+            0.0,
+            f64::MAX,
+            0.0,
+            ParamFlags::READWRITE | ParamFlags::CONSTRUCT,
+        )
+    }),
+    subclass::Property("base-uri", |name| {
+        ParamSpec::string(
+            name,
+            "Base URI",
+            "Base URI for resolving relative references",
+            None,
+            ParamFlags::READWRITE | ParamFlags::CONSTRUCT,
+        )
+    }),
+    subclass::Property("width", |name| {
+        ParamSpec::int(
+            name,
+            "Image width",
+            "Image width",
+            0,
+            i32::MAX,
+            0,
+            ParamFlags::READABLE,
+        )
+    }),
+    subclass::Property("height", |name| {
+        ParamSpec::int(
+            name,
+            "Image height",
+            "Image height",
+            0,
+            i32::MAX,
+            0,
+            ParamFlags::READABLE,
+        )
+    }),
+    subclass::Property("em", |name| {
+        ParamSpec::double(name, "em", "em", 0.0, f64::MAX, 0.0, ParamFlags::READABLE)
+    }),
+    subclass::Property("ex", |name| {
+        ParamSpec::double(name, "ex", "ex", 0.0, f64::MAX, 0.0, ParamFlags::READABLE)
+    }),
+    subclass::Property("title", |name| {
+        ParamSpec::string(name, "deprecated", "deprecated", None, ParamFlags::READABLE)
+    }),
+    subclass::Property("desc", |name| {
+        ParamSpec::string(name, "deprecated", "deprecated", None, ParamFlags::READABLE)
+    }),
+    subclass::Property("metadata", |name| {
+        ParamSpec::string(name, "deprecated", "deprecated", None, ParamFlags::READABLE)
+    }),
+];
+
+impl ObjectSubclass for Handle {
+    const NAME: &'static str = "RsvgHandle";
+
+    type ParentType = glib::Object;
+
+    // We don't use subclass:simple::InstanceStruct and ClassStruct
+    // because we need to maintain the respective _abi_padding of each
+    // of RsvgHandleClass and RsvgHandle.
+
+    type Instance = RsvgHandle;
+    type Class = RsvgHandleClass;
+
+    glib_object_subclass!();
+
+    fn class_init(klass: &mut RsvgHandleClass) {
+        klass.install_properties(&PROPERTIES);
+    }
+
+    fn new() -> Self {
+        Handle::new()
+    }
+}
+
+impl ObjectImpl for Handle {
+    glib_object_impl!();
+
+    fn set_property(&self, _obj: &glib::Object, id: usize, value: &glib::Value) {
+        let prop = &PROPERTIES[id];
+
+        match *prop {
+            subclass::Property("flags", ..) => {
+                let v: HandleFlags = value.get().expect("flags value has incorrect type");
+
+                self.set_load_flags(v);
+            }
+
+            subclass::Property("dpi-x", ..) => {
+                self.set_dpi_x(value.get().expect("dpi-x value has incorrect type"));
+            }
+
+            subclass::Property("dpi-y", ..) => {
+                self.set_dpi_y(value.get().expect("dpi-y value has incorrect type"));
+            }
+
+            subclass::Property("base-uri", ..) => {
+                let v: Option<String> = value.get();
+
+                // rsvg_handle_set_base_uri() expects non-NULL URI strings,
+                // but the "base-uri" property can be set to NULL due to a missing
+                // construct-time property.
+
+                if let Some(s) = v {
+                    self.set_base_url(&s);
+                }
+            }
+
+            _ => unreachable!("invalid property id {}", id),
+        }
+    }
+
+    fn get_property(&self, _obj: &glib::Object, id: usize) -> Result<glib::Value, ()> {
+        let prop = &PROPERTIES[id];
+
+        match *prop {
+            subclass::Property("flags", ..) => Ok(self.load_flags.get().to_flags().to_value()),
+            subclass::Property("dpi-x", ..) => Ok(self.dpi.get().x().to_value()),
+            subclass::Property("dpi-y", ..) => Ok(self.dpi.get().y().to_value()),
+
+            subclass::Property("base-uri", ..) => Ok(self
+                .base_url
+                .borrow()
+                .as_ref()
+                .map(|url| url.as_str())
+                .to_value()),
+
+            subclass::Property("width", ..) => Ok(self.get_dimensions_no_error().width.to_value()),
+            subclass::Property("height", ..) => {
+                Ok(self.get_dimensions_no_error().height.to_value())
+            }
+
+            subclass::Property("em", ..) => Ok(self.get_dimensions_no_error().em.to_value()),
+            subclass::Property("ex", ..) => Ok(self.get_dimensions_no_error().ex.to_value()),
+
+            // the following three are deprecated
+            subclass::Property("title", ..) => Ok((None as Option<String>).to_value()),
+            subclass::Property("desc", ..) => Ok((None as Option<String>).to_value()),
+            subclass::Property("metadata", ..) => Ok((None as Option<String>).to_value()),
+
+            _ => unreachable!("invalid property id={} for RsvgHandle", id),
+        }
+    }
+}
+
+pub fn get_rust_handle<'a>(handle: *const RsvgHandle) -> &'a Handle {
+    let handle = unsafe { &*handle };
+    handle.get_impl()
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_handle_rust_get_type() -> glib_sys::GType {
+    Handle::get_type().to_glib()
+}
 
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_rust_error_get_type() -> glib_sys::GType {
diff --git a/rsvg_internals/src/error.rs b/rsvg_internals/src/error.rs
index 8fd518d1..65225d5a 100644
--- a/rsvg_internals/src/error.rs
+++ b/rsvg_internals/src/error.rs
@@ -105,6 +105,7 @@ pub enum RenderingError {
     InvalidId(DefsLookupErrorKind),
     InvalidHref,
     OutOfMemory,
+    HandleIsNotLoaded,
 }
 
 impl From<cairo::Status> for RenderingError {
@@ -243,6 +244,7 @@ impl error::Error for RenderingError {
             RenderingError::InvalidId(_) => "invalid id",
             RenderingError::InvalidHref => "invalid href",
             RenderingError::OutOfMemory => "out of memory",
+            RenderingError::HandleIsNotLoaded => "SVG data is not loaded into handle",
         }
     }
 }
@@ -255,7 +257,8 @@ impl fmt::Display for RenderingError {
             RenderingError::CircularReference
             | RenderingError::InstancingLimit
             | RenderingError::InvalidHref
-            | RenderingError::OutOfMemory => write!(f, "{}", self.description()),
+            | RenderingError::OutOfMemory
+            | RenderingError::HandleIsNotLoaded => write!(f, "{}", self.description()),
         }
     }
 }
diff --git a/rsvg_internals/src/gradient.rs b/rsvg_internals/src/gradient.rs
index df27afc9..800fc6b5 100644
--- a/rsvg_internals/src/gradient.rs
+++ b/rsvg_internals/src/gradient.rs
@@ -65,12 +65,12 @@ impl Default for SpreadMethod {
     }
 }
 
-impl From<SpreadMethod> for cairo::enums::Extend {
-    fn from(s: SpreadMethod) -> cairo::enums::Extend {
+impl From<SpreadMethod> for cairo::Extend {
+    fn from(s: SpreadMethod) -> cairo::Extend {
         match s {
-            SpreadMethod::Pad => cairo::enums::Extend::Pad,
-            SpreadMethod::Reflect => cairo::enums::Extend::Reflect,
-            SpreadMethod::Repeat => cairo::enums::Extend::Repeat,
+            SpreadMethod::Pad => cairo::Extend::Pad,
+            SpreadMethod::Reflect => cairo::Extend::Reflect,
+            SpreadMethod::Repeat => cairo::Extend::Repeat,
         }
     }
 }
@@ -483,7 +483,7 @@ fn set_common_on_pattern<P: cairo::PatternTrait + cairo::Gradient>(
 
     affine.invert();
     pattern.set_matrix(affine);
-    pattern.set_extend(cairo::enums::Extend::from(
+    pattern.set_extend(cairo::Extend::from(
         gradient.common.spread.unwrap_or_default(),
     ));
 
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index f79feb32..34e4e414 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -13,6 +13,7 @@ use gdk_pixbuf::Pixbuf;
 use gdk_pixbuf_sys;
 use gio::{self, FileExt};
 use gio_sys;
+use glib::subclass::types::ObjectSubclass;
 use glib::translate::*;
 use glib::{self, Bytes, Cast};
 use glib_sys;
@@ -21,6 +22,7 @@ use libc;
 use url::Url;
 
 use allowed_url::{AllowedUrl, Href};
+use c_api::{get_rust_handle, HandleFlags, RsvgHandle, RsvgHandleFlags};
 use dpi::Dpi;
 use drawing_ctx::{DrawingCtx, RsvgRectangle};
 use error::{set_gerror, DefsLookupErrorKind, LoadingError, RenderingError};
@@ -35,10 +37,10 @@ use xml::XmlState;
 use xml2_load::xml_state_load_from_possibly_compressed_stream;
 
 // A *const RsvgHandle is just an opaque pointer we get from C
-#[repr(C)]
-pub struct RsvgHandle {
-    _private: [u8; 0],
-}
+// #[repr(C)]
+// pub struct RsvgHandle {
+//    _private: [u8; 0],
+// }
 
 // Keep in sync with rsvg.h:RsvgDimensionData
 #[repr(C)]
@@ -58,7 +60,7 @@ pub struct RsvgPositionData {
 
 /// Flags used during loading
 ///
-/// We communicate these to/from the C code with a guint <-> u32,
+/// We communicate these to/from the C code with a HandleFlags
 /// and this struct provides to_flags() and from_flags() methods.
 #[derive(Default, Copy, Clone)]
 pub struct LoadFlags {
@@ -145,20 +147,20 @@ impl Drop for SizeCallback {
 }
 
 pub struct Handle {
-    dpi: Cell<Dpi>,
-    base_url: RefCell<Option<Url>>,
+    pub dpi: Cell<Dpi>,
+    pub base_url: RefCell<Option<Url>>,
     base_url_cstring: RefCell<Option<CString>>, // needed because the C api returns *const char
     svg: RefCell<Option<Rc<Svg>>>,
-    load_flags: Cell<LoadFlags>,
+    pub load_flags: Cell<LoadFlags>,
     load_state: Cell<LoadState>,
-    buffer: Vec<u8>, // used by the legacy write() api
+    buffer: RefCell<Vec<u8>>, // used by the legacy write() api
     size_callback: RefCell<SizeCallback>,
     in_loop: Cell<bool>,
     is_testing: Cell<bool>,
 }
 
 impl Handle {
-    fn new() -> Handle {
+    pub fn new() -> Handle {
         Handle {
             dpi: Cell::new(Dpi::default()),
             base_url: RefCell::new(None),
@@ -166,7 +168,7 @@ impl Handle {
             svg: RefCell::new(None),
             load_flags: Cell::new(LoadFlags::default()),
             load_state: Cell::new(LoadState::Start),
-            buffer: Vec::new(),
+            buffer: RefCell::new(Vec::new()),
             size_callback: RefCell::new(SizeCallback::new()),
             in_loop: Cell::new(false),
             is_testing: Cell::new(false),
@@ -179,7 +181,8 @@ impl Handle {
         handle
     }
 
-    fn set_base_url(&self, url: &str) {
+    // from the public API
+    pub fn set_base_url(&self, url: &str) {
         if self.load_state.get() != LoadState::Start {
             panic!("Please set the base file or URI before loading any data into RsvgHandle",);
         }
@@ -212,7 +215,7 @@ impl Handle {
     }
 
     pub fn read_stream_sync(
-        &mut self,
+        &self,
         stream: &gio::InputStream,
         cancellable: Option<&gio::Cancellable>,
     ) -> Result<(), LoadingError> {
@@ -229,21 +232,45 @@ impl Handle {
         Ok(())
     }
 
+    fn check_is_loaded(self: &Handle) -> Result<(), RenderingError> {
+        match self.load_state.get() {
+            LoadState::Start => {
+                rsvg_g_warning("RsvgHandle has not been loaded");
+                Err(RenderingError::HandleIsNotLoaded)
+            }
+
+            LoadState::Loading => {
+                rsvg_g_warning("RsvgHandle is still loading; call rsvg_handle_close() first");
+                Err(RenderingError::HandleIsNotLoaded)
+            }
+
+            LoadState::ClosedOk => Ok(()),
+
+            LoadState::ClosedError => {
+                rsvg_g_warning(
+                    "RsvgHandle could not read or parse the SVG; did you check for errors during \
+                     the loading stage?",
+                );
+                Err(RenderingError::HandleIsNotLoaded)
+            }
+        }
+    }
+
     fn load_options(&self) -> LoadOptions {
         LoadOptions::new(self.load_flags.get(), self.base_url.borrow().clone())
     }
 
-    pub fn write(&mut self, buf: &[u8]) {
+    pub fn write(&self, buf: &[u8]) {
         match self.load_state.get() {
             LoadState::Start => self.load_state.set(LoadState::Loading),
             LoadState::Loading => (),
             _ => unreachable!(),
         };
 
-        self.buffer.extend_from_slice(buf);
+        self.buffer.borrow_mut().extend_from_slice(buf);
     }
 
-    pub fn close(&mut self) -> Result<(), LoadingError> {
+    pub fn close(&self) -> Result<(), LoadingError> {
         let res = match self.load_state.get() {
             LoadState::Start => {
                 self.load_state.set(LoadState::ClosedError);
@@ -251,7 +278,8 @@ impl Handle {
             }
 
             LoadState::Loading => {
-                let bytes = Bytes::from(&self.buffer);
+                let buffer = self.buffer.borrow();
+                let bytes = Bytes::from(&*buffer);
                 let stream = gio::MemoryInputStream::new_from_bytes(&bytes);
                 let mut xml = XmlState::new(&self.load_options());
 
@@ -311,7 +339,21 @@ impl Handle {
         draw_ctx
     }
 
+    pub fn has_sub(&self, id: &str) -> Result<bool, RenderingError> {
+        self.check_is_loaded()?;
+
+        match self.lookup_node(id) {
+            Ok(_) => Ok(true),
+
+            Err(DefsLookupErrorKind::NotFound) => Ok(false),
+
+            Err(e) => Err(RenderingError::InvalidId(e)),
+        }
+    }
+
     pub fn get_dimensions(&self) -> Result<RsvgDimensionData, RenderingError> {
+        self.check_is_loaded()?;
+
         // This function is probably called from the cairo_render functions,
         // or is being erroneously called within the size_func.
         // To prevent an infinite loop we are saving the state, and
@@ -334,7 +376,26 @@ impl Handle {
         res
     }
 
+    pub fn get_dimensions_no_error(&self) -> RsvgDimensionData {
+        match self.get_dimensions() {
+            Ok(dimensions) => dimensions,
+
+            Err(_) => {
+                RsvgDimensionData {
+                    width: 0,
+                    height: 0,
+                    em: 0.0,
+                    ex: 0.0,
+                }
+
+                // This old API doesn't even let us return an error, sigh.
+            }
+        }
+    }
+
     fn get_dimensions_sub(&self, id: Option<&str>) -> Result<RsvgDimensionData, RenderingError> {
+        self.check_is_loaded()?;
+
         let (ink_r, _) = self.get_geometry_sub(id)?;
 
         let (w, h) = self
@@ -350,7 +411,9 @@ impl Handle {
         })
     }
 
-    fn get_position_sub(&mut self, id: Option<&str>) -> Result<RsvgPositionData, RenderingError> {
+    fn get_position_sub(&self, id: Option<&str>) -> Result<RsvgPositionData, RenderingError> {
+        self.check_is_loaded()?;
+
         if let None = id {
             return Ok(RsvgPositionData { x: 0, y: 0 });
         }
@@ -418,11 +481,12 @@ impl Handle {
     }
 
     /// Returns (ink_rect, logical_rect)
-    pub fn get_geometry_sub(
+    fn get_geometry_sub(
         &self,
         id: Option<&str>,
     ) -> Result<(RsvgRectangle, RsvgRectangle), RenderingError> {
         let node = self.get_node_or_root(id)?;
+
         let root = self.get_root();
         let is_root = Rc::ptr_eq(&node, &root);
 
@@ -508,6 +572,7 @@ impl Handle {
         id: Option<&str>,
     ) -> Result<(), RenderingError> {
         check_cairo_context(cr)?;
+        self.check_is_loaded()?;
 
         let node = if let Some(id) = id {
             Some(self.lookup_node(id).map_err(RenderingError::InvalidId)?)
@@ -564,8 +629,26 @@ impl Handle {
         res
     }
 
+    fn get_pixbuf_sub(&self, id: Option<&str>) -> Result<Pixbuf, RenderingError> {
+        self.check_is_loaded()?;
+
+        let dimensions = self.get_dimensions()?;
+
+        let surface =
+            ImageSurface::create(cairo::Format::ARgb32, dimensions.width, dimensions.height)?;
+
+        {
+            let cr = cairo::Context::new(&surface);
+            self.render_cairo_sub(&cr, id)?;
+        }
+
+        let surface = SharedImageSurface::new(surface, SurfaceType::SRgb)?;
+
+        pixbuf_from_surface(&surface)
+    }
+
     fn construct_new_from_gfile_sync(
-        &mut self,
+        &self,
         file: &gio::File,
         cancellable: Option<&gio::Cancellable>,
     ) -> Result<(), LoadingError> {
@@ -574,7 +657,7 @@ impl Handle {
     }
 
     pub fn construct_read_stream_sync(
-        &mut self,
+        &self,
         stream: &gio::InputStream,
         base_file: Option<&gio::File>,
         cancellable: Option<&gio::Cancellable>,
@@ -592,6 +675,21 @@ impl Handle {
 
         svg.get_intrinsic_dimensions()
     }
+
+    // from the public API
+    pub fn set_load_flags(&self, flags: HandleFlags) {
+        self.load_flags.set(LoadFlags::from_flags(flags));
+    }
+
+    // from the public API
+    pub fn set_dpi_x(&self, dpi_x: f64) {
+        self.dpi.set(Dpi::new(dpi_x, self.dpi.get().y()));
+    }
+
+    // from the public API
+    pub fn set_dpi_y(&self, dpi_y: f64) {
+        self.dpi.set(Dpi::new(self.dpi.get().x(), dpi_y));
+    }
 }
 
 fn check_cairo_context(cr: &cairo::Context) -> Result<(), RenderingError> {
@@ -609,40 +707,29 @@ fn check_cairo_context(cr: &cairo::Context) -> Result<(), RenderingError> {
     }
 }
 
-// Keep these in sync with rsvg.h:RsvgHandleFlags
-const RSVG_HANDLE_FLAG_UNLIMITED: u32 = 1 << 0;
-const RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA: u32 = 1 << 1;
-
 impl LoadFlags {
-    pub fn from_flags(flags: u32) -> Self {
+    pub fn from_flags(flags: HandleFlags) -> Self {
         LoadFlags {
-            unlimited_size: (flags & RSVG_HANDLE_FLAG_UNLIMITED) != 0,
-            keep_image_data: (flags & RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA) != 0,
+            unlimited_size: flags.contains(HandleFlags::UNLIMITED),
+            keep_image_data: flags.contains(HandleFlags::KEEP_IMAGE_DATA),
         }
     }
 
-    fn to_flags(&self) -> u32 {
-        let mut flags = 0;
+    pub fn to_flags(&self) -> HandleFlags {
+        let mut flags = HandleFlags::empty();
 
         if self.unlimited_size {
-            flags |= RSVG_HANDLE_FLAG_UNLIMITED;
+            flags.insert(HandleFlags::UNLIMITED);
         }
 
         if self.keep_image_data {
-            flags |= RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA;
+            flags.insert(HandleFlags::KEEP_IMAGE_DATA);
         }
 
         flags
     }
 }
 
-#[allow(improper_ctypes)]
-extern "C" {
-    fn rsvg_handle_get_type() -> glib_sys::GType;
-
-    fn rsvg_handle_get_rust(handle: *const RsvgHandle) -> *mut Handle;
-}
-
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_new() -> *mut Handle {
     Box::into_raw(Box::new(Handle::new()))
@@ -654,13 +741,9 @@ pub unsafe extern "C" fn rsvg_handle_rust_free(raw_handle: *mut Handle) {
     Box::from_raw(raw_handle);
 }
 
-pub fn get_rust_handle<'a>(handle: *const RsvgHandle) -> &'a mut Handle {
-    unsafe { &mut *(rsvg_handle_get_rust(handle) as *mut Handle) }
-}
-
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_set_base_url(
-    raw_handle: *mut RsvgHandle,
+    raw_handle: *const RsvgHandle,
     uri: *const libc::c_char,
 ) {
     let rhandle = get_rust_handle(raw_handle);
@@ -685,7 +768,7 @@ pub unsafe extern "C" fn rsvg_handle_rust_get_base_gfile(
 
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_set_base_gfile(
-    raw_handle: *mut RsvgHandle,
+    raw_handle: *const RsvgHandle,
     raw_gfile: *mut gio_sys::GFile,
 ) {
     let rhandle = get_rust_handle(raw_handle);
@@ -710,7 +793,7 @@ pub unsafe extern "C" fn rsvg_handle_rust_get_base_url(
 }
 
 #[no_mangle]
-pub unsafe extern "C" fn rsvg_handle_rust_set_dpi_x(raw_handle: *mut RsvgHandle, dpi_x: f64) {
+pub unsafe extern "C" fn rsvg_handle_rust_set_dpi_x(raw_handle: *const RsvgHandle, dpi_x: f64) {
     let rhandle = get_rust_handle(raw_handle);
 
     rhandle.dpi.set(Dpi::new(dpi_x, rhandle.dpi.get().y()));
@@ -724,7 +807,7 @@ pub unsafe extern "C" fn rsvg_handle_rust_get_dpi_x(raw_handle: *const RsvgHandl
 }
 
 #[no_mangle]
-pub unsafe extern "C" fn rsvg_handle_rust_set_dpi_y(raw_handle: *mut RsvgHandle, dpi_y: f64) {
+pub unsafe extern "C" fn rsvg_handle_rust_set_dpi_y(raw_handle: *const RsvgHandle, dpi_y: f64) {
     let rhandle = get_rust_handle(raw_handle);
 
     rhandle.dpi.set(Dpi::new(rhandle.dpi.get().x(), dpi_y));
@@ -738,22 +821,29 @@ pub unsafe extern "C" fn rsvg_handle_rust_get_dpi_y(raw_handle: *const RsvgHandl
 }
 
 #[no_mangle]
-pub unsafe extern "C" fn rsvg_handle_rust_get_flags(raw_handle: *const RsvgHandle) -> u32 {
+pub unsafe extern "C" fn rsvg_handle_rust_get_flags(
+    raw_handle: *const RsvgHandle,
+) -> RsvgHandleFlags {
     let rhandle = get_rust_handle(raw_handle);
 
-    rhandle.load_flags.get().to_flags()
+    rhandle.load_flags.get().to_flags().to_glib()
 }
 
 #[no_mangle]
-pub unsafe extern "C" fn rsvg_handle_rust_set_flags(raw_handle: *const RsvgHandle, flags: u32) {
+pub unsafe extern "C" fn rsvg_handle_rust_set_flags(
+    raw_handle: *const RsvgHandle,
+    flags: RsvgHandleFlags,
+) {
     let rhandle = get_rust_handle(raw_handle);
 
-    rhandle.load_flags.set(LoadFlags::from_flags(flags));
+    rhandle
+        .load_flags
+        .set(LoadFlags::from_flags(from_glib(flags)));
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_set_size_callback(
-    raw_handle: *mut RsvgHandle,
+    raw_handle: *const RsvgHandle,
     size_func: RsvgSizeFunc,
     user_data: glib_sys::gpointer,
     destroy_notify: glib_sys::GDestroyNotify,
@@ -769,7 +859,7 @@ pub unsafe extern "C" fn rsvg_handle_rust_set_size_callback(
 
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_set_testing(
-    raw_handle: *mut RsvgHandle,
+    raw_handle: *const RsvgHandle,
     testing: glib_sys::gboolean,
 ) {
     let rhandle = get_rust_handle(raw_handle);
@@ -777,30 +867,9 @@ pub unsafe extern "C" fn rsvg_handle_rust_set_testing(
     rhandle.is_testing.set(from_glib(testing));
 }
 
-fn is_loaded(handle: &Handle) -> bool {
-    match handle.load_state.get() {
-        LoadState::Start => {
-            panic!("RsvgHandle has not been loaded");
-        }
-
-        LoadState::Loading => {
-            panic!("RsvgHandle is still loading; call rsvg_handle_close() first");
-        }
-
-        LoadState::ClosedOk => true,
-
-        LoadState::ClosedError => {
-            panic!(
-                "RsvgHandle could not read or parse the SVG; did you check for errors during the \
-                 loading stage?",
-            );
-        }
-    }
-}
-
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_read_stream_sync(
-    handle: *mut RsvgHandle,
+    handle: *const RsvgHandle,
     stream: *mut gio_sys::GInputStream,
     cancellable: *mut gio_sys::GCancellable,
     error: *mut *mut glib_sys::GError,
@@ -826,7 +895,7 @@ pub unsafe extern "C" fn rsvg_handle_rust_read_stream_sync(
 
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_write(
-    handle: *mut RsvgHandle,
+    handle: *const RsvgHandle,
     buf: *const u8,
     count: usize,
 ) {
@@ -845,7 +914,7 @@ pub unsafe extern "C" fn rsvg_handle_rust_write(
 
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_close(
-    handle: *mut RsvgHandle,
+    handle: *const RsvgHandle,
     error: *mut *mut glib_sys::GError,
 ) -> glib_sys::gboolean {
     let rhandle = get_rust_handle(handle);
@@ -862,17 +931,13 @@ pub unsafe extern "C" fn rsvg_handle_rust_close(
 
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_get_geometry_sub(
-    handle: *mut RsvgHandle,
+    handle: *const RsvgHandle,
     out_ink_rect: *mut RsvgRectangle,
     out_logical_rect: *mut RsvgRectangle,
     id: *const libc::c_char,
 ) -> glib_sys::gboolean {
     let rhandle = get_rust_handle(handle);
 
-    if !is_loaded(rhandle) {
-        return false.to_glib();
-    }
-
     let id: Option<String> = from_glib_none(id);
 
     match rhandle.get_geometry_sub(id.as_ref().map(String::as_str)) {
@@ -905,26 +970,23 @@ pub unsafe extern "C" fn rsvg_handle_rust_get_geometry_sub(
 
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_has_sub(
-    handle: *mut RsvgHandle,
+    handle: *const RsvgHandle,
     id: *const libc::c_char,
 ) -> glib_sys::gboolean {
     let rhandle = get_rust_handle(handle);
 
-    if !is_loaded(rhandle) {
-        return false.to_glib();
-    }
-
     if id.is_null() {
         return false.to_glib();
     }
 
     let id: String = from_glib_none(id);
-    rhandle.lookup_node(&id).is_ok().to_glib()
+    // FIXME: return a proper error code to the public API
+    rhandle.has_sub(&id).unwrap_or(false).to_glib()
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_render_cairo_sub(
-    handle: *mut RsvgHandle,
+    handle: *const RsvgHandle,
     cr: *mut cairo_sys::cairo_t,
     id: *const libc::c_char,
 ) -> glib_sys::gboolean {
@@ -932,10 +994,6 @@ pub unsafe extern "C" fn rsvg_handle_rust_render_cairo_sub(
     let cr = from_glib_none(cr);
     let id: Option<String> = from_glib_none(id);
 
-    if !is_loaded(rhandle) {
-        return false.to_glib();
-    }
-
     match rhandle.render_cairo_sub(&cr, id.as_ref().map(String::as_str)) {
         Ok(()) => true.to_glib(),
 
@@ -946,34 +1004,15 @@ pub unsafe extern "C" fn rsvg_handle_rust_render_cairo_sub(
     }
 }
 
-fn get_pixbuf_sub(handle: &mut Handle, id: Option<&str>) -> Result<Pixbuf, RenderingError> {
-    let dimensions = handle.get_dimensions()?;
-
-    let surface = ImageSurface::create(cairo::Format::ARgb32, dimensions.width, dimensions.height)?;
-
-    {
-        let cr = cairo::Context::new(&surface);
-        handle.render_cairo_sub(&cr, id)?;
-    }
-
-    let surface = SharedImageSurface::new(surface, SurfaceType::SRgb)?;
-
-    pixbuf_from_surface(&surface)
-}
-
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_get_pixbuf_sub(
-    handle: *mut RsvgHandle,
+    handle: *const RsvgHandle,
     id: *const libc::c_char,
 ) -> *mut gdk_pixbuf_sys::GdkPixbuf {
     let rhandle = get_rust_handle(handle);
     let id: Option<String> = from_glib_none(id);
 
-    if !is_loaded(rhandle) {
-        return ptr::null_mut();
-    }
-
-    match get_pixbuf_sub(rhandle, id.as_ref().map(String::as_str)) {
+    match rhandle.get_pixbuf_sub(id.as_ref().map(String::as_str)) {
         Ok(pixbuf) => pixbuf.to_glib_full(),
         Err(_) => ptr::null_mut(),
     }
@@ -981,45 +1020,22 @@ pub unsafe extern "C" fn rsvg_handle_rust_get_pixbuf_sub(
 
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_get_dimensions(
-    handle: *mut RsvgHandle,
+    handle: *const RsvgHandle,
     dimension_data: *mut RsvgDimensionData,
 ) {
     let rhandle = get_rust_handle(handle);
 
-    if !is_loaded(rhandle) {
-        return;
-    }
-
-    match rhandle.get_dimensions() {
-        Ok(dimensions) => {
-            *dimension_data = dimensions;
-        }
-
-        Err(_) => {
-            let d = &mut *dimension_data;
-
-            d.width = 0;
-            d.height = 0;
-            d.em = 0.0;
-            d.ex = 0.0;
-
-            // This old API doesn't even let us return an error, sigh.
-        }
-    }
+    *dimension_data = rhandle.get_dimensions_no_error();
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_get_dimensions_sub(
-    handle: *mut RsvgHandle,
+    handle: *const RsvgHandle,
     dimension_data: *mut RsvgDimensionData,
     id: *const libc::c_char,
 ) -> glib_sys::gboolean {
     let rhandle = get_rust_handle(handle);
 
-    if !is_loaded(rhandle) {
-        return false.to_glib();
-    }
-
     let id: Option<String> = from_glib_none(id);
 
     match rhandle.get_dimensions_sub(id.as_ref().map(String::as_str)) {
@@ -1044,16 +1060,12 @@ pub unsafe extern "C" fn rsvg_handle_rust_get_dimensions_sub(
 
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_get_position_sub(
-    handle: *mut RsvgHandle,
+    handle: *const RsvgHandle,
     position_data: *mut RsvgPositionData,
     id: *const libc::c_char,
 ) -> glib_sys::gboolean {
     let rhandle = get_rust_handle(handle);
 
-    if !is_loaded(rhandle) {
-        return false.to_glib();
-    }
-
     let id: Option<String> = from_glib_none(id);
 
     match rhandle.get_position_sub(id.as_ref().map(String::as_str)) {
@@ -1075,9 +1087,9 @@ pub unsafe extern "C" fn rsvg_handle_rust_get_position_sub(
 }
 
 #[no_mangle]
-pub unsafe extern "C" fn rsvg_handle_rust_new_with_flags(flags: u32) -> *mut RsvgHandle {
+pub unsafe extern "C" fn rsvg_handle_rust_new_with_flags(flags: u32) -> *const RsvgHandle {
     let obj: *mut gobject_sys::GObject =
-        glib::Object::new(from_glib(rsvg_handle_get_type()), &[("flags", &flags)])
+        glib::Object::new(Handle::get_type(), &[("flags", &flags)])
             .unwrap()
             .to_glib_full();
 
@@ -1088,7 +1100,7 @@ pub unsafe extern "C" fn rsvg_handle_rust_new_with_flags(flags: u32) -> *mut Rsv
 pub unsafe extern "C" fn rsvg_handle_rust_new_from_file(
     filename: *const libc::c_char,
     error: *mut *mut glib_sys::GError,
-) -> *mut RsvgHandle {
+) -> *const RsvgHandle {
     // This API lets the caller pass a URI, or a file name in the operating system's
     // encoding.  So, first we'll see if it's UTF-8, and in that case, try the URL version.
     // Otherwise, we'll try building a path name.
@@ -1111,7 +1123,7 @@ pub unsafe extern "C" fn rsvg_handle_rust_new_from_gfile_sync(
     flags: u32,
     cancellable: *mut gio_sys::GCancellable,
     error: *mut *mut glib_sys::GError,
-) -> *mut RsvgHandle {
+) -> *const RsvgHandle {
     let raw_handle = rsvg_handle_rust_new_with_flags(flags);
 
     let rhandle = get_rust_handle(raw_handle);
@@ -1137,7 +1149,7 @@ pub unsafe extern "C" fn rsvg_handle_rust_new_from_stream_sync(
     flags: u32,
     cancellable: *mut gio_sys::GCancellable,
     error: *mut *mut glib_sys::GError,
-) -> *mut RsvgHandle {
+) -> *const RsvgHandle {
     let raw_handle = rsvg_handle_rust_new_with_flags(flags);
 
     let rhandle = get_rust_handle(raw_handle);
@@ -1162,7 +1174,7 @@ pub unsafe extern "C" fn rsvg_handle_rust_new_from_data(
     data: *mut u8,
     len: usize,
     error: *mut *mut glib_sys::GError,
-) -> *mut RsvgHandle {
+) -> *const RsvgHandle {
     // We create the MemoryInputStream without the gtk-rs binding because of this:
     //
     // - The binding doesn't provide _new_from_data().  All of the binding's ways to
@@ -1222,7 +1234,7 @@ pub unsafe extern "C" fn rsvg_handle_rust_get_intrinsic_dimensions(
 ) {
     let rhandle = get_rust_handle(handle);
 
-    if !is_loaded(rhandle) {
+    if rhandle.check_is_loaded().is_err() {
         return;
     }
 
diff --git a/rsvg_internals/src/io.rs b/rsvg_internals/src/io.rs
index d6248496..7c937e6c 100644
--- a/rsvg_internals/src/io.rs
+++ b/rsvg_internals/src/io.rs
@@ -109,7 +109,7 @@ pub fn acquire_data(
         let (contents, _etag) = file.load_contents(cancellable)?;
 
         let (content_type, _uncertain) = gio::content_type_guess(uri, &contents);
-        let mime_type = gio::content_type_get_mime_type(&content_type);
+        let mime_type = gio::content_type_get_mime_type(&content_type).map(String::from);
 
         Ok(BinaryData {
             data: contents,
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 6aac6100..5f9b9b94 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -14,7 +14,6 @@ extern crate gdk_pixbuf;
 extern crate gdk_pixbuf_sys;
 extern crate gio;
 extern crate gio_sys;
-extern crate glib;
 extern crate glib_sys;
 extern crate gobject_sys;
 extern crate itertools;
@@ -32,6 +31,12 @@ extern crate regex;
 extern crate url;
 extern crate xml as xml_rs;
 
+#[macro_use]
+extern crate bitflags;
+
+#[macro_use]
+extern crate glib;
+
 #[macro_use]
 extern crate lazy_static;
 
diff --git a/rsvg_internals/src/pixbuf_utils.rs b/rsvg_internals/src/pixbuf_utils.rs
index bfdd6dbf..1bea47c9 100644
--- a/rsvg_internals/src/pixbuf_utils.rs
+++ b/rsvg_internals/src/pixbuf_utils.rs
@@ -7,8 +7,9 @@ use glib::translate::*;
 use glib_sys;
 use libc;
 
+use c_api::get_rust_handle;
 use error::{set_gerror, RenderingError};
-use handle::{get_rust_handle, rsvg_handle_rust_new_from_gfile_sync, Handle, RsvgDimensionData};
+use handle::{rsvg_handle_rust_new_from_gfile_sync, Handle, RsvgDimensionData};
 use rect::IRect;
 use surface_utils::{
     iterators::Pixels,
@@ -134,7 +135,7 @@ fn get_final_size(dimensions: &RsvgDimensionData, size_mode: &SizeMode) -> (i32,
 }
 
 fn render_to_pixbuf_at_size(
-    handle: &mut Handle,
+    handle: &Handle,
     dimensions: &RsvgDimensionData,
     width: i32,
     height: i32,
diff --git a/rsvg_internals/src/surface_utils/shared_surface.rs 
b/rsvg_internals/src/surface_utils/shared_surface.rs
index ad45c8fd..e91f1ceb 100644
--- a/rsvg_internals/src/surface_utils/shared_surface.rs
+++ b/rsvg_internals/src/surface_utils/shared_surface.rs
@@ -6,7 +6,7 @@ use std::ptr::NonNull;
 use cairo::prelude::SurfaceExt;
 use cairo::{self, ImageSurface};
 use cairo_sys;
-use gdk_pixbuf::{Colorspace, Pixbuf, PixbufExt};
+use gdk_pixbuf::{Colorspace, Pixbuf};
 use glib::translate::{Stash, ToGlibPtr};
 use nalgebra::{storage::Storage, Dim, Matrix};
 use rayon;
diff --git a/rsvg_internals/src/svg.rs b/rsvg_internals/src/svg.rs
index ec39f475..d775a24e 100644
--- a/rsvg_internals/src/svg.rs
+++ b/rsvg_internals/src/svg.rs
@@ -1,4 +1,3 @@
-use cairo::Status;
 use gdk_pixbuf::{PixbufLoader, PixbufLoaderExt};
 use gio;
 use glib::translate::*;
@@ -213,7 +212,7 @@ fn load_image(
                     length: libc::c_ulong,
                     destroy: cairo_sys::cairo_destroy_func_t,
                     closure: *mut libc::c_void,
-                ) -> Status;
+                ) -> cairo_sys::cairo_status_t;
             }
 
             unsafe {
@@ -224,11 +223,10 @@ fn load_image(
                     data.data.len() as libc::c_ulong,
                     Some(glib_sys::g_free),
                     data_ptr as *mut _,
-                )
-                .into();
+                );
 
-                if status != Status::Success {
-                    return Err(LoadingError::Cairo(status));
+                if status != cairo_sys::STATUS_SUCCESS {
+                    return Err(LoadingError::Cairo(status.into()));
                 }
             }
         }
diff --git a/rsvg_internals/src/text.rs b/rsvg_internals/src/text.rs
index a34be604..aa654e69 100644
--- a/rsvg_internals/src/text.rs
+++ b/rsvg_internals/src/text.rs
@@ -927,8 +927,8 @@ fn get_pango_context(cr: &cairo::Context, is_testing: bool) -> pango::Context {
         let mut options = cairo::FontOptions::new();
 
         options.set_antialias(cairo::Antialias::Gray);
-        options.set_hint_style(cairo::enums::HintStyle::Full);
-        options.set_hint_metrics(cairo::enums::HintMetrics::On);
+        options.set_hint_style(cairo::HintStyle::Full);
+        options.set_hint_metrics(cairo::HintMetrics::On);
 
         pangocairo::functions::context_set_font_options(&context, &options);
     }
diff --git a/tests/api.c b/tests/api.c
index 557eba18..af9f938e 100644
--- a/tests/api.c
+++ b/tests/api.c
@@ -888,6 +888,129 @@ cannot_request_external_elements (void)
     g_test_trap_assert_stderr ("*WARNING*the public API is not allowed to look up external references*");
 }
 
+static void
+test_flags (RsvgHandleFlags flags)
+{
+    guint read_flags;
+
+    RsvgHandle *handle = g_object_new (RSVG_TYPE_HANDLE,
+                                       "flags", flags,
+                                       NULL);
+    g_object_get (handle, "flags", &read_flags, NULL);
+    g_assert (read_flags == flags);
+
+    g_object_unref (handle);
+}
+
+static void
+property_flags (void)
+{
+    test_flags (RSVG_HANDLE_FLAGS_NONE);
+    test_flags (RSVG_HANDLE_FLAG_UNLIMITED);
+    test_flags (RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA);
+    test_flags (RSVG_HANDLE_FLAG_UNLIMITED | RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA);
+}
+
+static void
+property_dpi (void)
+{
+    RsvgHandle *handle = g_object_new (RSVG_TYPE_HANDLE,
+                                       "dpi-x", 42.0,
+                                       "dpi-y", 43.0,
+                                       NULL);
+    double x, y;
+
+    g_object_get (handle,
+                  "dpi-x", &x,
+                  "dpi-y", &y,
+                  NULL);
+
+    g_assert (x == 42.0);
+    g_assert (y == 43.0);
+
+    g_object_unref (handle);
+}
+
+static void
+property_base_uri (void)
+{
+    RsvgHandle *handle = g_object_new (RSVG_TYPE_HANDLE,
+                                       "base-uri", "file:///foo/bar.svg",
+                                       NULL);
+    char *uri;
+
+    g_object_get (handle,
+                  "base-uri", &uri,
+                  NULL);
+
+    g_assert (strcmp (uri, "file:///foo/bar.svg") == 0);
+    g_free (uri);
+
+    g_object_unref (handle);
+}
+
+static void
+property_dimensions (void)
+{
+    char *filename = get_test_filename ("example.svg");
+    GError *error = NULL;
+
+    RsvgHandle *handle = rsvg_handle_new_from_file (filename, &error);
+    g_free (filename);
+
+    g_assert (handle != NULL);
+    g_assert (error == NULL);
+
+    int width;
+    int height;
+    double em;
+    double ex;
+
+    g_object_get (handle,
+                  "width", &width,
+                  "height", &height,
+                  "em", &em,
+                  "ex", &ex,
+                  NULL);
+
+    g_assert_cmpint (width,  ==, EXAMPLE_WIDTH);
+    g_assert_cmpint (height, ==, EXAMPLE_HEIGHT);
+
+    g_assert_cmpfloat (em, ==, (double) EXAMPLE_WIDTH);
+    g_assert_cmpfloat (ex, ==, (double) EXAMPLE_HEIGHT);
+
+    g_object_unref (handle);
+}
+
+static void
+property_deprecated (void)
+{
+    char *filename = get_test_filename ("example.svg");
+    GError *error = NULL;
+
+    RsvgHandle *handle = rsvg_handle_new_from_file (filename, &error);
+    g_free (filename);
+
+    g_assert (handle != NULL);
+    g_assert (error == NULL);
+
+    char *title;
+    char *desc;
+    char *metadata;
+
+    g_object_get (handle,
+                  "title", &title,
+                  "desc", &desc,
+                  "metadata", &metadata,
+                  NULL);
+
+    g_assert (title == NULL);
+    g_assert (desc == NULL);
+    g_assert (metadata == NULL);
+
+    g_object_unref (handle);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -924,6 +1047,11 @@ main (int argc, char **argv)
     g_test_add_func ("/api/no_write_before_close", no_write_before_close);
     g_test_add_func ("/api/empty_write_close", empty_write_close);
     g_test_add_func ("/api/cannot_request_external_elements", cannot_request_external_elements);
+    g_test_add_func ("/api/property_flags", property_flags);
+    g_test_add_func ("/api/property_dpi", property_dpi);
+    g_test_add_func ("/api/property_base_uri", property_base_uri);
+    g_test_add_func ("/api/property_dimensions", property_dimensions);
+    g_test_add_func ("/api/property_deprecated", property_deprecated);
 
     return g_test_run ();
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]