From d9d3406be8640e30108dcef6d8b1111635fa189a Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Sat, 9 Jul 2022 14:37:46 +0200 Subject: [PATCH] Upgrade the bundled nanosvg library to current version For details see README.bundled-libs.txt. --- README.bundled-libs.txt | 69 +++++++++++++++++++++++++++++++++++++++-- nanosvg/nanosvg.h | 65 +++++++++++++++++++++++++++++++------- nanosvg/nanosvgrast.h | 16 +++++++--- 3 files changed, 131 insertions(+), 19 deletions(-) diff --git a/README.bundled-libs.txt b/README.bundled-libs.txt index 10b91addd..ceeb927fb 100644 --- a/README.bundled-libs.txt +++ b/README.bundled-libs.txt @@ -20,12 +20,12 @@ Current versions of bundled libraries (as of Sep 13, 2021): Library Version Release date FLTK Version -------------------------------------------------------------------------- jpeg jpeg-9d 2020-01-12 1.4.0 - nanosvg 461ad7de70 [1] 2021-09-13 1.4.0 + nanosvg 06a9113e29 [1] 2022-07-09 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 -------------------------------------------------------------------------- -Previous versions of bundled libraries: +Previous versions of bundled libraries (FLTK 1.3.x): Library Version Release date FLTK Version ------------------------------------------------------------------ @@ -271,3 +271,68 @@ nanosvg: nanosvg.h: Merge or download from FLTK's fork (see above). nanosvgrast.h: Merge or download from FLTK's fork (see above). + + Maintaining branch 'fltk' in FLTK's fork of nanosvg (fltk/nanosvg): + + Only maintainers with write access on fltk/nanosvg can do this. + Others can fork our fltk/nanosvg fork in their own GitHub account + and either open a PR on fltk/nanosvg or tell us about their + changes in fltk.development. + + Use something similar to the following commands to update FLTK's + fork of nanosvg to the latest version. Commands are only examples, + you may need to change more or less, depending on the outstanding + updates. + + Step 1: clone the fltk/nanosvg fork, set the remote 'upstream', + and update the 'master' branch: + + $ cd /to/your/dev/dir + $ git clone https://github.com/fltk/nanosvg.git nanosvg-fltk + $ cd nanosvg-fltk + $ git remote add upstream https://github.com/memononen/nanosvg + $ git checkout master + $ git pull upstream master + + Note: the 'master' branch must never be changed, i.e. it must + always be the same as 'upstream/master'. Never commit your own + (FLTK specific) changes to branch 'master'. + + Step 2: rebase branch 'fltk' on the new master (upstream/master), + fix potential conflicts, and tag the new branch. + + It is important to keep the individual FLTK specific patches intact + (one commit per patch) because this will preserve the history and + the committer and make it easier to skip single patches when they + are accepted upstream. + + $ git checkout fltk + $ git rebase upstream/master + + At this point you may need to fix conflicts! Do whatever is + necessary to update the branch 'fltk'. + + Now `git tag' the 'fltk' branch for later reference. + + Hint: use `git show ' to see its contents. + I like to write a summary of commits in the tag comment. + + $ git tag -a fltk_yyyy-mm-dd fltk + + Replace 'yyyy-mm-dd' with the current date and add a comment + when asked for it (your editor will open an empty file). + + Step 3: at this point it is recommended to copy the changed + header files to your working copy of the FLTK library and test + the changes. If anything is wrong, go back, fix the bugs + and change the git tag (delete and create a new one). + + Step 4: push the new branch 'fltk' and the tag to the fltk/nanosvg + repository: + + $ git push -f origin fltk + $ git push origin fltk_yyyy-mm-dd + + Step 5: copy the changed files to your working copy of the FLTK + repository (if not done already), update this file accordingly, + and commit/push the update to the fltk/fltk repository. diff --git a/nanosvg/nanosvg.h b/nanosvg/nanosvg.h index 0175ade74..24bdd46ce 100644 --- a/nanosvg/nanosvg.h +++ b/nanosvg/nanosvg.h @@ -181,12 +181,11 @@ void nsvgDelete(NSVGimage* image); #endif #endif -#endif // NANOSVG_H - #ifdef NANOSVG_IMPLEMENTATION #include #include +#include #include #define NSVG_PI (3.14159265358979323846264338327f) @@ -1231,18 +1230,58 @@ static unsigned int nsvg__parseColorHex(const char* str) return NSVG_RGB(128, 128, 128); } +// Parse rgb color. The pointer 'str' must point at "rgb(" (4+ characters). +// This function returns gray (rgb(128, 128, 128) == '#808080') on parse errors +// for backwards compatibility. Note: other image viewers return black instead. + static unsigned int nsvg__parseColorRGB(const char* str) { - 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; // FLTK: clip percentages >100 - g = (g <= 100) ? ((g*255)/100) : 255; - b = (b <= 100) ? ((b*255)/100) : 255; - return NSVG_RGB(r, g, b); + int i; + unsigned int rgbi[3]; + float rgbf[3]; + // try decimal integers first + if (sscanf(str, "rgb(%u, %u, %u)", &rgbi[0], &rgbi[1], &rgbi[2]) != 3) { + // integers failed, try percent values (float, locale independent) + const char delimiter[3] = {',', ',', ')'}; + str += 4; // skip "rgb(" + for (i = 0; i < 3; i++) { + while (*str && (nsvg__isspace(*str))) str++; // skip leading spaces + if (*str == '+') str++; // skip '+' (don't allow '-') + if (!*str) break; + rgbf[i] = nsvg__atof(str); + + // Note 1: it would be great if nsvg__atof() returned how many + // bytes it consumed but it doesn't. We need to skip the number, + // the '%' character, spaces, and the delimiter ',' or ')'. + + // Note 2: The following code does not allow values like "33.%", + // i.e. a decimal point w/o fractional part, but this is consistent + // with other image viewers, e.g. firefox, chrome, eog, gimp. + + while (*str && nsvg__isdigit(*str)) str++; // skip integer part + if (*str == '.') { + str++; + if (!nsvg__isdigit(*str)) break; // error: no digit after '.' + while (*str && nsvg__isdigit(*str)) str++; // skip fractional part + } + if (*str == '%') str++; else break; + while (nsvg__isspace(*str)) str++; + if (*str == delimiter[i]) str++; + else break; + } + if (i == 3) { + rgbi[0] = roundf(rgbf[0] * 2.55f); + rgbi[1] = roundf(rgbf[1] * 2.55f); + rgbi[2] = roundf(rgbf[2] * 2.55f); + } else { + rgbi[0] = rgbi[1] = rgbi[2] = 128; + } } - return NSVG_RGB(128, 128, 128); + // clip values as the CSS spec requires + for (i = 0; i < 3; i++) { + if (rgbi[i] > 255) rgbi[i] = 255; + } + return NSVG_RGB(rgbi[0], rgbi[1], rgbi[2]); } typedef struct NSVGNamedColor { @@ -3017,4 +3056,6 @@ void nsvgDelete(NSVGimage* image) free(image); } -#endif +#endif // NANOSVG_IMPLEMENTATION + +#endif // NANOSVG_H diff --git a/nanosvg/nanosvgrast.h b/nanosvg/nanosvgrast.h index 84a05a7f8..52986693e 100644 --- a/nanosvg/nanosvgrast.h +++ b/nanosvg/nanosvgrast.h @@ -31,6 +31,8 @@ #ifndef NANOSVGRAST_H #define NANOSVGRAST_H +#include "nanosvg.h" + #ifndef NANOSVGRAST_CPLUSPLUS #ifdef __cplusplus extern "C" { @@ -87,11 +89,11 @@ void nsvgDeleteRasterizer(NSVGrasterizer*); #endif #endif -#endif // NANOSVGRAST_H - #ifdef NANOSVGRAST_IMPLEMENTATION #include +#include +#include #define NSVG__SUBSAMPLES 5 #define NSVG__FIXSHIFT 10 @@ -972,7 +974,7 @@ static float nsvg__clampf(float a, float mn, float mx) { return a < mn ? mn : (a static unsigned int nsvg__RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) { - return (r) | (g << 8) | (b << 16) | (a << 24); + return ((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16) | ((unsigned int)a << 24); } static unsigned int nsvg__lerpRGBA(unsigned int c0, unsigned int c1, float u) @@ -1423,7 +1425,8 @@ void nsvgRasterizeXY(NSVGrasterizer* r, } // Rasterize edges - qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge); + if (r->nedges != 0) + qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge); // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule nsvg__initPaint(&cache, &shape->fill, shape->opacity); @@ -1449,7 +1452,8 @@ void nsvgRasterizeXY(NSVGrasterizer* r, } // Rasterize edges - qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge); + if (r->nedges != 0) + qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge); // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule nsvg__initPaint(&cache, &shape->stroke, shape->opacity); @@ -1474,3 +1478,5 @@ void nsvgRasterize(NSVGrasterizer* r, } #endif // NANOSVGRAST_IMPLEMENTATION + +#endif // NANOSVGRAST_H