all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
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


  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.