Weird SVG renders

Hey all, I hired a designer to help with the GUI and we’re getting really weird behavior when he exports to SVG. Here is an asset as it looks when opened in Inkscape:


And here is what it looks like as rendered by JUCE:


This is so wacky that I am inclined to believe that I am doing something wrong. But for other assets it works out just fine. I am simply loading the .svg with juce::Drawable::createFromSVGFile(juce::File(path_to_svg)) and then calling addAndMakeVisible and setBounds where appropriate.

It looks the same when loaded in the Projucer.

Any ideas what could be causing this behavior?

The short answer is that JUCE’s SVG support is quite limited.

Usually the best thing to do is to ensure you convert everything to curves and expand all strokes. Meaning that you should end up with a bunch of simple paths that will only be filled and not stroked.

Gradients, shadows, glow effects, etc. aren’t supported so you’ll either have to use bitmap images for those parts, or adjust your design accordingly.


Thanks for the direct answer. I wonder what it would take to fix this issue. What part of the SVG support is limited? Is it the parsing or the rendering? Would something like this this be of any use?

It seems like it shouldn’t be tons of trouble to dig into the JUCE code a little bit and address these shortcomings in a new git branch. Parse, render, wrap into JUCE classes. Simple, right? What am I missing?

SVG is surprisingly rich, and apparently it’s even Turing complete. Different browsers and programs also render SVG files differently, and without looking deeply into it my guess would be that the library which you linked to also supports SVG on face value just like JUCE does but when really you dig into it some things might be lacking (but am also willing to be pleasantly surprised if it turns out that it supports and render everything correctly).

Other than trying to minimize the examples until you find the root cause of what’s missing in JUCE and try to fix it, report it, or work around it (i.e for example by telling the graphic designer to try to avoid blurs), I can also suggest giving this tool svg-simplify a shot - I made it for exactly the same use case (SVG files which JUCE didn’t support). And also if there’s something simple it can do for you and doesn’t feel free to request in the issues.

1 Like

Thank you, this looks like it could be useful. If it can make my SVGs JUCE-compatible without degrading the image, then it seems like a good option.

But for unsupported things like gradients, shadows, and glow I assume your tool simply strips those things out? If so, I’m not sure I’d want to compromise.

Right now I’m looking at juce_SVGParser.cpp and wondering how much extra effort it would take to write new functions that handle what is currently missing.

In our experience, simple gradients work just fine. We use SVGs for our expansion icons, which all feature a gradient. What doesn’t work are masks, shadows, and blurs.

Maybe that green circle around the knob uses a mask, and then the whole rendering falls apart? At first glance, it looks simple enough that JUCE should handle it easily.

1 Like

Looking in the file… there is a radial gradient and Gaussian blur. No mask.

I found a fix! Figma exports are simpler than the original Adobe exports, not nested, just a list of paths, and with the new representation the JUCE SVG parser did a much better job.

To deal with SVG effects the plan is to convert the affected element to juce::Image and apply ImageEffectFilter to it, then layer it back in.

JUCE does support gradients.
An example for something JUCE doesn’t support is gradient masks, which this tool can sometimes turn into fills of gradients with alpha channels. As for shadows and glow I hadn’t come across SVGs with those yet in our designs.

1 Like

Only basic gradients though - e.g. these sorts of radial gradients aren’t supported:

      <radialGradient id="GradientPad"
            cx="0.5" cy="0.5" r="0.4" fx="0.75" fy="0.75"
        <stop offset="0%" stop-color="red"/>
        <stop offset="100%" stop-color="blue"/>
1 Like