diff options
Diffstat (limited to 'Build/source/texk/dvipsk/papersiz.c')
-rw-r--r-- | Build/source/texk/dvipsk/papersiz.c | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/Build/source/texk/dvipsk/papersiz.c b/Build/source/texk/dvipsk/papersiz.c new file mode 100644 index 00000000000..ea1d5fddde8 --- /dev/null +++ b/Build/source/texk/dvipsk/papersiz.c @@ -0,0 +1,135 @@ +/* + * This function calculates approximately (whole + num/den) * sf. + * No need for real extreme accuracy; one twenty thousandth of an + * inch should be sufficient. + * + * No `sf' parameter means to use an old one; inches are assumed + * originally. + * + * Assumptions: + * + * 0 <= num < den <= 20000 + * 0 <= whole + */ +#include "dvips.h" /* The copyright notice in that file is included too! */ +/* + * The external declarations: + */ +#include "protos.h" +static long +scale(long whole, long num, long den, long sf) +{ + long v; + + v = whole * sf + num * (sf / den); + if (v / sf != whole || v < 0 || v > 0x40000000L) + error("! arithmetic overflow in parameter"); + sf = sf % den; + v += (sf * num * 2 + den) / (2 * den); + return(v); +} +/* + * Convert a sequence of digits into a long; return -1 if no digits. + * Advance the passed pointer as well. + */ +static long +myatol(char **s) +{ + register char *p; + register long result; + + result = 0; + p = *s; + while ('0' <= *p && *p <= '9') { + if (result > 100000000) + error("! arithmetic overflow in parameter"); + result = 10 * result + *p++ - '0'; + } + if (p == *s && *p == '.') { + return 0; + } else if (p == *s) { +#ifdef KPATHSEA + error(concat3 ("expected number in ", *s, ", returning 10")); +#else + error("expected number! returning 10"); +#endif + return 10; + } else { + *s = p; + return(result); + } +} +/* + * Get a dimension, allowing all the various extensions, and + * defaults. Returns a value in scaled points. + */ +static long scalevals[] = { 1864680L, 65536L, 786432L, 186468L, + 1L, 65782L, 70124L, 841489L, 4736286L }; +static const char *scalenames = "cmptpcmmspbpddccin"; +static long +myatodim(char **s) +{ + register long w, num, den, sc; + register const char *q; + char *p; + int negative = 0, i; + + p = *s; + if (**s == '-') { + p++; + negative = 1; + } + w = myatol(&p); + if (w < 0) { + error("number too large; 1000 used"); + w = 1000; + } + num = 0; + den = 1; + if (*p == '.') { + p++; + while ('0' <= *p && *p <= '9') { + if (den <= 1000) { + den *= 10; + num = num * 10 + *p - '0'; + } else if (den == 10000) { + den *= 2; + num = num * 2 + (*p - '0') / 5; + } + p++; + } + } + while (*p == ' ') + p++; + for (i=0, q=scalenames;; i++, q += 2) + if (*q == 0) { +#ifdef KPATHSEA + error(concat3 ("expected units in ", *s, ", assuming inches.")); +#else + error("expected units! assuming inches."); +#endif + sc = scalevals[8]; + break; + } else if (*p == *q && p[1] == q[1]) { + sc = scalevals[i]; + p += 2; + break; + } + w = scale(w, num, den, sc); + *s = p; + return(negative?-w:w); +} +/* + * The routine where we handle the paper size special. We need to pass in + * the string after the `papersize=' specification. + */ +void +handlepapersize(char *p, integer *x, integer *y) +{ + while (*p == ' ') + p++; + *x = myatodim(&p); + while (*p == ' ' || *p == ',') + p++; + *y = myatodim(&p); +} |