Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

weirdly displaced vertices in SVG #5523

Closed
liquidev opened this issue Jun 3, 2018 · 5 comments
Closed

weirdly displaced vertices in SVG #5523

liquidev opened this issue Jun 3, 2018 · 5 comments

Comments

@liquidev
Copy link
Contributor

liquidev commented Jun 3, 2018

Description

I am trying to draw this file onto the screen, but the vertices are weirdly displaced.

Expected Behavior

The vertices should be drawn correctly, as seen in the Gist.

Current Behavior

Look at the shape on the right side. This happens in all circumstances, no matter if I scale it, translate it, apply a custom fill, it just always happens.
Image

P2D and P3D crash when trying to draw the SVG, with a tesselation error "out of memory".
FX2D doesn't handle the SVG at all, and it looks like garbage:
FX2D

I have also tried drawing this SVG, and it just crashes my sketch.

Update

I tried to split the shape in half, and the sketch just crashes with the following stack trace:

java.lang.ArrayIndexOutOfBoundsException: 1
	at processing.core.PShapeSVG.parsePoly(PShapeSVG.java:461)
	at processing.core.PShapeSVG.parseChild(PShapeSVG.java:335)
	at processing.core.PShapeSVG.parseChildren(PShapeSVG.java:289)
	at processing.core.PShapeSVG.<init>(PShapeSVG.java:209)
	at processing.core.PShapeSVG.<init>(PShapeSVG.java:116)
	at processing.awt.PShapeJava2D.<init>(PShapeJava2D.java:52)
	at processing.awt.PGraphicsJava2D.loadShape(PGraphicsJava2D.java:1839)
	at processing.core.PGraphics.loadShape(PGraphics.java:1744)
	at processing.core.PApplet.loadShape(PApplet.java:11526)
	at iliquid.excircuit.IconBank.load(IconBank.java:35)
	at iliquid.excircuit.IconBank.load(IconBank.java:59)
	at iliquid.excircuit.Loader.load_icons(Loader.java:33)
	at iliquid.excircuit.exCircuit.setup(exCircuit.java:185)
	at processing.core.PApplet.handleDraw(PApplet.java:2401)
	at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1557)
	at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:313)

(I use Processing in IntelliJ and my sketch is in a separate package, that's why there is iliquid.excircuit.IconBank.load, and not exCircuit$IconBank.load (or something like that))

Steps to Reproduce

Create a sketch that draws the problematic SVG.

Your Environment

  • Processing version: 3.3.7
  • Operating System and OS version: Windows 10 Spring Creators Update
  • Other information: Java 8u172, JAVA2D renderer. The SVG was exported with Adobe Illustrator.

Possible Causes/Solutions

I have been debugging for a bit of time, and I seem to have found the issue (only for the analog.svg crash, but that's still some progress):

https://github.com/processing/processing/blob/master/core/src/processing/core/PShapeSVG.java#L449-L464

Illustrator seems to export SVGs in a format that's different than Processing expects, take a peek at this part of the SVG:

<polygon points="18.72 4 13.39 20 10.61 20 5.28 4 7.39 4 12 17.84 16.61 4 18.72 4"/>

The points are formatted differently than Processing expects them to be. After a ton of debugging, I have came to the conclusion, that those two are the problematic lines of code:

https://github.com/processing/processing/blob/master/core/src/processing/core/PShapeSVG.java#L455

https://github.com/processing/processing/blob/master/core/src/processing/core/PShapeSVG.java#L459

And especially the second one. Line 455 splits the string by spaces, which yields an array like ["18.72", "4", "13.39"...], but this causes problems in the next few lines of code:

https://github.com/processing/processing/blob/master/core/src/processing/core/PShapeSVG.java#L459-L461

Lines 460 and 461 expect two array entries, but because of the first array, it can't find them.

I have no idea if this is an Illustrator or Processing issue, I am just pointing out what I found.

@liquidev
Copy link
Contributor Author

liquidev commented Jun 5, 2018

Okay, it seems that it was an issue with the SVG. I have optimized it - closed all paths, removed unneccessary verts, and now it works. This still doesn't change the fact that the renderer can't handle broken SVGs (whereas Webkit and others can), and this should be fixed.

@liquidev
Copy link
Contributor Author

liquidev commented Jun 5, 2018

Regarding the crash

So, according to the SVG spec, I have come to the conclusion that:

splitTokens() can't be used as the function that splits coord pairs in the SVG. Instead, I'd opt in for a regex solution:

([+-]?[\d]+(\.[\d]+)?([eE][+-][\d]+)?)(,?\s*)([+-]?[\d]+(\.[\d]+)?([eE][+-][\d]+)?)

Tested with RegExr

We can then extract the X coord from group 1, and the Y coord from group 5.

Here's the regex explained:

(                 # Match a number for the X coordinate
 [+-]?            # Optional + or - in front of the number
 [\d]+            # Sequence of digits, forming an integer
  (\.[\d]+)?      # Optionally, there can be a dot, and another sequence of digits for a floating point decimal
 ([eE][+-][\d]+)? # After the whole digit, optionally, there can be an exponent, like e+2
)
(    # Match the delimiter between two coords
 ,?  # The optional comma
 \s* # 0 or more spaces
)
([+-]?[\d]+(\.[\d]+)?([eE][+-][\d]+)?) # Match another number, same as group 1

The expression will match old style patterns, like 10,20, but also the problematic ones like 10 20. This shouldn't be a problem to implement, as Java natively supports regex with its Pattern and Matcher classes.

Why is this?

The polygon/polyline's EBNF specifies that the comma is optional, and a space can be used in place of it.

list-of-points:
    wsp* coordinate-pairs? wsp*
coordinate-pairs:
    coordinate-pair
    | coordinate-pair comma-wsp coordinate-pairs
coordinate-pair:
    coordinate comma-wsp coordinate              ; here, a comma-wsp is used
    | coordinate negative-coordinate
[...]
comma-wsp:
    ; the comma is optional, with the ? quantifier, and after that there is a * wsp, which means that it matches 0 or more of wsp
    ; this effectively makes the comma optional
    (wsp+ comma? wsp*) | (comma wsp*)
comma:
    ","
[...]
wsp:
    (#x20 | #x9 | #xD | #xA)+                    ; those are all whitespace characters

Source: SVG spec

Hopefully this shouldn't be too hard to implement. I'll have my own try at this, and submit a PR.

@liquidev
Copy link
Contributor Author

(Somewhat offtopic) Update

I might take a shot at this (for FX2D), but it would require a bit of a rewrite of how PShapeSVG works.

How this could potentially be fixed

I was learning about the JavaFX Canvas and GraphicsContext for a while, and I found this method: GraphicsContext#appendSVGPath(String path). If PShapeSVG was re-written to be an interface, and have a default implementation PShapeSVGDefault, and an FX2D-specific implementation PShapeSVGFX2D, the method for parsing and drawing the shape could be fundamentally different for any renderer, so FX2D could have a different method for drawing paths using GraphicsContext#appendSVGPath, potentially fixing the FX2D issue.

I am unsure about the original problem, but I'll definitely look into it now that I've got a better understanding of how Processing is structured internally.

@Ruchi195
Copy link

Ruchi195 commented Jul 7, 2019

Hi. I am facing a similar issue. I exported svg consisting numerous rotated rectangles stacked diagonally but when I import it back as svg in processing, they come out misaligned.
I don't know if its the same issue that you faced. I am a beginner. Any guidance would be helpful.Thanks.
Here's the link:
Ruchi195/Project-1#1 (comment)

@benfry
Copy link
Contributor

benfry commented Oct 5, 2019

Rolling SVG requests into #5935

@benfry benfry closed this as completed Oct 5, 2019
@processing processing locked as resolved and limited conversation to collaborators Oct 5, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants