/* * This file is part of LaTeXDraw. * Copyright (c) 2005-2017 Arnaud BLOUIN * LaTeXDraw is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later version. * LaTeXDraw is distributed without any warranty; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. */ package net.sf.latexdraw.parsers.svg.parsers; import java.awt.geom.Point2D; import java.text.ParseException; import java.util.ArrayList; import java.util.List; /** * Defines a parser that parses points from polygons and polylines. * @author Arnaud BLOUIN * @since 2.0.3 */ public class SVGPointsParser extends AbstractSVGParser { /** The parsed points. */ protected List<Point2D> points; /** * Creates and initialises the parser. * @param code The code to parse. * @since 2.0.3 * @throws IllegalArgumentException If the given code is null. */ public SVGPointsParser(final String code) { super(code); points = new ArrayList<>(); } /** * Parses the given code and return the parsed points or null. * @param code The code to parse. * @return The parsed points or null. * @since 2.0.3 */ public static List<Point2D> getPoints(final String code) { try { final SVGPointsParser pp = new SVGPointsParser(code); pp.parse(); return pp.getPoints(); } catch(final Exception e) { return null; } } @Override public void parse() throws ParseException { double c1; double c2; skipWSP(); while(!isEOC()) { c1 = readNumber(); skipWSPComma(); c2 = readNumber(); points.add(new Point2D.Double(c1, c2)); skipWSPComma(); } } /** * Reads a number. * @return The read number. * @throws ParseException If the number is not valid. * @since 2.0.3 */ public double readNumber() throws ParseException { final double n; final boolean isNegative; boolean isFractional = false; boolean isFloating = false; final StringBuilder strn = new StringBuilder(); skipWSP(); if(getChar()=='-' || getChar()=='+') { isNegative = getChar()=='-'; nextChar(); } else isNegative = false; while(!isWSP() && getChar()!=',' && !isEOC()) { switch(getChar()) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': break; case '.': if(isFractional) throw new ParseException("An unexpected dot was read: "+getCode(), getPosition()); //$NON-NLS-1$ isFractional = true; break; case 'e': case 'E': if(isFloating) throw new ParseException("An unexpected exponantial token was read: "+getCode(), getPosition()); //$NON-NLS-1$ isFloating = true; break; case '-': case '+': if(!isFloating) throw new ParseException("An unexpected sign was read: "+getCode(), getPosition()); //$NON-NLS-1$ break; default: throw new ParseException("The following character is not authorised:" + (char)getChar(), getPosition()); //$NON-NLS-1$ } strn.append((char)getChar()); nextChar(); } try { n = Double.parseDouble(strn.toString()); } catch(final Exception e) { throw new ParseException("Not able to parse to given number:" + strn, getPosition()); } //$NON-NLS-1$ return isNegative ? n*-1 : n; } /** * @return The points. * @since 2.0.3 */ public List<Point2D> getPoints() { return points; } }