Skip to content

Render SVG files at output resolution#79

Open
mstoeckl wants to merge 1 commit intoswaywm:masterfrom
mstoeckl:svg-direct
Open

Render SVG files at output resolution#79
mstoeckl wants to merge 1 commit intoswaywm:masterfrom
mstoeckl:svg-direct

Conversation

@mstoeckl
Copy link
Collaborator

@mstoeckl mstoeckl commented Oct 26, 2024

This PR would close #60 .

  • This adds an additional dependency, which recursively links a few more libraries; this increases startup time by about 10ms for me.
  • librsvg is LGPL, like libgdk-pixbuf
  • This opens the SVG file with rsvg_handle_new_from_stream_sync instead of rsvg_handle_new_from_file, to match the current and historical behavior of gdk-pixbuf in which linked images are not recursively loaded (see https://gnome.pages.gitlab.gnome.org/librsvg/Rsvg-2.0/class.Handle.html#security-and-locations-of-referenced-files ; SVGs can continue to embed other image types via data-URI, and librsvg blocks web resources entirely.)
  • This also fixed rendering of SVG files with width="100%" height="100%" viewport -- gdk-pixbuf loaded them at 1x1 size.

It is possible to render SVG files at higher resolution using just GdkPixbuf, but doing so is somewhat complicated, and appears to always preserve aspect ratio so that scaling/cropping afterwards is still necessary. See branch https://github.com/mstoeckl/swaybg/tree/pixbuf-scale for an example.

Edit: it looks like librsvg's headers produce a compilation error; this is probably something they should fix and that this should be considered blocked on? (filed as https://gitlab.gnome.org/GNOME/librsvg/-/issues/1136; edit: resolved, should appear in next release; edit2: 2.60 has been released with the fix.)

This adds an optional dependency on librsvg to directly render the
SVG images, instead of using gdk-pixbuf to draw them to an
intermediate image.
@emersion
Copy link
Member

Glycin supports SVG, do you know if it would be possible/reasonable to rely on glycin to render SVG images instead of having a separate codepath?

@mstoeckl
Copy link
Collaborator Author

mstoeckl commented Nov 22, 2025

Glycin supports SVG, do you know if it would be possible/reasonable to rely on glycin to render SVG images instead of having a separate codepath?

This can be done, since Glycin can perform SVG image scaling similarly to gdk-pixbuf. (Using gly_image_get_width()/height() to estimate the base size, and gly_frame_request_set_scale() + gly_image_get_specific_frame() to have glycin render the image at a target size.)

I've implemented a test branch doing this at https://github.com/mstoeckl/swaybg/commits/glycin-svg/ . The main limitations are:

  • Rendering the entire SVG image, instead of just the amount that it clipped to the display, can can lead to significant overdraw and memory use in fill mode if the SVG aspect ratio is very different from the display aspect ratio, or in center and tile modes if the SVG image has very large intrinsic size.
  • gly_image_get_width()/height() do not model "unsized" SVG files (with a header like <svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">) which have no intrinsic aspect ratio. (But such images appear to be quite rare.)

In practice, for wallpaper style images, I expect neither of these to be a significant issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Render SVG files at output resolution

2 participants