summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lispref/display.texi20
-rw-r--r--etc/NEWS12
-rw-r--r--lisp/svg.el13
-rw-r--r--src/image.c21
4 files changed, 59 insertions, 7 deletions
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index b9b05a2a422..2b3119ea590 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -5900,6 +5900,26 @@ string containing the image data as raw bytes. @var{image-type} should be a
@end lisp
@end defun
+@defun svg-embed-base-uri-image svg relative-filename &rest args
+To @var{svg} add an embedded (raster) image placed at
+@var{relative-filename}. @var{relative-filename} is searched inside
+@code{file-name-directory} of the @code{:base-uri} svg image property.
+This improves the performance of embedding large images.
+
+@lisp
+;; Embeding /tmp/subdir/rms.jpg and /tmp/another/rms.jpg
+(svg-embed-base-uri-image svg "subdir/rms.jpg"
+ :width "100px" :height "100px"
+ :x "50px" :y "75px")
+(svg-embed-base-uri-image svg "another/rms.jpg"
+ :width "100px" :height "100px"
+ :x "75px" :y "50px")
+(svg-image svg :scale 1.0
+ :base-uri "/tmp/dummy"
+ :width 175 :height 175)
+@end lisp
+@end defun
+
@defun svg-clip-path svg &rest args
Add a clipping path to @var{svg}. If applied to a shape via the
@var{:clip-path} property, parts of that shape which lie outside of
diff --git a/etc/NEWS b/etc/NEWS
index 9aa735da726..901a432d99e 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1111,6 +1111,18 @@ If 'shr-width' is non-nil, it overrides this variable.
** Images
+---
+** Can explicitly specify base_uri for svg images.
+':base-uri' image property can be used to explicitly specify base_uri
+for embedded images into svg. ':base-uri' is supported for both file
+and data svg images.
+
++++
+** 'svg-embed-base-uri-image' added to embed images
+'svg-embed-base-uri-image' can be used to embed images located
+relatively to 'file-name-directory' of the ':base-uri' svg image property.
+This works much faster then 'svg-embed'.
+
+++
*** New function 'image-cache-size'.
This function returns the size of the current image cache, in bytes.
diff --git a/lisp/svg.el b/lisp/svg.el
index eeb945f53b5..1ca59658aa7 100644
--- a/lisp/svg.el
+++ b/lisp/svg.el
@@ -184,6 +184,19 @@ otherwise. IMAGE-TYPE should be a MIME image type, like
`((xlink:href . ,(svg--image-data image image-type datap))
,@(svg--arguments svg args)))))
+(defun svg-embed-base-uri-image (svg relative-filename &rest args)
+ "Insert image placed at RELATIVE-FILENAME into the SVG structure.
+RELATIVE-FILENAME will be searched in `file-name-directory' of the
+image's `:base-uri' property. If `:base-uri' is not specified for the
+image, then embedding won't work. Embedding large images using this
+function is much faster than `svg-embed'."
+ (svg--append
+ svg
+ (dom-node
+ 'image
+ `((xlink:href . ,relative-filename)
+ ,@(svg--arguments svg args)))))
+
(defun svg-text (svg text &rest args)
"Add TEXT to SVG."
(svg--append
diff --git a/src/image.c b/src/image.c
index 54380d1cdfa..6b85ab78f61 100644
--- a/src/image.c
+++ b/src/image.c
@@ -9492,6 +9492,7 @@ enum svg_keyword_index
SVG_TYPE,
SVG_DATA,
SVG_FILE,
+ SVG_BASE_URI,
SVG_ASCENT,
SVG_MARGIN,
SVG_RELIEF,
@@ -9511,6 +9512,7 @@ static const struct image_keyword svg_format[SVG_LAST] =
{":type", IMAGE_SYMBOL_VALUE, 1},
{":data", IMAGE_STRING_VALUE, 0},
{":file", IMAGE_STRING_VALUE, 0},
+ {":base-uri", IMAGE_STRING_VALUE, 0},
{":ascent", IMAGE_ASCENT_VALUE, 0},
{":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
@@ -9743,10 +9745,11 @@ static bool
svg_load (struct frame *f, struct image *img)
{
bool success_p = 0;
- Lisp_Object file_name;
+ Lisp_Object file_name, base_uri;
/* If IMG->spec specifies a file name, create a non-file spec from it. */
file_name = image_spec_value (img->spec, QCfile, NULL);
+ base_uri = image_spec_value (img->spec, QCbase_uri, NULL);
if (STRINGP (file_name))
{
int fd;
@@ -9766,15 +9769,16 @@ 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,
- SSDATA (ENCODE_FILE (file)));
+ if (!STRINGP (base_uri))
+ base_uri = ENCODE_FILE (file);
+ success_p = svg_load_image (f, img, contents, size, SSDATA (base_uri));
xfree (contents);
}
/* Else it's not a file, it's a Lisp object. Load the image from a
Lisp object rather than a file. */
else
{
- Lisp_Object data, original_filename;
+ Lisp_Object data;
data = image_spec_value (img->spec, QCdata, NULL);
if (!STRINGP (data))
@@ -9782,10 +9786,10 @@ svg_load (struct frame *f, struct image *img)
image_error ("Invalid image data `%s'", data);
return 0;
}
- original_filename = BVAR (current_buffer, filename);
+ if (!STRINGP (base_uri))
+ base_uri = BVAR (current_buffer, filename);
success_p = svg_load_image (f, img, SSDATA (data), SBYTES (data),
- (NILP (original_filename) ? NULL
- : SSDATA (original_filename)));
+ (NILP (base_uri) ? NULL : SSDATA (base_uri)));
}
return success_p;
@@ -9886,6 +9890,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
FRAME_DISPLAY_INFO (f)->resy);
/* Set base_uri for properly handling referenced images (via 'href').
+ Can be explicitly specified using `:base_uri' image property.
See rsvg bug 596114 - "image refs are relative to curdir, not .svg file"
<https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */
if (filename)
@@ -10058,6 +10063,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
FRAME_DISPLAY_INFO (f)->resy);
/* Set base_uri for properly handling referenced images (via 'href').
+ Can be explicitly specified using `:base_uri' image property.
See rsvg bug 596114 - "image refs are relative to curdir, not .svg file"
<https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */
if (filename)
@@ -10740,6 +10746,7 @@ non-numeric, there is no explicit limit on the size of images. */);
#if defined (HAVE_RSVG)
DEFSYM (Qsvg, "svg");
+ DEFSYM (QCbase_uri, ":base-uri");
add_image_type (Qsvg);
#ifdef HAVE_NTGUI
/* Other libraries used directly by svg code. */