[librsvg: 11/15] Add new API rsvg_handle_render_document()



commit e943136ead95d2a818e10c8b14d1adc8afc827ff
Author: Federico Mena Quintero <federico gnome org>
Date:   Mon Jul 29 13:50:22 2019 -0500

    Add new API rsvg_handle_render_document()

 doc/rsvg-sections.txt           |  1 +
 librsvg/rsvg-cairo.h            |  6 ++++++
 librsvg/rsvg-handle.c           | 40 +++++++++++++++++++++++++++++++++++
 rsvg_internals/src/c_api.rs     | 29 +++++++++++++++++++++++++
 rsvg_internals/src/lib.rs       |  2 ++
 tests/api.c                     | 47 +++++++++++++++++++++++++++++++++++++++++
 tests/fixtures/api/document.svg |  6 ++++++
 7 files changed, 131 insertions(+)
---
diff --git a/doc/rsvg-sections.txt b/doc/rsvg-sections.txt
index 07661222..ad395bff 100644
--- a/doc/rsvg-sections.txt
+++ b/doc/rsvg-sections.txt
@@ -69,6 +69,7 @@ RSVG_TYPE_HANDLE_FLAGS
 <SECTION>
 <FILE>rsvg-cairo</FILE>
 <TITLE>Using RSVG with cairo</TITLE>
+rsvg_handle_render_document
 rsvg_handle_get_geometry_for_layer
 rsvg_handle_render_layer
 rsvg_handle_render_cairo
diff --git a/librsvg/rsvg-cairo.h b/librsvg/rsvg-cairo.h
index c70f83cc..408c77f8 100644
--- a/librsvg/rsvg-cairo.h
+++ b/librsvg/rsvg-cairo.h
@@ -39,6 +39,12 @@ gboolean    rsvg_handle_render_cairo     (RsvgHandle *handle, cairo_t *cr);
 RSVG_API
 gboolean    rsvg_handle_render_cairo_sub (RsvgHandle *handle, cairo_t *cr, const char *id);
 
+RSVG_API
+gboolean rsvg_handle_render_document (RsvgHandle           *handle,
+                                      cairo_t              *cr,
+                                      const RsvgRectangle  *viewport,
+                                      GError              **error);
+
 RSVG_API
 gboolean rsvg_handle_get_geometry_for_layer (RsvgHandle     *handle,
                                              const char     *id,
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index 0439bf59..7b5333cc 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -382,6 +382,10 @@ extern void rsvg_rust_handle_get_intrinsic_dimensions (RsvgHandle *handle,
                                                        RsvgLength *out_height,
                                                        gboolean   *out_has_viewbox,
                                                        RsvgRectangle *out_viewbox);
+extern gboolean rsvg_rust_handle_render_document (RsvgHandle           *handle,
+                                                  cairo_t              *cr,
+                                                  const RsvgRectangle  *viewport,
+                                                  GError              **error);
 extern gboolean rsvg_rust_handle_get_geometry_for_layer (RsvgHandle     *handle,
                                                          const char     *id,
                                                          const RsvgRectangle *viewport,
@@ -1229,6 +1233,42 @@ rsvg_handle_get_intrinsic_dimensions (RsvgHandle *handle,
                                                out_viewbox);
 }
 
+/**
+ * rsvg_handle_render_document:
+ * @handle: An #RsvgHandle
+ * @cr: A Cairo context
+ * @viewport: Viewport size at which the whole SVG would be fitted.
+ * @error: (allow-none): a location to store a #GError, or %NULL
+ *
+ * Renders the whole SVG document fitted to a viewport.
+ *
+ * The @viewport gives the position and size at which the whole SVG
+ * document will be rendered.
+ *
+ * The @cr must be in a #CAIRO_STATUS_SUCCESS state, or this function will not
+ * render anything, and instead will return an error.
+ *
+ * API ordering: This function must be called on a fully-loaded @handle.  See
+ * the section <link href="#API-ordering">API ordering</link> for details.
+ *
+ * Panics: this function will panic if the @handle is not fully-loaded.
+ *
+ * Since: 2.46
+ */
+gboolean
+rsvg_handle_render_document (RsvgHandle           *handle,
+                             cairo_t              *cr,
+                             const RsvgRectangle  *viewport,
+                             GError              **error)
+{
+    g_return_val_if_fail (RSVG_IS_HANDLE (handle), FALSE);
+    g_return_val_if_fail (cr != NULL, FALSE);
+    g_return_val_if_fail (viewport != NULL, FALSE);
+    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+    return rsvg_rust_handle_render_document (handle, cr, viewport, error);
+}
+
 /**
  * rsvg_handle_get_geometry_for_layer:
  * @handle: An #RsvgHandle
diff --git a/rsvg_internals/src/c_api.rs b/rsvg_internals/src/c_api.rs
index 74701a4a..bc66eabb 100644
--- a/rsvg_internals/src/c_api.rs
+++ b/rsvg_internals/src/c_api.rs
@@ -702,6 +702,15 @@ impl CHandle {
         handle.get_pixbuf_sub(id, self.dpi.get(), &*size_callback, self.is_testing.get())
     }
 
+    fn render_document(
+        &self,
+        cr: &cairo::Context,
+        viewport: &cairo::Rectangle,
+    ) -> Result<(), RenderingError> {
+        let handle = self.get_handle_ref()?;
+        handle.render_document(cr, viewport, self.dpi.get(), self.is_testing.get())
+    }
+
     fn get_geometry_for_layer(
         &self,
         id: Option<&str>,
@@ -1259,6 +1268,26 @@ pub unsafe extern "C" fn rsvg_rust_handle_get_intrinsic_dimensions(
     set_out_param(out_has_viewbox, out_viewbox, &r);
 }
 
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_rust_handle_render_document(
+    handle: *mut RsvgHandle,
+    cr: *mut cairo_sys::cairo_t,
+    viewport: *const RsvgRectangle,
+    error: *mut *mut glib_sys::GError,
+) -> glib_sys::gboolean {
+    let rhandle = get_rust_handle(handle);
+    let cr = from_glib_none(cr);
+
+    match rhandle.render_document(&cr, &(*viewport).into()) {
+        Ok(()) => true.to_glib(),
+
+        Err(e) => {
+            set_gerror(error, 0, &format!("{}", e));
+            false.to_glib()
+        }
+    }
+}
+
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_rust_handle_get_geometry_for_layer(
     handle: *mut RsvgHandle,
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 58070db5..149bf1d6 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -27,6 +27,8 @@ pub use crate::c_api::{
     rsvg_rust_handle_new_with_flags,
     rsvg_rust_handle_read_stream_sync,
     rsvg_rust_handle_render_cairo_sub,
+    rsvg_rust_handle_render_document,
+    rsvg_rust_handle_render_layer,
     rsvg_rust_handle_set_base_gfile,
     rsvg_rust_handle_set_base_url,
     rsvg_rust_handle_set_dpi_x,
diff --git a/tests/api.c b/tests/api.c
index 54298d6c..d8a8d7b7 100644
--- a/tests/api.c
+++ b/tests/api.c
@@ -943,6 +943,52 @@ get_intrinsic_dimensions (void)
     g_object_unref (handle);
 }
 
+static void
+render_document (void)
+{
+    char *filename = get_test_filename ("document.svg");
+    GError *error = NULL;
+
+    RsvgHandle *handle = rsvg_handle_new_from_file (filename, &error);
+    g_free (filename);
+
+    g_assert (handle != NULL);
+    g_assert (error == NULL);
+
+    cairo_surface_t *output = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 150, 150);
+    cairo_t *cr = cairo_create (output);
+
+    RsvgRectangle viewport = { 50.0, 50.0, 50.0, 50.0 };
+
+    g_assert (rsvg_handle_render_document (handle, cr, &viewport, &error));
+    g_assert (error == NULL);
+
+    cairo_destroy (cr);
+
+    cairo_surface_t *expected = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 150, 150);
+    cr = cairo_create (expected);
+
+    cairo_translate (cr, 50.0, 50.0);
+    cairo_rectangle (cr, 10.0, 10.0, 30.0, 30.0);
+    cairo_set_source_rgba (cr, 0.0, 0.0, 1.0, 0.5);
+    cairo_fill (cr);
+    cairo_destroy (cr);
+
+    cairo_surface_t *diff = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 150, 150);
+
+    TestUtilsBufferDiffResult result = {0, 0};
+    test_utils_compare_surfaces (output, expected, diff, &result);
+
+    if (result.pixels_changed && result.max_diff > 0) {
+        g_test_fail ();
+    }
+
+    cairo_surface_destroy (diff);
+    cairo_surface_destroy (expected);
+    cairo_surface_destroy (output);
+    g_object_unref (handle);
+}
+
 static void
 get_geometry_for_layer (void)
 {
@@ -1251,6 +1297,7 @@ main (int argc, char **argv)
     g_test_add_func ("/api/can_draw_to_non_image_surface", can_draw_to_non_image_surface);
     g_test_add_func ("/api/render_cairo_sub", render_cairo_sub);
     g_test_add_func ("/api/get_intrinsic_dimensions", get_intrinsic_dimensions);
+    g_test_add_func ("/api/render_document", render_document);
     g_test_add_func ("/api/get_geometry_for_layer", get_geometry_for_layer);
     g_test_add_func ("/api/render_layer", render_layer);
     g_test_add_func ("/api/no_write_before_close", no_write_before_close);
diff --git a/tests/fixtures/api/document.svg b/tests/fixtures/api/document.svg
new file mode 100644
index 00000000..49cfd07e
--- /dev/null
+++ b/tests/fixtures/api/document.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"; width="50" height="50">
+  <g opacity="0.5">
+    <rect x="10" y="10" width="30" height="30" fill="blue"/>
+  </g>
+</svg>


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