package org.newdawn.slick.svg.inkscape; import java.util.ArrayList; import java.util.StringTokenizer; import org.newdawn.slick.geom.Path; import org.newdawn.slick.geom.Shape; import org.newdawn.slick.geom.Transform; import org.newdawn.slick.svg.Diagram; import org.newdawn.slick.svg.Figure; import org.newdawn.slick.svg.Loader; import org.newdawn.slick.svg.NonGeometricData; import org.newdawn.slick.svg.ParsingException; import org.w3c.dom.Element; /** * A processor for the <polygon> and <path> elements marked as not an arc. * * @author kevin */ public class PathProcessor implements ElementProcessor { /** * Process the points in a polygon definition * * @param element The XML element being read * @param tokens The tokens representing the path * @return The number of points found * @throws ParsingException Indicates an invalid token in the path */ private static Path processPoly(Element element, StringTokenizer tokens) throws ParsingException { int count = 0; ArrayList pts = new ArrayList(); boolean moved = false; boolean reasonToBePath = false; Path path = null; while (tokens.hasMoreTokens()) { try { String nextToken = tokens.nextToken(); if (nextToken.equals("L")) { float x = Float.parseFloat(tokens.nextToken()); float y = Float.parseFloat(tokens.nextToken()); path.lineTo(x,y); continue; } if (nextToken.equals("z")) { path.close(); continue; } if (nextToken.equals("M")) { if (!moved) { moved = true; float x = Float.parseFloat(tokens.nextToken()); float y = Float.parseFloat(tokens.nextToken()); path = new Path(x,y); continue; } reasonToBePath = true; float x = Float.parseFloat(tokens.nextToken()); float y = Float.parseFloat(tokens.nextToken()); path.startHole(x,y); continue; } if (nextToken.equals("C")) { reasonToBePath = true; float cx1 = Float.parseFloat(tokens.nextToken()); float cy1 = Float.parseFloat(tokens.nextToken()); float cx2 = Float.parseFloat(tokens.nextToken()); float cy2 = Float.parseFloat(tokens.nextToken()); float x = Float.parseFloat(tokens.nextToken()); float y = Float.parseFloat(tokens.nextToken()); path.curveTo(x,y,cx1,cy1,cx2,cy2); continue; } } catch (NumberFormatException e) { throw new ParsingException(element.getAttribute("id"), "Invalid token in points list", e); } } if (!reasonToBePath) { return null; } return path; } /** * @see org.newdawn.slick.svg.inkscape.ElementProcessor#process(org.newdawn.slick.svg.Loader, org.w3c.dom.Element, org.newdawn.slick.svg.Diagram, org.newdawn.slick.geom.Transform) */ public void process(Loader loader, Element element, Diagram diagram, Transform t) throws ParsingException { Transform transform = Util.getTransform(element); transform = new Transform(t, transform); String points = element.getAttribute("points"); if (element.getNodeName().equals("path")) { points = element.getAttribute("d"); } StringTokenizer tokens = new StringTokenizer(points, ", "); Path path = processPoly(element, tokens); NonGeometricData data = Util.getNonGeometricData(element); if (path != null) { Shape shape = path.transform(transform); diagram.addFigure(new Figure(Figure.PATH, shape, data, transform)); } } /** * @see org.newdawn.slick.svg.inkscape.ElementProcessor#handles(org.w3c.dom.Element) */ public boolean handles(Element element) { if (element.getNodeName().equals("path")) { if (!"arc".equals(element.getAttributeNS(Util.SODIPODI, "type"))) { return true; } } return false; } }