home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume39 / psutils / part02 / psspec.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-20  |  6.9 KB  |  231 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 "patchlevel.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. void pstops(modulo, pps, nobind, specs, draw)
  103.      int modulo, pps, nobind;
  104.      double draw;
  105.      struct pagespec *specs;
  106. {
  107.    int thispg, maxpage;
  108.    int pageindex = 0;
  109.  
  110.    scanpages();
  111.  
  112.    maxpage = ((pages+modulo-1)/modulo)*modulo;
  113.  
  114.    /* rearrange pages: doesn't cope properly with loaded definitions */
  115.    writeheader((maxpage/modulo)*pps);
  116.    writestring("%%BeginProcSet: pstops");
  117.    if (width > 0 && height > 0)
  118.       writestring("-clip");
  119.    if (nobind)
  120.       writestring("-nobind");
  121. #ifdef SHOWPAGE_LOAD
  122.    writestring("-spload");
  123. #endif
  124.    writestring(" 1 0\n");
  125. #ifndef SHOWPAGE_LOAD
  126.    writestring("[/showpage/erasepage/copypage]{dup where{pop dup load\n");
  127.    writestring(" type/operatortype eq{1 array cvx dup 0 3 index cvx put\n");
  128.    writestring(" bind def}{pop}ifelse}{pop}ifelse}forall\n");
  129. #else
  130.    writestring("[/showpage/copypage/erasepage]{dup 10 string cvs dup\n");
  131.    writestring(" length 6 add string dup 0 (pstops) putinterval dup\n");
  132.    writestring(" 6 4 -1 roll putinterval 2 copy cvn dup where\n");
  133.    writestring(" {pop pop pop}{exch load def}ifelse cvx cvn 1 array cvx\n");
  134.    writestring(" dup 0 4 -1 roll put def}forall\n");
  135. #endif
  136.    writestring("[/letter/legal/executivepage/a4/a4small/b5/com10envelope\n");
  137.    writestring(" /monarchenvelope/c5envelope/dlenvelope/lettersmall/note\n");
  138.    writestring(" /folio/quarto/a5]{dup where{dup wcheck{exch{}put}\n");
  139.    writestring(" {pop{}def}ifelse}{pop}ifelse}forall\n");
  140.    writestring("/lcvx{dup load dup type dup/operatortype eq{pop exch pop}\n");
  141.    writestring(" {/arraytype eq{dup xcheck{exch pop aload pop}\n");
  142.    writestring(" {pop cvx}ifelse}{pop cvx}ifelse}ifelse}bind def\n");
  143.    writestring("/pstopsmatrix matrix currentmatrix def\n");
  144.    writestring("/pstopsxform matrix def\n");
  145.    writestring("/defaultmatrix{pstopsmatrix exch pstopsxform exch concatmatrix}bind def\n");
  146.    writestring("/initmatrix{matrix defaultmatrix setmatrix}bind def\n");
  147.    writestring("/pathtoproc{[{currentpoint}stopped{$error/newerror false\n");
  148.    writestring(" put{newpath}}{/newpath cvx 3 1 roll/moveto cvx 4 array\n");
  149.    writestring(" astore cvx}ifelse]{[/newpath cvx{/moveto cvx}{/lineto cvx}\n");
  150.    writestring(" {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}\n");
  151.    writestring(" stopped{$error/errorname get/invalidaccess eq{cleartomark\n");
  152.    writestring(" $error/newerror false put cvx exec}{stop}ifelse}if}def\n");
  153.    if (width > 0 && height > 0) {
  154.       char buffer[BUFSIZ];
  155.       writestring("/initclip[/matrix lcvx/currentmatrix lcvx/pstopsmatrix cvx/setmatrix lcvx\n");
  156.       writestring(" /pathtoproc lcvx/initclip lcvx/newpath lcvx\n");
  157.       writestring(" 0 0 /moveto lcvx");
  158.       sprintf(buffer,
  159.           " %lf 0/rlineto lcvx\n 0 %lf/rlineto lcvx -%lf 0/rlineto lcvx\n",
  160.           width, height, width);
  161.       writestring(buffer);
  162.       writestring(" /closepath lcvx/clip lcvx\n");
  163.       writestring(" /newpath lcvx/exec lcvx/setmatrix lcvx]cvx def\n");
  164.    }
  165.    writestring("/initgraphics{initmatrix newpath initclip 1 setlinewidth\n");
  166.    writestring(" 0 setlinecap 0 setlinejoin []0 setdash 0 setgray\n");
  167.    writestring(" 10 setmiterlimit}bind def\n");
  168.    if (nobind) /* desperation measures */
  169.       writestring("/bind{}def\n");
  170.    writestring("%%EndProcSet\n");
  171.    /* save transformation from original to current matrix */
  172.    writeprolog("/pstopsxform pstopsmatrix matrix currentmatrix matrix invertmatrix matrix concatmatrix matrix invertmatrix store\n");
  173.    for (thispg = 0; thispg < maxpage; thispg += modulo) {
  174.       int add_last = 0;
  175.       struct pagespec *ps;
  176.       for (ps = specs; ps != NULL; ps = ps->next) {
  177.      int actualpg;
  178.      int add_next = ((ps->flags & ADD_NEXT) != 0);
  179.      if (ps->reversed)
  180.         actualpg = maxpage-thispg-modulo+ps->pageno;
  181.      else
  182.         actualpg = thispg+ps->pageno;
  183.      if (actualpg < pages)
  184.         seekpage(actualpg);
  185.      if (!add_last) {
  186.         writepageheader("pstops", ++pageindex);
  187.      }
  188.      writestring("/pstopssaved save def\n");
  189.      if (ps->flags & GSAVE) {
  190.         char buffer[BUFSIZ];
  191.         writestring("pstopsmatrix setmatrix\n");
  192.         if (ps->flags & OFFSET) {
  193.            sprintf(buffer, "%lf %lf translate\n", ps->xoff, ps->yoff);
  194.            writestring(buffer);
  195.         }
  196.         if (ps->flags & ROTATE) {
  197.            sprintf(buffer, "%d rotate\n", ps->rotate);
  198.            writestring(buffer);
  199.         }
  200.         if (ps->flags & SCALE) {
  201.            sprintf(buffer, "%lf dup scale\n", ps->scale);
  202.            writestring(buffer);
  203.         }
  204.         if (width > 0 && height > 0) {
  205.            writestring("/pstopsmatrix matrix currentmatrix def\n");
  206.            writestring("initclip\n");
  207.            if (draw > 0) {
  208.           sprintf(buffer, "gsave clippath 0 setgray %lf setlinewidth stroke grestore\n", draw);
  209.           writestring(buffer);
  210.            }
  211.         }
  212.         writestring("pstopsxform concat\n");
  213.      }
  214.      if (add_next) {
  215. #ifndef SHOWPAGE_LOAD
  216.         writestring("/showpage{}def/copypage{}def/erasepage{}def\n");
  217. #else
  218.         writestring("/pstopsshowpage{}def/pstopscopypage{}def/pstopserasepage{}def\n");
  219. #endif
  220.      }
  221.      if (actualpg < pages)
  222.         writepagebody(actualpg);
  223.      else
  224.         writestring("showpage\n");
  225.      writestring("pstopssaved restore\n");
  226.      add_last = add_next;
  227.       }
  228.    }
  229.    writetrailer();
  230. }
  231.