update nanosvg

This commit is contained in:
TangoCash
2021-11-03 09:45:52 +01:00
committed by Thilo Graf
parent 49c7a4507a
commit c5447dce3c
2 changed files with 60 additions and 27 deletions

View File

@@ -419,6 +419,12 @@ enum NSVGunits
NSVG_UNITS_EX NSVG_UNITS_EX
}; };
enum NSVGvisibility
{
NSVG_VIS_DISPLAY = 1,
NSVG_VIS_VISIBLE = 2,
};
typedef struct NSVGcoordinate typedef struct NSVGcoordinate
{ {
float value; float value;
@@ -708,7 +714,7 @@ static NSVGparser* nsvg__createParser()
p->attr[0].miterLimit = 4; p->attr[0].miterLimit = 4;
p->attr[0].fillRule = NSVG_FILLRULE_NONZERO; p->attr[0].fillRule = NSVG_FILLRULE_NONZERO;
p->attr[0].hasFill = 1; p->attr[0].hasFill = 1;
p->attr[0].visible = 1; p->attr[0].visible = NSVG_VIS_DISPLAY | NSVG_VIS_VISIBLE;
return p; return p;
@@ -996,8 +1002,8 @@ static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const f
grad->xform[3] = r; grad->xform[3] = r;
grad->xform[4] = cx; grad->xform[4] = cx;
grad->xform[5] = cy; grad->xform[5] = cy;
grad->fx = fx / r; grad->fx = (fx - cx) / r;
grad->fy = fy / r; grad->fy = (fy - cy) / r;
} }
nsvg__xformMultiply(grad->xform, data->xform); nsvg__xformMultiply(grad->xform, data->xform);
@@ -1143,7 +1149,7 @@ static void nsvg__addShape(NSVGparser* p)
} }
// Set flags // Set flags
shape->flags = (attr->visible ? NSVG_FLAGS_VISIBLE : 0x00); shape->flags = ((attr->visible & NSVG_VIS_DISPLAY) && (attr->visible & NSVG_VIS_VISIBLE) ? NSVG_FLAGS_VISIBLE : 0x00);
// Add to tail // Add to tail
if (p->image->shapes == NULL) if (p->image->shapes == NULL)
@@ -1229,7 +1235,7 @@ static double nsvg__atof(const char* s)
char* cur = (char*)s; char* cur = (char*)s;
char* end = NULL; char* end = NULL;
double res = 0.0, sign = 1.0; double res = 0.0, sign = 1.0;
long long intPart = 0, fracPart = 0; double intPart = 0.0, fracPart = 0.0;
char hasIntPart = 0, hasFracPart = 0; char hasIntPart = 0, hasFracPart = 0;
// Parse optional sign // Parse optional sign
@@ -1247,10 +1253,10 @@ static double nsvg__atof(const char* s)
if (nsvg__isdigit(*cur)) if (nsvg__isdigit(*cur))
{ {
// Parse digit sequence // Parse digit sequence
intPart = strtoll(cur, &end, 10); intPart = (double)strtoll(cur, &end, 10);
if (cur != end) if (cur != end)
{ {
res = (double)intPart; res = intPart;
hasIntPart = 1; hasIntPart = 1;
cur = end; cur = end;
} }
@@ -1263,10 +1269,10 @@ static double nsvg__atof(const char* s)
if (nsvg__isdigit(*cur)) if (nsvg__isdigit(*cur))
{ {
// Parse digit sequence // Parse digit sequence
fracPart = strtoll(cur, &end, 10); fracPart = (double)strtoll(cur, &end, 10);
if (cur != end) if (cur != end)
{ {
res += (double)fracPart / pow(10.0, (double)(end - cur)); res += fracPart / pow(10.0, (double)(end - cur));
hasFracPart = 1; hasFracPart = 1;
cur = end; cur = end;
} }
@@ -1280,12 +1286,12 @@ static double nsvg__atof(const char* s)
// Parse optional exponent // Parse optional exponent
if (*cur == 'e' || *cur == 'E') if (*cur == 'e' || *cur == 'E')
{ {
long expPart = 0; double expPart = 0.0;
cur++; // skip 'E' cur++; // skip 'E'
expPart = strtol(cur, &end, 10); // Parse digit sequence with sign expPart = (double)strtol(cur, &end, 10); // Parse digit sequence with sign
if (cur != end) if (cur != end)
{ {
res *= pow(10.0, (double)expPart); res *= pow(10.0, expPart);
} }
} }
@@ -1382,23 +1388,37 @@ static unsigned int nsvg__parseColorRGB(const char* str)
if (sscanf(str, "rgb(%u, %u, %u)", &r, &g, &b) == 3) // decimal integers if (sscanf(str, "rgb(%u, %u, %u)", &r, &g, &b) == 3) // decimal integers
return NSVG_RGB(r, g, b); return NSVG_RGB(r, g, b);
if (sscanf(str, "rgb(%u%%, %u%%, %u%%)", &r, &g, &b) == 3) // decimal integer percentage if (sscanf(str, "rgb(%u%%, %u%%, %u%%)", &r, &g, &b) == 3) // decimal integer percentage
return NSVG_RGB(r*255/100, g*255/100, b*255/100); {
r = (r <= 100) ? ((r*255)/100) : 255; // FLTK: 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); return NSVG_RGB(128, 128, 128);
} }
static unsigned int nsvg__parseColorRGBA(const char* str) static unsigned int nsvg__parseColorRGBA(const char* str)
{ {
unsigned int r=0, g=0, b=0; int r = -1, g = -1, b = -1;
float a = 1.0; float a = -1;
if (sscanf(str, "rgba(%u, %u, %u, %f)", &r, &g, &b, &a) == 4) // decimal integers char s1[32]="", s2[32]="", s3[32]="";
sscanf(str + 5, "%d%[%%, \t]%d%[%%, \t]%d%[%%, \t]%f", &r, s1, &g, s2, &b, s3, &a);
if (strchr(s1, '%'))
{ {
float alpha = a * 255; r = (r <= 100) ? ((r*255)/100) : 255; // FLTK: clip percentages >100
if (alpha < 1.0) alpha = 1.0; g = (g <= 100) ? ((g*255)/100) : 255;
return NSVG_RGBA(r, g, b, alpha); b = (b <= 100) ? ((b*255)/100) : 255;
a = (a <= 100) ? ((a*255)/100) : 255;
return NSVG_RGBA(r,g,b,a);
}
else
{
r = (r <= 255) ? r : 255; // FLTK: clip percentages >100
g = (g <= 255) ? g : 255;
b = (b <= 255) ? b : 255;
a = (a <= 1.0) ? a*255 : 255;
return NSVG_RGBA(r,g,b,a);
} }
if (sscanf(str, "rgba(%u%%, %u%%, %u%%, %f)", &r, &g, &b, &a) == 4) // decimal integer percentage
return NSVG_RGBA((r*255)/100, (g*255)/100, (b*255)/100, (a*255)/100);
return NSVG_RGBA(128, 128, 128, 1.0);
} }
typedef struct NSVGNamedColor typedef struct NSVGNamedColor
@@ -1925,9 +1945,19 @@ static int nsvg__parseAttr(NSVGparser* p, const char* name, const char* value)
else if (strcmp(name, "display") == 0) else if (strcmp(name, "display") == 0)
{ {
if (strcmp(value, "none") == 0) if (strcmp(value, "none") == 0)
attr->visible = 0; attr->visible &= ~NSVG_VIS_DISPLAY;
// Don't reset ->visible on display:inline, one display:none hides the whole subtree // Don't reset ->visible on display:inline, one display:none hides the whole subtree
}
else if (strcmp(name, "visibility") == 0)
{
if (strcmp(value, "hidden") == 0)
{
attr->visible &= ~NSVG_VIS_VISIBLE;
}
else if (strcmp(value, "visible") == 0)
{
attr->visible |= NSVG_VIS_VISIBLE;
}
} }
else if (strcmp(name, "fill") == 0) else if (strcmp(name, "fill") == 0)
{ {

View File

@@ -361,10 +361,11 @@ static void nsvg__flattenCubicBez(NSVGrasterizer* r,
float x3, float y3, float x4, float y4, float x3, float y3, float x4, float y4,
int level, int type) int level, int type)
{ {
const int max_level = 10;
float x12,y12,x23,y23,x34,y34,x123,y123,x234,y234,x1234,y1234; float x12,y12,x23,y23,x34,y34,x123,y123,x234,y234,x1234,y1234;
float dx,dy,d2,d3; float dx,dy,d2,d3;
if (level > 10) return; if (level > max_level) return;
x12 = (x1+x2)*0.5f; x12 = (x1+x2)*0.5f;
y12 = (y1+y2)*0.5f; y12 = (y1+y2)*0.5f;
@@ -385,14 +386,16 @@ static void nsvg__flattenCubicBez(NSVGrasterizer* r,
nsvg__addPathPoint(r, x4, y4, type); nsvg__addPathPoint(r, x4, y4, type);
return; return;
} }
++level;
if (level > max_level) return;
x234 = (x23+x34)*0.5f; x234 = (x23+x34)*0.5f;
y234 = (y23+y34)*0.5f; y234 = (y23+y34)*0.5f;
x1234 = (x123+x234)*0.5f; x1234 = (x123+x234)*0.5f;
y1234 = (y123+y234)*0.5f; y1234 = (y123+y234)*0.5f;
nsvg__flattenCubicBez(r, x1,y1, x12,y12, x123,y123, x1234,y1234, level+1, 0); nsvg__flattenCubicBez(r, x1,y1, x12,y12, x123,y123, x1234,y1234, level, 0);
nsvg__flattenCubicBez(r, x1234,y1234, x234,y234, x34,y34, x4,y4, level+1, type); nsvg__flattenCubicBez(r, x1234,y1234, x234,y234, x34,y34, x4,y4, level, type);
} }
static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scalex, float scaley) static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scalex, float scaley)