This is interesting as I would have assumed that formats like SVG are "lossless" and wouldn't suffer from generation loss [0], but I hadn't considered that internally software might round some numbers.
What I've found working with geometric data like SVG is that your software will use some kind of internal representation that looks quite different than SVG, so you will do some kind of parsing into your data structure and then serializing out to SVG at the end. Even doing something like serialize(parse(number)) is not guaranteed to be lossless.
The only way to avoid doing that losslessly is to track the original text that you parsed into your IR nodes, which is a bit expensive if you think about it. A double is 64 bits, most shape/path data is packed and dense lists of doubles. Interleaving strings or ids that can be used to track them can be really annoying to thread through your program without performance or memory issues.
Inkscape is close to that. An Inkscape save file is a valid SVG file, but some SVG processors don't display all things correctly, so it also allows you to export it as "Plain SVG". But most browsers would read an inkscape save file just fine.
(Note that if you want to serve the SVG file, you should still "export as SVG" it, since Inkscape embeds a lot of semi-sensitive informations into the SVG like file path etc.)
This is a nice dive. I've also came across some SVG libraries that end up converting SVG path coordinates from original floating point values into integers, and then apply a scale/transform to that path to get the desired final size. Presumably this is/was faster for complicated paths or other elements.
Inkscape is missing there, and it scores perfectly, no precision loss.
The only discrepancy (apart from the XML formatting), is the addition of an ID to each object, if missing
From my experience, it is slow on every platform. I once wanted to make some vector art illustrations for a book a friend was working on, and ended up doing high-resolution raster graphics in GIMP instead because the vector graphics tools I tried (mainly Inkscape, because it had the best reviews) were either buggy or too painfully slow to use.
It's fast on Linux and Windows for me (no Mac experience), and I use it quite a bit. It does have some annoying limited precision behaviour in GUI input fields though, always (?) rounding to a small number of decimal places. This is problematic when you're doing things like rotating by 1/7 of a turn and need things to line up.
There is acknowledgement of slowness from the Inkscape dev team and some optimization efforts are underway, but they most likely won't land until 1.3.
If you're comfortable with outline view, that is a good way of speeding things up. However, for drawing it's a lot easier to rely on a raster sketch and then to trace the result in Inkscape either with the fill bucket or using the technical drawing and tweak tools. As of right now my experiences suggest that it's in a state where direct content creation can be really awkward, but it's very good for tracing and finishing images.
I once wrote an inkscape plugin to actually reduce precision. This would shrink the svg filesize quite considerably in some circumstances. This was particularly useful as some of the SVG's were modified by theming large sets of icons to particular branding colors and would take up quite a lot of space.
The Save As clearly outputs single precision floats.
Try putting the input values into e.g. https://www.h-schmidt.net/FloatConverter/IEEE754.html - the outputs are just the closest representable float numbers (converted back to a reasonable base-10 representation).
“Being a large app with multiple ways to do almost everything, Illustrator also has multiple methods to export SVGs.”
Bravo for phrasing that neutrally, because I see at least 4 ways to export SVGs, and I have no idea what Adobe actually wants you to use, because I increasingly think Adobe hates you.
1. Export for Screens… (which is what I generally use)
2. Export As…
3. The Asset Export panel.
4. Save As…
The first 3 all use the same export engine (or at least I think they do), but they all expose the settings in different locations. And then there is Save As… which tends to mangle things, as described in the article, and also lets you save as SVGZ, which is supposedly compressed, but it’s not.
This is probably pretty tongue in cheek, but this may be anecdotally more true than you think. I once had the privilege of being part of an Adobe Creative Cloud user research/focus group. It was appalling. They were very defensive of their product and even hostile towards certain kinds of feedback. It very much diminished my faith in Adobe as a company. At the time I just sort of shrugged it off because in many ways there just simply was no viable professional alternative, but I feel like this is increasingly not the case. In a way I think their chickens may be coming home to roost.
The chickens are definitely coming home to roost. Figma is eating everyone’s lunch right now, even if they score low on this list. Their engineering is soooo good. It’s amazing how buttery smooth their tool feels - you can tell they’re one of the few companies that really care about performance. That and they’re adding features that no other design tool could easily replicate.
I was thinking that the perfect SVG editor would use arbitrary-precision decimal math so that you'd never run into those 0.1 + 0.2 != 0.3 problems that are endemic when you use those "floating point" numbers that are approximate to those phony "real" numbers Cantor warned you about.
(Baudrillard would say that anybody using the word "real" is trying to bind you with illusion and like a wolf that craps on a trap to protect the pack he crapped on that word pretty bad!)
Came here to mention this, seeing those high precision decimals -- if you ever need to use their dimensions in any DOM arethmetic, be sure your process converts those to integers and back first (or use a lib like BigNumber, or the new JS BigInt). Many experienced front end devs ignore floating point issues unless they're doing financial math, then wonder why their JavaScript CSS calculations won't work out precicely.
In the case of the SVG editor I'd really like something that round-trips to and from SVG that looks nice in a text editor.
In a case like that it should "snap-to-grid" on the last decimal place of the number that's being edited, maybe the grid should even be displayed on the screen. That grid might be rotated or skewed because of coordinate transforms, and there ought to be some way to add another digit worth of fineness if not a factor of 2 or 5.
The question is what you try to achieve. At a certain precision you won't get any difference in any rasterized image anymore so you do not really care anymore. The SVG standard agrees there and states that 32 bit floating point is enough.
IEEE binary floating point numbers are widely supported and performant.
You can easily sidestep problems with errors of calculation (which includes already parsing decimal floats into binary floats, and happens here also with addition) by keeping the error smaller than what you care about: Read in as double precision float and use double for calculation, convert back to single precision before converting to decimal floating point. The error you will do in double precision will be smaller than what you loose converting to single precision.
You can use that for SVG path optimization where you will run across 0.1+0.2!=0.3 problems.
If you really want exact measurements, then you would want fractional numbers, so you can also cut lengths in e.g. three precisely.
IMHO it would be nice to see it used in larger-integer-presenting domains: with some limitations, accounting; interpreters where you want 0.1 + 0.2 == 0.3; anywhere there are measurements with units, and factor-of-ten scaling of finite digits is helpful; anywhere you want the simplicity of a single number-type and number-builder; possibly where you want to reserve some exponents for giving language keywords orthogonal number representations.
Super cool and simple test! One nitpick is the author says the following:
> "Black is the default shape colour for SVGs, so the fill attribute can be omitted entirely, as per the source SVG."
This isn't entirely true, as there's a specificity difference between having the attribute and not having it. I'm not sure which is the "right" approach though for a design tool. If this were purely a svg command line tool, I'd expect there to be no additional metadata, but considering this is the export from a design tool, I'm not sure what the right approach is. When you export something you often want it to look exactly as it is on the canvas, not to dynamically change color if there's a `fill` css declaration somewhere up the chain. Both Sketch and Figma* look like they've made the decision to go with consistency of visuals rather than consistency of meaning.
Very impressed with Sketch here in how accurately it preserves the precision, but disappointed it's exporting with non-unique IDs. Illustrator feels like it's doing a very Adobe thing - two different ways of doing something in the app results in either the best output or the worst output. Figma I'm disappointed transforms the rects into paths. This feels like it's optimizing for the general case rather than what the best output might be. I'll lump XD into the same category here with their transform hack for positioning. Not a fan of either.
Just wanted to say that I love Figma. Not sure what part of the system you work on, but every time I open the canvas, it blows my mind that I’m on a website. It’s so smooth it feels like native most days.
Thanks! That's awesome to hear - it's been super fun working for them. I've only been here about a year, so that near native experience is likely the result of https://twitter.com/evanwallace 's early webasm work on it.
I work on the design system features (components / variants / libraries / etc). Hit me up if you have any feedback! Happy to route it to the right people.
The general rule for serializing floating point representations to strings is not to output a fixed number of digits (DBL_DIG or otherwise), but rather to output sufficient digits that your inverse operation of parsing gives a bitwise identical floating point number.
Often, you can considerably reduce the file size of an SVG text file without a noticeable reduction in perceptual quality just by reducing the precision of the coordinates.
The awesome SVG Optimizer [1] has a filter (cleanupNumericValues) to process SVG files to a fixed precision.
The equally awesome SVG Optimizer Missing Gui (SVGOMG) [2] provides a web-based GUI [3] to interactively adjust precision and see the resulting render (and file-size).
I don't know if this exist, but I think it should exist a way of telling the software what maximum or minimum decimal precision you want to prevent this kind of situation.
We have to add custom classes and styles to SVG files in our products which requires hand coding. There is no design tool out there that won't completely destroy any hand-coded SVG styles or even attempt to work with them.
I make a rough draft of the icon in Figma or Affinity then export it and do the rest by hand and it can never be viewed in a visual editor again. Our design tools have failed us at providing good tooling for web and product work.
I’ve found Boxy SVG (https://boxy-svg.com) to be a good visual SVG editor. You can edit the SVG markup or use the visual tools. The markup is preserved on save.
Inkscape is very much an "SVG editor" and largely preserves what you have. I think most if these other tools are general design tools with SVG output which means that you don't expect much correlation to the input.
Something I learned recently while making a rough and dirty thing that generated SVG from JS: SVG does not do great with exponent forms (i.e. 1e+21). Probably not something that's normally encountered, but worth considering.
I don't know that much about SVG, but if it's vectorial, why even have decimal points? I guess 1 represents 1 pixel, but why? 100 could means 1 pixel too... and if that's enough precision to you, you'll even save a few hundreds dots in your file size ;) (though it's true that 1% of the time you would also save 2 digits and the dot, and 10% of the time you'll save a digit).
42 comments
[ 3.4 ms ] story [ 96.8 ms ] thread[0] https://en.wikipedia.org/wiki/Generation_loss
The only way to avoid doing that losslessly is to track the original text that you parsed into your IR nodes, which is a bit expensive if you think about it. A double is 64 bits, most shape/path data is packed and dense lists of doubles. Interleaving strings or ids that can be used to track them can be really annoying to thread through your program without performance or memory issues.
(Note that if you want to serve the SVG file, you should still "export as SVG" it, since Inkscape embeds a lot of semi-sensitive informations into the SVG like file path etc.)
If you're comfortable with outline view, that is a good way of speeding things up. However, for drawing it's a lot easier to rely on a raster sketch and then to trace the result in Inkscape either with the fill bucket or using the technical drawing and tweak tools. As of right now my experiences suggest that it's in a state where direct content creation can be really awkward, but it's very good for tracing and finishing images.
Try putting the input values into e.g. https://www.h-schmidt.net/FloatConverter/IEEE754.html - the outputs are just the closest representable float numbers (converted back to a reasonable base-10 representation).
Bravo for phrasing that neutrally, because I see at least 4 ways to export SVGs, and I have no idea what Adobe actually wants you to use, because I increasingly think Adobe hates you.
1. Export for Screens… (which is what I generally use)
2. Export As…
3. The Asset Export panel.
4. Save As…
The first 3 all use the same export engine (or at least I think they do), but they all expose the settings in different locations. And then there is Save As… which tends to mangle things, as described in the article, and also lets you save as SVGZ, which is supposedly compressed, but it’s not.
This is probably pretty tongue in cheek, but this may be anecdotally more true than you think. I once had the privilege of being part of an Adobe Creative Cloud user research/focus group. It was appalling. They were very defensive of their product and even hostile towards certain kinds of feedback. It very much diminished my faith in Adobe as a company. At the time I just sort of shrugged it off because in many ways there just simply was no viable professional alternative, but I feel like this is increasingly not the case. In a way I think their chickens may be coming home to roost.
(Baudrillard would say that anybody using the word "real" is trying to bind you with illusion and like a wolf that craps on a trap to protect the pack he crapped on that word pretty bad!)
In a case like that it should "snap-to-grid" on the last decimal place of the number that's being edited, maybe the grid should even be displayed on the screen. That grid might be rotated or skewed because of coordinate transforms, and there ought to be some way to add another digit worth of fineness if not a factor of 2 or 5.
You can easily sidestep problems with errors of calculation (which includes already parsing decimal floats into binary floats, and happens here also with addition) by keeping the error smaller than what you care about: Read in as double precision float and use double for calculation, convert back to single precision before converting to decimal floating point. The error you will do in double precision will be smaller than what you loose converting to single precision. You can use that for SVG path optimization where you will run across 0.1+0.2!=0.3 problems.
If you really want exact measurements, then you would want fractional numbers, so you can also cut lengths in e.g. three precisely.
https://www.crockford.com/dec64.html
IMHO it would be nice to see it used in larger-integer-presenting domains: with some limitations, accounting; interpreters where you want 0.1 + 0.2 == 0.3; anywhere there are measurements with units, and factor-of-ten scaling of finite digits is helpful; anywhere you want the simplicity of a single number-type and number-builder; possibly where you want to reserve some exponents for giving language keywords orthogonal number representations.
> "Black is the default shape colour for SVGs, so the fill attribute can be omitted entirely, as per the source SVG."
This isn't entirely true, as there's a specificity difference between having the attribute and not having it. I'm not sure which is the "right" approach though for a design tool. If this were purely a svg command line tool, I'd expect there to be no additional metadata, but considering this is the export from a design tool, I'm not sure what the right approach is. When you export something you often want it to look exactly as it is on the canvas, not to dynamically change color if there's a `fill` css declaration somewhere up the chain. Both Sketch and Figma* look like they've made the decision to go with consistency of visuals rather than consistency of meaning.
Very impressed with Sketch here in how accurately it preserves the precision, but disappointed it's exporting with non-unique IDs. Illustrator feels like it's doing a very Adobe thing - two different ways of doing something in the app results in either the best output or the worst output. Figma I'm disappointed transforms the rects into paths. This feels like it's optimizing for the general case rather than what the best output might be. I'll lump XD into the same category here with their transform hack for positioning. Not a fan of either.
* Disclaimer: I work for Figma.
I work on the design system features (components / variants / libraries / etc). Hit me up if you have any feedback! Happy to route it to the right people.
The awesome SVG Optimizer [1] has a filter (cleanupNumericValues) to process SVG files to a fixed precision.
The equally awesome SVG Optimizer Missing Gui (SVGOMG) [2] provides a web-based GUI [3] to interactively adjust precision and see the resulting render (and file-size).
[1] https://github.com/svg/svgo
[2] https://github.com/jakearchibald/svgomg
[3] https://jakearchibald.github.io/svgomg
I make a rough draft of the icon in Figma or Affinity then export it and do the rest by hand and it can never be viewed in a visual editor again. Our design tools have failed us at providing good tooling for web and product work.
Inkscape is very much an "SVG editor" and largely preserves what you have. I think most if these other tools are general design tools with SVG output which means that you don't expect much correlation to the input.