[librsvg: 9/15] Add C version of rsvg_handle_render_layer()
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 9/15] Add C version of rsvg_handle_render_layer()
- Date: Tue, 30 Jul 2019 17:33:01 +0000 (UTC)
commit c2c79030ebe0b10079a8b4bbc520fa5bfbcdb969
Author: Federico Mena Quintero <federico gnome org>
Date: Mon Jul 29 13:12:40 2019 -0500
Add C version of rsvg_handle_render_layer()
doc/rsvg-sections.txt | 3 ++-
librsvg/rsvg-cairo.h | 16 +++++++++++++++
librsvg/rsvg-handle.c | 21 +++++++++++++++++++
librsvg/rsvg.h | 8 --------
librsvg_crate/src/lib.rs | 30 +++++++++++++++++++++++++++
rsvg_internals/src/c_api.rs | 32 +++++++++++++++++++++++++++++
tests/api.c | 47 +++++++++++++++++++++++++++++++++++++++++++
tests/fixtures/api/layers.svg | 5 +++++
8 files changed, 153 insertions(+), 9 deletions(-)
---
diff --git a/doc/rsvg-sections.txt b/doc/rsvg-sections.txt
index 53c7f304..07661222 100644
--- a/doc/rsvg-sections.txt
+++ b/doc/rsvg-sections.txt
@@ -26,7 +26,6 @@ rsvg_handle_get_dimensions
rsvg_handle_get_dimensions_sub
rsvg_handle_get_position_sub
rsvg_handle_get_intrinsic_dimensions
-rsvg_handle_get_geometry_for_element
rsvg_handle_has_sub
rsvg_handle_get_title
rsvg_handle_get_desc
@@ -70,6 +69,8 @@ RSVG_TYPE_HANDLE_FLAGS
<SECTION>
<FILE>rsvg-cairo</FILE>
<TITLE>Using RSVG with cairo</TITLE>
+rsvg_handle_get_geometry_for_layer
+rsvg_handle_render_layer
rsvg_handle_render_cairo
rsvg_handle_render_cairo_sub
</SECTION>
diff --git a/librsvg/rsvg-cairo.h b/librsvg/rsvg-cairo.h
index 3a75c629..c70f83cc 100644
--- a/librsvg/rsvg-cairo.h
+++ b/librsvg/rsvg-cairo.h
@@ -39,6 +39,22 @@ 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_get_geometry_for_layer (RsvgHandle *handle,
+ const char *id,
+ const RsvgRectangle *viewport,
+ RsvgRectangle *out_ink_rect,
+ RsvgRectangle *out_logical_rect,
+ GError **error);
+
+RSVG_API
+gboolean rsvg_handle_render_layer (RsvgHandle *handle,
+ cairo_t *cr,
+ const char *id,
+ const RsvgRectangle *viewport,
+ GError **error);
+
+
G_END_DECLS
#endif
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index 5b32dc04..42be2e67 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -388,6 +388,12 @@ extern gboolean rsvg_rust_handle_get_geometry_for_layer (RsvgHandle *handle,
RsvgRectangle *out_ink_rect,
RsvgRectangle *out_logical_rect,
GError **error);
+extern gboolean rsvg_rust_handle_render_layer (RsvgHandle *handle,
+ cairo_t *cr,
+ const char *id,
+ const RsvgRectangle *viewport,
+ GError **error);
+
/* Implemented in rsvg_internals/src/c_api.rs */
@@ -1285,6 +1291,21 @@ rsvg_handle_get_geometry_for_layer (RsvgHandle *handle,
error);
}
+gboolean
+rsvg_handle_render_layer (RsvgHandle *handle,
+ cairo_t *cr,
+ const char *id,
+ 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_layer (handle, cr, id, viewport, error);
+}
+
/**
* rsvg_handle_internal_set_testing:
* @handle: a #RsvgHandle
diff --git a/librsvg/rsvg.h b/librsvg/rsvg.h
index 5cd2be90..476c3025 100644
--- a/librsvg/rsvg.h
+++ b/librsvg/rsvg.h
@@ -280,14 +280,6 @@ void rsvg_handle_get_intrinsic_dimensions (RsvgHandle *handle,
gboolean *out_has_viewbox,
RsvgRectangle *out_viewbox);
-RSVG_API
-gboolean rsvg_handle_get_geometry_for_layer (RsvgHandle *handle,
- const char *id,
- const RsvgRectangle *viewport,
- RsvgRectangle *out_ink_rect,
- RsvgRectangle *out_logical_rect,
- GError **error);
-
/* GIO APIs */
/**
diff --git a/librsvg_crate/src/lib.rs b/librsvg_crate/src/lib.rs
index e904076c..3ab58117 100644
--- a/librsvg_crate/src/lib.rs
+++ b/librsvg_crate/src/lib.rs
@@ -455,6 +455,36 @@ impl<'a> CairoRenderer<'a> {
.render_layer(cr, id, viewport, self.dpi, false)
}
+ /// Computes the (ink_rect, logical_rect) of a single SVG element
+ ///
+ /// While `geometry_for_layer` computes the geometry of an SVG element subtree with
+ /// its transformation matrix, this other function will compute the element's geometry
+ /// as if it were being rendered under an identity transformation by itself. That is,
+ /// the resulting geometry is as if the element got extracted by itself from the SVG.
+ ///
+ /// This function is the counterpart to `render_element`.
+ ///
+ /// Element IDs should look like an URL fragment identifier; for
+ /// example, pass `Some("#foo")` to get the geometry of the
+ /// element that has an `id="foo"` attribute.
+ ///
+ /// The "ink rectangle" is the bounding box that would be painted
+ /// for fully- stroked and filled elements.
+ ///
+ /// The "logical rectangle" just takes into account the unstroked
+ /// paths and text outlines.
+ ///
+ /// Note that these bounds are not minimum bounds; for example,
+ /// clipping paths are not taken into account.
+ ///
+ /// You can pass `None` for the `id` if you want to measure all
+ /// the elements in the SVG, i.e. to measure everything from the
+ /// root element.
+ ///
+ /// This operation is not constant-time, as it involves going through all
+ /// the child elements.
+ ///
+ /// FIXME: example
pub fn geometry_for_element(
&self,
id: Option<&str>,
diff --git a/rsvg_internals/src/c_api.rs b/rsvg_internals/src/c_api.rs
index d876c31d..74701a4a 100644
--- a/rsvg_internals/src/c_api.rs
+++ b/rsvg_internals/src/c_api.rs
@@ -711,6 +711,16 @@ impl CHandle {
handle.get_geometry_for_layer(id, viewport, self.dpi.get(), self.is_testing.get())
}
+ fn render_layer(
+ &self,
+ cr: &cairo::Context,
+ id: Option<&str>,
+ viewport: &cairo::Rectangle,
+ ) -> Result<(), RenderingError> {
+ let handle = self.get_handle_ref()?;
+ handle.render_layer(cr, id, viewport, self.dpi.get(), self.is_testing.get())
+ }
+
fn get_intrinsic_dimensions(&self) -> Result<IntrinsicDimensions, RenderingError> {
let handle = self.get_handle_ref()?;
Ok(handle.get_intrinsic_dimensions())
@@ -1282,6 +1292,28 @@ pub unsafe extern "C" fn rsvg_rust_handle_get_geometry_for_layer(
}
}
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_rust_handle_render_layer(
+ handle: *mut RsvgHandle,
+ cr: *mut cairo_sys::cairo_t,
+ id: *const libc::c_char,
+ viewport: *const RsvgRectangle,
+ error: *mut *mut glib_sys::GError,
+) -> glib_sys::gboolean {
+ let rhandle = get_rust_handle(handle);
+ let cr = from_glib_none(cr);
+ let id: Option<String> = from_glib_none(id);
+
+ match rhandle.render_layer(&cr, id.as_ref().map(String::as_str), &(*viewport).into()) {
+ Ok(()) => true.to_glib(),
+
+ Err(e) => {
+ set_gerror(error, 0, &format!("{}", e));
+ false.to_glib()
+ }
+ }
+}
+
/// Detects whether a `*const libc::c_char` is a path or a URI
///
/// `rsvg_handle_new_from_file()` takes a `filename` argument, and advertises
diff --git a/tests/api.c b/tests/api.c
index bb18169b..54298d6c 100644
--- a/tests/api.c
+++ b/tests/api.c
@@ -983,6 +983,52 @@ get_geometry_for_layer (void)
g_object_unref (handle);
}
+static void
+render_layer (void)
+{
+ char *filename = get_test_filename ("layers.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, 300, 300);
+ cairo_t *cr = cairo_create (output);
+
+ RsvgRectangle viewport = { 100.0, 100.0, 100.0, 100.0 };
+
+ g_assert (rsvg_handle_render_layer (handle, cr, "#bar", &viewport, &error));
+ g_assert (error == NULL);
+
+ cairo_destroy (cr);
+
+ cairo_surface_t *expected = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 300, 300);
+ cr = cairo_create (expected);
+
+ cairo_translate (cr, 100.0, 100.0);
+ cairo_rectangle (cr, 20.0, 20.0, 30.0, 30.0);
+ cairo_set_source_rgba (cr, 0.0, 0.0, 1.0, 1.0);
+ cairo_fill (cr);
+ cairo_destroy (cr);
+
+ cairo_surface_t *diff = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 300, 300);
+
+ 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);
+}
+
/* https://gitlab.gnome.org/GNOME/librsvg/issues/385 */
static void
no_write_before_close (void)
@@ -1206,6 +1252,7 @@ main (int argc, char **argv)
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/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);
g_test_add_func ("/api/empty_write_close", empty_write_close);
g_test_add_func ("/api/cannot_request_external_elements", cannot_request_external_elements);
diff --git a/tests/fixtures/api/layers.svg b/tests/fixtures/api/layers.svg
new file mode 100644
index 00000000..73fc5cb9
--- /dev/null
+++ b/tests/fixtures/api/layers.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+ <rect id="foo" x="10" y="10" width="30" height="30" fill="#00ff00"/>
+ <rect id="bar" x="20" y="20" width="30" height="30" fill="#0000ff"/>
+</svg>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]