From: Evgeny Zajcev <lg.zevlg@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: emacs-devel <emacs-devel@gnu.org>
Subject: Re: Loading svg from memory using custom filename for base_uri
Date: Thu, 3 Dec 2020 18:47:37 +0300 [thread overview]
Message-ID: <CAO=W_ZrMTRDeb8xPF3Hf1VPc3Nv4c0zntnGwFB0O=tBO7-B39g@mail.gmail.com> (raw)
In-Reply-To: <CAO=W_Zr8PzZpn60fVVXFCaQJMOAuSLq=mumD_0AOsvYEhS4nFw@mail.gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 4277 bytes --]
пн, 25 февр. 2019 г. в 13:23, Evgeny Zajcev <lg.zevlg@gmail.com>:
>
>
> сб, 23 февр. 2019 г. в 10:45, Eli Zaretskii <eliz@gnu.org>:
>
>> > From: Evgeny Zajcev <lg.zevlg@gmail.com>
>> > Date: Sat, 23 Feb 2019 01:01:02 +0300
>> >
>> > Currently, when SVG image is loaded with `svg_load` it first examines
>> :file value and only if :file is missing it
>> > looks for :data, using current buffer's filename (if any) as base_uri
>> >
>> > Would not it be better to check for :data first and if present, then
>> use :file as value for base_uri? Falling back
>> > to current buffer filename in case :file is missing
>> >
>> > Unfortunately embedding raster images into svg with base64 encoding,
>> using `svg-embed` is slow.
>>
>> I don't think I understand what you are saying here. The test whether
>> an image spec specifies a file or not is just 2 lines of C:
>>
>>
> Ah, sorry, let me explain in more details. SVG has ability embedding
> raster images using "image" node with "xlink:href" attribute pointing to
> the filename to embed. rsvg library disallows absolute path names in
> "xlin:href" due to security reasons. To refer the filename with rsvg you
> need to setup base_filename (aka base_uri) and then point to the file
> relatively to this base_filename. If you load .svg from filename, then
> this filename is used as base_filename, but if you load SVG from memory you
> need to specify base_uri explicitly.
>
> `svg-embed` from svg.el does not bother with base_uri stuff and just
> embeds raster images using base64 trick: it reads content of the file,
> encode it with base64 and inserts encoded data into "image" node. This is
> relative slow thing to do.
>
> To suppress this base64 trick, I want "xlink:href" to point directly to
> filename, so I need some way to explicitly specify base_uri for rsvg to
> use. svg_load() from "image.c" uses `:file` as base_uri if loading from
> filename, and current buffer's filename if loading from memory via `:data`.
>
> I want to load svg `:data` from memory and specify base_uri, using image's
> `:file` attribute. This is not possible right now because `:file`
> attribute is examined first in svg_load() function
>
>
> /* If IMG->spec specifies a file name, create a non-file spec from it.
>> */
>> file_name = image_spec_value (img->spec, QCfile, NULL);
>> if (STRINGP (file_name))
>> {
>> [load an image from file...]
>> }
>> /* Else its not a file, it's a lisp object. Load the image from a
>> lisp object rather than a file. */
>> else
>> {
>> [load an image from data...]
>> }
>>
>> And image_spec_value just walks a Lisp list looking for ':file':
>>
>> static Lisp_Object
>> image_spec_value (Lisp_Object spec, Lisp_Object key, bool *found)
>> {
>> Lisp_Object tail;
>>
>> eassert (valid_image_p (spec));
>>
>> for (tail = XCDR (spec);
>> CONSP (tail) && CONSP (XCDR (tail));
>> tail = XCDR (XCDR (tail)))
>> {
>> if (EQ (XCAR (tail), key))
>> {
>> if (found)
>> *found = 1;
>> return XCAR (XCDR (tail));
>> }
>> }
>>
>> So I don't see how reversing the order would speed up SVG loading.
>> What did I miss?
>>
>
`:file' property is hardly could be used for this, because it is used in
many different places beside svg, so I come up with next solution,
introducing `:base-uri' image property to explicitly set base_uri for
embedding images into svg
To test this feature, copy any .jpg image to /tmp/soviet.jpg and eval in
scratch
(insert-image '(image :type svg :data "<svg width=\"100\" height=\"100\"
version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"
http://www.w3.org/1999/xlink\"> <image xlink:href=\"soviet.jpg\"
height=\"40\" width=\"40\" y=\"10\" x=\"10\"></image></svg>" :scale 1.0
:base-uri "/tmp/soviet.jpg" :width 100 :height 100 :ascent center))
svg with embedded image should be inserted.
To check where or not Emacs supports this feature use:
(obarray-get c-keywords-obarray :base-uri)
This could be used to fallback to base64 encoding trick in older Emacs
Thanks
--
lg
[-- Attachment #1.2: Type: text/html, Size: 5735 bytes --]
[-- Attachment #2: 0001-Explicitly-specify-svg-base_uri-using-base-uri-image.patch --]
[-- Type: text/x-patch, Size: 1936 bytes --]
From 9a5ef4707502ed37c2bef677482c27db1dca78b6 Mon Sep 17 00:00:00 2001
From: Zajcev Evgeny <zevlg@yandex.ru>
Date: Thu, 3 Dec 2020 18:37:18 +0300
Subject: [PATCH] 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
---
src/image.c | 5 ++++-
src/xdisp.c | 1 +
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/image.c b/src/image.c
index 5eb4132295..fa818d5446 100644
--- a/src/image.c
+++ b/src/image.c
@@ -9737,7 +9737,9 @@ svg_load (struct frame *f, struct image *img)
image_error ("Invalid image data `%s'", data);
return 0;
}
- original_filename = BVAR (current_buffer, filename);
+ original_filename = image_spec_value (img->spec, QCbase_uri, NULL);
+ if (!STRINGP (original_filename))
+ original_filename = BVAR (current_buffer, filename);
success_p = svg_load_image (f, img, SSDATA (data), SBYTES (data),
(NILP (original_filename) ? NULL
: SSDATA (original_filename)));
@@ -10002,6 +10004,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
eassume (rsvg_handle);
/* 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)
diff --git a/src/xdisp.c b/src/xdisp.c
index 76ef420a36..51735b269d 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -34631,6 +34631,7 @@ syms_of_xdisp (void)
DEFSYM (QCeval, ":eval");
DEFSYM (QCpropertize, ":propertize");
DEFSYM (QCfile, ":file");
+ DEFSYM (QCbase_uri, ":base-uri");
DEFSYM (Qfontified, "fontified");
DEFSYM (Qfontification_functions, "fontification-functions");
--
2.25.1
next prev parent reply other threads:[~2020-12-03 15:47 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-22 22:01 Loading svg from memory using custom filename for base_uri Evgeny Zajcev
2019-02-23 7:45 ` Eli Zaretskii
2019-02-25 10:23 ` Evgeny Zajcev
2020-12-03 15:47 ` Evgeny Zajcev [this message]
2020-12-03 16:16 ` Alan Third
2020-12-03 16:25 ` lg.zevlg
2020-12-03 16:30 ` Alan Third
2020-12-03 16:54 ` Evgeny Zajcev
2020-12-03 17:50 ` Evgeny Zajcev
2020-12-03 19:57 ` Alan Third
2020-12-03 22:11 ` Evgeny Zajcev
2020-12-03 23:02 ` Evgeny Zajcev
2020-12-12 5:46 ` lg.zevlg
2020-12-12 10:45 ` Alan Third
2020-12-12 11:52 ` Evgeny Zajcev
2020-12-12 12:50 ` Alan Third
2020-12-03 16:56 ` Vasilij Schneidermann
2020-12-03 16:50 ` Vasilij Schneidermann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAO=W_ZrMTRDeb8xPF3Hf1VPc3Nv4c0zntnGwFB0O=tBO7-B39g@mail.gmail.com' \
--to=lg.zevlg@gmail.com \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.