Fix for issue #90 - use custom strong to float conversion
Use custom strong to float conversion instead of the one from std library to fix parsing floats with locales which use different number format than specified by SVG.
This commit is contained in:
parent
e41d60761f
commit
9b51689812
@ -215,7 +215,7 @@ static int nsvg__isspace(char c)
|
|||||||
|
|
||||||
static int nsvg__isdigit(char c)
|
static int nsvg__isdigit(char c)
|
||||||
{
|
{
|
||||||
return strchr("0123456789", c) != 0;
|
return c >= '0' && c <= '9';
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nsvg__isnum(char c)
|
static int nsvg__isnum(char c)
|
||||||
@ -1075,6 +1075,66 @@ error:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We roll our own string to float because the std library one uses locale and messes things up.
|
||||||
|
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;
|
||||||
|
char hasIntPart = 0, hasFracPart = 0;
|
||||||
|
|
||||||
|
// Parse optional sign
|
||||||
|
if (*cur == '+') {
|
||||||
|
cur++;
|
||||||
|
} else if (*cur == '-') {
|
||||||
|
sign = -1;
|
||||||
|
cur++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse integer part
|
||||||
|
if (nsvg__isdigit(*cur)) {
|
||||||
|
// Parse digit sequence
|
||||||
|
intPart = (double)strtoll(cur, &end, 10);
|
||||||
|
if (cur != end) {
|
||||||
|
res = (double)intPart;
|
||||||
|
hasIntPart = 1;
|
||||||
|
cur = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse fractional part.
|
||||||
|
if (*cur == '.') {
|
||||||
|
cur++; // Skip '.'
|
||||||
|
if (nsvg__isdigit(*cur)) {
|
||||||
|
// Parse digit sequence
|
||||||
|
fracPart = strtoll(cur, &end, 10);
|
||||||
|
if (cur != end) {
|
||||||
|
res += (double)fracPart / pow(10.0, (double)(end - cur)) * sign;
|
||||||
|
hasFracPart = 1;
|
||||||
|
cur = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A valid number should have integer or fractional part.
|
||||||
|
if (!hasIntPart && !hasFracPart)
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
// Parse optional exponent
|
||||||
|
if (*cur == 'e' || *cur == 'E') {
|
||||||
|
int expPart = 0;
|
||||||
|
cur++; // skip 'E'
|
||||||
|
expPart = strtol(cur, &end, 10); // Parse digit sequence with sign
|
||||||
|
if (cur != end) {
|
||||||
|
res *= pow(10.0, (double)expPart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res * sign;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char* nsvg__parseNumber(const char* s, char* it, const int size)
|
static const char* nsvg__parseNumber(const char* s, char* it, const int size)
|
||||||
{
|
{
|
||||||
const int last = size-1;
|
const int last = size-1;
|
||||||
@ -1434,7 +1494,7 @@ static int nsvg__parseTransformArgs(const char* str, float* args, int maxNa, int
|
|||||||
if (*ptr == '-' || *ptr == '+' || *ptr == '.' || nsvg__isdigit(*ptr)) {
|
if (*ptr == '-' || *ptr == '+' || *ptr == '.' || nsvg__isdigit(*ptr)) {
|
||||||
if (*na >= maxNa) return 0;
|
if (*na >= maxNa) return 0;
|
||||||
ptr = nsvg__parseNumber(ptr, it, 64);
|
ptr = nsvg__parseNumber(ptr, it, 64);
|
||||||
args[(*na)++] = (float)atof(it);
|
args[(*na)++] = (float)nsvg__atof(it);
|
||||||
} else {
|
} else {
|
||||||
++ptr;
|
++ptr;
|
||||||
}
|
}
|
||||||
@ -2079,7 +2139,7 @@ static void nsvg__pathArcTo(NSVGparser* p, float* cpx, float* cpy, float* args,
|
|||||||
// if (vecrat(ux,uy,vx,vy) <= -1.0f) da = NSVG_PI;
|
// if (vecrat(ux,uy,vx,vy) <= -1.0f) da = NSVG_PI;
|
||||||
// if (vecrat(ux,uy,vx,vy) >= 1.0f) da = 0;
|
// if (vecrat(ux,uy,vx,vy) >= 1.0f) da = 0;
|
||||||
|
|
||||||
if (fs == 0 && da > 0)
|
if (fs == 0 && da > 0)
|
||||||
da -= 2 * NSVG_PI;
|
da -= 2 * NSVG_PI;
|
||||||
else if (fs == 1 && da < 0)
|
else if (fs == 1 && da < 0)
|
||||||
da += 2 * NSVG_PI;
|
da += 2 * NSVG_PI;
|
||||||
@ -2152,7 +2212,7 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
|
|||||||
if (!*item) break;
|
if (!*item) break;
|
||||||
if (nsvg__isnum(item[0])) {
|
if (nsvg__isnum(item[0])) {
|
||||||
if (nargs < 10)
|
if (nargs < 10)
|
||||||
args[nargs++] = (float)atof(item);
|
args[nargs++] = (float)nsvg__atof(item);
|
||||||
if (nargs >= rargs) {
|
if (nargs >= rargs) {
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case 'm':
|
case 'm':
|
||||||
@ -2409,7 +2469,7 @@ static void nsvg__parsePoly(NSVGparser* p, const char** attr, int closeFlag)
|
|||||||
nargs = 0;
|
nargs = 0;
|
||||||
while (*s) {
|
while (*s) {
|
||||||
s = nsvg__getNextPathItem(s, item);
|
s = nsvg__getNextPathItem(s, item);
|
||||||
args[nargs++] = (float)atof(item);
|
args[nargs++] = (float)nsvg__atof(item);
|
||||||
if (nargs >= 2) {
|
if (nargs >= 2) {
|
||||||
if (npts == 0)
|
if (npts == 0)
|
||||||
nsvg__moveTo(p, args[0], args[1]);
|
nsvg__moveTo(p, args[0], args[1]);
|
||||||
|
Loading…
Reference in New Issue
Block a user