Update bundled nanosvg library to latest version

For details see:

- README.bundled-libs.txt
- nanosvg/README.txt
This commit is contained in:
Albrecht Schlosser 2021-02-22 14:36:44 +01:00
parent 28aaa4d4ce
commit 9f84fd05e8
3 changed files with 126 additions and 48 deletions

View File

@ -17,7 +17,7 @@ Current versions of bundled libraries:
Library Version Release date FLTK Version
--------------------------------------------------------------------------
jpeg jpeg-9c 2018-01-14 1.4.0
nanosvg f31098fa85 [1] 2019-05-23 1.4.0
nanosvg a1eea27b3d [1] 2021-02-21 1.4.0
png libpng-1.6.37 2019-04-14 1.4.0
zlib zlib-1.2.11 2017-01-15 1.4.0
@ -25,13 +25,14 @@ Previous versions of bundled libraries:
Library Version Release date FLTK Version
------------------------------------------------------------------
nanosvg ce81a6577c [1] 2018-07-01 1.4.0
nanosvg f31098fa85 [1] 2019-05-23 1.4.x
jpeg jpeg-9a 2014-01-19 1.3.5
png libpng-1.6.16 2014-12-22 1.3.5
zlib zlib-1.2.8 2013-04-28 1.3.5
[1] Git commit in: https://github.com/fltk/nanosvg
See also git tag 'fltk_yyyy-mm-dd' where yyyy-mm-dd == "Release date".
See also git tag 'fltk_yyyy-mm-dd' where yyyy-mm-dd == "Release date"
and file nanosvg/README.txt.
General information:
@ -191,6 +192,9 @@ nanosvg:
so we no longer need our own patches.
AlbrechtS, 04 Feb 2018.
Update (Feb 22, 2021): The upstream library is officially no longer
maintained (see README.md) although updates appear from time to time.
Use this clone (branch 'fltk') to get the nanosvg library with FLTK
specific patches:

View File

@ -11,9 +11,49 @@ The original library can be found here:
https://github.com/memononen/nanosvg
The modified library was cloned and can be found here:
The modified library was forked and can be found here:
https://github.com/fltk/nanosvg
For more information see README.bundled-libs.txt in FLTK's root directory.
Changes in the FLTK fork, branch 'fltk':
-----------------------------------------
$ git show --no-patch fltk_2021-02-22
tag fltk_2021-02-22
Tagger: Albrecht Schlosser <...>
Date: Mon Feb 22 14:16:58 2021 +0100
Included in FLTK 1.4.x as of Feb 22, 2021
Latest upstream changes:
------------------------
commit 3e403ec72a9145cbbcc6c63d94a4caf079aafec2
Merge: cc6c08d 45eb9f8
Author: Mikko Mononen <...>
Date: Fri Nov 20 12:53:11 2020 +0200
Merge pull request #189 from fvogelnew1/Fix-for-#188
Update nanosvg.h
Changes in branch 'fltk':
$ git shortlog master..fltk
AlbrechtS (2):
Fix Visual Studio compilation error (missing long long).
Modify rasterizer to support non-square X,Y axes scaling.
Greg Ercolano (1):
Address crash defined in fltk's issue 180
commit a1eea27b3db2d15d924ea823dd0acc5bd2aa56f1
Author: Greg Ercolano <...>
Date: Mon Jan 18 15:05:13 2021 -0800
Address crash defined in fltk's issue 180

View File

@ -225,11 +225,6 @@ 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; }
@ -736,9 +731,11 @@ 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)
{
nsvg__addPoint(p, cpx1, cpy1);
nsvg__addPoint(p, cpx2, cpy2);
nsvg__addPoint(p, x, y);
if (p->npts > 0) {
nsvg__addPoint(p, cpx1, cpy1);
nsvg__addPoint(p, cpx2, cpy2);
nsvg__addPoint(p, x, y);
}
}
static NSVGattrib* nsvg__getAttr(NSVGparser* p)
@ -808,7 +805,9 @@ static float nsvg__convertToPixels(NSVGparser* p, NSVGcoordinate c, float orig,
static NSVGgradientData* nsvg__findGradientData(NSVGparser* p, const char* id)
{
NSVGgradientData* grad = p->gradients;
while (grad) {
if (id == NULL || *id == '\0')
return NULL;
while (grad != NULL) {
if (strcmp(grad->id, id) == 0)
return grad;
grad = grad->next;
@ -825,19 +824,26 @@ 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;
}
ref = nsvg__findGradientData(p, ref->ref);
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
}
if (stops == NULL) return NULL;
@ -1040,6 +1046,10 @@ 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));
@ -1213,35 +1223,28 @@ 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);
// FLTK: Solve fltk issue#180 / CVE-2019-1000032
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); // has 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);
// FLTK: Solve fltk issue#180 / CVE-2019-1000032
unsigned int r=0, g=0, b=0;
if (sscanf(str, "rgb(%u, %u, %u)", &r, &g, &b) == 3) // decimal integers
return NSVG_RGB(r, g, b);
if (sscanf(str, "rgb(%u%%, %u%%, %u%%)", &r, &g, &b) == 3) { // decimal integer percentage
r = (r <= 100) ? ((r*255)/100) : 255; // clip percentages >100
g = (g <= 100) ? ((g*255)/100) : 255;
b = (b <= 100) ? ((b*255)/100) : 255;
return NSVG_RGB(r, g, b);
}
return NSVG_RGB(128, 128, 128);
}
typedef struct NSVGNamedColor {
@ -1466,6 +1469,15 @@ 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, or start by a dot
return (nsvg__isdigit(*s) || *s == '.');
}
static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str)
{
NSVGcoordinate coord = {0, NSVG_UNITS_USER};
@ -1605,25 +1617,32 @@ 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)
str += nsvg__parseMatrix(t, str);
len = nsvg__parseMatrix(t, str);
else if (strncmp(str, "translate", 9) == 0)
str += nsvg__parseTranslate(t, str);
len = nsvg__parseTranslate(t, str);
else if (strncmp(str, "scale", 5) == 0)
str += nsvg__parseScale(t, str);
len = nsvg__parseScale(t, str);
else if (strncmp(str, "rotate", 6) == 0)
str += nsvg__parseRotate(t, str);
len = nsvg__parseRotate(t, str);
else if (strncmp(str, "skewX", 5) == 0)
str += nsvg__parseSkewX(t, str);
len = nsvg__parseSkewX(t, str);
else if (strncmp(str, "skewY", 5) == 0)
str += nsvg__parseSkewY(t, str);
len = nsvg__parseSkewY(t, str);
else{
++str;
continue;
}
if (len != 0) {
str += len;
} else {
++str;
continue;
}
nsvg__xformPremultiply(xform, t);
}
@ -1884,8 +1903,11 @@ static int nsvg__getArgsPerElement(char cmd)
case 'a':
case 'A':
return 7;
case 'z':
case 'Z':
return 0;
}
return 0;
return -1;
}
static void nsvg__pathMoveTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
@ -2195,6 +2217,7 @@ 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;
@ -2217,13 +2240,14 @@ 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 (nsvg__isnum(item[0])) {
if (cmd != '\0' && nsvg__isCoordinate(item)) {
if (nargs < 10)
args[nargs++] = (float)nsvg__atof(item);
if (nargs >= rargs) {
@ -2236,6 +2260,7 @@ 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':
@ -2285,7 +2310,6 @@ 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)
@ -2294,7 +2318,11 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
nsvg__resetPath(p);
closedFlag = 0;
nargs = 0;
} else if (cmd == 'Z' || cmd == 'z') {
} 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') {
closedFlag = 1;
// Commit path.
if (p->npts > 0) {
@ -2310,6 +2338,12 @@ 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.