Add SVG support for custom button icons
Support for using SVGs as custom icons in the buttons toolbar has been requested a couple of times.
https://github.com/sammycage/lunasvg is one library that could be used for this. (The compiled size of any such library is also a consideration, as it will add to the component download size.)
Personally, I think it is acceptable.
That lib adds around 200KB to the overall component size. I'm using it for my JScript Panel component...
https://marc2k3.github.io/jscript-panel/docs/namespaces/utils/#utilsloadsvgpath_or_xml-max_width
I had a look at lunasvg and resvg a couple of months ago.
The first thing to note with lunasvg is that its SVG support is pretty limited (less than 25% of the resvg test suite according to the README for resvg). But the more notable problem with both was that there were aliasing artefacts that weren't in the PNGs I rendered using Inkscape.
The other library I've seen (which I haven't tried yet) is librsvg. I'm guessing it'll give similar quality to Inkscape since they both use Cairo. But its SVG support is more limited than resvg.
Both resvg and librsvg are large libraries as well (taking into account dependencies). resvg also currently can't be installed using vcpkg.
What I probably need to do next is investigate whether doing something like rendering at a higher resolution, and then resampling the rendered image, gets rid of the artefacts.
Apart from that, I see three options:
- Use lunasvg directly in Columns UI.
- Create a separate component (using either resvg or librsvg) which has a small API for rendering SVGs (which CUI can use).
- Use the Inkscape CLI to render the SVGs instead of a library.
At this point, I'm leaning towards 2., because if SVG support is going to be added, it may as well be done properly.
I was far too lazy to investigate very deeply. As a noob, it was easy for me to implement and I thought it was "good enough".
As per the TODO section on the project homepage, I was aware of the lack of TEXT support meaning it can't render SVGs such as your album art placeholder here...
https://github.com/reupen/columns_ui/blob/master/foo_ui_columns/assets/source/dark-placeholder-artwork.svg
but it rendered your buttons OK and I thought nothing of it since!
Yes, font and text support is a good point. Luckily resvg does support those.
It was specifically the default buttons I was looking at 🙂
Here's a comparison between Inkscape (top) and resvg (bottom):

You can hopefully see the circle for resvg is less smooth.
Here's the same comparison, but this time resvg rendered at 300% of the target size, and then resized afterwards:

They are very similar in this case, so I'm happy with that – and rendering at 300% should be fine as button images are generally small anyway.
As it turns out, the default rendering of resvg is actually fine. I didn't notice it was using pre-multiplied alpha, and so the alpha rendering was incorrect.