From acfe4770cdcddf37457f90980e55fe658773a070 Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Fri, 27 May 2022 17:29:50 +0300
Subject: [PATCH] nanosvg: sync with mainstream:
This imports the following four commits from mainstream nanosvg:
https://github.com/memononen/nanosvg/commit/3cdd4a9d788695699799b37d492e45e2c3625790
https://github.com/memononen/nanosvg/commit/ccdb1995134d340a93fb20e3a3d323ccb3838dd0
https://github.com/memononen/nanosvg/commit/214cf85efcdc67524335ad0e2a2d5982246b6a72
https://github.com/memononen/nanosvg/commit/3bcdf2f3cdc1bf9197c2dce81368bfc6f99205a7
This adds roundf() as a new dependency: Since SDL_roundf() requires
SDL >= 2.0.16, invented a tiny local SDLIMAGE_roundf() function for
it instead.
---
IMG_svg.c | 5 ++++
nanosvg.h | 69 ++++++++++++++++++++++-----------------------------
nanosvgrast.h | 4 +--
3 files changed, 36 insertions(+), 42 deletions(-)
diff --git a/IMG_svg.c b/IMG_svg.c
index e834c7db..03f281da 100644
--- a/IMG_svg.c
+++ b/IMG_svg.c
@@ -27,6 +27,10 @@
#ifdef LOAD_SVG
+static float SDLCALL SDLIMAGE_roundf(float x) {
+ return (x >= 0.0f) ? SDL_floorf(x + 0.5f) : SDL_ceilf(x - 0.5f);
+}
+
/* Replace C runtime functions with SDL C runtime functions for building on Windows */
#define free SDL_free
#define malloc SDL_malloc
@@ -63,6 +67,7 @@
#define sqrt SDL_sqrt
#define sqrtf SDL_sqrtf
#define tanf SDL_tanf
+#define roundf SDLIMAGE_roundf
#ifndef FLT_MAX
#define FLT_MAX 3.402823466e+38F
#endif
diff --git a/nanosvg.h b/nanosvg.h
index bc45cfb2..0ceb2c75 100644
--- a/nanosvg.h
+++ b/nanosvg.h
@@ -189,8 +189,6 @@ NSVG_EXPORT void nsvgDelete(NSVGimage* image);
#endif
#endif
-#endif // NANOSVG_H
-
#ifdef NANOSVG_IMPLEMENTATION
/*
@@ -1246,35 +1244,23 @@ static const char* nsvg__getNextPathItem(const char* s, char* it)
static unsigned int nsvg__parseColorHex(const char* str)
{
- unsigned int c = 0, r = 0, g = 0, b = 0;
- int n = 0;
- str++; // skip #
- // Calculate number of characters.
- while(str[n] && !nsvg__isspace(str[n]))
- n++;
- if (n == 6) {
- sscanf(str, "%x", &c);
- } else if (n == 3) {
- sscanf(str, "%x", &c);
- c = (c&0xf) | ((c&0xf0) << 4) | ((c&0xf00) << 8);
- c |= c<<4;
- }
- r = (c >> 16) & 0xff;
- g = (c >> 8) & 0xff;
- b = c & 0xff;
- return NSVG_RGB(r,g,b);
+ unsigned int r=0, g=0, b=0;
+ if (sscanf(str, "#%2x%2x%2x", &r, &g, &b) == 3 ) // 2 digit hex
+ return NSVG_RGB(r, g, b);
+ if (sscanf(str, "#%1x%1x%1x", &r, &g, &b) == 3 ) // 1 digit hex, e.g. #abc -> 0xccbbaa
+ return NSVG_RGB(r*17, g*17, b*17); // same effect as (r<<4|r), (g<<4|g), ..
+ return NSVG_RGB(128, 128, 128);
}
static unsigned int nsvg__parseColorRGB(const char* str)
{
- int r = -1, g = -1, b = -1;
- char s1[32]="", s2[32]="";
- sscanf(str + 4, "%d%[%%, \t]%d%[%%, \t]%d", &r, s1, &g, s2, &b);
- if (strchr(s1, '%')) {
- return NSVG_RGB((r*255)/100,(g*255)/100,(b*255)/100);
- } else {
- return NSVG_RGB(r,g,b);
- }
+ unsigned int r=0, g=0, b=0;
+ float rf=0, gf=0, bf=0;
+ if (sscanf(str, "rgb(%u, %u, %u)", &r, &g, &b) == 3) // decimal integers
+ return NSVG_RGB(r, g, b);
+ if (sscanf(str, "rgb(%f%%, %f%%, %f%%)", &rf, &gf, &bf) == 3) // decimal integer percentage
+ return NSVG_RGB(roundf(rf*2.55f), roundf(gf*2.55f), roundf(bf*2.55f)); // (255 / 100.0f)
+ return NSVG_RGB(128, 128, 128);
}
typedef struct NSVGNamedColor {
@@ -1849,10 +1835,9 @@ static int nsvg__parseAttr(NSVGparser* p, const char* name, const char* value)
if (style) {
nsvg__parseStyle(p, style->description);
}
- }
- else {
+ } else {
return 0;
- }
+ }
return 1;
}
@@ -2232,7 +2217,12 @@ static void nsvg__pathArcTo(NSVGparser* p, float* cpx, float* cpy, float* args,
// The loop assumes an iteration per end point (including start and end), this +1.
ndivs = (int)(fabsf(da) / (NSVG_PI*0.5f) + 1.0f);
hda = (da / (float)ndivs) / 2.0f;
- kappa = fabsf(4.0f / 3.0f * (1.0f - cosf(hda)) / sinf(hda));
+ // Fix for ticket #179: division by 0: avoid cotangens around 0 (infinite)
+ if ((hda < 1e-3f) && (hda > -1e-3f))
+ hda *= 0.5f;
+ else
+ hda = (1.0f - cosf(hda)) / sinf(hda);
+ kappa = fabsf(4.0f / 3.0f * hda);
if (da < 0.0f)
kappa = -kappa;
@@ -2844,10 +2834,10 @@ static char *nsvg__strndup(const char *s, size_t n)
static void nsvg__content(void* ud, const char* s)
{
NSVGparser* p = (NSVGparser*)ud;
- if (p->styleFlag) {
+ if (p->styleFlag) {
int state = 0;
- const char* start = s;
+ const char* start = s;
while (*s) {
char c = *s;
if (nsvg__isspace(c) || c == '{') {
@@ -2859,15 +2849,14 @@ static void nsvg__content(void* ud, const char* s)
p->styles->name = nsvg__strndup(start, (size_t)(s - start));
start = s + 1;
state = 2;
- }
+ }
} else if (state == 2 && c == '}') {
p->styles->description = nsvg__strndup(start, (size_t)(s - start));
state = 0;
- }
- else if (state == 0) {
+ } else if (state == 0) {
start = s;
state = 1;
- }
+ }
s++;
}
// if (*s == '{' && state == NSVG_XML_CONTENT) {
@@ -2888,9 +2877,7 @@ static void nsvg__content(void* ud, const char* s)
// s++;
// }
//}
-
}
- // empty
}
static void nsvg__imageBounds(NSVGparser* p, float* bounds)
@@ -3109,7 +3096,7 @@ NSVG_EXPORT NSVGpath* nsvgDuplicatePath(NSVGpath* p)
}
return NULL;
}
-#endif // 0
+#endif
NSVG_EXPORT void nsvgDelete(NSVGimage* image)
{
@@ -3128,3 +3115,5 @@ NSVG_EXPORT void nsvgDelete(NSVGimage* image)
}
#endif
+
+#endif // NANOSVG_H
diff --git a/nanosvgrast.h b/nanosvgrast.h
index b45430ac..b2a7cf59 100644
--- a/nanosvgrast.h
+++ b/nanosvgrast.h
@@ -76,8 +76,6 @@ NSVG_EXPORT void nsvgDeleteRasterizer(NSVGrasterizer*);
#endif
#endif
-#endif // NANOSVGRAST_H
-
#ifdef NANOSVGRAST_IMPLEMENTATION
/*
@@ -1463,3 +1461,5 @@ NSVG_EXPORT void nsvgRasterize(NSVGrasterizer* r,
}
#endif
+
+#endif // NANOSVGRAST_H