Summary
Paths in an SVG file are not drawn correctly in Processing (PShape Implementation) (v 2.1.1, 32-bit and 64-bit on Windows 7) when the path contains more than one relative moveto instruction (m).
Section 8.3.2 of the W3C SVG recommendation specifies that
If a relative moveto (m) appears as the first element of the path, then it is treated as a pair of absolute coordinates. In this case, subsequent pairs of coordinates are treated as relative even though the initial moveto is interpreted as an absolute moveto.
When a path begins with a relative moveto, Processing treats it as relative to the last absolute path. More generally, Processing uses the starting point of the last absolute subpath (or (0,0) if none is defined) for relatively-defined moveto commands.
Demonstration
The following SVG file is an example of a file that will not draw correctly as a result of this issue:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="80" height="60">
<path d="m 20,20 0,10 10,0 0,-10 z
m 15,0 0,10 10,0 0,-10 z
m 15,0 0,10 10,0 0,-10 z" />
</svg>
The expected output is three horizontally-aligned squares:

The Processing output is two offset squares (the second and third subpaths are overlaid).

void draw() {
size(80, 60);
background(255);
shape(loadShape("<path to svg>"));
}
The issue can also be observed in running the USA map example on the Wikipedia Processing page. The states of Virginia and Hawaii are offset from their expected positions, with shapes clustered in the top left corner instead:

Patch
The error appears to be in processing.core.PShapeSvg beginning at line 586:
case 'm': // m - move to (relative)
cx = cx + PApplet.parseFloat(pathTokens[i + 1]);
cy = cy + PApplet.parseFloat(pathTokens[i + 2]);
parsePathMoveto(cx, cy);
implicitCommand = 'l';
i += 3;
break;
The movetoX and movetoY variables should be set as the initial point of the new subpath:
case 'm': // m - move to (relative)
cx = cx + PApplet.parseFloat(pathTokens[i + 1]);
cy = cy + PApplet.parseFloat(pathTokens[i + 2]);
// need to add next two lines
movetoX = cx;
movetoY = cy;
parsePathMoveto(cx, cy);
implicitCommand = 'l';
i += 3;
break;
Workaround
The issue can be worked around by replacing the relative moveto commands with an absolute moveto command followed by a relative path beginning with (0, 0). For example,
<path d="m 20,20 0,10 10,0 0,-10 z
m 15,0 0,10 10,0 0,-10 z
m 15,0 0,10 10,0 0,-10 z" />
can be equivalently written as:
<path d="M 20, 20 m 0,0 0,10 10,0 0,-10 z
M 35, 20 m 0,0 0,10 10,0 0,-10 z
M 50, 20 m 0,0 0,10 10,0 0,-10 z" />
This will draw correctly in Processing and other SVG viewers. It requires that the absolute starting point of each subpath be computed.
Summary
Paths in an SVG file are not drawn correctly in Processing (PShape Implementation) (v 2.1.1, 32-bit and 64-bit on Windows 7) when the path contains more than one relative moveto instruction (
m).Section 8.3.2 of the W3C SVG recommendation specifies that
When a path begins with a relative moveto, Processing treats it as relative to the last absolute path. More generally, Processing uses the starting point of the last absolute subpath (or
(0,0)if none is defined) for relatively-defined moveto commands.Demonstration
The following SVG file is an example of a file that will not draw correctly as a result of this issue:
The expected output is three horizontally-aligned squares:
The Processing output is two offset squares (the second and third subpaths are overlaid).
The issue can also be observed in running the USA map example on the Wikipedia Processing page. The states of Virginia and Hawaii are offset from their expected positions, with shapes clustered in the top left corner instead:
Patch
The error appears to be in
processing.core.PShapeSvgbeginning at line 586:The
movetoXandmovetoYvariables should be set as the initial point of the new subpath:Workaround
The issue can be worked around by replacing the relative moveto commands with an absolute moveto command followed by a relative path beginning with (0, 0). For example,
can be equivalently written as:
This will draw correctly in Processing and other SVG viewers. It requires that the absolute starting point of each subpath be computed.