|
@@ -225,6 +225,11 @@ static int nsvg__isdigit(char c)
|
|
|
return c >= '0' && c <= '9';
|
|
|
}
|
|
|
|
|
|
+static int nsvg__isnum(char c)
|
|
|
+{
|
|
|
+ return strchr("0123456789+-.eE", c) != 0;
|
|
|
+}
|
|
|
+
|
|
|
static NSVG_INLINE float nsvg__minf(float a, float b) { return a < b ? a : b; }
|
|
|
static NSVG_INLINE float nsvg__maxf(float a, float b) { return a > b ? a : b; }
|
|
|
|
|
@@ -731,11 +736,9 @@ static void nsvg__lineTo(NSVGparser* p, float x, float y)
|
|
|
|
|
|
static void nsvg__cubicBezTo(NSVGparser* p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y)
|
|
|
{
|
|
|
- if (p->npts > 0) {
|
|
|
- nsvg__addPoint(p, cpx1, cpy1);
|
|
|
- nsvg__addPoint(p, cpx2, cpy2);
|
|
|
- nsvg__addPoint(p, x, y);
|
|
|
- }
|
|
|
+ nsvg__addPoint(p, cpx1, cpy1);
|
|
|
+ nsvg__addPoint(p, cpx2, cpy2);
|
|
|
+ nsvg__addPoint(p, x, y);
|
|
|
}
|
|
|
|
|
|
static NSVGattrib* nsvg__getAttr(NSVGparser* p)
|
|
@@ -805,9 +808,7 @@ static float nsvg__convertToPixels(NSVGparser* p, NSVGcoordinate c, float orig,
|
|
|
static NSVGgradientData* nsvg__findGradientData(NSVGparser* p, const char* id)
|
|
|
{
|
|
|
NSVGgradientData* grad = p->gradients;
|
|
|
- if (id == NULL || *id == '\0')
|
|
|
- return NULL;
|
|
|
- while (grad != NULL) {
|
|
|
+ while (grad) {
|
|
|
if (strcmp(grad->id, id) == 0)
|
|
|
return grad;
|
|
|
grad = grad->next;
|
|
@@ -824,26 +825,19 @@ static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const f
|
|
|
NSVGgradient* grad;
|
|
|
float ox, oy, sw, sh, sl;
|
|
|
int nstops = 0;
|
|
|
- int refIter;
|
|
|
|
|
|
data = nsvg__findGradientData(p, id);
|
|
|
if (data == NULL) return NULL;
|
|
|
|
|
|
// TODO: use ref to fill in all unset values too.
|
|
|
ref = data;
|
|
|
- refIter = 0;
|
|
|
while (ref != NULL) {
|
|
|
- NSVGgradientData* nextRef = NULL;
|
|
|
if (stops == NULL && ref->stops != NULL) {
|
|
|
stops = ref->stops;
|
|
|
nstops = ref->nstops;
|
|
|
break;
|
|
|
}
|
|
|
- nextRef = nsvg__findGradientData(p, ref->ref);
|
|
|
- if (nextRef == ref) break; // prevent infite loops on malformed data
|
|
|
- ref = nextRef;
|
|
|
- refIter++;
|
|
|
- if (refIter > 32) break; // prevent infite loops on malformed data
|
|
|
+ ref = nsvg__findGradientData(p, ref->ref);
|
|
|
}
|
|
|
if (stops == NULL) return NULL;
|
|
|
|
|
@@ -1046,10 +1040,6 @@ static void nsvg__addPath(NSVGparser* p, char closed)
|
|
|
if (closed)
|
|
|
nsvg__lineTo(p, p->pts[0], p->pts[1]);
|
|
|
|
|
|
- // Expect 1 + N*3 points (N = number of cubic bezier segments).
|
|
|
- if ((p->npts % 3) != 1)
|
|
|
- return;
|
|
|
-
|
|
|
path = (NSVGpath*)malloc(sizeof(NSVGpath));
|
|
|
if (path == NULL) goto error;
|
|
|
memset(path, 0, sizeof(NSVGpath));
|
|
@@ -1468,15 +1458,6 @@ static int nsvg__parseUnits(const char* units)
|
|
|
return NSVG_UNITS_USER;
|
|
|
}
|
|
|
|
|
|
-static int nsvg__isCoordinate(const char* s)
|
|
|
-{
|
|
|
- // optional sign
|
|
|
- if (*s == '-' || *s == '+')
|
|
|
- s++;
|
|
|
- // must have at least one digit
|
|
|
- return nsvg__isdigit(*s);
|
|
|
-}
|
|
|
-
|
|
|
static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str)
|
|
|
{
|
|
|
NSVGcoordinate coord = {0, NSVG_UNITS_USER};
|
|
@@ -1616,32 +1597,25 @@ static int nsvg__parseRotate(float* xform, const char* str)
|
|
|
static void nsvg__parseTransform(float* xform, const char* str)
|
|
|
{
|
|
|
float t[6];
|
|
|
- int len;
|
|
|
nsvg__xformIdentity(xform);
|
|
|
while (*str)
|
|
|
{
|
|
|
if (strncmp(str, "matrix", 6) == 0)
|
|
|
- len = nsvg__parseMatrix(t, str);
|
|
|
+ str += nsvg__parseMatrix(t, str);
|
|
|
else if (strncmp(str, "translate", 9) == 0)
|
|
|
- len = nsvg__parseTranslate(t, str);
|
|
|
+ str += nsvg__parseTranslate(t, str);
|
|
|
else if (strncmp(str, "scale", 5) == 0)
|
|
|
- len = nsvg__parseScale(t, str);
|
|
|
+ str += nsvg__parseScale(t, str);
|
|
|
else if (strncmp(str, "rotate", 6) == 0)
|
|
|
- len = nsvg__parseRotate(t, str);
|
|
|
+ str += nsvg__parseRotate(t, str);
|
|
|
else if (strncmp(str, "skewX", 5) == 0)
|
|
|
- len = nsvg__parseSkewX(t, str);
|
|
|
+ str += nsvg__parseSkewX(t, str);
|
|
|
else if (strncmp(str, "skewY", 5) == 0)
|
|
|
- len = nsvg__parseSkewY(t, str);
|
|
|
+ str += nsvg__parseSkewY(t, str);
|
|
|
else{
|
|
|
++str;
|
|
|
continue;
|
|
|
}
|
|
|
- if (len != 0) {
|
|
|
- str += len;
|
|
|
- } else {
|
|
|
- ++str;
|
|
|
- continue;
|
|
|
- }
|
|
|
|
|
|
nsvg__xformPremultiply(xform, t);
|
|
|
}
|
|
@@ -1902,11 +1876,8 @@ static int nsvg__getArgsPerElement(char cmd)
|
|
|
case 'a':
|
|
|
case 'A':
|
|
|
return 7;
|
|
|
- case 'z':
|
|
|
- case 'Z':
|
|
|
- return 0;
|
|
|
}
|
|
|
- return -1;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static void nsvg__pathMoveTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
|
|
@@ -2216,7 +2187,6 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
|
|
|
float args[10];
|
|
|
int nargs;
|
|
|
int rargs = 0;
|
|
|
- char initPoint;
|
|
|
float cpx, cpy, cpx2, cpy2;
|
|
|
const char* tmp[4];
|
|
|
char closedFlag;
|
|
@@ -2239,14 +2209,13 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
|
|
|
nsvg__resetPath(p);
|
|
|
cpx = 0; cpy = 0;
|
|
|
cpx2 = 0; cpy2 = 0;
|
|
|
- initPoint = 0;
|
|
|
closedFlag = 0;
|
|
|
nargs = 0;
|
|
|
|
|
|
while (*s) {
|
|
|
s = nsvg__getNextPathItem(s, item);
|
|
|
if (!*item) break;
|
|
|
- if (cmd != '\0' && nsvg__isCoordinate(item)) {
|
|
|
+ if (nsvg__isnum(item[0])) {
|
|
|
if (nargs < 10)
|
|
|
args[nargs++] = (float)nsvg__atof(item);
|
|
|
if (nargs >= rargs) {
|
|
@@ -2259,7 +2228,6 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
|
|
|
cmd = (cmd == 'm') ? 'l' : 'L';
|
|
|
rargs = nsvg__getArgsPerElement(cmd);
|
|
|
cpx2 = cpx; cpy2 = cpy;
|
|
|
- initPoint = 1;
|
|
|
break;
|
|
|
case 'l':
|
|
|
case 'L':
|
|
@@ -2309,6 +2277,7 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
|
|
|
}
|
|
|
} else {
|
|
|
cmd = item[0];
|
|
|
+ rargs = nsvg__getArgsPerElement(cmd);
|
|
|
if (cmd == 'M' || cmd == 'm') {
|
|
|
// Commit path.
|
|
|
if (p->npts > 0)
|
|
@@ -2317,11 +2286,7 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
|
|
|
nsvg__resetPath(p);
|
|
|
closedFlag = 0;
|
|
|
nargs = 0;
|
|
|
- } else if (initPoint == 0) {
|
|
|
- // Do not allow other commands until initial point has been set (moveTo called once).
|
|
|
- cmd = '\0';
|
|
|
- }
|
|
|
- if (cmd == 'Z' || cmd == 'z') {
|
|
|
+ } else if (cmd == 'Z' || cmd == 'z') {
|
|
|
closedFlag = 1;
|
|
|
// Commit path.
|
|
|
if (p->npts > 0) {
|
|
@@ -2337,12 +2302,6 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
|
|
|
closedFlag = 0;
|
|
|
nargs = 0;
|
|
|
}
|
|
|
- rargs = nsvg__getArgsPerElement(cmd);
|
|
|
- if (rargs == -1) {
|
|
|
- // Command not recognized
|
|
|
- cmd = '\0';
|
|
|
- rargs = 0;
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
// Commit path.
|