diff options
| author | Zajcev Evgeny | 2020-12-03 18:37:18 +0300 |
|---|---|---|
| committer | Alan Third | 2020-12-12 12:48:32 +0000 |
| commit | f45ce78c40e37bf2aab83d2d1183ed896c5c1c4c (patch) | |
| tree | 489dd8e710e0e5a6eec73b95ace3ad47987c7688 | |
| parent | 8ff70045c371253b3c2c22c4f62bd9f911bccd51 (diff) | |
| download | emacs-f45ce78c40e37bf2aab83d2d1183ed896c5c1c4c.tar.gz emacs-f45ce78c40e37bf2aab83d2d1183ed896c5c1c4c.zip | |
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'
| -rw-r--r-- | doc/lispref/display.texi | 20 | ||||
| -rw-r--r-- | etc/NEWS | 12 | ||||
| -rw-r--r-- | lisp/svg.el | 13 | ||||
| -rw-r--r-- | src/image.c | 21 |
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 | |||
| 5900 | @end lisp | 5900 | @end lisp |
| 5901 | @end defun | 5901 | @end defun |
| 5902 | 5902 | ||
| 5903 | @defun svg-embed-base-uri-image svg relative-filename &rest args | ||
| 5904 | To @var{svg} add an embedded (raster) image placed at | ||
| 5905 | @var{relative-filename}. @var{relative-filename} is searched inside | ||
| 5906 | @code{file-name-directory} of the @code{:base-uri} svg image property. | ||
| 5907 | This improves the performance of embedding large images. | ||
| 5908 | |||
| 5909 | @lisp | ||
| 5910 | ;; Embeding /tmp/subdir/rms.jpg and /tmp/another/rms.jpg | ||
| 5911 | (svg-embed-base-uri-image svg "subdir/rms.jpg" | ||
| 5912 | :width "100px" :height "100px" | ||
| 5913 | :x "50px" :y "75px") | ||
| 5914 | (svg-embed-base-uri-image svg "another/rms.jpg" | ||
| 5915 | :width "100px" :height "100px" | ||
| 5916 | :x "75px" :y "50px") | ||
| 5917 | (svg-image svg :scale 1.0 | ||
| 5918 | :base-uri "/tmp/dummy" | ||
| 5919 | :width 175 :height 175) | ||
| 5920 | @end lisp | ||
| 5921 | @end defun | ||
| 5922 | |||
| 5903 | @defun svg-clip-path svg &rest args | 5923 | @defun svg-clip-path svg &rest args |
| 5904 | Add a clipping path to @var{svg}. If applied to a shape via the | 5924 | Add a clipping path to @var{svg}. If applied to a shape via the |
| 5905 | @var{:clip-path} property, parts of that shape which lie outside of | 5925 | @var{:clip-path} property, parts of that shape which lie outside of |
| @@ -1111,6 +1111,18 @@ If 'shr-width' is non-nil, it overrides this variable. | |||
| 1111 | 1111 | ||
| 1112 | ** Images | 1112 | ** Images |
| 1113 | 1113 | ||
| 1114 | --- | ||
| 1115 | ** Can explicitly specify base_uri for svg images. | ||
| 1116 | ':base-uri' image property can be used to explicitly specify base_uri | ||
| 1117 | for embedded images into svg. ':base-uri' is supported for both file | ||
| 1118 | and data svg images. | ||
| 1119 | |||
| 1120 | +++ | ||
| 1121 | ** 'svg-embed-base-uri-image' added to embed images | ||
| 1122 | 'svg-embed-base-uri-image' can be used to embed images located | ||
| 1123 | relatively to 'file-name-directory' of the ':base-uri' svg image property. | ||
| 1124 | This works much faster then 'svg-embed'. | ||
| 1125 | |||
| 1114 | +++ | 1126 | +++ |
| 1115 | *** New function 'image-cache-size'. | 1127 | *** New function 'image-cache-size'. |
| 1116 | This function returns the size of the current image cache, in bytes. | 1128 | 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 | |||
| 184 | `((xlink:href . ,(svg--image-data image image-type datap)) | 184 | `((xlink:href . ,(svg--image-data image image-type datap)) |
| 185 | ,@(svg--arguments svg args))))) | 185 | ,@(svg--arguments svg args))))) |
| 186 | 186 | ||
| 187 | (defun svg-embed-base-uri-image (svg relative-filename &rest args) | ||
| 188 | "Insert image placed at RELATIVE-FILENAME into the SVG structure. | ||
| 189 | RELATIVE-FILENAME will be searched in `file-name-directory' of the | ||
| 190 | image's `:base-uri' property. If `:base-uri' is not specified for the | ||
| 191 | image, then embedding won't work. Embedding large images using this | ||
| 192 | function is much faster than `svg-embed'." | ||
| 193 | (svg--append | ||
| 194 | svg | ||
| 195 | (dom-node | ||
| 196 | 'image | ||
| 197 | `((xlink:href . ,relative-filename) | ||
| 198 | ,@(svg--arguments svg args))))) | ||
| 199 | |||
| 187 | (defun svg-text (svg text &rest args) | 200 | (defun svg-text (svg text &rest args) |
| 188 | "Add TEXT to SVG." | 201 | "Add TEXT to SVG." |
| 189 | (svg--append | 202 | (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 | |||
| 9492 | SVG_TYPE, | 9492 | SVG_TYPE, |
| 9493 | SVG_DATA, | 9493 | SVG_DATA, |
| 9494 | SVG_FILE, | 9494 | SVG_FILE, |
| 9495 | SVG_BASE_URI, | ||
| 9495 | SVG_ASCENT, | 9496 | SVG_ASCENT, |
| 9496 | SVG_MARGIN, | 9497 | SVG_MARGIN, |
| 9497 | SVG_RELIEF, | 9498 | SVG_RELIEF, |
| @@ -9511,6 +9512,7 @@ static const struct image_keyword svg_format[SVG_LAST] = | |||
| 9511 | {":type", IMAGE_SYMBOL_VALUE, 1}, | 9512 | {":type", IMAGE_SYMBOL_VALUE, 1}, |
| 9512 | {":data", IMAGE_STRING_VALUE, 0}, | 9513 | {":data", IMAGE_STRING_VALUE, 0}, |
| 9513 | {":file", IMAGE_STRING_VALUE, 0}, | 9514 | {":file", IMAGE_STRING_VALUE, 0}, |
| 9515 | {":base-uri", IMAGE_STRING_VALUE, 0}, | ||
| 9514 | {":ascent", IMAGE_ASCENT_VALUE, 0}, | 9516 | {":ascent", IMAGE_ASCENT_VALUE, 0}, |
| 9515 | {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0}, | 9517 | {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0}, |
| 9516 | {":relief", IMAGE_INTEGER_VALUE, 0}, | 9518 | {":relief", IMAGE_INTEGER_VALUE, 0}, |
| @@ -9743,10 +9745,11 @@ static bool | |||
| 9743 | svg_load (struct frame *f, struct image *img) | 9745 | svg_load (struct frame *f, struct image *img) |
| 9744 | { | 9746 | { |
| 9745 | bool success_p = 0; | 9747 | bool success_p = 0; |
| 9746 | Lisp_Object file_name; | 9748 | Lisp_Object file_name, base_uri; |
| 9747 | 9749 | ||
| 9748 | /* If IMG->spec specifies a file name, create a non-file spec from it. */ | 9750 | /* If IMG->spec specifies a file name, create a non-file spec from it. */ |
| 9749 | file_name = image_spec_value (img->spec, QCfile, NULL); | 9751 | file_name = image_spec_value (img->spec, QCfile, NULL); |
| 9752 | base_uri = image_spec_value (img->spec, QCbase_uri, NULL); | ||
| 9750 | if (STRINGP (file_name)) | 9753 | if (STRINGP (file_name)) |
| 9751 | { | 9754 | { |
| 9752 | int fd; | 9755 | int fd; |
| @@ -9766,15 +9769,16 @@ svg_load (struct frame *f, struct image *img) | |||
| 9766 | return 0; | 9769 | return 0; |
| 9767 | } | 9770 | } |
| 9768 | /* If the file was slurped into memory properly, parse it. */ | 9771 | /* If the file was slurped into memory properly, parse it. */ |
| 9769 | success_p = svg_load_image (f, img, contents, size, | 9772 | if (!STRINGP (base_uri)) |
| 9770 | SSDATA (ENCODE_FILE (file))); | 9773 | base_uri = ENCODE_FILE (file); |
| 9774 | success_p = svg_load_image (f, img, contents, size, SSDATA (base_uri)); | ||
| 9771 | xfree (contents); | 9775 | xfree (contents); |
| 9772 | } | 9776 | } |
| 9773 | /* Else it's not a file, it's a Lisp object. Load the image from a | 9777 | /* Else it's not a file, it's a Lisp object. Load the image from a |
| 9774 | Lisp object rather than a file. */ | 9778 | Lisp object rather than a file. */ |
| 9775 | else | 9779 | else |
| 9776 | { | 9780 | { |
| 9777 | Lisp_Object data, original_filename; | 9781 | Lisp_Object data; |
| 9778 | 9782 | ||
| 9779 | data = image_spec_value (img->spec, QCdata, NULL); | 9783 | data = image_spec_value (img->spec, QCdata, NULL); |
| 9780 | if (!STRINGP (data)) | 9784 | if (!STRINGP (data)) |
| @@ -9782,10 +9786,10 @@ svg_load (struct frame *f, struct image *img) | |||
| 9782 | image_error ("Invalid image data `%s'", data); | 9786 | image_error ("Invalid image data `%s'", data); |
| 9783 | return 0; | 9787 | return 0; |
| 9784 | } | 9788 | } |
| 9785 | original_filename = BVAR (current_buffer, filename); | 9789 | if (!STRINGP (base_uri)) |
| 9790 | base_uri = BVAR (current_buffer, filename); | ||
| 9786 | success_p = svg_load_image (f, img, SSDATA (data), SBYTES (data), | 9791 | success_p = svg_load_image (f, img, SSDATA (data), SBYTES (data), |
| 9787 | (NILP (original_filename) ? NULL | 9792 | (NILP (base_uri) ? NULL : SSDATA (base_uri))); |
| 9788 | : SSDATA (original_filename))); | ||
| 9789 | } | 9793 | } |
| 9790 | 9794 | ||
| 9791 | return success_p; | 9795 | return success_p; |
| @@ -9886,6 +9890,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents, | |||
| 9886 | FRAME_DISPLAY_INFO (f)->resy); | 9890 | FRAME_DISPLAY_INFO (f)->resy); |
| 9887 | 9891 | ||
| 9888 | /* Set base_uri for properly handling referenced images (via 'href'). | 9892 | /* Set base_uri for properly handling referenced images (via 'href'). |
| 9893 | Can be explicitly specified using `:base_uri' image property. | ||
| 9889 | See rsvg bug 596114 - "image refs are relative to curdir, not .svg file" | 9894 | See rsvg bug 596114 - "image refs are relative to curdir, not .svg file" |
| 9890 | <https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */ | 9895 | <https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */ |
| 9891 | if (filename) | 9896 | if (filename) |
| @@ -10058,6 +10063,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents, | |||
| 10058 | FRAME_DISPLAY_INFO (f)->resy); | 10063 | FRAME_DISPLAY_INFO (f)->resy); |
| 10059 | 10064 | ||
| 10060 | /* Set base_uri for properly handling referenced images (via 'href'). | 10065 | /* Set base_uri for properly handling referenced images (via 'href'). |
| 10066 | Can be explicitly specified using `:base_uri' image property. | ||
| 10061 | See rsvg bug 596114 - "image refs are relative to curdir, not .svg file" | 10067 | See rsvg bug 596114 - "image refs are relative to curdir, not .svg file" |
| 10062 | <https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */ | 10068 | <https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */ |
| 10063 | if (filename) | 10069 | if (filename) |
| @@ -10740,6 +10746,7 @@ non-numeric, there is no explicit limit on the size of images. */); | |||
| 10740 | 10746 | ||
| 10741 | #if defined (HAVE_RSVG) | 10747 | #if defined (HAVE_RSVG) |
| 10742 | DEFSYM (Qsvg, "svg"); | 10748 | DEFSYM (Qsvg, "svg"); |
| 10749 | DEFSYM (QCbase_uri, ":base-uri"); | ||
| 10743 | add_image_type (Qsvg); | 10750 | add_image_type (Qsvg); |
| 10744 | #ifdef HAVE_NTGUI | 10751 | #ifdef HAVE_NTGUI |
| 10745 | /* Other libraries used directly by svg code. */ | 10752 | /* Other libraries used directly by svg code. */ |