From 197a9e0c9e0c73ea5e76c10980e6265dd99439d9 Mon Sep 17 00:00:00 2001 From: Ulf Jasper Date: Wed, 17 Dec 2014 20:50:12 +0100 Subject: [PATCH] Fix problem with images referenced within svg files. (bug#19373) Fixes: debbugs:19373 * src/image.c: Additional parameter 'filename' for svg_load_image. Include "buffer.h". Define library function rsvg_handle_set_base_uri for WINDOWSNT. (init_svg_functions): Initialize rsvg_handle_set_base_uri. (fn_rsvg_handle_set_base_uri): Define fn_rsvg_handle_set_base_uri. (svg_load): Pass a filename to svg_load_image: either name of actual file or of current buffer's file. (svg_load_image): New parameter 'filename', used for setting base_uri, necessary for loading referenced images. --- src/ChangeLog | 14 ++++++++++++++ src/image.c | 23 ++++++++++++++++++----- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index aa8adabfede..1e10ffd8fcd 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2014-12-17 Ulf Jasper + + Fix problem with images referenced within svg files. (bug#19373) + + * image.c: Additional parameter 'filename' for + svg_load_image. Include "buffer.h". Define library function + rsvg_handle_set_base_uri for WINDOWSNT. + (init_svg_functions): Initialize rsvg_handle_set_base_uri. + (fn_rsvg_handle_set_base_uri): Define fn_rsvg_handle_set_base_uri. + (svg_load): Pass a filename to svg_load_image: either name of + actual file or of current buffer's file. + (svg_load_image): New parameter 'filename', used for setting + base_uri, necessary for loading referenced images. (bug#19373) + 2014-12-16 Paul Eggert * lread.c (init_obarray): Declare Qt as special. diff --git a/src/image.c b/src/image.c index 1a2c0e29dde..0bebd45d893 100644 --- a/src/image.c +++ b/src/image.c @@ -33,6 +33,7 @@ along with GNU Emacs. If not, see . */ #include "lisp.h" #include "frame.h" #include "window.h" +#include "buffer.h" #include "dispextern.h" #include "blockinput.h" #include "systime.h" @@ -8600,7 +8601,7 @@ static bool svg_image_p (Lisp_Object object); static bool svg_load (struct frame *f, struct image *img); static bool svg_load_image (struct frame *, struct image *, - unsigned char *, ptrdiff_t); + unsigned char *, ptrdiff_t, char*); /* The symbol `svg' identifying images of this type. */ @@ -8688,6 +8689,7 @@ DEF_IMGLIB_FN (void, rsvg_handle_get_dimensions, (RsvgHandle *, RsvgDimensionDat DEF_IMGLIB_FN (gboolean, rsvg_handle_write, (RsvgHandle *, const guchar *, gsize, GError **)); DEF_IMGLIB_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **)); DEF_IMGLIB_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *)); +DEF_IMGLIB_FN (void, rsvg_handle_set_base_uri, (RsvgHandle *, const char *)); DEF_IMGLIB_FN (int, gdk_pixbuf_get_width, (const GdkPixbuf *)); DEF_IMGLIB_FN (int, gdk_pixbuf_get_height, (const GdkPixbuf *)); @@ -8727,6 +8729,7 @@ init_svg_functions (void) LOAD_IMGLIB_FN (library, rsvg_handle_write); LOAD_IMGLIB_FN (library, rsvg_handle_close); LOAD_IMGLIB_FN (library, rsvg_handle_get_pixbuf); + LOAD_IMGLIB_FN (library, rsvg_handle_set_base_uri); LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_width); LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_height); @@ -8754,6 +8757,7 @@ init_svg_functions (void) #define fn_rsvg_handle_write rsvg_handle_write #define fn_rsvg_handle_close rsvg_handle_close #define fn_rsvg_handle_get_pixbuf rsvg_handle_get_pixbuf +#define fn_rsvg_handle_set_base_uri rsvg_handle_set_base_uri #define fn_gdk_pixbuf_get_width gdk_pixbuf_get_width #define fn_gdk_pixbuf_get_height gdk_pixbuf_get_height @@ -8803,14 +8807,14 @@ svg_load (struct frame *f, struct image *img) return 0; } /* If the file was slurped into memory properly, parse it. */ - success_p = svg_load_image (f, img, contents, size); + success_p = svg_load_image (f, img, contents, size, SSDATA(file)); xfree (contents); } /* Else its not a file, its a lisp object. Load the image from a lisp object rather than a file. */ else { - Lisp_Object data; + Lisp_Object data, original_filename; data = image_spec_value (img->spec, QCdata, NULL); if (!STRINGP (data)) @@ -8818,7 +8822,9 @@ svg_load (struct frame *f, struct image *img) image_error ("Invalid image data `%s'", data, Qnil); return 0; } - success_p = svg_load_image (f, img, SDATA (data), SBYTES (data)); + original_filename = BVAR (current_buffer, filename); + success_p = svg_load_image (f, img, SDATA (data), SBYTES (data), + SDATA(original_filename)); } return success_p; @@ -8835,7 +8841,8 @@ static bool svg_load_image (struct frame *f, /* Pointer to emacs frame structure. */ struct image *img, /* Pointer to emacs image structure. */ unsigned char *contents, /* String containing the SVG XML data to be parsed. */ - ptrdiff_t size) /* Size of data in bytes. */ + ptrdiff_t size, /* Size of data in bytes. */ + char *filename) /* Name of SVG file being loaded. */ { RsvgHandle *rsvg_handle; RsvgDimensionData dimension_data; @@ -8860,6 +8867,12 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. * /* Make a handle to a new rsvg object. */ rsvg_handle = fn_rsvg_handle_new (); + /* Set base_uri for properly handling referenced images (via 'href'). + See rsvg bug 596114 - "image refs are relative to curdir, not .svg file" + (https://bugzilla.gnome.org/show_bug.cgi?id=596114). */ + if (filename) + fn_rsvg_handle_set_base_uri(rsvg_handle, filename); + /* Parse the contents argument and fill in the rsvg_handle. */ fn_rsvg_handle_write (rsvg_handle, contents, size, &err); if (err) goto rsvg_error; -- 2.39.2