emacs-devel
[Top][All Lists]
Advanced

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

Re: Loading svg from memory using custom filename for base_uri


From: Evgeny Zajcev
Subject: Re: Loading svg from memory using custom filename for base_uri
Date: Thu, 3 Dec 2020 18:47:37 +0300



пн, 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="" 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: 0001-Explicitly-specify-svg-base_uri-using-base-uri-image.patch
Description: Text Data


reply via email to

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