summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipsk/papersiz.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvipsk/papersiz.c')
-rw-r--r--Build/source/texk/dvipsk/papersiz.c135
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);
+}