Index: ChangeLog =================================================================== --- ChangeLog (revision 1174) +++ ChangeLog (revision 1175) @@ -1,5 +1,16 @@ 2008-08-26 Dominic Lachowicz + * rsvg-cairo.h: Make cairo render functions return a gboolean. Returns TRUE + if the image can't be rendered + * rsvg.c: Check && handle the return value + * rsvg-cairo-render.c: Implement the above. Also, return FALSE if we're asked + to render an ID that doesn't exist + + Collectively, fixes #540383 - rsvg_handle_render_cairo_sub - if ID not found, + return an error and/or dont render whole SVG + +2008-08-26 Dominic Lachowicz + * rsvg-private.h: #539488 - migrate use of GMemChunk to GSlice, from Felix Riemann * rsvg-base.c: ditto * rsvg-styles.c: ditto Index: rsvg.c =================================================================== --- rsvg.c (revision 1174) +++ rsvg.c (revision 1175) @@ -94,23 +94,26 @@ surface = cairo_image_surface_create_for_data (pixels, CAIRO_FORMAT_ARGB32, dimensions.width, dimensions.height, rowstride); - cr = cairo_create (surface); + cairo_surface_destroy (surface); - rsvg_handle_render_cairo_sub (handle, cr, id); - rsvg_cairo_to_pixbuf (pixels, rowstride, dimensions.height); + if (rsvg_handle_render_cairo_sub (handle, cr, id)) { + rsvg_cairo_to_pixbuf (pixels, rowstride, dimensions.height); - output = gdk_pixbuf_new_from_data (pixels, - GDK_COLORSPACE_RGB, - TRUE, - 8, - dimensions.width, - dimensions.height, - rowstride, - (GdkPixbufDestroyNotify) rsvg_pixmap_destroy, NULL); + output = gdk_pixbuf_new_from_data (pixels, + GDK_COLORSPACE_RGB, + TRUE, + 8, + dimensions.width, + dimensions.height, + rowstride, + (GdkPixbufDestroyNotify) rsvg_pixmap_destroy, NULL); + } else { + g_free (pixels); + output = NULL; + } cairo_destroy (cr); - cairo_surface_destroy (surface); return output; } Index: rsvg-cairo.h =================================================================== --- rsvg-cairo.h (revision 1174) +++ rsvg-cairo.h (revision 1175) @@ -29,8 +29,8 @@ G_BEGIN_DECLS -void rsvg_handle_render_cairo (RsvgHandle * handle, cairo_t * cr); -void rsvg_handle_render_cairo_sub (RsvgHandle * handle, cairo_t * cr, const char *id); +gboolean rsvg_handle_render_cairo (RsvgHandle * handle, cairo_t * cr); +gboolean rsvg_handle_render_cairo_sub (RsvgHandle * handle, cairo_t * cr, const char *id); G_END_DECLS Index: rsvg-cairo-render.c =================================================================== --- rsvg-cairo-render.c (revision 1174) +++ rsvg-cairo-render.c (revision 1175) @@ -196,24 +196,29 @@ * * Since: 2.14 */ -void +gboolean rsvg_handle_render_cairo_sub (RsvgHandle * handle, cairo_t * cr, const char *id) { RsvgDrawingCtx *draw; RsvgNode *drawsub = NULL; - g_return_if_fail (handle != NULL); + g_return_val_if_fail (handle != NULL, FALSE); if (!handle->priv->finished) - return; + return FALSE; + if (id && *id) + drawsub = rsvg_defs_lookup (handle->priv->defs, id); + + if (drawsub == NULL && id != NULL) { + /* todo: there's no way to signal that @id doesn't exist */ + return FALSE; + } + draw = rsvg_cairo_new_drawing_ctx (cr, handle); if (!draw) - return; + return FALSE; - if (id && *id) - drawsub = rsvg_defs_lookup (handle->priv->defs, id); - while (drawsub != NULL) { draw->drawsub_stack = g_slist_prepend (draw->drawsub_stack, drawsub); drawsub = drawsub->parent; @@ -227,6 +232,8 @@ cairo_restore (cr); rsvg_state_pop (draw); rsvg_drawing_ctx_free (draw); + + return TRUE; } /** @@ -238,8 +245,8 @@ * * Since: 2.14 */ -void +gboolean rsvg_handle_render_cairo (RsvgHandle * handle, cairo_t * cr) { - rsvg_handle_render_cairo_sub (handle, cr, NULL); + return rsvg_handle_render_cairo_sub (handle, cr, NULL); }