private static double readDouble(PushbackReader read) throws IOException { StringBuffer s = new StringBuffer(); int count = -1; while (true) { char ch = (char) read.read(); // skip spaces if (ch == ' ') continue; count++; // allow a - only if at the beginning if (ch == '-' && count == 0) { // u.p("negative number"); s.append(ch); continue; } if ((ch >= '0' && ch <= '9') || ch == '.') { // u.p("got double part " + ch); s.append(ch); } else { if (ch != ',') { read.unread(ch); } break; } } return Double.parseDouble(s.toString()); }
private static SNode parsePathNode(Elem root) throws IOException { SPath path = new SPath(); String d = root.attr("d"); PushbackReader read = new PushbackReader(new StringReader(d)); int count = 0; double x = 0; double y = 0; SPath.PathPoint prev = null; boolean go = true; while (go) { count++; char ch = (char) read.read(); if (ch == -1) break; double x1, x2, y1, y2; u.p("ch = " + ch); switch (ch) { // absolute move case 'M': x = readDouble(read); y = readDouble(read); prev = path.moveTo(x, y); continue; // relative vertical lineto case 'v': y += readDouble(read); prev = path.lineTo(x, y); continue; // absolute vertical lineto case 'V': y = readDouble(read); prev = path.lineTo(x, y); continue; // relative horiz lineto case 'h': x += readDouble(read); prev = path.lineTo(x, y); continue; case 'H': x = readDouble(read); prev = path.lineTo(x, y); continue; // relative lineto case 'l': x += readDouble(read); y += readDouble(read); prev = path.lineTo(x, y); continue; case 'L': x = readDouble(read); y = readDouble(read); prev = path.lineTo(x, y); continue; // relative cubic curve case 'c': x1 = x + readDouble(read); y1 = y + readDouble(read); x2 = x + readDouble(read); y2 = y + readDouble(read); x += readDouble(read); y += readDouble(read); prev = path.curveTo(prev, x1, y1, x2, y2, x, y); continue; // relative shorthand curve case 's': x2 = x + readDouble(read); y2 = y + readDouble(read); x += readDouble(read); y += readDouble(read); double dx = prev.x - prev.cx1; double dy = prev.y - prev.cy1; double rx = prev.x + dx; double ry = prev.y + dy; prev = path.curveTo(prev, rx, ry, x2, y2, x, y); continue; // absolute cubic curve case 'C': x1 = readDouble(read); y1 = readDouble(read); x2 = readDouble(read); y2 = readDouble(read); x = readDouble(read); y = readDouble(read); prev = path.curveTo(prev, x1, y1, x2, y2, x, y); continue; case 'z': path.close(); break; case ' ': continue; case '\n': continue; // end of string case (char) -1: go = false; break; default: u.p("unrecognized character! " + ch + " " + ((int) ch)); go = false; break; } } parseFill(path, root); parseStroke(path, root); return path; }