Updated NanoSVG to latest version (22 April 2019)
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / third-party / nanosvg / nanosvg.cc
old mode 100644 (file)
new mode 100755 (executable)
index 1022a98..31f5f44
@@ -39,7 +39,7 @@
 #include <math.h>
 
 #define NSVG_PI (3.14159265358979323846264338327f)
-#define NSVG_KAPPA90 (0.5522847493f)    // Lenght proportional to radius of a cubic bezier handle for 90deg arcs.
+#define NSVG_KAPPA90 (0.5522847493f)   // Length proportional to radius of a cubic bezier handle for 90deg arcs.
 
 #define NSVG_ALIGN_MIN 0
 #define NSVG_ALIGN_MID 1
 #define NSVG_NOTUSED(v) do { (void)(1 ? (void)0 : ( (void)(v) ) ); } while(0)
 #define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16))
 
-#define NSVG_INLINE inline
+#ifdef _MSC_VER
+       #pragma warning (disable: 4996) // Switch off security warnings
+       #pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings
+       #ifdef __cplusplus
+       #define NSVG_INLINE inline
+       #else
+       #define NSVG_INLINE
+       #endif
+#else
+       #define NSVG_INLINE inline
+#endif
 
 
 static int nsvg__isspace(char c)
@@ -839,7 +849,6 @@ static void nsvg__addShape(NSVGparser* p)
                shape->fill.color = attr->fillColor;
                shape->fill.color |= (unsigned int)(attr->fillOpacity*255) << 24;
        } else if (attr->hasFill == 2) {
-               shape->opacity *= attr->fillOpacity;
                float inv[6], localBounds[4];
                nsvg__xformInverse(inv, attr->xform);
                nsvg__getLocalBounds(localBounds, shape, inv);
@@ -957,7 +966,7 @@ static double nsvg__atof(const char* s)
        // Parse integer part
        if (nsvg__isdigit(*cur)) {
                // Parse digit sequence
-               intPart = (double)strtoll(cur, &end, 10);
+               intPart = strtoll(cur, &end, 10);
                if (cur != end) {
                        res = (double)intPart;
                        hasIntPart = 1;
@@ -985,7 +994,7 @@ static double nsvg__atof(const char* s)
 
        // Parse optional exponent
        if (*cur == 'e' || *cur == 'E') {
-               int expPart = 0;
+               long expPart = 0;
                cur++; // skip 'E'
                expPart = strtol(cur, &end, 10); // Parse digit sequence with sign
                if (cur != end) {
@@ -1023,7 +1032,7 @@ static const char* nsvg__parseNumber(const char* s, char* it, const int size)
                }
        }
        // exponent
-       if (*s == 'e' || *s == 'E') {
+       if ((*s == 'e' || *s == 'E') && (s[1] != 'm' && s[1] != 'x')) {
                if (i < last) it[i++] = *s;
                s++;
                if (*s == '-' || *s == '+') {
@@ -1082,7 +1091,7 @@ static unsigned int nsvg__parseColorHex(const char* str)
 static unsigned int nsvg__parseColorRGB(const char* str)
 {
        int r = -1, g = -1, b = -1;
-       char s1[32]="", s2[32]="";
+       char s1[33]="", s2[33]="";
        /**
         * In the original file, the formatted data reading did not specify the string with width limitation.
         * To prevent the possible overflow, we replace '%s' with '%32s' here.
@@ -1113,6 +1122,10 @@ NSVGNamedColor nsvg__colors[] = {
        { "gray", NSVG_RGB(128, 128, 128) },
        { "white", NSVG_RGB(255, 255, 255) },
 
+/**
+ * In the original software, it needs to define "NANOSVG_ALL_COLOR_KEYWORDS" in order to support
+ * the following colors. We have removed this because we want to support all the colors.
+ */
        { "aliceblue", NSVG_RGB(240, 248, 255) },
        { "antiquewhite", NSVG_RGB(250, 235, 215) },
        { "aqua", NSVG_RGB( 0, 255, 255) },
@@ -1279,8 +1292,7 @@ static unsigned int nsvg__parseColor(const char* str)
 
 static float nsvg__parseOpacity(const char* str)
 {
-       float val = 0;
-       sscanf(str, "%f", &val);
+       float val = nsvg__atof(str);
        if (val < 0.0f) val = 0.0f;
        if (val > 1.0f) val = 1.0f;
        return val;
@@ -1288,8 +1300,7 @@ static float nsvg__parseOpacity(const char* str)
 
 static float nsvg__parseMiterLimit(const char* str)
 {
-       float val = 0;
-       sscanf(str, "%f", &val);
+       float val = nsvg__atof(str);
        if (val < 0.0f) val = 0.0f;
        return val;
 }
@@ -1320,13 +1331,9 @@ static int nsvg__parseUnits(const char* units)
 static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str)
 {
        NSVGcoordinate coord = {0, NSVG_UNITS_USER};
-       char units[32]="";
-       /**
-        * In the original file, the formatted data reading did not specify the string with width limitation.
-        * To prevent the possible overflow, we replace '%s' with '%32s' here.
-        */
-       sscanf(str, "%f%32s", &coord.value, units);
-       coord.units = nsvg__parseUnits(units);
+       char buf[64];
+       coord.units = nsvg__parseUnits(nsvg__parseNumber(str, buf, 64));
+       coord.value = nsvg__atof(buf);
        return coord;
 }
 
@@ -1518,7 +1525,7 @@ static char nsvg__parseLineJoin(const char* str)
        else if (strcmp(str, "bevel") == 0)
                return NSVG_JOIN_BEVEL;
        // TODO: handle inherit.
-       return NSVG_CAP_BUTT;
+       return NSVG_JOIN_MITER;
 }
 
 static char nsvg__parseFillRule(const char* str)
@@ -2362,11 +2369,26 @@ static void nsvg__parseSVG(NSVGparser* p, const char** attr)
        for (i = 0; attr[i]; i += 2) {
                if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
                        if (strcmp(attr[i], "width") == 0) {
-                               p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 1.0f);
+                               p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
                        } else if (strcmp(attr[i], "height") == 0) {
-                               p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 1.0f);
+                               p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
                        } else if (strcmp(attr[i], "viewBox") == 0) {
-                               sscanf(attr[i + 1], "%f%*[%%, \t]%f%*[%%, \t]%f%*[%%, \t]%f", &p->viewMinx, &p->viewMiny, &p->viewWidth, &p->viewHeight);
+                               const char *s = attr[i + 1];
+                               char buf[64];
+                               s = nsvg__parseNumber(s, buf, 64);
+                               p->viewMinx = nsvg__atof(buf);
+                               while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) s++;
+                               if (!*s) return;
+                               s = nsvg__parseNumber(s, buf, 64);
+                               p->viewMiny = nsvg__atof(buf);
+                               while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) s++;
+                               if (!*s) return;
+                               s = nsvg__parseNumber(s, buf, 64);
+                               p->viewWidth = nsvg__atof(buf);
+                               while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) s++;
+                               if (!*s) return;
+                               s = nsvg__parseNumber(s, buf, 64);
+                               p->viewHeight = nsvg__atof(buf);
                        } else if (strcmp(attr[i], "preserveAspectRatio") == 0) {
                                if (strstr(attr[i + 1], "none") != 0) {
                                        // No uniform scaling
@@ -2753,14 +2775,21 @@ NSVGimage* nsvgParse(char* input, const char* units, float dpi)
 NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi)
 {
        FILE* fp = NULL;
-       size_t size;
+       size_t size = 0;
+       long value = 0;
        char* data = NULL;
        NSVGimage* image = NULL;
 
        fp = fopen(filename, "rb");
        if (!fp) goto error;
        fseek(fp, 0, SEEK_END);
-       size = ftell(fp);
+       value = ftell(fp);
+       /**
+        * In the original file, unsigned long type 'size' gets a return value. But, the return value of 'ftell()' is
+        * signed long type. To prevent interpreting an unexpected large value, we put the comparitive condition here.
+        */
+       if( value < 0 ) goto error;
+       size = value;
        fseek(fp, 0, SEEK_SET);
        data = (char*)malloc(size+1);
        if (data == NULL) goto error;
@@ -2779,10 +2808,40 @@ error:
        return NULL;
 }
 
+NSVGpath* nsvgDuplicatePath(NSVGpath* p)
+{
+    NSVGpath* res = NULL;
+
+    if (p == NULL)
+        return NULL;
+
+    res = (NSVGpath*)malloc(sizeof(NSVGpath));
+    if (res == NULL) goto error;
+    memset(res, 0, sizeof(NSVGpath));
+
+    res->pts = (float*)malloc(p->npts*2*sizeof(float));
+    if (res->pts == NULL) goto error;
+    memcpy(res->pts, p->pts, p->npts * sizeof(float) * 2);
+    res->npts = p->npts;
+
+    memcpy(res->bounds, p->bounds, sizeof(p->bounds));
+
+    res->closed = p->closed;
+
+    return res;
+
+error:
+    if (res != NULL) {
+        free(res->pts);
+        free(res);
+    }
+    return NULL;
+}
+
 void nsvgDelete(NSVGimage* image)
 {
-    if (image == NULL) return;
        NSVGshape *snext, *shape;
+       if (image == NULL) return;
        shape = image->shapes;
        while (shape != NULL) {
                snext = shape->next;