summaryrefslogtreecommitdiffstats
path: root/src/svg/svg-length.cpp
diff options
context:
space:
mode:
authorJasper van de Gronde <jasper.vandegronde@gmail.com>2008-07-18 19:10:58 +0000
committerjaspervdg <jaspervdg@users.sourceforge.net>2008-07-18 19:10:58 +0000
commit50a6044bb4ab605004e5c82733f8f4fb7042f311 (patch)
treee35cb9f6b9cfc057f2493662c8dbecd0ddb56a0d /src/svg/svg-length.cpp
parentmake the resolution for create bitmap copy settable in ui (diff)
downloadinkscape-50a6044bb4ab605004e5c82733f8f4fb7042f311.tar.gz
inkscape-50a6044bb4ab605004e5c82733f8f4fb7042f311.zip
Fix for PathString to prevent it from getting into a very, very long copying run and make it use minimumexponent. Plus some extra tests.
(bzr r6355)
Diffstat (limited to 'src/svg/svg-length.cpp')
-rw-r--r--src/svg/svg-length.cpp88
1 files changed, 54 insertions, 34 deletions
diff --git a/src/svg/svg-length.cpp b/src/svg/svg-length.cpp
index 182fff496..8c2a8caf3 100644
--- a/src/svg/svg-length.cpp
+++ b/src/svg/svg-length.cpp
@@ -64,29 +64,38 @@ unsigned int sp_svg_number_read_d(gchar const *str, double *val)
return 1;
}
+static unsigned int sp_svg_number_write_ui(gchar *buf, unsigned int val)
+{
+ unsigned int i = 0;
+ char c[16u];
+ do {
+ c[16u - (++i)] = '0' + (val % 10u);
+ val /= 10u;
+ } while (val > 0u);
+
+ memcpy(buf, &c[16u - i], i);
+ buf[i] = 0;
+
+ return i;
+}
+
static unsigned int sp_svg_number_write_i(gchar *buf, int val)
{
int p = 0;
+ unsigned int uval;
if (val < 0) {
buf[p++] = '-';
- val = -val;
+ uval = (unsigned int)-val;
+ } else {
+ uval = (unsigned int)val;
}
-
- int i = 0;
- char c[32];
- do {
- c[32 - (++i)] = '0' + (val % 10);
- val /= 10;
- } while (val > 0);
-
- memcpy(buf + p, &c[32 - i], i);
- p += i;
- buf[p] = 0;
+
+ p += sp_svg_number_write_ui(buf+p, uval);
return p;
}
-static unsigned sp_svg_number_write_d(gchar *buf, double val, unsigned int tprec, unsigned int fprec, unsigned int padf)
+static unsigned sp_svg_number_write_d(gchar *buf, double val, unsigned int tprec, unsigned int fprec)
{
/* Process sign */
int i = 0;
@@ -98,23 +107,30 @@ static unsigned sp_svg_number_write_d(gchar *buf, double val, unsigned int tprec
/* Determine number of integral digits */
int idigits = 0;
if (val >= 1.0) {
- idigits = (int) floor(log10(val));
+ idigits = (int) floor(log10(val)) + 1;
}
/* Determine the actual number of fractional digits */
- fprec = MAX(fprec, tprec - idigits - 1);
+ fprec = MAX(fprec, tprec - idigits);
/* Round value */
- val += 0.5 * pow(10.0, - ((double) fprec));
+ val += 0.5 / pow(10.0, fprec);
/* Extract integral and fractional parts */
double dival = floor(val);
- int ival = (int) dival;
double fval = val - dival;
/* Write integra */
- i += sp_svg_number_write_i(buf + i, ival);
+ if (idigits > (int)tprec) {
+ i += sp_svg_number_write_ui(buf + i, (unsigned int)floor(dival/pow(10.0, idigits-tprec) + .5));
+ for(unsigned int j=0; j<(unsigned int)idigits-tprec; j++) {
+ buf[i+j] = '0';
+ }
+ i += idigits-tprec;
+ } else {
+ i += sp_svg_number_write_ui(buf + i, (unsigned int)dival);
+ }
int end_i = i;
- if (fprec > 0 && (padf || fval > 0.0)) {
+ if (fprec > 0 && fval > 0.0) {
buf[i++] = '.';
- while ((fprec > 0) && (padf || (fval > 0.0))) {
+ do {
fval *= 10.0;
dival = floor(fval);
fval -= dival;
@@ -124,27 +140,31 @@ static unsigned sp_svg_number_write_d(gchar *buf, double val, unsigned int tprec
end_i = i;
}
fprec -= 1;
- }
+ } while(fprec > 0 && fval > 0.0);
}
buf[end_i] = 0;
return end_i;
}
-unsigned int sp_svg_number_write_de(gchar *buf, double val, unsigned int tprec, int min_exp, unsigned int padf)
+unsigned int sp_svg_number_write_de(gchar *buf, double val, unsigned int tprec, int min_exp)
{
- if (val == 0.0 || (fabs(val) >= 0.1 && fabs(val) < 10000000)) {
- return sp_svg_number_write_d(buf, val, tprec, 0, padf);
+ int eval = (int)floor(log10(fabs(val)));
+ if (val == 0.0 || eval < min_exp) {
+ return sp_svg_number_write_ui(buf, 0);
+ }
+ unsigned int maxnumdigitsWithoutExp = // This doesn't include the sign because it is included in either representation
+ eval<0?tprec+(unsigned int)-eval+1:
+ eval+1<(int)tprec?tprec+1:
+ (unsigned int)eval+1;
+ unsigned int maxnumdigitsWithExp = tprec + ( eval<0 ? 4 : 3 ); // It's not necessary to take larger exponents into account, because then maxnumdigitsWithoutExp is DEFINITELY larger
+ if (maxnumdigitsWithoutExp <= maxnumdigitsWithExp) {
+ return sp_svg_number_write_d(buf, val, tprec, 0);
} else {
- double eval = floor(log10(fabs(val)));
- if ((int) eval < min_exp) {
- return sp_svg_number_write_d(buf, 0, tprec, 0, padf);
- } else {
- val = val / pow(10.0, eval);
- int p = sp_svg_number_write_d(buf, val, tprec, 0, padf);
- buf[p++] = 'e';
- p += sp_svg_number_write_i(buf + p, (int) eval);
- return p;
- }
+ val = eval < 0 ? val * pow(10.0, -eval) : val / pow(10.0, eval);
+ int p = sp_svg_number_write_d(buf, val, tprec, 0);
+ buf[p++] = 'e';
+ p += sp_svg_number_write_i(buf + p, eval);
+ return p;
}
}