Example usage for android.graphics Path rMoveTo

List of usage examples for android.graphics Path rMoveTo

Introduction

In this page you can find the example usage for android.graphics Path rMoveTo.

Prototype

public void rMoveTo(float dx, float dy) 

Source Link

Document

Set the beginning of the next contour relative to the last point on the previous contour.

Usage

From source file:com.larvalabs.svgandroid.SVGParser.java

/**
 * This is where the hard-to-parse paths are handled.
 * Uppercase rules are absolute positions, lowercase are relative.
 * Types of path rules:/*from   www .j  a  v  a2 s  .c  om*/
 * <p/>
 * <ol>
 * <li>M/m - (x y)+ - Move to (without drawing)
 * <li>Z/z - (no params) - Close path (back to starting point)
 * <li>L/l - (x y)+ - Line to
 * <li>H/h - x+ - Horizontal ine to
 * <li>V/v - y+ - Vertical line to
 * <li>C/c - (x1 y1 x2 y2 x y)+ - Cubic bezier to
 * <li>S/s - (x2 y2 x y)+ - Smooth cubic bezier to (shorthand that assumes the x2, y2 from previous C/S is the x1, y1 of this bezier)
 * <li>Q/q - (x1 y1 x y)+ - Quadratic bezier to
 * <li>T/t - (x y)+ - Smooth quadratic bezier to (assumes previous control point is "reflection" of last one w.r.t. to current point)
 * </ol>
 * <p/>
 * Numbers are separate by whitespace, comma or nothing at all (!) if they are self-delimiting, (ie. begin with a - sign)
 *
 * @param s the path string from the XML
 */
private static Path doPath(String s) {
    int n = s.length();
    ParserHelper ph = new ParserHelper(s, 0);
    ph.skipWhitespace();
    Path p = new Path();
    float lastX = 0;
    float lastY = 0;
    float lastX1 = 0;
    float lastY1 = 0;
    RectF r = new RectF();
    char cmd = 'x';
    while (ph.pos < n) {
        char next = s.charAt(ph.pos);
        if (!Character.isDigit(next) && !(next == '.') && !(next == '-')) {
            cmd = next;
            ph.advance();
        } else if (cmd == 'M') { // implied command
            cmd = 'L';
        } else if (cmd == 'm') { // implied command
            cmd = 'l';
        } else { // implied command
            // Log.d(TAG, "Implied command: " + cmd);
        }
        p.computeBounds(r, true);
        // Log.d(TAG, "  " + cmd + " " + r);
        // Util.debug("* Commands remaining: '" + path + "'.");
        boolean wasCurve = false;
        switch (cmd) {
        case 'M':
        case 'm': {
            float x = ph.nextFloat();
            float y = ph.nextFloat();
            if (cmd == 'm') {
                p.rMoveTo(x, y);
                lastX += x;
                lastY += y;
            } else {
                p.moveTo(x, y);
                lastX = x;
                lastY = y;
            }
            break;
        }
        case 'Z':
        case 'z': {
            p.close();
            break;
        }
        case 'L':
        case 'l': {
            float x = ph.nextFloat();
            float y = ph.nextFloat();
            if (cmd == 'l') {
                p.rLineTo(x, y);
                lastX += x;
                lastY += y;
            } else {
                p.lineTo(x, y);
                lastX = x;
                lastY = y;
            }
            break;
        }
        case 'H':
        case 'h': {
            float x = ph.nextFloat();
            if (cmd == 'h') {
                p.rLineTo(x, 0);
                lastX += x;
            } else {
                p.lineTo(x, lastY);
                lastX = x;
            }
            break;
        }
        case 'V':
        case 'v': {
            float y = ph.nextFloat();
            if (cmd == 'v') {
                p.rLineTo(0, y);
                lastY += y;
            } else {
                p.lineTo(lastX, y);
                lastY = y;
            }
            break;
        }
        case 'C':
        case 'c': {
            wasCurve = true;
            float x1 = ph.nextFloat();
            float y1 = ph.nextFloat();
            float x2 = ph.nextFloat();
            float y2 = ph.nextFloat();
            float x = ph.nextFloat();
            float y = ph.nextFloat();
            if (cmd == 'c') {
                x1 += lastX;
                x2 += lastX;
                x += lastX;
                y1 += lastY;
                y2 += lastY;
                y += lastY;
            }
            p.cubicTo(x1, y1, x2, y2, x, y);
            lastX1 = x2;
            lastY1 = y2;
            lastX = x;
            lastY = y;
            break;
        }
        case 'S':
        case 's': {
            wasCurve = true;
            float x2 = ph.nextFloat();
            float y2 = ph.nextFloat();
            float x = ph.nextFloat();
            float y = ph.nextFloat();
            if (cmd == 's') {
                x2 += lastX;
                x += lastX;
                y2 += lastY;
                y += lastY;
            }
            float x1 = 2 * lastX - lastX1;
            float y1 = 2 * lastY - lastY1;
            p.cubicTo(x1, y1, x2, y2, x, y);
            lastX1 = x2;
            lastY1 = y2;
            lastX = x;
            lastY = y;
            break;
        }
        case 'A':
        case 'a': {
            float rx = ph.nextFloat();
            float ry = ph.nextFloat();
            float theta = ph.nextFloat();
            int largeArc = (int) ph.nextFloat();
            int sweepArc = (int) ph.nextFloat();
            float x = ph.nextFloat();
            float y = ph.nextFloat();
            if (cmd == 'a') {
                x += lastX;
                y += lastY;
            }
            drawArc(p, lastX, lastY, x, y, rx, ry, theta, largeArc == 1, sweepArc == 1);
            lastX = x;
            lastY = y;
            break;
        }
        default:
            Log.d(TAG, "Invalid path command: " + cmd);
            ph.advance();
        }
        if (!wasCurve) {
            lastX1 = lastX;
            lastY1 = lastY;
        }
        ph.skipWhitespace();
    }
    return p;
}

From source file:com.jiahuan.svgmapview.core.helper.map.SVGParser.java

/**
 * This is where the hard-to-parse paths are handled. Uppercase rules are
 * absolute positions, lowercase are relative. Types of path rules:
 * <p/>/*from   w  ww  . ja va2s . c o m*/
 * <ol>
 * <li>M/m - (x y)+ - Move to (without drawing)
 * <li>Z/z - (no params) - Close path (back to starting point)
 * <li>L/l - (x y)+ - Line to
 * <li>H/h - x+ - Horizontal ine to
 * <li>V/v - y+ - Vertical line to
 * <li>C/c - (x1 y1 x2 y2 x y)+ - Cubic bezier to
 * <li>S/s - (x2 y2 x y)+ - Smooth cubic bezier to (shorthand that assumes
 * the x2, y2 from previous C/S is the x1, y1 of this bezier)
 * <li>Q/q - (x1 y1 x y)+ - Quadratic bezier to
 * <li>T/t - (x y)+ - Smooth quadratic bezier to (assumes previous control
 * point is "reflection" of last one w.r.t. to current point)
 * </ol>
 * <p/>
 * Numbers are separate by whitespace, comma or nothing at all (!) if they
 * are self-delimiting, (ie. begin with a - sign)
 * 
 * @param s
 *            the path string from the XML
 */
private static Path doPath(String s) {
    int n = s.length();
    ParserHelper ph = new ParserHelper(s, 0);
    ph.skipWhitespace();
    Path p = new Path();
    float lastX = 0;
    float lastY = 0;
    float lastX1 = 0;
    float lastY1 = 0;
    float subPathStartX = 0;
    float subPathStartY = 0;
    char prevCmd = 0;
    while (ph.pos < n) {
        char cmd = s.charAt(ph.pos);
        switch (cmd) {
        case '-':
        case '+':
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            if (prevCmd == 'm' || prevCmd == 'M') {
                cmd = (char) ((prevCmd) - 1);
                break;
            } else if (("lhvcsqta").indexOf(Character.toLowerCase(prevCmd)) >= 0) {
                cmd = prevCmd;
                break;
            }
        default: {
            ph.advance();
            prevCmd = cmd;
        }
        }

        boolean wasCurve = false;
        switch (cmd) {
        case 'M':
        case 'm': {
            float x = ph.nextFloat();
            float y = ph.nextFloat();
            if (cmd == 'm') {
                subPathStartX += x;
                subPathStartY += y;
                p.rMoveTo(x, y);
                lastX += x;
                lastY += y;
            } else {
                subPathStartX = x;
                subPathStartY = y;
                p.moveTo(x, y);
                lastX = x;
                lastY = y;
            }
            break;
        }
        case 'Z':
        case 'z': {
            p.close();
            p.moveTo(subPathStartX, subPathStartY);
            lastX = subPathStartX;
            lastY = subPathStartY;
            lastX1 = subPathStartX;
            lastY1 = subPathStartY;
            wasCurve = true;
            break;
        }
        case 'T':
        case 't':
            // todo - smooth quadratic Bezier (two parameters)
        case 'L':
        case 'l': {
            float x = ph.nextFloat();
            float y = ph.nextFloat();
            if (cmd == 'l') {
                p.rLineTo(x, y);
                lastX += x;
                lastY += y;
            } else {
                p.lineTo(x, y);
                lastX = x;
                lastY = y;
            }
            break;
        }
        case 'H':
        case 'h': {
            float x = ph.nextFloat();
            if (cmd == 'h') {
                p.rLineTo(x, 0);
                lastX += x;
            } else {
                p.lineTo(x, lastY);
                lastX = x;
            }
            break;
        }
        case 'V':
        case 'v': {
            float y = ph.nextFloat();
            if (cmd == 'v') {
                p.rLineTo(0, y);
                lastY += y;
            } else {
                p.lineTo(lastX, y);
                lastY = y;
            }
            break;
        }
        case 'C':
        case 'c': {
            wasCurve = true;
            float x1 = ph.nextFloat();
            float y1 = ph.nextFloat();
            float x2 = ph.nextFloat();
            float y2 = ph.nextFloat();
            float x = ph.nextFloat();
            float y = ph.nextFloat();
            if (cmd == 'c') {
                x1 += lastX;
                x2 += lastX;
                x += lastX;
                y1 += lastY;
                y2 += lastY;
                y += lastY;
            }
            p.cubicTo(x1, y1, x2, y2, x, y);
            lastX1 = x2;
            lastY1 = y2;
            lastX = x;
            lastY = y;
            break;
        }
        case 'Q':
        case 'q':
            // todo - quadratic Bezier (four parameters)
        case 'S':
        case 's': {
            wasCurve = true;
            float x2 = ph.nextFloat();
            float y2 = ph.nextFloat();
            float x = ph.nextFloat();
            float y = ph.nextFloat();
            if (Character.isLowerCase(cmd)) {
                x2 += lastX;
                x += lastX;
                y2 += lastY;
                y += lastY;
            }
            float x1 = 2 * lastX - lastX1;
            float y1 = 2 * lastY - lastY1;
            p.cubicTo(x1, y1, x2, y2, x, y);
            lastX1 = x2;
            lastY1 = y2;
            lastX = x;
            lastY = y;
            break;
        }
        case 'A':
        case 'a': {
            float rx = ph.nextFloat();
            float ry = ph.nextFloat();
            float theta = ph.nextFloat();
            int largeArc = ph.nextFlag();
            int sweepArc = ph.nextFlag();
            float x = ph.nextFloat();
            float y = ph.nextFloat();
            if (cmd == 'a') {
                x += lastX;
                y += lastY;
            }
            drawArc(p, lastX, lastY, x, y, rx, ry, theta, largeArc, sweepArc);
            lastX = x;
            lastY = y;
            break;
        }
        default:
            Log.w(TAG, "Invalid path command: " + cmd);
            ph.advance();
        }
        if (!wasCurve) {
            lastX1 = lastX;
            lastY1 = lastY;
        }
        ph.skipWhitespace();
    }
    return p;
}