> 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?