in packages/serverless-workflow-diagram-editor/lienzo-core/src/main/java/com/ait/lienzo/client/core/shape/SVGPath.java [100:496]
public static final void parse(final PathPartList partlist, String path) {
partlist.clear();
path = path.replaceAll("\\s+", " ").trim();
for (int n = 0; n < COMMANDS.length; n++) {
path = path.replaceAll(COMMANDS[n] + " ", COMMANDS[n]);
}
path = path.replaceAll(" ", ",");
for (int n = 0; n < COMMANDS.length; n++) {
path = path.replaceAll(COMMANDS[n], "#" + COMMANDS[n]);
}
final String[] list = path.split("#");
double cpx = 0;
double cpy = 0;
for (int n = 1, l = list.length; n < l; n++) {
String str = list[n];
char chr = str.charAt(0);
str = str.substring(1).replaceAll(",-", "-").replaceAll("-", ",-").replaceAll("e,-", "e-");
final String[] pts = str.split(",");
int beg = 0;
if ((pts.length > 0) && (pts[0].isEmpty())) {
beg = 1;
}
final NFastDoubleArray source = new NFastDoubleArray();
for (int i = beg, z = pts.length; i < z; i++) {
source.push(Double.valueOf(pts[i]).doubleValue());
}
PathPartEntryJSO prev;
double ctx, cty;
while (source.size() > 0) {
int cmd = PathPartEntryJSO.UNDEFINED_PATH_PART;
final NFastDoubleArray points = new NFastDoubleArray();
switch (chr) {
case 'l':
cpx += source.shift();
cpy += source.shift();
points.push(cpx);
points.push(cpy);
cmd = PathPartEntryJSO.LINETO_ABSOLUTE;
break;
case 'L':
cpx = source.shift();
cpy = source.shift();
points.push(cpx);
points.push(cpy);
cmd = PathPartEntryJSO.LINETO_ABSOLUTE;
break;
case 'm':
final double dx = source.shift();
final double dy = source.shift();
cpx += dx;
cpy += dy;
final int size = partlist.size();
if (size > 2 && partlist.get(size - 1).getCommand() == PathPartEntryJSO.CLOSE_PATH_PART) {
for (int idx = size - 2; idx >= 0; idx--) {
prev = partlist.get(idx);
if (prev.getCommand() == PathPartEntryJSO.MOVETO_ABSOLUTE) {
cpx = prev.getPoints()[0] + dx;
cpy = prev.getPoints()[1] + dy;
break;
}
}
}
points.push(cpx);
points.push(cpy);
chr = 'l';
cmd = PathPartEntryJSO.MOVETO_ABSOLUTE;
break;
case 'M':
cpx = source.shift();
cpy = source.shift();
points.push(cpx);
points.push(cpy);
chr = 'L';
cmd = PathPartEntryJSO.MOVETO_ABSOLUTE;
break;
case 'h':
cpx += source.shift();
points.push(cpx);
points.push(cpy);
cmd = PathPartEntryJSO.LINETO_ABSOLUTE;
break;
case 'H':
cpx = source.shift();
points.push(cpx);
points.push(cpy);
cmd = PathPartEntryJSO.LINETO_ABSOLUTE;
break;
case 'v':
cpy += source.shift();
points.push(cpx);
points.push(cpy);
cmd = PathPartEntryJSO.LINETO_ABSOLUTE;
break;
case 'V':
cpy = source.shift();
points.push(cpx);
points.push(cpy);
cmd = PathPartEntryJSO.LINETO_ABSOLUTE;
break;
case 'C':
points.push(source.shift());
points.push(source.shift());
points.push(source.shift());
points.push(source.shift());
cpx = source.shift();
cpy = source.shift();
points.push(cpx);
points.push(cpy);
cmd = PathPartEntryJSO.BEZIER_CURVETO_ABSOLUTE;
break;
case 'c':
points.push(cpx + source.shift());
points.push(cpy + source.shift());
points.push(cpx + source.shift());
points.push(cpy + source.shift());
cpx += source.shift();
cpy += source.shift();
points.push(cpx);
points.push(cpy);
cmd = PathPartEntryJSO.BEZIER_CURVETO_ABSOLUTE;
break;
case 'S':
ctx = cpx;
cty = cpy;
prev = partlist.get(partlist.size() - 1);
if (prev.getCommand() == PathPartEntryJSO.BEZIER_CURVETO_ABSOLUTE) {
ctx = cpx + (cpx - prev.getPoints()[2]);
cty = cpy + (cpy - prev.getPoints()[3]);
}
points.push(ctx);
points.push(cty);
points.push(source.shift());
points.push(source.shift());
cpx = source.shift();
cpy = source.shift();
points.push(cpx);
points.push(cpy);
cmd = PathPartEntryJSO.BEZIER_CURVETO_ABSOLUTE;
break;
case 's':
ctx = cpx;
cty = cpy;
prev = partlist.get(partlist.size() - 1);
if (prev.getCommand() == PathPartEntryJSO.BEZIER_CURVETO_ABSOLUTE) {
ctx = cpx + (cpx - prev.getPoints()[2]);
cty = cpy + (cpy - prev.getPoints()[3]);
}
points.push(ctx);
points.push(cty);
points.push(cpx + source.shift());
points.push(cpy + source.shift());
cpx += source.shift();
cpy += source.shift();
points.push(cpx);
points.push(cpy);
cmd = PathPartEntryJSO.BEZIER_CURVETO_ABSOLUTE;
break;
case 'Q':
points.push(source.shift());
points.push(source.shift());
cpx = source.shift();
cpy = source.shift();
points.push(cpx);
points.push(cpy);
cmd = PathPartEntryJSO.QUADRATIC_CURVETO_ABSOLUTE;
break;
case 'q':
points.push(cpx + source.shift());
points.push(cpy + source.shift());
cpx += source.shift();
cpy += source.shift();
points.push(cpx);
points.push(cpy);
cmd = PathPartEntryJSO.QUADRATIC_CURVETO_ABSOLUTE;
break;
case 'T':
ctx = cpx;
cty = cpy;
prev = partlist.get(partlist.size() - 1);
if (prev.getCommand() == PathPartEntryJSO.QUADRATIC_CURVETO_ABSOLUTE) {
ctx = cpx + (cpx - prev.getPoints()[0]);
cty = cpy + (cpy - prev.getPoints()[1]);
}
cpx = source.shift();
cpy = source.shift();
points.push(ctx);
points.push(cty);
points.push(cpx);
points.push(cpy);
cmd = PathPartEntryJSO.QUADRATIC_CURVETO_ABSOLUTE;
break;
case 't':
ctx = cpx;
cty = cpy;
prev = partlist.get(partlist.size() - 1);
if (prev.getCommand() == PathPartEntryJSO.QUADRATIC_CURVETO_ABSOLUTE) {
ctx = cpx + (cpx - prev.getPoints()[0]);
cty = cpy + (cpy - prev.getPoints()[1]);
}
cpx += source.shift();
cpy += source.shift();
points.push(ctx);
points.push(cty);
points.push(cpx);
points.push(cpy);
cmd = PathPartEntryJSO.QUADRATIC_CURVETO_ABSOLUTE;
break;
case 'A': {
final double rx = source.shift();
final double ry = source.shift();
final double ps = source.shift();
final double fa = source.shift();
final double fs = source.shift();
final double x1 = cpx;
final double y1 = cpy;
cpx = source.shift();
cpy = source.shift();
PathPartList.convertEndpointToCenterParameterization(points, x1, y1, cpx, cpy, fa, fs, rx, ry, ps);
points.push(cpx);
points.push(cpy);
cmd = PathPartEntryJSO.ARCTO_ABSOLUTE;
break;
}
case 'a': {
final double rx = source.shift();
final double ry = source.shift();
final double ps = source.shift();
final double fa = source.shift();
final double fs = source.shift();
final double x1 = cpx;
final double y1 = cpy;
cpx += source.shift();
cpy += source.shift();
PathPartList.convertEndpointToCenterParameterization(points, x1, y1, cpx, cpy, fa, fs, rx, ry, ps);
points.push(cpx);
points.push(cpy);
cmd = PathPartEntryJSO.ARCTO_ABSOLUTE;
break;
}
}
if (cmd != PathPartEntryJSO.UNDEFINED_PATH_PART) {
partlist.push(PathPartEntryJSO.make(cmd, points.toArray()));
}
}
if ((chr == 'z') || (chr == 'Z')) {
partlist.Z();
}
}
}