]> git.eshelyaron.com Git - emacs.git/commitdiff
Explicitly specify svg base_uri using `:base-uri' image property
authorZajcev Evgeny <zevlg@yandex.ru>
Thu, 3 Dec 2020 15:37:18 +0000 (18:37 +0300)
committerAlan Third <alan@idiocy.org>
Sat, 12 Dec 2020 12:48:32 +0000 (12:48 +0000)
* src/image.c (svg_load): Check `:base-uri' image property to
explicitly set base_uri for images embedded into SVG
(enum svg_keyword_index):
(svg_format): Add :base-uri.
* lisp/svg.el (svg-embed-base-uri-image): New function to embed images
located relative to images `:base-uri'

doc/lispref/display.texi
etc/NEWS
lisp/svg.el
src/image.c

index b9b05a2a422006d784fa15f81ab607b6c1d5305b..2b3119ea5903c63c0d88dea077804e11f7b05b69 100644 (file)
@@ -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
index 9aa735da7262ba1ca2f318e47b6ea98e23719be1..901a432d99e7e8672c2a8b69cddba1b3e7994f06 100644 (file)
--- 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.
index eeb945f53b54c8cc4d7ac89b936dac80a7ce7eb1..1ca59658aa75a4ae3604f2cab2357c39122b7a12 100644 (file)
@@ -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
index 54380d1cdfa9e98c170d6750e711834ed1d92c3d..6b85ab78f61289ec1edcec34bdd1001fb38db759 100644 (file)
@@ -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.  */