Evgeniy Raizner announced the first public release of libresvg. This new SVG rendering library aims to replace librsvg and QtSvg, as well as become alternative for using Inkscape as an SVG to PNG converter.

In the community, Evgeniy is mostly known for SVG Cleaner, a very useful tool for making SVG files a lot smaller by removing all the cruft such as unused and invisible elements. He started libresvg about a year ago and has been working on the first release ever since. Today, libresvg v0.1 supports a subset of SVG Full 1.1 without a number of elements (more on that later).

The reason why libresvg exists is that Evgeniy is quite unhappy with existing options such as librsvg (further as rsvg) and QtSvg (SVG Cleaner has a Qt GUI). He claims that the former has serious architectural issues, plethora of parser bugs, and is difficult to ship on platforms other than Linux (being hardwired to Cairo and glib).

At the same time, QtSvg has a rather incomplete support for SVG elements.

Design specifics

While libresvg is written in Rust, and librsvg is being ported to Rust as well, there are some technical differences between the two that Evgeniy outlined in both his original post at linux.org.ru and a private email exchange. They mostly boil down to how he tries to avoid things he sees as architectural imperfections of rsvg.

First of all, libresvg is designed differently. It parses an SVG document into DOM, does some preprocessing such as cruft removal and markup normalization, then constructs a simplified DOM that contains commands for the rendering backend. Parsing and other steps are done with his own toolchain (xmlparser, svgparser, svgdom) compiled into a single binary file that is a command-line converter.

With libresvg, preprocessing only happens once (Evgeniy claims that it doesn’t seem to be the case for rsvg when rendering to canvas), then 99% of the rendering time is spent on the Cairo/Qt side. Which also means smaller CPU footprint for the library.

So yes, there’s that too: libresvg supports multiple drawing backends. Qt and Cairo are already done, Skia is on the roadmap.

How much of SVG is supported

As of v0.1, libresvg surpasses QtSvg in terms of SVG compliance, but needs to gain support for more SVG elements to be on par with rsvg. The support for animations, scripting, and SVG fonts is not planned.

When compared to rsvg, this is what libresvg v0.1 looks like:

Libresvg doesn’t yet support filters, clipping paths, masks, markers, and patterns (which rsvg does support to an extent).

Libresvg has a complete support for gradient fills, while rsvg cannot inherit attributes and validate them, nor can it read single-stop gradients (swatches, typical for SVG documents produced with Inkscape).

Libresvg has better support for text rendering: librsvg doesn’t read xml:space and text-decoration, it also doesn’t always render multiline text correctly and doesn’t support tspan very well.

Libresvg has better, though still incomplete support for CSS 2.

Evgeniy is currently hesitant to start working on SVG 2 support as the spec isn’t completed yet, nor has there been decision on what new features will make it to the W3C recommendation.

Further work

One last important thing is that support for sprites is currently planned for v0.2. So if you expected to start using libresvg instead of Inkscape to convert master SVG documents (e.g. all icons in a single SVG file) to multiple PNG files, you’ll have to wait a bit. The developer will have to implement transferring element IDs from the original document to simplified DOM first.

Evgeniy doesn’t yet use his new library in SVG Cleaner, but that’s temporarily. He says he might return to this after releasing libresvg v0.3.

Source code of libresvg and the involved toolchain is available on GitHub. At some point in the future, the project will probably be renamed for fairly obvious reasons. Evgeniy accepts ideas on that.