
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include <ctype.h>
#include "SkDrawPath.h"
#include "SkParse.h"
#include "SkPoint.h"
#include "SkUtils.h"
#define QUADRATIC_APPROXIMATION 1

#if QUADRATIC_APPROXIMATION
////////////////////////////////////////////////////////////////////////////////////
//functions to approximate a cubic using two quadratics

//      midPt sets the first argument to be the midpoint of the other two
//      it is used by quadApprox
static inline void midPt(SkPoint& dest,const SkPoint& a,const SkPoint& b)
{
    dest.set(SkScalarAve(a.fX, b.fX),SkScalarAve(a.fY, b.fY));
}
//      quadApprox - makes an approximation, which we hope is faster
static void quadApprox(SkPath &fPath, const SkPoint &p0, const SkPoint &p1, const SkPoint &p2)
{
    //divide the cubic up into two cubics, then convert them into quadratics
    //define our points
    SkPoint c,j,k,l,m,n,o,p,q, mid;
    fPath.getLastPt(&c);
    midPt(j, p0, c);
    midPt(k, p0, p1);
    midPt(l, p1, p2);
    midPt(o, j, k);
    midPt(p, k, l);
    midPt(q, o, p);
    //compute the first half
    m.set(SkScalarHalf(3*j.fX - c.fX), SkScalarHalf(3*j.fY - c.fY));
    n.set(SkScalarHalf(3*o.fX -q.fX), SkScalarHalf(3*o.fY - q.fY));
    midPt(mid,m,n);
    fPath.quadTo(mid,q);
    c = q;
    //compute the second half
    m.set(SkScalarHalf(3*p.fX - c.fX), SkScalarHalf(3*p.fY - c.fY));
    n.set(SkScalarHalf(3*l.fX -p2.fX),SkScalarHalf(3*l.fY -p2.fY));
    midPt(mid,m,n);
    fPath.quadTo(mid,p2);
}
#endif


static inline bool is_between(int c, int min, int max)
{
    return (unsigned)(c - min) <= (unsigned)(max - min);
}

static inline bool is_ws(int c)
{
    return is_between(c, 1, 32);
}

static inline bool is_digit(int c)
{
    return is_between(c, '0', '9');
}

static inline bool is_sep(int c)
{
    return is_ws(c) || c == ',';
}

static const char* skip_ws(const char str[])
{
    SkASSERT(str);
    while (is_ws(*str))
        str++;
    return str;
}

static const char* skip_sep(const char str[])
{
    SkASSERT(str);
    while (is_sep(*str))
        str++;
    return str;
}

static const char* find_points(const char str[], SkPoint value[], int count,
     bool isRelative, SkPoint* relative)
{
    str = SkParse::FindScalars(str, &value[0].fX, count * 2);
    if (isRelative) {
        for (int index = 0; index < count; index++) {
            value[index].fX += relative->fX;
            value[index].fY += relative->fY;
        }
    }
    return str;
}

static const char* find_scalar(const char str[], SkScalar* value,
    bool isRelative, SkScalar relative)
{
    str = SkParse::FindScalar(str, value);
    if (isRelative)
        *value += relative;
    return str;
}

void SkDrawPath::parseSVG() {
    fPath.reset();
    const char* data = d.c_str();
    SkPoint f = {0, 0};
    SkPoint c = {0, 0};
    SkPoint lastc = {0, 0};
    SkPoint points[3];
    char op = '\0';
    char previousOp = '\0';
    bool relative = false;
    do {
        data = skip_ws(data);
        if (data[0] == '\0')
            break;
        char ch = data[0];
        if (is_digit(ch) || ch == '-' || ch == '+') {
            if (op == '\0')
                return;
        }
        else {
            op = ch;
            relative = false;
            if (islower(op)) {
                op = (char) toupper(op);
                relative = true;
            }
            data++;
            data = skip_sep(data);
        }
        switch (op) {
            case 'M':
                data = find_points(data, points, 1, relative, &c);
                fPath.moveTo(points[0]);
                op = 'L';
                c = points[0];
                break;
            case 'L':
                data = find_points(data, points, 1, relative, &c);
                fPath.lineTo(points[0]);
                c = points[0];
                break;
            case 'H': {
                SkScalar x;
                data = find_scalar(data, &x, relative, c.fX);
                fPath.lineTo(x, c.fY);
                c.fX = x;
            }
                break;
            case 'V': {
                SkScalar y;
                data = find_scalar(data, &y, relative, c.fY);
                fPath.lineTo(c.fX, y);
                c.fY = y;
            }
                break;
            case 'C':
                data = find_points(data, points, 3, relative, &c);
                goto cubicCommon;
            case 'S':
                data = find_points(data, &points[1], 2, relative, &c);
                points[0] = c;
                if (previousOp == 'C' || previousOp == 'S') {
                    points[0].fX -= lastc.fX - c.fX;
                    points[0].fY -= lastc.fY - c.fY;
                }
            cubicCommon:
    //          if (data[0] == '\0')
    //              return;
#if QUADRATIC_APPROXIMATION
                    quadApprox(fPath, points[0], points[1], points[2]);
#else   //this way just does a boring, slow old cubic
                    fPath.cubicTo(points[0], points[1], points[2]);
#endif
        //if we are using the quadApprox, lastc is what it would have been if we had used
        //cubicTo
                    lastc = points[1];
                    c = points[2];
                break;
            case 'Q':  // Quadratic Bezier Curve
                data = find_points(data, points, 2, relative, &c);
                goto quadraticCommon;
            case 'T':
                data = find_points(data, &points[1], 1, relative, &c);
                points[0] = points[1];
                if (previousOp == 'Q' || previousOp == 'T') {
                    points[0].fX = c.fX * 2 - lastc.fX;
                    points[0].fY = c.fY * 2 - lastc.fY;
                }
            quadraticCommon:
                fPath.quadTo(points[0], points[1]);
                lastc = points[0];
                c = points[1];
                break;
            case 'Z':
                fPath.close();
#if 0   // !!! still a bug?
                if (fPath.isEmpty() && (f.fX != 0 || f.fY != 0)) {
                    c.fX -= SkScalar.Epsilon;   // !!! enough?
                    fPath.moveTo(c);
                    fPath.lineTo(f);
                    fPath.close();
                }
#endif
                c = f;
                op = '\0';
                break;
            case '~': {
                SkPoint args[2];
                data = find_points(data, args, 2, false, NULL);
                fPath.moveTo(args[0].fX, args[0].fY);
                fPath.lineTo(args[1].fX, args[1].fY);
            }
                break;
            default:
                SkASSERT(0);
                return;
        }
        if (previousOp == 0)
            f = c;
        previousOp = op;
    } while (data[0] > 0);
}
