fabricjs / fabric.js

Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) Parser
http://fabricjs.com
Other
28.74k stars 3.49k forks source link

Improving SVG Parsing #1055

Open adastier opened 10 years ago

adastier commented 10 years ago

Hi! I keep hitting issues with SVG parsing, so figured I would do a summary of the information I gathered on the bugs in the SVG parser. I am reviewing the code, but that will not be enough, I think... Multiple issues have been opened about svg parsing bugs, and a few of them are pretty similar.

So here is a quick recap of what I found so far :

The example on the W3C page is not rendered correctly (imported in kitchensink). A lot of .svg I use, created with Adobe Illustrator or Inkscape, were not correctly rendered if a group contained a transform matrix (while being correctly rendered in Chrome/IE/Firefox).

I think this is related to #562 ( "Inspecting the parsed object from the SVG string showed that the transform matrix only accounted for the transform applied to the <path> and not the <g>."), #705 , #975, #474 , #567 , #502 , #905 , #975 (here I think the SVG output is correct, but the SVG is not parsed correctly when re-parsing), #384 , #443 , #917 , #1023 , #1280

As seen in issues #547 , #974 , #1023

As seen in #420 , #502 , #384 , #1280

Part of it was because of numbers that have the form 1.11111e-5 and was fixed. Why other files seem to fail is the same way remains an open question. As seen in #961 (now fixed) , ( #1021 was fixed, the issue was with fill-rule="evenodd")

I figured having a place to check them all could be useful. I hope this will help some of you. I'll try to update as I continue to investigate the issue. Please feel free to contribute if I missed some issues or if you have any idea/comment !

Most fiddles in the referenced issues will not work because they use the old all.js reference. For them to work, the Externel Resource all.js must be replaced with https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

kangax commented 10 years ago

@adastier No worries, and thanks for collecting it all in one bunch. Any help with these would be very welcome of course. Negative exponent should be the easiest to fix. Others need deeper investigation.

kangax commented 10 years ago

I fixed #961 with https://github.com/kangax/fabric.js/commit/d478482a1939ae253c8a9b1b2dd2e45484dc75d3 but #1021 still fails so it's something else. Please investigate more if you have a chance!

adastier commented 10 years ago

Thanks! I will continue to look for the reasons the svg are rendered that way, and then solutions! I think impleting the SVG Test Suite from the W3C like Inkscape is doing instead of the current huge test page could help identify specific issues, but that is quite a task. Just an idea for later.

kangax commented 10 years ago

I actually tried adopting W3C test loooong time ago (not sure if it was the same one) — http://fabricjs.com/test/functional/

On Wed, Dec 18, 2013 at 12:02 PM, Adrien notifications@github.com wrote:

Thanks! I will continue to look for the reasons the svg are rendered that way, and then solutions! I think impleting the SVG Test Suite from the W3Chttp://www.w3.org/Graphics/SVG/WG/wiki/Test_Suite_Overviewlike Inkscape is doinghttp://wiki.inkscape.org/wiki/index.php/SVG_Test_Suite_Complianceinstead of the current huge test page could help identify specific issues, but that is quite a task. Just an idea for later.

— Reply to this email directly or view it on GitHubhttps://github.com/kangax/fabric.js/issues/1055#issuecomment-30833080 .

hybra commented 10 years ago

To me, it also looks like fabricjs is working with some attributes value that are in percentage format, while they don't work in decimal format. For example, a simple SVG like

<?xml version="1.0"?>
<svg width="282" height="292" xmlns="http://www.w3.org/2000/svg">
 <defs>
  <radialGradient id="svg_9" spreadMethod="pad" cx="0.5" cy="0.5" r="0.5">
   <stop stop-color="#00ffff" stop-opacity="0.015625" offset="0.488281"/>
   <stop stop-color="#000000" stop-opacity="0.996094" offset="1"/>
  </radialGradient>
  <radialGradient id="svg_10" spreadMethod="pad" cx="0.5" cy="0.5" r="0.5">
   <stop stop-color="#ffffff" stop-opacity="0.011719" offset="0"/>
   <stop stop-color="#ffffff" stop-opacity="0.007813" offset="0.503906"/>
   <stop stop-color="#000000" offset="1"/>
  </radialGradient>
 </defs>
 <g>
  <title>Layer 1</title>
  <g id="svg_3">
   <rect fill="url(#svg_10)" stroke-width="5" x="0" y="-0.000003" width="282" height="291.999988" id="svg_1" stroke="#000000"/>
   <circle stroke="#000000" fill="url(#svg_9)" stroke-width="5" cx="141.000003" cy="143.999987" r="140.852371" id="svg_2"/>
  </g>
 </g>
</svg>

if you replace the radial gradient cx, cy and r values from "0.5" to "50%" it works as expected (try this in kitchensink):

<?xml version="1.0"?>
<svg width="282" height="292" xmlns="http://www.w3.org/2000/svg">
 <defs>
  <radialGradient id="svg_9" spreadMethod="pad" cx="50%" cy="50%" r="50%">
   <stop stop-color="#00ffff" stop-opacity="0.015625" offset="0.488281"/>
   <stop stop-color="#000000" stop-opacity="0.996094" offset="1"/>
  </radialGradient>
  <radialGradient id="svg_10" spreadMethod="pad" cx="50%" cy="50%" r="50%">
   <stop stop-color="#ffffff" stop-opacity="0.011719" offset="0"/>
   <stop stop-color="#ffffff" stop-opacity="0.007813" offset="0.503906"/>
   <stop stop-color="#000000" offset="1"/>
  </radialGradient>
 </defs>
 <g>
  <title>Layer 1</title>
  <g id="svg_3">
   <rect fill="url(#svg_10)" stroke-width="5" x="0" y="-0.000003" width="282" height="291.999988" id="svg_1" stroke="#000000"/>
   <circle stroke="#000000" fill="url(#svg_9)" stroke-width="5" cx="141.000003" cy="143.999987" r="140.852371" id="svg_2"/>
  </g>
 </g>
</svg>
kangax commented 10 years ago

/cc @Kienz

alisspers commented 10 years ago

Has there been any work done regarding this issue yet?

We're experiencing these problems with SVG files that have been converted from pdf with inkscape, and I'm wondering whether we should (1) give this issue a go or (2) try to find out how to make SVG files that do parse correctly in fabric.

adastier commented 10 years ago

I stopped working on it 6 weeks ago, and I did not spent enough time on it before that to make significant progress. I mostly tried to analyze fabric.js source code, inkscape source code, and played around with fabric a bit. I don't know about other people's work. I don't have time to put into svg parsing before April at least (as its not critical for me), but will gladly keep updating the first post with any progress/discovery of new issues in the meantime.

alisspers commented 10 years ago

Thanks for your reply. We've never worked with SVG parsing before so it might be hard for us to get around to helping with this issue, but if we get around to it, I'll comment here (and quite possibly ask for help with understanding the current code).

sreeasdf commented 10 years ago

svg file ungroup and edit issue #1269

daboom commented 10 years ago

I'm trying to use loadSVGFromURL with many svg (don't know if from Inkscape or not) and everytime it fails to put the handling borders on canvas. Sometimes they're larger than the real img size, sometimes they're of the right size but far away from the image. This is the pice of code I use:

var svg = "pear.svg";
//load SVG 1
fabric.loadSVGFromURL("svg/" + svg, function(objects,options) {
    var obj = fabric.util.groupSVGElements(objects, options);
    canvas.add(obj).renderAll();
});

Is there a way to transorm any SVG file in a cleaned SVG file accepted by Fabric.js parser?

Thx

Siyfion commented 10 years ago

@adastier if you're trying to keep all the issues in one place, you might want to add / look at my issues described in #1280

adastier commented 10 years ago

I added it to the main post, thank you for the notice.

Also, people looking for solutions to issues with the viewBox attribute might want to take a look at what was suggested in #1137 by @kabab (PR #1248 still open because the build fails).

asturur commented 10 years ago

I add my failing svg, i get impressive rates in failing them. link to svgs: http://demologhi.romacityweb.com/logos_manager/get_svg.php?id=2 autobot logo, i get black copy of it on the left http://demologhi.romacityweb.com/logos_manager/get_svg.php?id=3 arduino logo, i don't get anythimg http://demologhi.romacityweb.com/logos_manager/get_svg.php?id=4 wikimedia logo, not getting clipped, incorrect position of red dot http://demologhi.romacityweb.com/logos_manager/get_svg.php?id=5 creative common logo, getting misplaced border http://demologhi.romacityweb.com/logos_manager/get_svg.php?id=6 html 5 logo not getting transparencies

http://demologhi.romacityweb.com/logos_manager/demo.php?id=2 to load them change the id parameter with one of the examples.

best regards

kangax commented 10 years ago

http://demologhi.romacityweb.com/logos_manager/get_svg.php?id=2 autobot logo, i get black copy of it on the left

This is because the black shape is "offscreen" in SVG (coordinates are negative), but in Fabric SVG is parsed into an object that's positioned on a canvas and there's no such notion as "offscreen" (there's clipping but I don't think it makes sense to apply it in cases like this)

kangax commented 10 years ago

http://demologhi.romacityweb.com/logos_manager/get_svg.php?id=3 arduino logo, i don't get anythimg

This is the usual Inkscape problem. They use tags like "svg:g", "svg:path", etc. Also, what is this — <ndash/> — don't see a mention of such tag anywhere...

kangax commented 10 years ago

Added #1290

sreeasdf commented 10 years ago

coming out put is:

coming

but actuval out put is:

actuvaloutput

kangax commented 10 years ago

Added #1305

lukluk commented 10 years ago

Solved ! http://jsfiddle.net/9fRjq/1/ or http://jsfiddle.net/9fRjq/

asturur commented 10 years ago

http://demologhi.romacityweb.com/logos_manager/get_svg.php?id=4

This is one viewbox problem. Usually viewbox is something like ='0 0 x y' And to my short studies looks like that fabricjs use x and y instead of width and height if those are not specified in attributes of svg. (am i wrong till now?)

From what i read arounf viewbox is a translation of internal coordinates, in my example the attr are viewBox="-599 -599 1198 1198" width="1024" height="1024" (http://tutorials.jenkov.com/svg/svg-viewport-view-box.html#viewbox)

it should mean that any x and y attribute ( cx and cy and so on ) should be interpreted like this: if cy=-100 we have to do 1198 - ( -599 ) to get that hour viewbox is 1797 units high. (added later: maybe i'm wrong, it looks like 1198 is commonly referred as width and heigth, anyway the important part is the negative value from wich it starts) so -100 from - 599 means that we start at +499 in our canvas. Finally we scale 499 by ( 1024 / 1797 ).

If i follow this path, the circles in the svg get correctly aligned in the fabric canvas as in the svg rendered by firefox itself. even the clip path alignes itself to the shape ( i cannot clip, i just moved the clip as a path in the group and it render good over the image ) I'm not enough classe expert to write a pull request even just for fabric.Circle subclass. Some method should be done to translate the coordinates globally in the prototype. Someonw want to try?.

asturur commented 10 years ago

my contribution to some of those issues: https://github.com/kangax/fabric.js/pull/1383

asturur commented 10 years ago

Please check even #1407 and #1408 they fix something of my case and svg_import tests.

asturur commented 10 years ago

@adastier If possible check "support of use" as resolved.

yacodes commented 9 years ago

Hey, guys, I've got som eproblem with svg parsing here: http://stackoverflow.com/questions/28364546/fabricjs-svg-parsing-error If you have any ideas, how to improve this stuff i'll aprecciate that very much.

asturur commented 9 years ago

hey @canvaskisa i just replied you on SO to use latest version. please accept answer so people see before asking anything to trynat least kitchensink demo. regards

yacodes commented 9 years ago

@asturur, weird, i'm using npm version "fabric": "^1.4.13"

asturur commented 9 years ago

but on kitchensink renders good. so please pull from the website itself, maybe kangax updated the dist folder but did not release the 1.4.14 would you mind to try to pull the latest and try?

yacodes commented 9 years ago

@asturur, i tried the last version from site, and everything is fine, seems like it's an old version of fabric in npm. thanks for help, man

asturur commented 9 years ago

please, even if my answer is incorrect in this case, just mark it, testing kitchensink is something people are not doing, and they just open issues here or in SO.

if you do not mind of course. Il 09/feb/2015 11:26 "aleksandr" notifications@github.com ha scritto:

@asturur https://github.com/asturur, i tried the last version from site, and everything is fine, seems like it's an old version of fabric in npm. thanks for help, man

— Reply to this email directly or view it on GitHub https://github.com/kangax/fabric.js/issues/1055#issuecomment-73486513.

kotevcode commented 4 years ago

6023

@asturur I've opened a pr fixing a lot of svg parsing errors I've seen here.. way too much for giving examples. Took it from svgo package.. see if that works for you.

curvedriver commented 4 years ago

Hi, I found some issues while parsing a SVG which contains other nested SVG elements. The positions and the sizes of the inner SVG elements are not correct.

Is that already considered by one of the existing tasks?

I created a fiddle for that: https://jsfiddle.net/curvedriver/qjouaxgs/15/

The browsers native svg visualization (chrome: Version 79.0.3945.117) looks as expected. image

asturur commented 4 years ago

no is not, would be nice if you open its own issue with that. thanks.

curvedriver commented 4 years ago

Thanks @asturur! Done -> https://github.com/fabricjs/fabric.js/issues/6105