[librsvg] (#309): Don't panic if rendering to a non-image surface
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] (#309): Don't panic if rendering to a non-image surface
- Date: Tue, 31 Jul 2018 04:26:02 +0000 (UTC)
commit e7de8f25b8049c186975ef510e2bd41d62397ae7
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Jul 20 10:27:42 2018 -0700
(#309): Don't panic if rendering to a non-image surface
The somewhat convoluted code in with_discrete_layer() was trying to
create a cairo::ImageSurface from the incoming cr's target, which may
in fact not be an image surface.
We now have a test for this, too.
https://gitlab.gnome.org/GNOME/librsvg/issues/309
rsvg_internals/src/drawing_ctx.rs | 48 ++++++++++++++++++---------------------
tests/api.c | 33 +++++++++++++++++++++++++++
2 files changed, 55 insertions(+), 26 deletions(-)
---
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index d90b072a..afa8ae71 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -301,39 +301,35 @@ impl<'a> DrawingCtx<'a> {
&& comp_op == CompOp::SrcOver
&& enable_background == EnableBackground::Accumulate);
- let child_surface = {
- if needs_temporary_surface {
- // FIXME: in the following, we unwrap() the result of
- // ImageSurface::create(). We have to decide how to handle
- // out-of-memory here.
- let surface = cairo::ImageSurface::create(
- cairo::Format::ARgb32,
- self.rect.width as i32,
- self.rect.height as i32,
- ).unwrap();
-
- if filter.is_some() {
- self.surfaces_stack.push(surface.clone());
- }
-
- let cr = cairo::Context::new(&surface);
- cr.set_matrix(affine);
+ if needs_temporary_surface {
+ // FIXME: in the following, we unwrap() the result of
+ // ImageSurface::create(). We have to decide how to handle
+ // out-of-memory here.
+ let surface = cairo::ImageSurface::create(
+ cairo::Format::ARgb32,
+ self.rect.width as i32,
+ self.rect.height as i32,
+ ).unwrap();
+
+ if filter.is_some() {
+ self.surfaces_stack.push(surface.clone());
+ }
- self.cr_stack.push(self.cr.clone());
- self.cr = cr.clone();
+ let cr = cairo::Context::new(&surface);
+ cr.set_matrix(affine);
- self.bbox_stack.push(self.bbox);
- self.bbox = BoundingBox::new(&affine);
+ self.cr_stack.push(self.cr.clone());
+ self.cr = cr.clone();
- surface
- } else {
- cairo::ImageSurface::from(original_cr.get_target()).unwrap()
- }
- };
+ self.bbox_stack.push(self.bbox);
+ self.bbox = BoundingBox::new(&affine);
+ }
draw_fn(self);
if needs_temporary_surface {
+ let child_surface = cairo::ImageSurface::from(self.cr.get_target()).unwrap();
+
let filter_result_surface = filter
.and_then(|_| {
// About the following unwrap(), see the FIXME above. We should be pushing
diff --git a/tests/api.c b/tests/api.c
index 75b5d7af..73412041 100644
--- a/tests/api.c
+++ b/tests/api.c
@@ -491,6 +491,38 @@ detects_cairo_context_in_error (void)
g_test_trap_assert_stderr ("*WARNING*cannot render on a cairo_t with a failure status*");
}
+static void
+can_draw_to_non_image_surface (void)
+{
+ cairo_rectangle_t rect;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ char *filename = get_test_filename ("example.svg");
+ GError *error = NULL;
+
+ RsvgHandle *handle = rsvg_handle_new_from_file (filename, &error);
+ g_assert (handle != NULL);
+ g_assert (error == NULL);
+
+ rect.x = 0.0;
+ rect.y = 0.0;
+ rect.width = 100.0;
+ rect.height = 100.0;
+
+ /* We create a surface that is not a Cairo image surface,
+ * so we can test that in fact we can render to non-image surfaces.
+ */
+ surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, &rect);
+ cr = cairo_create (surface);
+
+ g_assert (rsvg_handle_render_cairo (handle, cr));
+
+ g_object_unref (handle);
+
+ cairo_destroy (cr);
+}
+
int
main (int argc, char **argv)
{
@@ -518,6 +550,7 @@ main (int argc, char **argv)
g_test_add_func ("/api/handle_get_pixbuf_sub", handle_get_pixbuf_sub);
g_test_add_func ("/api/dimensions_and_position", dimensions_and_position);
g_test_add_func ("/api/detects_cairo_context_in_error", detects_cairo_context_in_error);
+ g_test_add_func ("/api/can_draw_to_non_image_surface", can_draw_to_non_image_surface);
return g_test_run ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]