emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master f45ce78 2/2: Explicitly specify svg base_uri using `:base-uri' im


From: Alan Third
Subject: master f45ce78 2/2: Explicitly specify svg base_uri using `:base-uri' image property
Date: Sat, 12 Dec 2020 07:48:47 -0500 (EST)

branch: master
commit f45ce78c40e37bf2aab83d2d1183ed896c5c1c4c
Author: Zajcev Evgeny <zevlg@yandex.ru>
Commit: Alan Third <alan@idiocy.org>

    Explicitly specify svg base_uri using `:base-uri' image property
    
    * 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 | 20 ++++++++++++++++++++
 etc/NEWS                 | 12 ++++++++++++
 lisp/svg.el              | 13 +++++++++++++
 src/image.c              | 21 ++++++++++++++-------
 4 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index b9b05a2..2b3119e 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 9aa735d..901a432 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 eeb945f..1ca5965 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 54380d1..6b85ab7 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.  */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]