[cairo] [PATCH] Enable links to image files in SVG backend

Alexander Shulgin alex.shulgin at gmail.com
Thu Dec 24 04:19:46 PST 2009


Hi,

Attached is a patch against git/master to enable SVG backend to put
hrefs to image files on disk instead of base64-encoded image data in
the SVG output.

I'm scratching my personal itch here as I writing a simple Ruby
program to generate nice calendars.  I've used rcairo and pango and
everything worked well except for putting photographic images into SVG
files.  Here comes inevitable rant... ;)

1. I have to convert[1] images from JPEG to PNG beforehand (a bit slow)
2. Then load them with rcairo (slow)
3. And render on SVG surface (even slower)
4. And then I get the output file of ridiculous 10-15 megs in size
5. Which can be finally loaded with Inkscape (really slow again) to
fine-tune it.

Now, with the patch, everything is blazing-fast (except for Inkscape,
heh) and average SVG file size is much more reasonable (about
50-100kb).

The idea behind the change is really simple: client code loads the
image using some third-party library (in my case it's enough to know
just the image dimensions, since pixels are not touched), then it sets
origin filename using new API
cairo_image_surface_set_origin_filename() and tweaks SVG surface to
use this information when producing the output file using yet again
new API cairo_svg_surface_set_links_image_files_enabled().

Now when SVG backend is about to emit image tag it will check to see
if the image have origin filename associated with it and it is not
tainted (no drawing occurred on the surface): if so, it must be safe
to put a mere link to the file instead of inline-encoding it.

A few notes on the logic of the patch:

1. I've tried to make it as simple as possible, so there's no checks
when setting filename for a tainted surface, or surface which already
have this information set.

2. I've had to override all drawing primitives for cairo_image_surface
backend to inject calls to cairo_image_surface_taint(), but except for
show_text_glyphs, as it currently works through show_glyphs (already
overridden).

3. I've had to put _cairo_surface_fallback_paint() et al prototypes
into cairoint.h so they can be used from my
_cairo_image_surface_paint() overrides.  Don't know if this is a
"No-No"; it can be dropped in favor of returning
CAIRO_INT_STATUS_UNSUPPORTED though.

4. Nothing is changed from client perspective is he's not calling
cairo_svg_surface_set_links_image_files_enabled().

And last, but not the least, thanks for such a great library--I'm
really enjoying using it!

--
Regards,
Alex

[1] Again, I'm doing my stuff in Ruby, and I found no way to obtain
necessary image data from JPEG file to feed to
cairo_image_surface_create_for_data().  Using gdk-pixbuf is of no help
as it gives BGR instead of RGB expected by cairo (or vice-versa).

I'd also would like to see something like
cairo_placeholder_surface_create(width, height) which will create a
surface with no image data associated--I don't need it to render to
SVG with links to file.  Currently I'm forced to use
cairo_image_surface_create() which still allocates height*stride
bytes.  No problem for a desktop, but can hurt some server's memory
footprint.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: svg-enable-image-links-to-origin-file-v1.patch
Type: text/x-patch
Size: 17960 bytes
Desc: not available
Url : http://lists.cairographics.org/archives/cairo/attachments/20091224/080a6ea7/attachment.bin 


More information about the cairo mailing list