package latexDraw.parsers.pst;
import java.awt.Color;
import java.awt.geom.Point2D;
import latexDraw.parsers.CodeParser;
import latexDraw.parsers.IgnoreCommandException;
import latexDraw.parsers.InvalidFormatCommandException;
import latexDraw.parsers.UnclosedBracketsException;
import latexDraw.psTricks.DviPsColors;
import latexDraw.psTricks.PSTricksConstants;
/**
* Defines a parser that parses pstricks parameters ([...]) and related pstricks stuffs like
* real numbers, strings, and so on. To be efficient, the code core of a pstricks parser should
* be shared with the pstricks parameters parser.<br>
*<br>
* This file is part of LaTeXDraw.<br>
* Copyright (c) 2005-2008 Arnaud BLOUIN<br>
*<br>
* 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.<br>
*<br>
* 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.<br>
*<br>
* 11/21/08<br>
* @author Arnaud BLOUIN<br>
* @version 2.0.2<br>
*/
public class PSTParametersParser extends CodeParser
{
/** The current pstricks parameters. */
protected PSTParameters param;
/**
* Creates and initialises a pstricks parameters parser.
* @param code The code to parse.
* @param params The current pstricks parameters that will be filled
* during the parsing. Can be null.
* @throws IllegalArgumentException If the given code is null.
*/
public PSTParametersParser(String code, PSTParameters params)
{
super(code);
this.param = params;
}
/**
* Skips the useless characters and a possible comma.
* @since 2.0.2
*/
public void skipWSPComma()
{
skipWSP();
if(getChar()==',')
{
nextChar();
skipWSP();
}
}
private void parse_s() throws IgnoreCommandException
{
switch(nextChar())
{
case 'h' : //sh
switch(nextChar())
{
case 'a' : // sha
if(nextChar()=='d' && nextChar()=='o' && nextChar()=='w') // shadow
switch(nextChar())
{
case 's' : // shadowsize = Real unit
if(nextChar()=='i' && nextChar()=='z' && nextChar()=='e' && (nextChar()=='=' || isWSPComment()))
{
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.shadowSize = val;
}
else
throw new IgnoreCommandException(-1);
break;
case 'a' : // shadowangle = Real
if(nextChar()=='n' && nextChar()=='g' && nextChar()=='l' && nextChar()=='e' &&
(nextChar()=='=' || isWSPComment()))
{
double val = readEqualReal();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.shadowAngle = val;
}
else
throw new IgnoreCommandException(-1);
break;
case 'c' : // shadowcolor = String
if(nextChar()=='o' && nextChar()=='l' && nextChar()=='o' && nextChar()=='r' &&
(nextChar()=='=' || isWSPComment()))
{
String s2 = readEqualString(true);
Color c = DviPsColors.getColour(s2); // We search the colour
if(c==null) throw new IgnoreCommandException(-1);
param.shadowCol = c;
}
else throw new IgnoreCommandException(-1);
break;
default :
skipWSPComments();
if((getChar()=='=' || isWSPComment()))
{// shadow
String s = readEqualString(false);
if("true".equals(s)) param.isShadow = true;//$NON-NLS-1$
else if("false".equals(s)) param.isShadow = false;//$NON-NLS-1$
else throw new IgnoreCommandException(-1);
}
else
throw new IgnoreCommandException(-1);
}
else throw new IgnoreCommandException(-1);
break;
case 'o' : // sho
if(nextChar()=='w')//show
switch(nextChar())
{
case 'p'://showp
if(nextChar()=='o' && nextChar()=='i' && nextChar()=='n' && nextChar()=='t' &&
nextChar()=='s' && (nextChar()=='=' || isWSPComment()))
{//showpoints = true|false
String s = readEqualString(false);
if("true".equals(s)) param.showPoints = true;//$NON-NLS-1$
else if("false".equals(s)) param.showPoints = false;//$NON-NLS-1$
else throw new IgnoreCommandException(-1);
}
else throw new IgnoreCommandException(-1);
break;
case 'o'://showo
if(nextChar()=='r' && nextChar()=='i' && nextChar()=='g' && nextChar()=='i' &&
nextChar()=='n' && (nextChar()=='=' || isWSPComment()))
{//showorigin = true|false
String s = readEqualString(false);
if("true".equals(s)) param.showOrigin = true;//$NON-NLS-1$
else if("false".equals(s)) param.showOrigin = false;//$NON-NLS-1$
else throw new IgnoreCommandException(-1);
}
else throw new IgnoreCommandException(-1);
break;
default: throw new IgnoreCommandException(-1);
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
break;
case 'u' : // su
if(nextChar()=='b' && nextChar()=='g' && nextChar()=='r' && nextChar()=='i' && nextChar()=='d') // subgrid
{
switch(nextChar())
{
case 'd' : // subgridd
switch(nextChar())
{
case 'o' : // subgriddots = Integer
if(nextChar()=='t' && nextChar()=='s' && (nextChar()=='=' || isWSPComment()))
{
int val = readEqualInteger();
if(val==Integer.MAX_VALUE) throw new IgnoreCommandException(-1);
param.subGridDots = val;
}
else throw new IgnoreCommandException(-1);
break;
case 'i' : // subgriddiv = Integer
if(nextChar()=='v' && (nextChar()=='=' || isWSPComment()))
{
int val = readEqualInteger();
if(val==Integer.MAX_VALUE) throw new IgnoreCommandException(-1);
param.subGridDiv = val;
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
break;
case 'w' : // subgridwidth = Real unit
if(nextChar()=='i' && nextChar()=='d' && nextChar()=='t' && nextChar()=='h' &&
(nextChar()=='=' || isWSPComment()))
{
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.subGridWidth = val;
}
else throw new IgnoreCommandException(-1);
break;
case 'c': // subgridcolor = String
if(nextChar()=='o' && nextChar()=='l' && nextChar()=='o' && nextChar()=='r' &&
(nextChar()=='=' || isWSPComment()))
{
String s2 = readEqualString(true);
Color c = DviPsColors.getColour(s2); // We search the colour
if(c==null) throw new IgnoreCommandException(-1);
param.subGridCol = c;
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
}else throw new IgnoreCommandException(-1);
break;
case 'w' : // swapaxes = true|false
if(nextChar()=='a' && nextChar()=='p' && nextChar()=='a' && nextChar()=='x' &&
nextChar()=='e' && nextChar()=='s' && (nextChar()=='=' || isWSPComment()))
{
String s = readEqualString(false);
if("true".equals(s)) param.swapAxes = true;//$NON-NLS-1$
else if("false".equals(s)) param.swapAxes = false;//$NON-NLS-1$
else throw new IgnoreCommandException(-1);
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
}
private void parse_d() throws IgnoreCommandException
{
switch(nextChar())
{
case 'o' : // do
switch(nextChar())
{
case 't' : // dot
switch(nextChar())
{
case 's' : // dots
switch(nextChar())
{
case 'i' : //dotsize = Real unit Real
if(nextChar()=='z' && nextChar()=='e' && (nextChar()=='=' || isWSPComment()))
{
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.arrowDotSD = val;
skipWSPComments();
if(Character.isDigit(getChar()) || getChar()=='.')
{
val = readReal();// If there is the x, we read it
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.arrowDotSN = val;
}
else param.arrowDotSN = 0.;
}
else throw new IgnoreCommandException(-1);
break;
case 't' : // dotstyle = String
if(nextChar()=='y' && nextChar()=='l' && nextChar()=='e' &&
(nextChar()=='=' || isWSPComment()))
{
skipWSPComments();
if(getChar()!='=')
throw new IgnoreCommandException(-1);
nextChar();
skipWSPComments();
String s;
if(getChar()=='|' || getChar()=='+')
{
s = String.valueOf((char)getChar());
nextChar();
}
else
{
s = readString(false);
if(getChar()=='*')
{
s+=String.valueOf((char)getChar());
nextChar();
}
}
if(!PSTricksConstants.isValidDotStyle(s))
throw new IgnoreCommandException(-1);
param.dotStyle = s;
}
else throw new IgnoreCommandException(-1);
break;
case 'c' : // dotscale = Real Real
if(nextChar()=='a' && nextChar()=='l' && nextChar()=='e' &&
(nextChar()=='=' || isWSPComment()))
{
double val = readEqualReal(); // We read the first parameter
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.dotScale1 = val;
if(Character.isDigit(getChar()) || getChar()=='.')
{
val = readReal();// If there is the x, we read it
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.dotScale2 = val;
}
else param.dotScale2 = 1.;
}
else throw new IgnoreCommandException(-1);
break;
case 'e' : // dotsep = Real unit
if(nextChar()=='p' && (nextChar()=='=' || isWSPComment()))
{
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.dotStep = val;
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
break;
case 'a' : // dotangle = Real
if(nextChar()=='n' && nextChar()=='g' && nextChar()=='l' && nextChar()=='e' &&
(nextChar()=='=' || isWSPComment()))
{
double val = readEqualReal();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.dotAngle = val;
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
break;
case 'u' : // dou
if(nextChar()=='b' && nextChar()=='l' && nextChar()=='e') // double
switch(nextChar())
{
case 'l' : // doubleline = true/false
if(nextChar()=='i' && nextChar()=='n' && nextChar()=='e' &&
(nextChar()=='=' || isWSPComment()))
{
String s = readEqualString(false);
if(s==null) throw new IgnoreCommandException(-1);
if(s.equals("true")) param.dbleLine = true;//$NON-NLS-1$
else if(s.equals("false")) param.dbleLine = false;//$NON-NLS-1$
}
else throw new IgnoreCommandException(-1);
break;
case 's' : // doublesep = Real unit
if(nextChar()=='e' && nextChar()=='p' && (nextChar()=='=' || isWSPComment()))
{
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.dbleSep = val;
}
else throw new IgnoreCommandException(-1);
break;
case 'c' : // doubleColor = String
if(nextChar()=='o' && nextChar()=='l' && nextChar()=='o' && nextChar()=='r' &&
(nextChar()=='=' || isWSPComment()))
{
String s2 = readEqualString(true);
Color c = DviPsColors.getColour(s2); // We search the colour
if(c==null) throw new IgnoreCommandException(-1);
param.dbleColor = c;
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
break;
case 'i' : // dimen = outer|inner|middle
if(nextChar()=='m' && nextChar()=='e' && nextChar()=='n' && (nextChar()=='=' || isWSPComment()))
{
String s = readEqualString(false);
if(PSTricksConstants.BORDERS_INSIDE.equals(s) || PSTricksConstants.BORDERS_MIDDLE.equals(s) ||
PSTricksConstants.BORDERS_OUTSIDE.equals(s))
param.borderPos = s;
else throw new IgnoreCommandException(-1);
}
else throw new IgnoreCommandException(-1);
break;
case 'a' : // dash = Real unit Real unit
if(nextChar()=='s' && nextChar()=='h' && (nextChar()=='=' || isWSPComment()))
{
double r1 = readEqualRealUnit();
if(Double.isNaN(r1)) throw new IgnoreCommandException(-1);
double r2 = readRealUnit(); // We read the second parameter
if(Double.isNaN(r2)) throw new IgnoreCommandException(-1);
param.dashBlack = r1;
param.dashWhite = r2;
}
else throw new IgnoreCommandException(-1);
break;
case 'x'://dx = real unit
if((nextChar()=='=' || isWSPComment()))
{
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.dxLabelDist = val;
}
else throw new IgnoreCommandException(-1);
break;
case 'y'://dy = real unit
if((nextChar()=='=' || isWSPComment()))
{
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.dyLabelDist = val;
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
}
private void parse_a() throws IgnoreCommandException
{
switch(getChar())
{
case 'r':
switch(nextChar())
{
case 'c' : //arc
if(nextChar()=='s' && nextChar()=='e' && nextChar()=='p') // arcsep
switch(nextChar())
{
case 'A' : // arcsepA = Real unit
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.arcSepA = val;
break;
case 'B' : // arcSepB = Real unit
val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.arcSepB = val;
break;
default :
if(nextChar()=='=' || isWSPComment())
{ // arcsep = Real
val = readEqualReal();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.arcSep = val;
}
else throw new IgnoreCommandException(-1);
}
else throw new IgnoreCommandException(-1);
break;
case 'r' : //arr
if(nextChar()=='o' && nextChar()=='w') // arrow
switch(nextChar())
{
case 's' : // arrows
switch(nextChar())
{
case 'i' : // arrowsize= Real unit Real
if(nextChar()=='z' && nextChar()=='e' && (nextChar()=='=' || isWSPComment()))
{
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.arrowSizeD = val;
skipWSPComments();
if((getChar()>='0' && getChar()<='9') || getChar()=='.')
{
val = readReal();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.arrowSizeN = val;// If there is the x, we read it
}
}
else throw new IgnoreCommandException(-1);
break;
case '=':
nextChar();
skipWSPComments();
if(getChar()!='-')
{
param.arrowStyle[0] = String.valueOf((char)getChar());
nextChar();
skipWSPComments();
if(getChar()!='-')
throw new IgnoreCommandException(-1);
}
nextChar();
skipWSPComments();
if(getChar()!=',' || getChar()!=']')
param.arrowStyle[1] = String.valueOf((char)getChar());
nextChar();
break;
default: throw new IgnoreCommandException(-1);
}
break;
case 'l' : // arrowlength = Real
if(nextChar()=='e' && nextChar()=='n' && nextChar()=='g' && nextChar()=='t' &&
nextChar()=='h' && (nextChar()=='=' || isWSPComment()))
{
double val = readEqualReal();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.arrowLgth = val;
}
else throw new IgnoreCommandException(-1);
break;
case 'i' : // arrowinset = Real
if(nextChar()=='n' && nextChar()=='s' && nextChar()=='e' && nextChar()=='t' &&
(nextChar()=='=' || isWSPComment()))
{
double val = readEqualReal();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.arrowInset = val;
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
} // switch(params.charAt(id[0]))
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
} // switch(params.charAt(id[0]))
break;
case 'x': // ax
if(nextChar()=='e' && nextChar()=='s' && nextChar()=='s' &&
nextChar()=='t' && nextChar()=='y' && nextChar()=='l' && nextChar()=='e' &&
(nextChar()=='=' || isWSPComment()))
{// axestyle
String val = readEqualString(true);
if(val==null) throw new IgnoreCommandException(-1);
param.axesStyle = val;
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
}
private void parse_g() throws IgnoreCommandException
{
switch(nextChar())
{
case 'r' : //gr
switch(nextChar())
{
case 'i':
if(nextChar()=='d')// grid
switch(nextChar())
{
case 'l' ://gridl
if(nextChar()=='a' && nextChar()=='b' && nextChar()=='e' && nextChar()=='l')// gridlabel
switch(nextChar())
{
case 's' : // gridlabels = Real unit
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.gridLabel = val;
break;
case 'c' : // gridlabelcolor = string
Color c = DviPsColors.getColour(readEqualString(true));
if(c==null) throw new IgnoreCommandException(-1);
param.labelsGridCol = c;
break;
default : throw new IgnoreCommandException(-1);
}
else throw new IgnoreCommandException(-1);
break;
case 'w' : //gridwidth = Real unit
if(nextChar()=='i' && nextChar()=='d' && nextChar()=='t' && nextChar()=='h' &&
(nextChar()=='=' || isWSPComment()))
{
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.gridWidth = val;
}
else throw new IgnoreCommandException(-1);
break;
case 'c' : // gridcolor = string
if(nextChar()=='o' && nextChar()=='l' && nextChar()=='o' && nextChar()=='r' &&
(nextChar()=='=' || isWSPComment()))
{
String s = readEqualString(true);
Color c = DviPsColors.getColour(s); // We search the colour
if(c==null) throw new IgnoreCommandException(-1);
param.gridColor = c;
}
else throw new IgnoreCommandException(-1);
break;
case 'd' : // griddots = Integer
if(nextChar()=='o' && nextChar()=='t' && nextChar()=='s' &&
(nextChar()=='=' || isWSPComment()))
{
int val = readEqualInteger();
if(val==Integer.MAX_VALUE) throw new IgnoreCommandException(-1);
param.gridDots = val;
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
else throw new IgnoreCommandException(-1);
break;
case 'a'://gra
if(nextChar()=='d')// grad
switch(nextChar())
{
case 'b' : //gradbegin
if(nextChar()=='e' && nextChar()=='g' && nextChar()=='i' && nextChar()=='n' &&
(nextChar()=='=' || isWSPComment()))
{
Color c = DviPsColors.getColour(readEqualString(true)); // We search the colour
if(c==null) throw new IgnoreCommandException(-1);
param.gradBegin = c;
}
else throw new IgnoreCommandException(-1);
break;
case 'e' : //gradend
if(nextChar()=='n' && nextChar()=='d' && (nextChar()=='=' || isWSPComment()))
{
Color c = DviPsColors.getColour(readEqualString(true)); // We search the colour
if(c==null) throw new IgnoreCommandException(-1);
param.gradEnd = c;
}
else throw new IgnoreCommandException(-1);
break;
case 'l' : //gradlines
if(nextChar()=='i' && nextChar()=='n' && nextChar()=='e' && nextChar()=='s' &&
(nextChar()=='=' || isWSPComment()))
{
int val = readEqualInteger();
if(val==Integer.MAX_VALUE) throw new IgnoreCommandException(-1);
param.gradLines = val;
}
else throw new IgnoreCommandException(-1);
break;
case 'm' : //gradmidpoint
if(nextChar()=='i' && nextChar()=='d' && nextChar()=='p' && nextChar()=='o' &&
nextChar()=='i' && nextChar()=='n' && nextChar()=='t' &&
(nextChar()=='=' || isWSPComment()))
{
double midPt = readEqualReal();
if(midPt>=0 && midPt<=1)
param.gradMidPoint = midPt;
else throw new IgnoreCommandException(-1);
}
else throw new IgnoreCommandException(-1);
break;
case 'a' : //gradangle
if(nextChar()=='n' && nextChar()=='g' && nextChar()=='l' && nextChar()=='e' &&
(nextChar()=='=' || isWSPComment()))
{
double val = readEqualReal();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.gradAngle = val;
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
break;
case 'a' : //gangle
if(nextChar()=='n' && nextChar()=='g' && nextChar()=='l' && nextChar()=='e' &&
(nextChar()=='=' || isWSPComment()))
{
double val = readEqualReal();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.gangle = val;
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
}
private void parse_l() throws IgnoreCommandException
{
switch(nextChar())
{
case 'i':// li
if(nextChar()=='n' && nextChar()=='e')// line
switch(nextChar())
{
case 'w' : // linewidth = Real unit
if(nextChar()=='i' && nextChar()=='d' && nextChar()=='t' && nextChar()=='h' &&
(nextChar()=='=' || isWSPComment()))
{
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.lineWidth = val;
}
else throw new IgnoreCommandException(-1);
break;
case 'c' : // lineColor = string
if(nextChar()=='o' && nextChar()=='l' && nextChar()=='o' && nextChar()=='r' &&
(nextChar()=='=' || isWSPComment()))
{
Color c = DviPsColors.getColour(readEqualString(true)); // We search the colour
if(c==null) throw new IgnoreCommandException(-1);
param.lineColor = c;
}
else throw new IgnoreCommandException(-1);
break;
case 'a' : // linearc = Real unit
if(nextChar()=='r' && nextChar()=='c' && (nextChar()=='=' || isWSPComment()))
{
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.lineArc = val;
}
else throw new IgnoreCommandException(-1);
break;
case 's' : //lines
if(nextChar()=='t' && nextChar()=='y' && nextChar()=='l' && nextChar()=='e' &&
(nextChar()=='=' || isWSPComment()))// linestyle = string
{
String val = readEqualString(false);
if(val==null || val.length()==0) throw new IgnoreCommandException(-1);
param.lineStyle = val;
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
else throw new IgnoreCommandException(-1);
break;
case 'a':// la
if(nextChar()=='b' && nextChar()=='e' && nextChar()=='l' && nextChar()=='s'&&
(nextChar()=='=' || isWSPComment()))//labels
{
String val = readEqualString(false);
if(val==null) throw new IgnoreCommandException(-1);
param.labels = val;
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
}
private void parse_f() throws IgnoreCommandException
{
switch(nextChar())
{
case 'i': //fi
if(nextChar()=='l' && nextChar()=='l')//fill
{
if(nextChar()=='c')//fillc
{
if(nextChar()=='o' && nextChar()=='l' && nextChar()=='o' && nextChar()=='r' &&
(nextChar()=='=' || isWSPComment()))
{ // fillColor = string
Color c = DviPsColors.getColour(readEqualString(true)); // We search the colour
if(c==null) throw new IgnoreCommandException(-1);
param.fillColor = c;
}
else throw new IgnoreCommandException(-1);
}else
if(getChar()=='s')//fills
{
if(nextChar()=='t' && nextChar()=='y' && nextChar()=='l' && nextChar()=='e' &&
(nextChar()=='=' || isWSPComment()))
{ // fillstyle = string
String r = readEqualString(false);
if(r==null || r.length()==0) throw new IgnoreCommandException(-1);
if(getChar()=='*') // We add the '*' the fillstyle
{
r+=String.valueOf((char)getChar());
nextChar();
}
param.fillStyle = r;
}else throw new IgnoreCommandException(-1);
}else throw new IgnoreCommandException(-1);
}else throw new IgnoreCommandException(-1);
break;
case 'r': //fr
if(nextChar()=='a' && nextChar()=='m' && nextChar()=='e')//frame
switch(nextChar())
{
case 'a' : // framearc = real
if(nextChar()=='r' && nextChar()=='c' && (nextChar()=='=' || isWSPComment()))
{
double val = readEqualReal();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.frameArc = val;
}
else throw new IgnoreCommandException(-1);
break;
case 's' : // framesep = real unit
if(nextChar()=='e' && nextChar()=='p' && (nextChar()=='=' || isWSPComment()))
{
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.frameSep = val;
}
else throw new IgnoreCommandException(-1);
break;
default :
throw new IgnoreCommandException(-1);
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
}
private void parse_b() throws IgnoreCommandException
{
switch(nextChar())
{
case 'o' ://bo
switch(nextChar())
{
case 'r'://bor
if(nextChar()=='d' && nextChar()=='e' && nextChar()=='r')//border
if(nextChar()=='c')//borderc
{
if(nextChar()=='o' && nextChar()=='l' && nextChar()=='o' &&
nextChar()=='r' && (nextChar()=='=' || isWSPComment()))
{ // bordercolor = string
Color c = DviPsColors.getColour(readEqualString(true)); // We search the colour
if(c==null) throw new IgnoreCommandException(-1);
param.borderColor = c;
}
else throw new IgnoreCommandException(-1);
}else
if(nextChar()=='=' || isWSPComment())
{// border = Real unit
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.border = val;
}
else throw new IgnoreCommandException(-1);
else throw new IgnoreCommandException(-1);
break;
case 'x' :
if(nextChar()=='s' && nextChar()=='e' && nextChar()=='p' && (nextChar()=='=' || isWSPComment()))
{//boxsep = true|false
String s = readEqualString(false);
if(s==null) throw new IgnoreCommandException(-1);
if(s.equals("true")) param.boxSep = true;//$NON-NLS-1$
else if(s.equals("false")) param.boxSep = false;//$NON-NLS-1$
}
else throw new IgnoreCommandException(-1);
break;
default :
throw new IgnoreCommandException(-1);
}
break;
case 'r' :
if(nextChar()=='a' && nextChar()=='c' && nextChar()=='k' &&
nextChar()=='e' && nextChar()=='t' && nextChar()=='l' &&
nextChar()=='e' && nextChar()=='n' && nextChar()=='g' &&
nextChar()=='t' && nextChar()=='h' && (nextChar()=='=' || isWSPComment()))
{
double val = readEqualReal();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.arrowBrLgth = val;
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
}
private void parse_c() throws IgnoreCommandException
{
switch(nextChar())
{
case 'o' : // cornersize = absolute/relative
if(nextChar()=='r' && nextChar()=='n' && nextChar()=='e' &&
nextChar()=='r' && nextChar()=='s' && nextChar()=='i' &&
nextChar()=='z' && nextChar()=='e' &&(nextChar()=='=' || isWSPComment()))
{
String r = readString(false); // We read the parameter
if(r==null) throw new IgnoreCommandException(-1);
r = r.toLowerCase();
if(r.equals(PSTricksConstants.TOKEN_ABSOLUTE))
param.isCornerRel = false;
else if(r.equals(PSTricksConstants.TOKEN_RELATIVE))
param.isCornerRel = true;
else throw new IgnoreCommandException(-1);
}
else throw new IgnoreCommandException(-1);
break;
case 'u' : // curvate = Real Real Real
if(nextChar()=='r' && nextChar()=='v' && nextChar()=='a' &&
nextChar()=='t' && nextChar()=='e' && (nextChar()=='=' || isWSPComment()))
{
double val1 = readEqualReal();
if(Double.isNaN(val1)) throw new IgnoreCommandException(-1);
double val2 = readReal();
if(Double.isNaN(val2)) throw new IgnoreCommandException(-1);
double val3 = readReal();
if(Double.isNaN(val3)) throw new IgnoreCommandException(-1);
param.curvature1 = val1;
param.curvature2 = val2;
param.curvature3 = val3;
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
}
private void parse_o() throws IgnoreCommandException
{
if(nextChar()=='r' && nextChar()=='i' && nextChar()=='g' &&
nextChar()=='i' && nextChar()=='n' && (nextChar()=='=' || isWSPComment()))
{// origin
skipWSPComments();
if(getChar()!='=') throw new IgnoreCommandException(-1);
nextChar();
skipWSPComments();
double x=Double.NaN, y=Double.NaN;
int c = getChar();
if((c>='0' && c<='9') || c=='.' || c=='-')
{
x = readRealUnit();// If there is the x, we read it
if(Double.isNaN(x)) throw new IgnoreCommandException(-1);
}
skipWSPComments();
if(getChar()!=',') throw new IgnoreCommandException(-1);
nextChar();
skipWSPComments();
c = getChar();
if((c>='0' && c<='9') || c=='.' || c=='-')
{
y = readRealUnit();// If there is the y, we read it
if(Double.isNaN(y)) throw new IgnoreCommandException(-1);
}
skipWSPComments();
if(getChar()!='}') throw new IgnoreCommandException(-1);
nextChar();
skipWSPComments();
if(!Double.isNaN(x)) param.origin.x = x;
if(!Double.isNaN(y)) param.origin.y = y;
}
else throw new IgnoreCommandException(-1);
}
private void parse_h() throws IgnoreCommandException
{
if(nextChar()=='a' && nextChar()=='t' && nextChar()=='c' && nextChar()=='h')
switch(nextChar())
{
case 'a' : // hatchangle = Real
if(nextChar()=='n' && nextChar()=='g' && nextChar()=='l' && nextChar()=='e' &&
(nextChar()=='=' || isWSPComment()))
{
double val = readEqualReal();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.hatchAngle = val;
}
else throw new IgnoreCommandException(-1);
break;
case 'w' : // hatchwidth = Real unit
if(nextChar()=='i' && nextChar()=='d' && nextChar()=='t' && nextChar()=='h' &&
(nextChar()=='=' || isWSPComment()))
{
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.hatchWidth = val;
}
else throw new IgnoreCommandException(-1);
break;
case 's' : // hatchsep = Real unit
if(nextChar()=='e' && nextChar()=='p' && (nextChar()=='=' || isWSPComment()))
{
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.hatchSep = val;
}
else throw new IgnoreCommandException(-1);
break;
case 'c' : // hatchcolor = colour
if(nextChar()=='o' && nextChar()=='l' && nextChar()=='o' && nextChar()=='r' &&
(nextChar()=='=' || isWSPComment()))
{
Color c = DviPsColors.getColour(readEqualString(true)); // We search the colour
if(c==null) throw new IgnoreCommandException(-1);
param.hatchCol = c;
}
else throw new IgnoreCommandException(-1);
break;
default : throw new IgnoreCommandException(-1);
}
else throw new IgnoreCommandException(-1);
}
private void parse_r() throws IgnoreCommandException
{
if(nextChar()=='b' && nextChar()=='r' && nextChar()=='a' &&
nextChar()=='c' && nextChar()=='k' && nextChar()=='e' &&
nextChar()=='t' && nextChar()=='l' && nextChar()=='e' &&
nextChar()=='n' && nextChar()=='g' && nextChar()=='t' &&
nextChar()=='h' && (nextChar()=='=' || isWSPComment()))
{ // bracketlength = real
double val = readEqualReal();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.arrowrBrLgth = val;
}
else throw new IgnoreCommandException(-1);
}
private void parse_t() throws IgnoreCommandException
{
switch(nextChar())
{
case 'b': //tb
if(nextChar()=='a' && nextChar()=='r' && nextChar()=='s' && nextChar()=='i' &&
nextChar()=='z' && nextChar()=='e' && (nextChar()=='=' || isWSPComment()))
{ // tbarsize = Real unit Real
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.arrowTBarSD = val;
skipWSPComments();
if((getChar()>='0' && getChar()<='9') || getChar()=='.')
{
val = readReal();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.arrowTBarSN = val;
}
}
else throw new IgnoreCommandException(-1);
break;
case 'i': //ti
if(nextChar()=='c' && nextChar()=='k' && nextChar()=='s')// ticks
switch(nextChar())
{
case 't'://tickst
if(nextChar()=='y' && nextChar()=='l' && nextChar()=='e' &&
(nextChar()=='=' || isWSPComment()))
{//tickstyle = string
String val = readString(false);
if(val==null) throw new IgnoreCommandException(-1);
param.ticksStyle = val;
}
else throw new IgnoreCommandException(-1);
break;
case 'i'://ticksi
if(nextChar()=='z' && nextChar()=='e' && (nextChar()=='=' || isWSPComment()))
{//ticksize = real unit
double val = readEqualRealUnit();
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.ticksSize = val;
}
else throw new IgnoreCommandException(-1);
break;
default :
if(getChar()=='=' || isWSPComment())//ticks = string
{
String val = readString(false);
if(val==null) throw new IgnoreCommandException(-1);
param.ticks = val;
}
else throw new IgnoreCommandException(-1);
}
break;
}
}
private void parse_u() throws IgnoreCommandException
{
if(nextChar()=='n' && nextChar()=='i' && nextChar()=='t' && (nextChar()=='=' || isWSPComment()))
{ // unit = real
double r = readEqualReal();
if(Double.isNaN(r)) throw new IgnoreCommandException(-1);
skipWSPComments();
int c = getChar();
if((c>='0' && c<='9') && c!=',')
{
r = convertInCm(r, readString(false));
if(Double.isNaN(r)) throw new IgnoreCommandException(-1);
param.unit = r;
}
else
param.unit *= r;
}
else throw new IgnoreCommandException(-1);
}
private void parse_x() throws IgnoreCommandException
{
if(nextChar()=='u' && nextChar()=='n' && nextChar()=='i' &&
nextChar()=='t' && (nextChar()=='=' || isWSPComment()))
{ // xunit = real
double r = readEqualReal();
if(Double.isNaN(r)) throw new IgnoreCommandException(-1);
skipWSPComments();
int c = getChar();
if((c>='0' && c<='9') && c!=',')
{
r = convertInCm(r, readString(false));
if(Double.isNaN(r)) throw new IgnoreCommandException(-1);
param.xUnit = r;
}
else param.xUnit *= r;
}
else throw new IgnoreCommandException(-1);
}
private void parse_y() throws IgnoreCommandException
{
if(nextChar()=='u' && nextChar()=='n' && nextChar()=='i' &&
nextChar()=='t' && (nextChar()=='=' || isWSPComment()))
{// yunit = real
double r = readEqualReal(); // We read the parameter
if(Double.isNaN(r)) throw new IgnoreCommandException(-1);
skipWSPComments();
int c = getChar();
if((c>='0' && c<='9') && c!=',')
{
r = convertInCm(r, readString(false));
if(Double.isNaN(r)) throw new IgnoreCommandException(-1);
param.yUnit = r;
}
else param.yUnit *= r;
}
else throw new IgnoreCommandException(-1);
}
private void parse_O() throws IgnoreCommandException
{
switch(nextChar())
{
case 'x': // Ox
double val = readEqualReal(); // We read the parameter
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.ox = val;
break;
case 'y': // Oy
val = readEqualReal(); // We read the parameter
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.oy = val;
break;
default: throw new IgnoreCommandException(-1);
}
}
private void parse_D() throws IgnoreCommandException
{
switch(nextChar())
{
case 'x': // Dx
double val = readEqualReal(); // We read the parameter
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.dxIncrement = val;
break;
case 'y': // Dy
val = readEqualReal(); // We read the parameter
if(Double.isNaN(val)) throw new IgnoreCommandException(-1);
param.dyIncrement = val;
break;
default: throw new IgnoreCommandException(-1);
}
}
@Override
public void parse() throws UnclosedBracketsException
{
skipWSPComments();
if(getChar()!='[')
return ;
nextChar();
skipWSPComments();
while(!isEOC() && getChar()!=']')
try
{
switch(getChar())
{
case 's' :
parse_s();
break;
case 'd' :
parse_d();
break;
case 'a' :
parse_a();
break;
case 'g' :
parse_g();
break;
case 'l' :
parse_l();
break;
case 'f' :
parse_f();
break;
case 'b' :
parse_b();
break;
case 'c' :
parse_c();
break;
case 'o' : // origin = {Real unit, Real unit}
parse_o();
break;
case 'h' :
parse_h();
break;
case 'r' :// rbracketlength = Real
parse_r();
break;
case 't' :
parse_t();
break;
case 'u' : // unit = Real unit
parse_u();
break;
case 'x' : // xunit = Real unit
parse_x();
break;
case 'y' : // yunit = Real unit
parse_y();
break;
case 'O':
parse_O();
break;
case 'D':
parse_D();
break;
case 9 : // '\t'
case ',' :
case ' ' :
nextChar();
skipWSPComments();
break;
default :
if(isWSPComment())
{
if(isEOL()) incLinePosition();
skipWSPComments();
}
else throw new IgnoreCommandException(-1);
}//switch
}
catch(IgnoreCommandException e) // We jump to the next parameter
{//TODO add something to collect the errors.
int cptPar = 0;
int cptBrack = 0;
int c = getChar();
while((c!=',' || cptPar!=0 || cptBrack!=0) && !isEOC() && c!=']')
{
if(c=='{') cptBrack++;
else if(c=='(') cptPar++;
else if(c=='}') cptBrack--;
else if(c==')') cptPar--;
c = nextChar();
}
if(c!=']')
nextChar();
}
if(getChar()!=']')
throw new UnclosedBracketsException();
nextChar();
}
@Override
public boolean isComment()
{
return getChar()=='%';
}
@Override
public String skipComment()
{
String comment;
if(isComment())
{
comment = "";
char c;
while(!isEOL() && !isEOC())
{
c = (char)nextChar();
if(!isEOL() && !isEOC())
comment += c;
}
nextChar();
incLinePosition();
skipWSP();
}
else comment = null;
return comment;
}
@Override
public void skipWSP()
{
while(getChar()==' ' || isEOL() || getChar()=='\t')
{
if(isEOL())
incLinePosition();
nextChar();
}
}
@Override
public boolean isWSP()
{
int c = getChar();
return c==' ' || c=='\n' || c=='\r';
}
/**
* @return True if the current token is a WPS or a comment token.
* @since 2.0.2
*/
public boolean isWSPComment()
{
return isWSP() || getChar()=='%' || getChar()=='\t';
}
/**
* Reads '= Real'.
* @return The read value.
*/
public double readEqualReal()
{
skipWSPComments();
if(getChar()!='=')
return Double.NaN;
nextChar();
return readReal();
}
/**
* Reads the next real.
* @return The real.
*/
public double readReal()
{
StringBuffer sb = new StringBuffer();
int c;
int i = 0;
int lgth;
double v;
boolean positive = true;
boolean again = true;
skipWSPComments();
c = getChar();
while(c=='-'||c=='+'||c=='.' || (c>='0' && c<='9')) {
sb.append((char)c);
c = nextChar();
}
lgth = sb.length();
while(i<lgth && again)
switch(sb.charAt(i)) {
case '-':
positive = !positive;
i++;
break;
case '+':
i++;
break;
default:
again = false;
break;
}
if(!again && i>0)
sb.delete(0, i);
try { v = Double.valueOf(sb.toString()); }
catch(Exception e) { v = Double.NaN; }
v = positive ? v : -1*v;
return v;
}
/**
* Reads '= Real unit'
* @return The read value in cm or NaN.
*/
public double readEqualRealUnit()
{
double v = readEqualReal();
String lgth;
skipWSPComments();
lgth = readString(false);
return convertInCm(v, lgth);
}
/**
* Reads the next string.
* @return The string
*/
public String readString(boolean withNumber)
{
StringBuffer sb = new StringBuffer();
int c;
skipWSPComments();
c = getChar();
if(withNumber)
while((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9'))
{
sb.append((char)c);
c = nextChar();
}
else
while((c>='a' && c<='z') || (c>='A' && c<='Z'))
{
sb.append((char)c);
c = nextChar();
}
return sb.toString();
}
/**
* Converts a value with a given unit of length (cm, pt, mm, in, or nothing) to centimetre
* @param value The value to convert.
* @param lgth The unit of length of value.
* @return The value in centimetre (may be NaN).
*/
public static double convertInCm(double value, String lgth)
{
if(lgth==null || lgth.length()==0)
return value;
lgth = lgth.toLowerCase();
if(lgth.equals(PSTricksConstants.TOKEN_PS_PT))
value/= PSTricksConstants.CM_VAL_PT; //by default the unit is postscript point
else if(lgth.equals(PSTricksConstants.TOKEN_INCH))
value*=PSTricksConstants.INCH_VAL_CM;
else if(lgth.equals(PSTricksConstants.TOKEN_MM))
value/=10.;
else if(!lgth.equals(PSTricksConstants.TOKEN_CM))
value = Double.NaN;
return value;
}
/**
* Reads '= string'
* @param withNumber If true The string can contains number like 'color0'
* @return The read string or null.
*/
public String readEqualString(boolean withNumber)
{
skipWSPComments();
if(getChar()!='=')
return null;
nextChar();
return readString(withNumber);
}
/**
* Reads '= Integer'
* @return The read value or MAX_VALUE.
*/
public int readEqualInteger()
{
skipWSPComments();
if(getChar()!='=')
return Integer.MAX_VALUE;
nextChar();
return readInteger();
}
/**
* Reads the next integer.
* @return The integer or MAX_VALUE.
*/
public int readInteger()
{
StringBuffer sb = new StringBuffer();
int c;
int value;
skipWSPComments();
c = getChar();
while(c=='+' || (c>='0' && c<='9')) {
sb.append((char)c);
c = nextChar();
}
try { value = Integer.valueOf(sb.toString()); }
catch(Exception e) { value = Integer.MAX_VALUE; }
return value;
}
/**
* Reads 'Real unit' converted in cm.
* @return The read value or NaN.
*/
public double readRealUnit()
{
double r = readReal(); // We read the parameter
String lgth = readString(false); // If there is a unit of length, we read it
r = convertInCm(r, lgth);
return r;
}
/**
* Reads one coordinate: (x,y). Beware, for missing coordinates like (5,)
* this function will return (5,NaN) instead of (5,1); because in several cases,
* the missing coordinate is very important.
* @return The read coordinate or null.
* @throws InvalidFormatCommandException If the format of the command is not respected.
*/
public Point2D.Double readOneCoordinate(boolean withUnit) throws InvalidFormatCommandException
{
skipWSPComments();
if(getChar()!='(')
throw new InvalidFormatCommandException(getLinePosition());
double x;
double y;
int c;
nextChar();
skipWSPComments();
c = getChar();
if((c>='0' && c<='9') || c=='.' || c=='-' || c=='+')
x = withUnit ? readRealUnit() : readReal();
else x = Double.NaN;
skipWSPComments();
if(getChar()!=',')
throw new InvalidFormatCommandException(getLinePosition());
nextChar();
skipWSPComments();
c = getChar();
if((c>='0' && c<='9') || c=='.' || c=='-' || c=='+')
y = withUnit ? readRealUnit() : readReal();
else y = Double.NaN;
skipWSPComments();
if(getChar()!=')')
throw new InvalidFormatCommandException(getLinePosition());
nextChar();
return new Point2D.Double(x, y);
}
/**
* @return the current pstricks parameters.
* @since 2.0.2
*/
public PSTParameters getParam()
{
return param;
}
/**
* @param p the current pstricks parameters to set.
* @since 2.0.2
*/
public void setParam(PSTParameters p)
{
this.param = p;
}
}
|