пн, 25 февр. 2019 г. в 13:23, Evgeny Zajcev : > > > сб, 23 февр. 2019 г. в 10:45, Eli Zaretskii : > >> > From: Evgeny Zajcev >> > 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 " " :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