SVG to juce draw commands

I know it's kinda strange request, but anybody has a SVG to juce C++ converter utility (or done something similar) ? Something that converts a simple SVG to juce Path and Graphics drawing code...

I know i can look at the Drawable code to take inspiration but this would definately save me some time...

Any suggestion is really appreciated :)

1 Like

Have you seen the SVG path helper in the tools menu of the Introjucer? Does this solve your problem?

Like paintcode on osx :)

exactly... only for juce :)

well, yes and no. it doesn't generate the single path generation commands but it convert the path to a binary string:


static const unsigned char pathData[] = { 110,109,102,102,62,65,102,102,190,64,98,102,102,62,65,119,190,19,65,119,190,19,65,102,102,62,65,102,102,190,64,102,102,62,65,98,190,159,42,64,102,102,62,65,0,0,0,0,119,190,19,65,0,0,0,0,102,102,190,64,98,0,0,0,0,190,159,42,64,190,159,42,64,0,0,0,0,102,
102,190,64,0,0,0,0,98,119,190,19,65,0,0,0,0,102,102,62,65,190,159,42,64,102,102,62,65,102,102,190,64,99,101,0,0 };

Path path;
path.loadPathFromData (pathData, sizeof (pathData));

This isn't exaclty what i'm looking for...

Also, it doesn't take AffineTransform and fill/stroke with Colour and Gradient classes (which is the tricky part).

It'd be a fun project, though TBH not sure how much sense it would make - I don't think that generated code would be significantly faster than just loading SVG as a Drawable and drawing it.

it's not about drawing speed, it's about speed of reusing svg controls created by graphic artists and tweak them in code based on the state (for example change a single path stroke color without having to mess with another svg, import it and so on).

If you want to change part of an svg on the fly that's the only way, convert it to juce draw calls. Sure i can make the graphic designer use the Introjucer to draw but that's far from optimal (and the designer is going to insult me a lot of times when he discover there is no path::union or path::intersection features in Introjucer, just to name a few)...

 

That would be a very good idea

One possible way to generalise this is to make a flattening LowLevelGraphicsContext that simply records and prints all of the draw commands that it gets. This way you can convert not just SVG but any JUCE drawing code to “flattened” JUCE drawing code.

3 Likes

If someone don’t know what to do with his free time :stuck_out_tongue:

I wrote such converter for SVG files. It takes SVG’s and converts them into JUCE paths with additional info about colours, and stores everything in ValueTrees. Exactly for the reasons described above, but also to convert texts to curves without using external software and to avoid all ugly font related problems. Loading such files is faster than reading equivalent SVG’s.

I’ve also found that loading SVGs to juce::ValueTree makes it super easy to parameterise things like colours.

You can also then use juce::Value/juce::CachedValue to make it super convenient to change colours by simply assigning a juce::Colour to those values.

2 Likes

Yeah, exactly! I think that apart from all audio capabilities, ValueTree is one of the best features in the whole framework.

2 Likes

If you’re embedding a lot of SVGs (or other XML data), it can be useful to convert them to a binary format using juce::ValueTree::writeToStream() to reduce the binary size, which also has the added bonus of obfuscating them so they’re less discoverable when bundled in your app.

What may seem strange, reading ValueTree from this binary format is slower than from the text format. I have to handle thousands of SVG’s, so I pack everything to a very big file with additional compression and encryption (if needed). It is not read fully at once, rather mapped to memory and there is a navigator class to read parts on demand (something like BinaryData). This has an advantage on mobile platforms when there is a limit of how many file handles can be opened at the same time.

1 Like