Add new API rsvg_handle_render_document()

parent 16d8b476
......@@ -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
......
......@@ -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,
......
......@@ -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
......
......@@ -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,
......
......@@ -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,
......
......@@ -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);
......
<?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>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment