Open FredHappyface opened 4 years ago
Hello!
There's certainly something mighty strange going on in this file, the path is unlikely to occur, I think. Perhaps they are doing it to save bytes? It's very hacky, it self-intersects.
In Inkscape, if you select the path and do «Path→Break Apart», you'll see how weird they drew this heart— it's essentially two shapes.
Of course, I'm not excusing the bug, please don't take it that way—just trying to provide context.
Even without simplification and direction correction, I get the same bizarre result:
So, the bug is confirmed. I'm going to ask @skef to comment, as he's the resident SVG expert.
By the way, in case this is somewhat "urgent" for you @FredHappyface, you can in Inkscape do «Path→Union», save SVG.
Please don't close the bug—workarounds do not close bugs on our tracker, only actual fixes.
Hi,
Thanks for looking at this. I have no idea either. Seems completely absurd to say the least. They have done it with a good chunk of the fonts. Interesting how they've gone about it.
Thanks for the workaround too. The best one I had found was much more, shall we say, 'fiddly'. For reference, it is as follows:
Would you know how to apply this to the full icon set? (there are probably around 200 and I'll be up until lunch time tomorrow if I take the manual approach)
Thanks again 👍
I'd start here.
Perfect thanks :)
I view the SVG import feature as primarily a way of importing cubic or quadratic paths from other tools (and the export feature as the reverse). It's also provides a means of translating most SVG files into contours, which is handy. Expecting to be able to do that with any SVG input may not be realistic.
Anyway, with this one the primary issue turns out to be pretty simple. I took the file and enlarged it in Inkscape by 16 times, saved, and imported in FontForge:
So ultimately the problem here is that the way that FontForge currently calculates (elliptical) arcs is sensitive to scale, and the scale of this shape is tiny. And although Fontforge normally scales the input based on font metrics it does that at the end. We could add an "upscale" option, or even an "upscale for conversion and then downscale back" option. I'm not sure it's worth the development time, though.
One thing that would be really useful would be the ability to scale pasted glyphs
One moderately quick workaround I have automated is inkscape.com -g --batch-process [icon].svg --verb='EditSelectAll;SelectionUnion;FileSave'
. The issue, however is that some icons change such as image.svg
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M1.75 2.5a.25.25 0 00-.25.25v10.5c0 .138.112.25.25.25h.94a.76.76 0 01.03-.03l6.077-6.078a1.75 1.75 0 012.412-.06L14.5 10.31V2.75a.25.25 0 00-.25-.25H1.75zm12.5 11H4.81l5.048-5.047a.25.25 0 01.344-.009l4.298 3.889v.917a.25.25 0 01-.25.25zm1.75-.25V2.75A1.75 1.75 0 0014.25 1H1.75A1.75 1.75 0 000 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0016 13.25zM5.5 6a.5.5 0 11-1 0 .5.5 0 011 0zM7 6a2 2 0 11-4 0 2 2 0 014 0z"/></svg>
I'll probably look at batch scaling the glyphs and importing that way (I'll drop a follow up with the sample command for that in case someone finds it useful)
Thanks
If you mean scale the glyph after pasting it you can just do a uniform scale transform. If you want every glyph to be scaled to a particular height and moved to a particular position (for example), you can write a little python snippet for the tools menu.
I was thinking it may be better to scale first to correct the scale when importing. I've found that modifying the document properties does the trick. I've no idea how to automate that at this point but if I import a glyph then it auto scales anyway. Also importing without scaling and then manually scaling makes no difference. Some of the curves still go crazy
Oh, yeah, FontForge can only scale interpreted contours, not (currently) the SVG input prior to interpretation.
I was going to suggest throwing a <g transform="scale(16)">
element around the content but that doesn't work either -- FontForge transforms interprets paths first and then scales them (which is fairly normal practice).
Sorry about this -- I realize that it sounds funny for a tool to be sensitive to scale when interpreting a format that isn't (or isn't supposed to be). It turns out to be hard enough just to make floating point calculations work at a target scale. Even if we fixed the arc calculations (which are causing your problem) the expand stroke code would still fail at these scales.
That makes sense. Would you be able to recommend a tool to batch resize svgs? Ive tried scripting inkscape, rsvg-convert and neither of those work. The only solution I have found is https://www.iloveimg.com/resize-image/resize-svg but that limits you to about 16 and I would rather use something local if possible.
Yeah the transform thing was pretty much the first thing I tried. Turns out inkskape works but I can't seem to automate that.
Not at all. Does sound a bit odd I admit but I can imagine that it will be for a good reason. The fact that there seem to be so many ways to achieve the same thing in svg makes it one of those magical formats as far as I am concerned!
Right found a rather convoluted but so far working solution
Note that the preferred solution is the new one but I've added the other solutions below
inkscape.com [icon].svg -w 160 -y 255 -o [icon].png
for each svgconvert [icon].png [icon].bmp
potrace [icon].bmp -s -o [icon].svg
To do this all in one go, run batchProcessLinux.py in linux or wsl.
inkscape.com -g --batch-process [icon].svg --verb='EditSelectAll;SelectionUnion;FileSave'
for each svg filebatchProcessLinux.py
""" script to batch process a directory of svgs """
from subprocess import Popen
from os.path import isfile, join
from os import listdir
from pathlib import Path
THISDIR = str(Path(__file__).resolve().parent)
files = [
file.replace(".svg", "") for file in listdir(THISDIR)
if isfile(join(THISDIR, file)) and file.endswith(".svg")]
for file in files:
with Popen(f"inkscape.com {file}.svg -w 160 -y 255 -o {file}.png;convert {file}.png {file}.bmp;potrace {file}.bmp -s -o {file}.svg;rm {file}.png;rm {file}.bmp", shell=True) as process:
exitCode = process.wait()
if exitCode > 0:
print(f"error for file: {file}")
else:
print(f"success for file: {file}")
Not sure why potrace would be preferred? Its output won't be that great most of the time...
I'll think about how hard it would be to add a "temp scale" option to the SVG import code (at some point -- probably not soon) to close this issue. It might not be too hard to just multiply the values as they are read by a parameter and then scale down at the end.
Cool; for now I'd say that @FredHappyface's "alternative 1" is the best solution :-)
Alternative 1 appears to be the best solution for the particular shape chosen to represent the issue. Alternative 2 is the best solution for the general scaling problem -- any shape with extremely tight (i.e. high curvature) elliptical arcs could wind up with problems like the illustration.
(I haven't checked but Inkscape's Union algorithm might be reducing arcs to quadratic or cubic splines; I'm not sure why else it would be fixing the problem. I verified that just increasing the size with Inkscape doesn't eliminate the arcs, which increases my confidence in the scale diagnosis.)
I've found that potrace was perfect for the 250 icons at 160x160 and eliminated the issues that alternative 1 gave me. Alternative 2 worked but seemed more fiddly for my use case and the 'preferred' method could be automated with ease
OK. The reason I say it's not generally applicable is that most font designers expect their points to persist across imports. Potrace will do things like collapse corners into curves with very short Bézier handles, or collapse tight curves into points. It will usually destroy small details like inktraps, seeing them as not relevant to the shape. It will not put points in optimal places, nor at extrema. Etc. Etc.
This is because it works by rasterizing and retracing the SVG, which destroys the original data.
I am not really writing this for you, but rather for Googlers who may arrive here. :-)
In an icon font, I can see why these considerations do not matter, although due to my OCD, I would still preserve curves.
Ah yeah I hadn't considered those points... Makes sense how that would be a horrible solution in those cases. I'm my case that's what I will be going with as I am not bothered about preserving any of those details
FYI. Just had this problem in my own project, so am here to offer a more complete solution.
I used two tools to fix it: svgcleaner
and rsvg-convert
.
My zoom icon was getting a very weird outline and the same kind of brokenness @FredHappyface observed.
Basically this was enough to solve the problem after svgcleaner
took care of junk Inkscape left behind which was confusing rsvg-convert
:
for f in *.svg; do rsvg-convert.exe --zoom=10.0 -f svg "$f" -o "${f%.svg}"2.svg && rm "$f"; done
rsvg-convert
is used on Wikipedia. Works well now.
Before:
After:
And for posterity:
The "2" ones are the good ones.
Hi it's been about 18 months or so since the last comment, so shall I close the issue or leave it open for the time being? :)
There are many open FontForge issues that are older and sillier than this one, so you shouldn't feel any pressure to close it. Sometimes this kind of problem doesn't get fixed and sometimes a fix gets rolled into a collection of changes. There are no immediate plans to integrate a pre/post scaling option into the tool, however.
Happy to do whatever is easiest for you, really. Don't see much point in keeping it open if the issue is dead but if you use gh issues as a sort of backlog then I could see the point in leaving it open :)
It's easiest for us for you to stop making comments like this across multiple issues please. It's bothering nobody. If someone pushes a fix that closes 5 or 10 issues, which has happened and could happen, then it'll be closed. Or someone could have your exact problem and more skills and so fix only this issue. Or it could never be fixed and will be here, open, in a decade. Either way we do not need reminders that it's still open.
Important
Mark with [x] to select. Leave as [ ] to unselect.
When reporting a bug/issue:
When you open an issue for a change/improvement/feature request:
Version
FontForge 20200314 as available https://ci.appveyor.com/project/fontforge/fontforge/build/artifacts Windows 10 1909
Description and screenshots
When importing the heart-fill.svg from Octicons v10, FontForge 20200314 crashes. Using https://ci.appveyor.com/project/fontforge/fontforge/build/artifacts prevents the crash but the icon looks rather unusual
Sample SVG
FontForge render
SVG render
Using https://github.com/lishu/vscode-svg2 the svg file renders as such:
Thank you for your time