home *** CD-ROM | disk | FTP | other *** search
/ Mega Top 1 / os2_top1.zip / os2_top1 / APPS / TEKST / PSUTILS / PSSPEC.C < prev    next >
C/C++ Source or Header  |  1993-11-29  |  7KB  |  256 lines

  1. /* psspec.c
  2.  * AJCD 5/6/93
  3.  * page spec routines for page rearrangement
  4.  */
  5.  
  6. #include "psutil.h"
  7. #include "psspec.h"
  8. #include "patchlev.h"
  9.  
  10. double width = -1;
  11. double height = -1;
  12.  
  13. /* create a new page spec */
  14. struct pagespec *newspec()
  15. {
  16.    struct pagespec *temp = (struct pagespec *)malloc(sizeof(struct pagespec));
  17.    if (temp == NULL) {
  18.       fprintf(stderr, "%s: out of memory\n", prog);
  19.       fflush(stderr);
  20.       exit(1);
  21.    }
  22.    temp->reversed = temp->pageno = temp->flags = temp->rotate = 0;
  23.    temp->scale = 1;
  24.    temp->xoff = temp->yoff = 0;
  25.    temp->next = NULL;
  26.    return (temp);
  27. }
  28.  
  29. /* dimension parsing routines */
  30. int parseint(sp)
  31.      char **sp;
  32. {
  33.    char *s = *sp;
  34.    int num = atoi(s);
  35.  
  36.    while (isdigit(*s))
  37.       s++;
  38.    if (*sp == s) argerror();
  39.    *sp = s;
  40.    return (num);
  41. }
  42.  
  43. double parsedouble(sp)
  44.      char **sp;
  45. {
  46.    char *s = *sp;
  47.    double num = atof(s);
  48.  
  49.    while (isdigit(*s) || *s == '-' || *s == '.')
  50.       s++;
  51.    if (*sp == s) argerror();
  52.    *sp = s;
  53.    return (num);
  54. }
  55.  
  56. double parsedimen(sp)
  57.      char **sp;
  58. {
  59.    double num = parsedouble(sp);
  60.    char *s = *sp;
  61.  
  62.    if (strncmp(s, "pt", 2) == 0) {
  63.       s += 2;
  64.    } else if (strncmp(s, "in", 2) == 0) {
  65.       num *= 72;
  66.       s += 2;
  67.    } else if (strncmp(s, "cm", 2) == 0) {
  68.       num *= 28.346456692913385211;
  69.       s += 2;
  70.    } else if (strncmp(s, "mm", 2) == 0) {
  71.       num *= 2.8346456692913385211;
  72.       s += 2;
  73.    } else if (*s == 'w') {
  74.       if (width < 0) {
  75.      fprintf(stderr, "%s: width not initialised\n", prog);
  76.      fflush(stderr);
  77.      exit(1);
  78.       }
  79.       num *= width;
  80.       s++;
  81.    } else if (*s == 'h') {
  82.       if (height < 0) {
  83.      fprintf(stderr, "%s: height not initialised\n", prog);
  84.      fflush(stderr);
  85.      exit(1);
  86.       }
  87.       num *= height;
  88.       s++;
  89.    }
  90.    *sp = s;
  91.    return (num);
  92. }
  93.  
  94. double singledimen(str)
  95.      char *str;
  96. {
  97.    double num = parsedimen(&str);
  98.    if (*str) usage();
  99.    return (num);
  100. }
  101.  
  102. static char *prologue[] = { /* PStoPS procset */
  103. #ifndef SHOWPAGE_LOAD
  104.    "userdict begin",
  105.    "[/showpage/erasepage/copypage]{dup where{pop dup load",    /* prevent */
  106.    " type/operatortype eq{1 array cvx dup 0 3 index cvx put",    /* binding */
  107.    " bind def}{pop}ifelse}{pop}ifelse}forall",            /* in prolog */
  108. #else
  109.    "[/showpage/copypage/erasepage]{dup 10 string cvs dup",
  110.    " length 6 add string dup 0 (PStoPS) putinterval dup",
  111.    " 6 4 -1 roll putinterval 2 copy cvn dup where",
  112.    " {pop pop pop}{exch load def}ifelse cvx cvn 1 array cvx",
  113.    " dup 0 4 -1 roll put def}forall",
  114. #endif
  115.    "[/letter/legal/executivepage/a4/a4small/b5/com10envelope",    /* nullify */
  116.    " /monarchenvelope/c5envelope/dlenvelope/lettersmall/note",    /* paper */
  117.    " /folio/quarto/a5]{dup where{dup wcheck{exch{}put}",    /* operators */
  118.    " {pop{}def}ifelse}{pop}ifelse}forall",
  119.    "/PStoPSmatrix matrix currentmatrix def",
  120.    "/PStoPSxform matrix def/PStoPSclip{clippath}def",
  121.    "/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def",
  122.    "/initmatrix{matrix defaultmatrix setmatrix}bind def",
  123.    "/initclip[{matrix currentmatrix PStoPSmatrix setmatrix",
  124.    " [{currentpoint}stopped{$error/newerror false put{newpath}}",
  125.    " {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]",
  126.    " {[/newpath cvx{/moveto cvx}{/lineto cvx}",
  127.    " {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}",
  128.    " stopped{$error/errorname get/invalidaccess eq{cleartomark",
  129.    " $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop",
  130.    " /initclip dup load dup type dup/operatortype eq{pop exch pop}",
  131.    " {dup/arraytype eq exch/packedarraytype eq or",
  132.    "  {dup xcheck{exch pop aload pop}{pop cvx}ifelse}",
  133.    "  {pop cvx}ifelse}ifelse",
  134.    " {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def",
  135.    "/initgraphics{initmatrix newpath initclip 1 setlinewidth",
  136.    " 0 setlinecap 0 setlinejoin []0 setdash 0 setgray",
  137.    " 10 setmiterlimit}bind def",
  138.    "end",
  139.    NULL
  140.    };
  141.  
  142. void pstops(modulo, pps, nobind, specs, draw)
  143.      int modulo, pps, nobind;
  144.      double draw;
  145.      struct pagespec *specs;
  146. {
  147.    int thispg, maxpage;
  148.    int pageindex = 0;
  149.    char **pro;
  150.  
  151.    scanpages();
  152.  
  153.    maxpage = ((pages+modulo-1)/modulo)*modulo;
  154.  
  155.    /* rearrange pages: doesn't cope properly with loaded definitions */
  156.    writeheader((maxpage/modulo)*pps);
  157. #ifndef SHOWPAGE_LOAD
  158.    writestring("%%BeginProcSet: PStoPS");
  159. #else
  160.    writestring("%%BeginProcSet: PStoPS-spload");
  161. #endif
  162.    if (nobind)
  163.       writestring("-nobind");
  164.    writestring(" 1 13\n");
  165.    for (pro = prologue; *pro; pro++) {
  166.       writestring(*pro);
  167.       writestring("\n");
  168.    }
  169.    if (nobind) /* desperation measures */
  170.       writestring("/bind{}def\n");
  171.    writestring("%%EndProcSet\n");
  172.    /* save transformation from original to current matrix */
  173.    if (writepartprolog()) {
  174.       writestring("userdict/PStoPSxform PStoPSmatrix matrix currentmatrix\n");
  175.       writestring(" matrix invertmatrix matrix concatmatrix\n");
  176.       writestring(" matrix invertmatrix put\n");
  177.    }
  178.    writesetup();
  179.    for (thispg = 0; thispg < maxpage; thispg += modulo) {
  180.       int add_last = 0;
  181.       struct pagespec *ps;
  182.       for (ps = specs; ps != NULL; ps = ps->next) {
  183.      int actualpg;
  184.      int add_next = ((ps->flags & ADD_NEXT) != 0);
  185.      if (ps->reversed)
  186.         actualpg = maxpage-thispg-modulo+ps->pageno;
  187.      else
  188.         actualpg = thispg+ps->pageno;
  189.      if (actualpg < pages)
  190.         seekpage(actualpg);
  191.      if (!add_last) {    /* page label contains original pages */
  192.         struct pagespec *np = ps;
  193.         char *eob = pagelabel;
  194.         char sep = '(';
  195.         do {
  196.            *eob++ = sep;
  197.            if (np->reversed)
  198.           sprintf(eob, "%d", maxpage-thispg-modulo+np->pageno);
  199.            else
  200.           sprintf(eob, "%d", thispg+np->pageno);
  201.            eob = eob + strlen(eob);
  202.            sep = ',';
  203.         } while ((np->flags & ADD_NEXT) && (np = np->next));
  204.         strcpy(eob, ")");
  205.         writepageheader(pagelabel, ++pageindex);
  206.      }
  207.      writestring("userdict/PStoPSsaved save put\n");
  208.      if (ps->flags & GSAVE) {
  209.         char buffer[BUFSIZ];
  210.         writestring("PStoPSmatrix setmatrix\n");
  211.         if (ps->flags & OFFSET) {
  212.            sprintf(buffer, "%lf %lf translate\n", ps->xoff, ps->yoff);
  213.            writestring(buffer);
  214.         }
  215.         if (ps->flags & ROTATE) {
  216.            sprintf(buffer, "%d rotate\n", ps->rotate);
  217.            writestring(buffer);
  218.         }
  219.         if (ps->flags & SCALE) {
  220.            sprintf(buffer, "%lf dup scale\n", ps->scale);
  221.            writestring(buffer);
  222.         }
  223.         writestring("userdict/PStoPSmatrix matrix currentmatrix put\n");
  224.         if (width > 0 && height > 0) {
  225.            char buffer[BUFSIZ];
  226.            writestring("userdict/PStoPSclip{0 0 moveto\n");
  227.            sprintf(buffer, " %lf 0 rlineto 0 %lf rlineto -%lf 0 rlineto\n",
  228.                width, height, width);
  229.            writestring(buffer);
  230.            writestring(" closepath}put initclip\n");
  231.            if (draw > 0) {
  232.           sprintf(buffer, "gsave clippath 0 setgray %lf setlinewidth stroke grestore\n", draw);
  233.           writestring(buffer);
  234.            }
  235.         }
  236.      }
  237.      if (add_next) {
  238. #ifndef SHOWPAGE_LOAD
  239.         writestring("/showpage{}def/copypage{}def/erasepage{}def\n");
  240. #else
  241.         writestring("/PStoPSshowpage{}store/PStoPScopypage{}store/PStoPSerasepage{}store\n");
  242. #endif
  243.      }
  244.      if (actualpg < pages) {
  245.         writepagesetup();
  246.         writestring("PStoPSxform concat\n");
  247.         writepagebody(actualpg);
  248.      } else
  249.         writestring("showpage\n");
  250.      writestring("PStoPSsaved restore\n");
  251.      add_last = add_next;
  252.       }
  253.    }
  254.    writetrailer();
  255. }
  256.