Chlumsky / msdfgen

Multi-channel signed distance field generator
MIT License
3.97k stars 412 forks source link

Support for basic SVG shapes #99

Closed grapefrukt closed 4 years ago

grapefrukt commented 4 years ago

Hello,

I've been using this tool to make SDF's for my games for a while, and a thing that I keep stumbling over is that Illustrator (which I typically use to make vector stuff) really likes to make SVG that looks like this:

<?xml version="1.0" encoding="utf-8"?>
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="64px"
     height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
<circle cx="32" cy="32" r="31"/>
</svg>

This is functionally identical to this:

<?xml version="1.0" encoding="UTF-8"?>
<svg width="64px" height="64px" enable-background="new 0 0 64 64" version="1.0" viewBox="0 0 64 64" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<path d="m32 1a31 31 0 0 0-31 31 31 31 0 0 0 31 31 31 31 0 0 0 31-31 31 31 0 0 0-31-31z"/>
</svg>

Which makes sense for compactness and overall readability, but your svg parser doesn't like this at all. Typically I go in and poke a vertex to make it not quite a circle, or open it in InkScape and hope for the best.

Either way, this seems like a thing that would greatly improve compatibility with SVGs across the board.

I went looking at the SVG specs and they do in fact define "equivalent paths" for the rect,
circle, ellipse, line, polyline, and polygon elements. I suppose this means it would be possible to essentially pre-process the shapes before sending them off to be parsed?

It also seems this has been done before: https://github.com/JFXtras/jfxtras-labs/blob/2.2/src/main/java/jfxtras/labs/util/ShapeConverter.java https://github.com/svg/svgo/blob/master/plugins/convertShapeToPath.js

I may take a crack at implementing this myself, but I'm not to be trusted around c++ ;)

Chlumsky commented 4 years ago

The purpose of this software is only to convert properly formed shapes represented by closed paths into various types of distance fields. Comprehensive decoding of SVG and other vector formats is out of its scope. The SVG parser is only very rudimentary and has only been added to simplify testing with inputs made in an editor. I admit that I probably should have stressed this more in the documentation, and looking back, I now think that including SVG and font loading in the base library was a mistake, since 90% of the reported problems stem from that.

In conclusion, anyone is welcome to make a separate project that takes care of loading SVG's perfectly or maybe even Adobe Illustrator files directly, generating proper non-intersecting shape geometry, and using Msdfgen as a library to generate the final distance field.

grapefrukt commented 4 years ago

That is entirely fair! Thanks for taking the time to explain (and for a very useful tool!).

grapefrukt commented 4 years ago

Should anyone need it, I decided to tackle this myself, despite my self-described non-trustworthiness. I added support for circle, rect, polygon and ellipse. It's not thoroughly tested yet, but works well enough for what I need.

https://github.com/Chlumsky/msdfgen/compare/master...grapefrukt:master