SVG path parsing bug fixes

Did some heavy SVG parsing during the last week. Found a couple of bugs in the juce SVG parser method parsePathString().

  • Fix 1: Many SVGs seems to implicitly expect a path close when the next path command is an ‘M’ or ‘m’.

  • Fix 2: The ‘S’ and ‘s’ command has a special case according the SVG spec: “(If there is no previous command or if the previous command was not an C, c, S or s, assume the first control point is coincident with the current point.)”. This was not correctly implemented in the parser.

  • Fix 3: The ‘T’ and ‘t’ command suffered from the same error as an fix 2.

  • Fix 4: Many times there is no explicit close of the sub path if it is the last thing. Making the path.closeSubPath() statement unconditional in the parser seemed to fix the last issue I could see.

After having parsed 10’s of thousands of SVGs from the web, the parser seems to work really well now.

edit: Here is a good site with SVGs that I tested: https://icongr.am/

6 Likes

Bump!

Any devs want to consider merging this fix to develop branch?

1 Like

the usual route is to submit a Pull Request if you want anyone from the JUCE team to look at your solution in depth.

How are you verifying what the correct behaviour is?

Applying “fixes” 1 and 4 would mean that we render things differently to Chrome. This simple example would have extra lines which the browser doesn’t display.

<svg xmlns="http://www.w3.org/2000/svg">
    <path d="M 10 10 h 80 v 80 h -80 M 100 100 h 80 v 80 h -80" fill="yellow" stroke="red"/>
</svg>

Fixes 2 and 3 are definitely bugs in JUCE’s parser. Thank you for reporting!

Funny you mentioned how I verified my 4 fixes… I actually loaded an rendered all of the thousands of svgs found on https://icongr.am/
I compared with how chrome rendered them and the only way they all look like how chrome does it is with my 4 “fixes”. I am currently on vacation and cannot point out the exact ones that cause troubles right now. Happy to show you in a couple of weeks. Anyway thanks for what you pushed so far!