FileDocCategorySizeDatePackage
PathParser.javaAPI DocphoneME MR2 API (J2ME)22967Wed May 02 18:00:36 BST 2007com.sun.perseus.parser

PathParser

public class PathParser extends NumberParser
The PathParser class converts attributes conforming to the SVG path syntax with the limitation of SVG Tiny which says that SVG Tiny does not support arc to commands.
version
$Id: PathParser.java,v 1.4 2006/04/21 06:40:37 st125089 Exp $

Fields Summary
private float
currentX
Current x and y positions in the path, set by commands such as moveTo or lineTo.
private float
currentY
private float
lastMoveToX
Last moveTo command.
private float
lastMoveToY
private float
smoothQCenterX
The smoothQCenter point is used for smootg quad curves
private float
smoothQCenterY
private float
smoothCCenterX
The smoothQCenter point is used for smooth cubic curves
private float
smoothCCenterY
private com.sun.perseus.j2d.Path
p
The GeneralPath under construction
Constructors Summary
Methods Summary
public com.sun.perseus.j2d.PathgetPath()
Returns the current working path. This can be used, for example, when the parsePath method throws an error to retrieve the state of the path at the time the error occured

return
the Path built from the parsed String

        return p;
    
protected final voidparseC()
Parses a 'C' command.

        current = read();
        skipSpaces();
       
        for (;;) {
            switch (current) {
            default:
                return;
            case '+": case '-": case '.":
            case '0": case '1": case '2": case '3": case '4":
            case '5": case '6": case '7": case '8": case '9":
            }

            float x1 = parseNumber();
            skipCommaSpaces();
            float y1 = parseNumber();
            skipCommaSpaces();
            float x2 = parseNumber();
            skipCommaSpaces();
            float y2 = parseNumber();
            skipCommaSpaces();
            float x = parseNumber();
            skipCommaSpaces();
            float y = parseNumber();

            smoothCCenterX = x2;
            smoothCCenterY = y2;
            currentX = x;
            currentY = y;
            p.curveTo(x1, y1, smoothCCenterX, smoothCCenterY, 
                      currentX, currentY);
            smoothQCenterX = currentX;
            smoothQCenterY = currentY;
            skipCommaSpaces();
        }
    
protected final voidparseH()
Parses a 'H' command.

        current = read();
        skipSpaces();

        for (;;) {
            switch (current) {
            case '+": case '-": case '.":
            case '0": case '1": case '2": case '3": case '4":
            case '5": case '6": case '7": case '8": case '9":
                float x = parseNumber();
                currentX = x;
                smoothQCenterX = x;
                smoothCCenterX = x;

                smoothQCenterY = currentY;
                smoothCCenterY = currentY;
                p.lineTo(smoothCCenterX, smoothCCenterY);
                break;
            default:
                return;
            }
            skipCommaSpaces();
        }
    
protected final voidparseL()
Parses a 'L' command.

        if (current == 'L") {
            current = read();
        }
        skipSpaces();
        for (;;) {
            switch (current) {
            case '+": case '-": case '.":
            case '0": case '1": case '2": case '3": case '4":
            case '5": case '6": case '7": case '8": case '9":
                float x = parseNumber();
                skipCommaSpaces();
                float y = parseNumber();

                currentX = x;
                smoothQCenterX = x;
                smoothCCenterX = x;

                currentY = y;
                smoothQCenterY = y;
                smoothCCenterY = y;

                p.lineTo(smoothCCenterX, smoothCCenterY);
                break;
            default:
                return;
            }
            skipCommaSpaces();
        }
    
protected final voidparseM()
Parses a 'M' command.

        current = read();
        skipSpaces();

        float x = parseNumber();
        skipCommaSpaces();
        float y = parseNumber();
          
        currentX = x;
        smoothQCenterX = x;
        smoothCCenterX = x;

        currentY = y;
        smoothQCenterY = y;
        smoothCCenterY = y;
        p.moveTo(x, y);
        lastMoveToX = x;
        lastMoveToY = y;

        skipCommaSpaces();
    
public com.sun.perseus.j2d.PathparsePath(java.lang.String s)
Parses the input String and returns the corresponding Path if no error is found. If an error occurs, this method throws an IllegalArgumentException.

param
s the String to parse.
return
the Path built from the parsed String

        setString(s);
        p = preparePath();

        setString(s);

        currentX = 0;
        currentY = 0;
        smoothQCenterX = 0;
        smoothQCenterY = 0;
        smoothCCenterX = 0;
        smoothCCenterY = 0;

        current = read();
        skipSpaces();

        // Multiple coordinate pairs after a moveto
        // are like a moveto followed by lineto
        switch(current) {
        case 'm":
            parsem();
            parsel();
            break;
        case 'M":
            parseM();
            parseL();
            break;
	case -1:
 	    //an empty path is valid.
 	    break;        
        default:
            throw new IllegalArgumentException();
        }

        loop: for (;;) {
            switch (current) {
            case 0xD:
            case 0xA: 
            case 0x20:
            case 0x9:
                current = read();
                break;
            case 'z":
            case 'Z":
                current = read();
                p.close();
                currentX = lastMoveToX;
                currentY = lastMoveToY;
                break;
            case 'm":
                parsem();
            case 'l":
                parsel();
                break;
            case 'M":
                parseM();
            case 'L":
                parseL();
                break;
            case 'h":
                parseh();
                break;
            case 'H":
                parseH();
                break;
            case 'v":
                parsev();
                break;
            case 'V":
                parseV();
                break;
            case 'c":
                parsec();
                break;
            case 'C":
                parseC();
                break;
            case 'q":
                parseq();
                break;
            case 'Q":
                parseQ();
                break;
            case 's":
                parses();
                break;
            case 'S":
                parseS();
                break;
            case 't":
                parset();
                break;
            case 'T":
                parseT();
                break;
            case -1:
                break loop;
            default:
                throw new IllegalArgumentException();
            }
          
        }

        skipSpaces();
        if (current != -1) {
            throw new IllegalArgumentException();
        }

        return p;
    
public com.sun.perseus.j2d.PathparsePoints(java.lang.String s)
Parses the input String and returns the corresponding Path.

param
s the String to parse.
return
the GeneralPath built from the parsed String.

        setString(s);
        p = preparePath();

        setString(s);
        
        current = read();

        skipSpaces();
        if (current == -1) {
            // No coordinate pair
            return p;
        }

        // Initial moveTo
        float x = parseNumber();
        skipCommaSpaces();
        float y = parseNumber();
        p.moveTo(x, y);
        lastMoveToX = x;
        lastMoveToY = y;

        while (current != -1) {
            skipSpaces();
            if (current != -1) {
                skipCommaSpaces();
                x = parseNumber();
                skipCommaSpaces();
                y = parseNumber();
                p.lineTo(x, y);
            }
        }

        return p;
    
protected final voidparseQ()
Parses a 'Q' command.

        current = read();
        skipSpaces();

        for (;;) {
            switch (current) {
            default:
                return;
            case '+": case '-": case '.":
            case '0": case '1": case '2": case '3": case '4":
            case '5": case '6": case '7": case '8": case '9":
            }

            float x1 = parseNumber();
            skipCommaSpaces();
            float y1 = parseNumber();
            skipCommaSpaces();
            float x = parseNumber();
            skipCommaSpaces();
            float y = parseNumber();

            smoothQCenterX = x1;
            smoothQCenterY = y1;
            currentX = x;
            currentY = y;
            p.quadTo(smoothQCenterX, smoothQCenterY, currentX, currentY);
            smoothCCenterX = currentX;
            smoothCCenterY = currentY;
            skipCommaSpaces();
        }
    
protected final voidparseS()
Parses a 'S' command.

        current = read();
        skipSpaces();

        for (;;) {
            switch (current) {
            default:
                return;
            case '+": case '-": case '.":
            case '0": case '1": case '2": case '3": case '4":
            case '5": case '6": case '7": case '8": case '9":
            }
          
            float x2 = parseNumber();
            skipCommaSpaces();
            float y2 = parseNumber();
            skipCommaSpaces();
            float x = parseNumber();
            skipCommaSpaces();
            float y = parseNumber();

            float smoothX = currentX * 2 - smoothCCenterX;
            float smoothY = currentY * 2 - smoothCCenterY;
            currentX = x;
            currentY = y;
            p.curveTo(smoothX, smoothY,
                      x2, y2,
                      currentX, currentY);
            smoothCCenterX = x2;
            smoothCCenterY = y2;
            smoothQCenterX = currentX;
            smoothQCenterY = currentY;

            skipCommaSpaces();
        }
    
protected final voidparseT()
Parses a 'T' command.

        current = read();
        skipSpaces();

        for (;;) {
            switch (current) {
            default:
                return;
            case '+": case '-": case '.":
            case '0": case '1": case '2": case '3": case '4":
            case '5": case '6": case '7": case '8": case '9":
            }

            float x = parseNumber();
            skipCommaSpaces();
            float y = parseNumber();

            smoothQCenterX = currentX * 2 - smoothQCenterX;
            smoothQCenterY = currentY * 2 - smoothQCenterY;
            currentX = x;
            currentY = y;
            p.quadTo(smoothQCenterX, smoothQCenterY,
                     currentX, currentY);
            smoothCCenterX = currentX;
            smoothCCenterY = currentY;
            skipCommaSpaces();
        }               
    
protected final voidparseV()
Parses a 'V' command.

        current = read();
        skipSpaces();

        for (;;) {
            switch (current) {
            case '+": case '-": case '.":
            case '0": case '1": case '2": case '3": case '4":
            case '5": case '6": case '7": case '8": case '9":
                float y = parseNumber();
                smoothQCenterX = currentX;
                smoothCCenterX = currentX;

                currentY = y;
                smoothQCenterY = y;
                smoothCCenterY = y;
                p.lineTo(smoothCCenterX, smoothCCenterY);
                break;
            default:
                return;
            }
            skipCommaSpaces();
        }
    
protected final voidparsec()
Parses a 'c' command.

        current = read();
        skipSpaces();
       
        for (;;) {
            switch (current) {
            default:
                return;
            case '+": case '-": case '.":
            case '0": case '1": case '2": case '3": case '4":
            case '5": case '6": case '7": case '8": case '9":
            }

            float x1 = parseNumber();
            skipCommaSpaces();
            float y1 = parseNumber();
            skipCommaSpaces();
            float x2 = parseNumber();
            skipCommaSpaces();
            float y2 = parseNumber();
            skipCommaSpaces();
            float x = parseNumber();
            skipCommaSpaces();
            float y = parseNumber();

            smoothCCenterX = currentX + x2;
            smoothCCenterY = currentY + y2;
            smoothQCenterX = currentX + x;
            smoothQCenterY = currentY + y;
            p.curveTo(currentX + x1, currentY + y1,
                      smoothCCenterX, smoothCCenterY,
                      smoothQCenterX, smoothQCenterY);
            currentX = smoothQCenterX;
            currentY = smoothQCenterY;
            skipCommaSpaces();
        }
    
protected final voidparseh()
Parses a 'h' command.

        current = read();
        skipSpaces();

        for (;;) {
            switch (current) {
            case '+": case '-": case '.":
            case '0": case '1": case '2": case '3": case '4":
            case '5": case '6": case '7": case '8": case '9":
                float x = parseNumber();
                currentX += x;
                smoothQCenterX = currentX;
                smoothCCenterX = currentX;

                smoothQCenterY = currentY;
                smoothCCenterY = currentY;
                p.lineTo(smoothCCenterX, smoothCCenterY);
                break;
            default:
                return;
            }
            skipCommaSpaces();
        }
    
protected final voidparsel()
Parses a 'l' command.

        if (current == 'l") {
            current = read();
        }
        skipSpaces();
        for (;;) {
            switch (current) {
            case '+": case '-": case '.":
            case '0": case '1": case '2": case '3": case '4":
            case '5": case '6": case '7": case '8": case '9":
                float x = parseNumber();
                skipCommaSpaces();
                float y = parseNumber();

                currentX += x;
                smoothQCenterX = currentX;
                smoothCCenterX = currentX;

                currentY += y;
                smoothQCenterY = currentY;
                smoothCCenterY = currentY;
                p.lineTo(smoothCCenterX, smoothCCenterY);
                break;
            default:
                return;
            }
            skipCommaSpaces();
        }
    
protected final voidparsem()
Parses a 'm' command.

        current = read();
        skipSpaces();

        final float x = parseNumber();
        skipCommaSpaces();
        final float y = parseNumber();

        currentX += x;
        smoothQCenterX = currentX;
        smoothCCenterX = currentX;
        currentY += y;
        smoothQCenterY = currentY;
        smoothCCenterY = currentY;
        p.moveTo(smoothCCenterX, smoothCCenterY);
        lastMoveToX = smoothCCenterX;
        lastMoveToY = smoothCCenterY;

        skipCommaSpaces();
    
protected final voidparseq()
Parses a 'q' command.

        current = read();
        skipSpaces();

        for (;;) {
            switch (current) {
            default:
                return;
            case '+": case '-": case '.":
            case '0": case '1": case '2": case '3": case '4":
            case '5": case '6": case '7": case '8": case '9":
            }

            float x1 = parseNumber();
            skipCommaSpaces();
            float y1 = parseNumber();
            skipCommaSpaces();
            float x = parseNumber();
            skipCommaSpaces();
            float y = parseNumber();

            smoothQCenterX = currentX + x1;
            smoothQCenterY = currentY + y1;
            currentX += x; 
            currentY += y;
            p.quadTo(smoothQCenterX, smoothQCenterY, currentX, currentY);
            smoothCCenterX = currentX;
            smoothCCenterY = currentY;

            skipCommaSpaces();
        }
    
protected final voidparses()
Parses a 's' command.

        current = read();
        skipSpaces();

        for (;;) {
            switch (current) {
            default:
                return;
            case '+": case '-": case '.":
            case '0": case '1": case '2": case '3": case '4":
            case '5": case '6": case '7": case '8": case '9":
            }
          
            float x2 = parseNumber();
            skipCommaSpaces();
            float y2 = parseNumber();
            skipCommaSpaces();
            float x = parseNumber();
            skipCommaSpaces();
            float y = parseNumber();

            float smoothX = currentX * 2 - smoothCCenterX;
            float smoothY = currentY * 2 - smoothCCenterY;
            smoothCCenterX = currentX + x2;
            smoothCCenterY = currentY + y2;
            currentX += x;
            currentY += y;

            p.curveTo(smoothX, smoothY,
                      smoothCCenterX, smoothCCenterY,
                      currentX, currentY);

            smoothQCenterX = currentX;
            smoothQCenterY = currentY;
            skipCommaSpaces();
        }
    
protected final voidparset()
Parses a 't' command.

        current = read();
        skipSpaces();

        for (;;) {
            switch (current) {
            default:
                return;
            case '+": case '-": case '.":
            case '0": case '1": case '2": case '3": case '4":
            case '5": case '6": case '7": case '8": case '9":
            }

            float x = parseNumber();
            skipCommaSpaces();
            float y = parseNumber();
          
            smoothQCenterX = currentX * 2 - smoothQCenterX;
            smoothQCenterY = currentY * 2 - smoothQCenterY;
            currentX += x;
            currentY += y;
            p.quadTo(smoothQCenterX, smoothQCenterY, currentX, currentY);
            smoothCCenterX = currentX;
            smoothCCenterY = currentY;
            skipCommaSpaces();
        }               
    
protected final voidparsev()
Parses a 'v' command.

        current = read();
        skipSpaces();

        for (;;) {
            switch (current) {
            case '+": case '-": case '.":
            case '0": case '1": case '2": case '3": case '4":
            case '5": case '6": case '7": case '8": case '9":
                float y = parseNumber();
                smoothQCenterX = currentX;
                smoothCCenterX = currentX;

                currentY += y;
                smoothQCenterY = currentY;
                smoothCCenterY = currentY;
                p.lineTo(smoothCCenterX, smoothCCenterY);
                break;
            default:
                return;
            }
            skipCommaSpaces();
        }
    
protected com.sun.perseus.j2d.PathpreparePath()
Pre-parses the path data to allocate the optimal number of commands and data for the path.

return
p a path with the proper capacity for the comming path.

        int commandCapacity = 0;
        int dataCapacity = 0;

        current = read();
        
        while (current != -1) {
            skipCommaSpaces();
            switch (current) {
            case 'z":
            case 'Z":
                commandCapacity++;
                break;
            case 'm":
            case 'l":
            case 'M":
            case 'L":
            case 'h":
            case 'H":
            case 'v":
            case 'V":
                commandCapacity++;
                dataCapacity += 1;
                break;
            case 'c":
            case 'C":
            case 's":
            case 'S":
                commandCapacity++;
                dataCapacity += 3;
                break;
            case 'q":
            case 'Q":
            case 't":
            case 'T":
                commandCapacity++;
                dataCapacity += 2;
                break;
            default:
                break;
            }
            current = read();
        }

        return new Path(commandCapacity, dataCapacity);