diff options
Diffstat (limited to 'nanosvg/nanosvg.h')
| -rw-r--r-- | nanosvg/nanosvg.h | 65 |
1 files changed, 53 insertions, 12 deletions
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 <string.h> #include <stdlib.h> +#include <stdio.h> #include <math.h> #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 |
