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: Mon, 25 Feb 2019 13:23:56 +0300



сб, 23 февр. 2019 г. в 10:45, Eli Zaretskii <address@hidden>:
> From: Evgeny Zajcev <address@hidden>
> 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?


--
lg

reply via email to

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