From c5447dce3cbd72b3f8b3684ea2366c23e14f5b0d Mon Sep 17 00:00:00 2001 From: TangoCash Date: Wed, 3 Nov 2021 09:45:52 +0100 Subject: [PATCH] update nanosvg --- src/driver/pictureviewer/nanosvg.h | 78 ++++++++++++++++++-------- src/driver/pictureviewer/nanosvgrast.h | 9 ++- 2 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/driver/pictureviewer/nanosvg.h b/src/driver/pictureviewer/nanosvg.h index c02a8a0fc..22666a499 100644 --- a/src/driver/pictureviewer/nanosvg.h +++ b/src/driver/pictureviewer/nanosvg.h @@ -419,6 +419,12 @@ enum NSVGunits NSVG_UNITS_EX }; +enum NSVGvisibility +{ + NSVG_VIS_DISPLAY = 1, + NSVG_VIS_VISIBLE = 2, +}; + typedef struct NSVGcoordinate { float value; @@ -708,7 +714,7 @@ static NSVGparser* nsvg__createParser() p->attr[0].miterLimit = 4; p->attr[0].fillRule = NSVG_FILLRULE_NONZERO; p->attr[0].hasFill = 1; - p->attr[0].visible = 1; + p->attr[0].visible = NSVG_VIS_DISPLAY | NSVG_VIS_VISIBLE; return p; @@ -996,8 +1002,8 @@ static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const f grad->xform[3] = r; grad->xform[4] = cx; grad->xform[5] = cy; - grad->fx = fx / r; - grad->fy = fy / r; + grad->fx = (fx - cx) / r; + grad->fy = (fy - cy) / r; } nsvg__xformMultiply(grad->xform, data->xform); @@ -1143,7 +1149,7 @@ static void nsvg__addShape(NSVGparser* p) } // 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 if (p->image->shapes == NULL) @@ -1229,7 +1235,7 @@ static double nsvg__atof(const char* s) char* cur = (char*)s; char* end = NULL; 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; // Parse optional sign @@ -1247,10 +1253,10 @@ static double nsvg__atof(const char* s) if (nsvg__isdigit(*cur)) { // Parse digit sequence - intPart = strtoll(cur, &end, 10); + intPart = (double)strtoll(cur, &end, 10); if (cur != end) { - res = (double)intPart; + res = intPart; hasIntPart = 1; cur = end; } @@ -1263,10 +1269,10 @@ static double nsvg__atof(const char* s) if (nsvg__isdigit(*cur)) { // Parse digit sequence - fracPart = strtoll(cur, &end, 10); + fracPart = (double)strtoll(cur, &end, 10); if (cur != end) { - res += (double)fracPart / pow(10.0, (double)(end - cur)); + res += fracPart / pow(10.0, (double)(end - cur)); hasFracPart = 1; cur = end; } @@ -1280,12 +1286,12 @@ static double nsvg__atof(const char* s) // Parse optional exponent if (*cur == 'e' || *cur == 'E') { - long expPart = 0; + double expPart = 0.0; 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) { - 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 return NSVG_RGB(r, g, b); 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); } static unsigned int nsvg__parseColorRGBA(const char* str) { - unsigned int r=0, g=0, b=0; - float a = 1.0; - if (sscanf(str, "rgba(%u, %u, %u, %f)", &r, &g, &b, &a) == 4) // decimal integers + int r = -1, g = -1, b = -1; + float a = -1; + 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; - if (alpha < 1.0) alpha = 1.0; - return NSVG_RGBA(r, g, b, alpha); + 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; + 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 @@ -1925,9 +1945,19 @@ static int nsvg__parseAttr(NSVGparser* p, const char* name, const char* value) else if (strcmp(name, "display") == 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 - + } + 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) { diff --git a/src/driver/pictureviewer/nanosvgrast.h b/src/driver/pictureviewer/nanosvgrast.h index 83b55f8ed..ad8a45513 100644 --- a/src/driver/pictureviewer/nanosvgrast.h +++ b/src/driver/pictureviewer/nanosvgrast.h @@ -361,10 +361,11 @@ static void nsvg__flattenCubicBez(NSVGrasterizer* r, float x3, float y3, float x4, float y4, int level, int type) { + const int max_level = 10; float x12,y12,x23,y23,x34,y34,x123,y123,x234,y234,x1234,y1234; float dx,dy,d2,d3; - if (level > 10) return; + if (level > max_level) return; x12 = (x1+x2)*0.5f; y12 = (y1+y2)*0.5f; @@ -385,14 +386,16 @@ static void nsvg__flattenCubicBez(NSVGrasterizer* r, nsvg__addPathPoint(r, x4, y4, type); return; } + ++level; + if (level > max_level) return; x234 = (x23+x34)*0.5f; y234 = (y23+y34)*0.5f; x1234 = (x123+x234)*0.5f; y1234 = (y123+y234)*0.5f; - nsvg__flattenCubicBez(r, x1,y1, x12,y12, x123,y123, x1234,y1234, level+1, 0); - nsvg__flattenCubicBez(r, x1234,y1234, x234,y234, x34,y34, x4,y4, level+1, type); + 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, type); } static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scalex, float scaley)