summaryrefslogtreecommitdiff
path: root/Build/source/utils/psutils/psspec.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/psutils/psspec.c')
-rw-r--r--Build/source/utils/psutils/psspec.c249
1 files changed, 249 insertions, 0 deletions
diff --git a/Build/source/utils/psutils/psspec.c b/Build/source/utils/psutils/psspec.c
new file mode 100644
index 00000000000..88d46f07a43
--- /dev/null
+++ b/Build/source/utils/psutils/psspec.c
@@ -0,0 +1,249 @@
+/* psspec.c
+ * Copyright (C) Angus J. C. Duggan 1991-1995
+ * See file LICENSE for details.
+ *
+ * page spec routines for page rearrangement
+ */
+
+#include "psutil.h"
+#include "psspec.h"
+#include "pserror.h"
+#include "patchlev.h"
+
+#include <string.h>
+
+double width = -1;
+double height = -1;
+
+/* create a new page spec */
+PageSpec *newspec(void)
+{
+ PageSpec *temp = (PageSpec *)malloc(sizeof(PageSpec));
+ if (temp == NULL)
+ message(FATAL, "out of memory\n");
+ temp->reversed = temp->pageno = temp->flags = temp->rotate = 0;
+ temp->scale = 1;
+ temp->xoff = temp->yoff = 0;
+ temp->next = NULL;
+ return (temp);
+}
+
+/* dimension parsing routines */
+int parseint(char **sp, void (*errorfn)(void))
+{
+ char *s = *sp;
+ int num = atoi(s);
+
+ while (isdigit(*s))
+ s++;
+ if (*sp == s) (*errorfn)() ;
+ *sp = s;
+ return (num);
+}
+
+double parsedouble(char **sp, void (*errorfn)(void))
+{
+ char *s = *sp;
+ double num = atof(s);
+
+ while (isdigit(*s) || *s == '-' || *s == '.')
+ s++;
+ if (*sp == s) (*errorfn)() ;
+ *sp = s;
+ return (num);
+}
+
+double parsedimen(char **sp, void (*errorfn)(void))
+{
+ double num = parsedouble(sp, errorfn);
+ char *s = *sp;
+
+ if (strncmp(s, "pt", 2) == 0) {
+ s += 2;
+ } else if (strncmp(s, "in", 2) == 0) {
+ num *= 72;
+ s += 2;
+ } else if (strncmp(s, "cm", 2) == 0) {
+ num *= 28.346456692913385211;
+ s += 2;
+ } else if (strncmp(s, "mm", 2) == 0) {
+ num *= 2.8346456692913385211;
+ s += 2;
+ } else if (*s == 'w') {
+ if (width < 0)
+ message(FATAL, "width not initialised\n");
+ num *= width;
+ s++;
+ } else if (*s == 'h') {
+ if (height < 0)
+ message(FATAL, "height not initialised\n");
+ num *= height;
+ s++;
+ }
+ *sp = s;
+ return (num);
+}
+
+double singledimen(char *str, void (*errorfn)(void), void (*usagefn)(void))
+{
+ double num = parsedimen(&str, errorfn);
+ if (*str) (*usagefn)();
+ return (num);
+}
+
+static char *prologue[] = { /* PStoPS procset */
+#ifndef SHOWPAGE_LOAD
+ "userdict begin",
+ "[/showpage/erasepage/copypage]{dup where{pop dup load", /* prevent */
+ " type/operatortype eq{1 array cvx dup 0 3 index cvx put", /* binding */
+ " bind def}{pop}ifelse}{pop}ifelse}forall", /* in prolog */
+#else
+ "userdict begin",
+ "[/showpage/copypage/erasepage]{dup 10 string cvs dup",
+ " length 6 add string dup 0 (PStoPS) putinterval dup",
+ " 6 4 -1 roll putinterval 2 copy cvn dup where",
+ " {pop pop pop}{exch load def}ifelse cvx cvn 1 array cvx",
+ " dup 0 4 -1 roll put def}forall",
+#endif
+ "[/letter/legal/executivepage/a4/a4small/b5/com10envelope", /* nullify */
+ " /monarchenvelope/c5envelope/dlenvelope/lettersmall/note", /* paper */
+ " /folio/quarto/a5]{dup where{dup wcheck{exch{}put}", /* operators */
+ " {pop{}def}ifelse}{pop}ifelse}forall",
+ "/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}",
+ " {pop def}ifelse}{def}ifelse",
+ "/PStoPSmatrix matrix currentmatrix def",
+ "/PStoPSxform matrix def/PStoPSclip{clippath}def",
+ "/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def",
+ "/initmatrix{matrix defaultmatrix setmatrix}bind def",
+ "/initclip[{matrix currentmatrix PStoPSmatrix setmatrix",
+ " [{currentpoint}stopped{$error/newerror false put{newpath}}",
+ " {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]",
+ " {[/newpath cvx{/moveto cvx}{/lineto cvx}",
+ " {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}",
+ " stopped{$error/errorname get/invalidaccess eq{cleartomark",
+ " $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop",
+ " /initclip dup load dup type dup/operatortype eq{pop exch pop}",
+ " {dup/arraytype eq exch/packedarraytype eq or",
+ " {dup xcheck{exch pop aload pop}{pop cvx}ifelse}",
+ " {pop cvx}ifelse}ifelse",
+ " {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def",
+ "/initgraphics{initmatrix newpath initclip 1 setlinewidth",
+ " 0 setlinecap 0 setlinejoin []0 setdash 0 setgray",
+ " 10 setmiterlimit}bind def",
+ "end",
+ NULL
+ };
+
+void pstops(int modulo, int pps, int nobind, PageSpec *specs, double draw)
+{
+ int thispg, maxpage;
+ int pageindex = 0;
+ char **pro;
+
+ scanpages();
+
+ maxpage = ((pages+modulo-1)/modulo)*modulo;
+
+ /* rearrange pages: doesn't cope properly with loaded definitions */
+ writeheader((maxpage/modulo)*pps);
+#ifndef SHOWPAGE_LOAD
+ writestring("%%BeginProcSet: PStoPS");
+#else
+ writestring("%%BeginProcSet: PStoPS-spload");
+#endif
+ if (nobind)
+ writestring("-nobind");
+ writestring(" 1 15\n");
+ for (pro = prologue; *pro; pro++) {
+ writestring(*pro);
+ writestring("\n");
+ }
+ if (nobind) /* desperation measures */
+ writestring("/bind{}def\n");
+ writestring("%%EndProcSet\n");
+ /* save transformation from original to current matrix */
+ if (writepartprolog()) {
+ writestring("userdict/PStoPSxform PStoPSmatrix matrix currentmatrix\n");
+ writestring(" matrix invertmatrix matrix concatmatrix\n");
+ writestring(" matrix invertmatrix put\n");
+ }
+ writesetup();
+ for (thispg = 0; thispg < maxpage; thispg += modulo) {
+ int add_last = 0;
+ PageSpec *ps;
+ for (ps = specs; ps != NULL; ps = ps->next) {
+ int actualpg;
+ int add_next = ((ps->flags & ADD_NEXT) != 0);
+ if (ps->reversed)
+ actualpg = maxpage-thispg-modulo+ps->pageno;
+ else
+ actualpg = thispg+ps->pageno;
+ if (actualpg < pages)
+ seekpage(actualpg);
+ if (!add_last) { /* page label contains original pages */
+ PageSpec *np = ps;
+ char *eob = pagelabel;
+ char sep = '(';
+ do {
+ *eob++ = sep;
+ if (np->reversed)
+ sprintf(eob, "%d", maxpage-thispg-modulo+np->pageno);
+ else
+ sprintf(eob, "%d", thispg+np->pageno);
+ eob = eob + strlen(eob);
+ sep = ',';
+ } while ((np->flags & ADD_NEXT) && (np = np->next));
+ strcpy(eob, ")");
+ writepageheader(pagelabel, ++pageindex);
+ }
+ writestring("userdict/PStoPSsaved save put\n");
+ if (ps->flags & GSAVE) {
+ char buffer[BUFSIZ];
+ writestring("PStoPSmatrix setmatrix\n");
+ if (ps->flags & OFFSET) {
+ sprintf(buffer, "%f %f translate\n", ps->xoff, ps->yoff);
+ writestring(buffer);
+ }
+ if (ps->flags & ROTATE) {
+ sprintf(buffer, "%d rotate\n", ps->rotate);
+ writestring(buffer);
+ }
+ if (ps->flags & SCALE) {
+ sprintf(buffer, "%f dup scale\n", ps->scale);
+ writestring(buffer);
+ }
+ writestring("userdict/PStoPSmatrix matrix currentmatrix put\n");
+ if (width > 0 && height > 0) {
+ char buffer[BUFSIZ];
+ writestring("userdict/PStoPSclip{0 0 moveto\n");
+ sprintf(buffer, " %f 0 rlineto 0 %f rlineto -%f 0 rlineto\n",
+ width, height, width);
+ writestring(buffer);
+ writestring(" closepath}put initclip\n");
+ if (draw > 0) {
+ sprintf(buffer, "gsave clippath 0 setgray %f setlinewidth stroke grestore\n", draw);
+ writestring(buffer);
+ }
+ }
+ }
+ if (add_next) {
+#ifndef SHOWPAGE_LOAD
+ writestring("/showpage{}def/copypage{}def/erasepage{}def\n");
+#else
+ writestring("/PStoPSshowpage{}store/PStoPScopypage{}store/PStoPSerasepage{}store\n");
+#endif
+ }
+ if (actualpg < pages) {
+ writepagesetup();
+ writestring("PStoPSxform concat\n");
+ writepagebody(actualpg);
+ } else {
+ writestring("PStoPSxform concat\n");
+ writestring("showpage\n");
+ }
+ writestring("PStoPSsaved restore\n");
+ add_last = add_next;
+ }
+ }
+ writetrailer();
+}