home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2089 / ps.c
Encoding:
C/C++ Source or Header  |  1990-12-28  |  18.0 KB  |  677 lines

  1. /*    Copyright 1985, 1986, 1987, 1988 Chris Lewis
  2.         All Rights Reserved
  3.  
  4.     Permission to copy and further distribute is freely given provided
  5.     this copyright notice remains intact and that this software is not
  6.     sold for profit.
  7.  
  8.     Project:    Generic Troff drivers
  9.     Module:        ps.c
  10.     Author:     Chris Lewis
  11.     Specs:        PostScript driver
  12.  */
  13.  
  14. #include "defs.h"
  15.  
  16. #ifdef    PS
  17. #include "ps.h"
  18.  
  19. #ifndef    lint
  20. static char SCCSid[] =
  21.     "@(#)ps.c: 2.2 Copyright 90/10/12 13:09:32 Chris Lewis";
  22. #endif
  23.  
  24. /*    ps.c will generate some additional "print" commands to cause
  25.     the printer to "print" back who did the job, and how long it
  26.     took.  define NOCHATTER if you don't want this.
  27.  */
  28. static long charCount;
  29.  
  30. #ifdef    FORM
  31. static char Overlay[100] = {""};
  32. #endif
  33.  
  34. #define    USED    01
  35.  
  36. struct troff2befont psStdFont[108] = {
  37.  
  38. /*    Note on X-shift, Y-shift and point scale factor:
  39.     The first two are shifts in the baseline position of the
  40.     character, and the third is a multiplier of the point size.
  41.     If they are zero, nothing happens.  If they are non-zero,
  42.     they are first multiplied by .01, then (in the case of the
  43.     shifts), multiplied by the current points to get a shift
  44.     value in TROFF2PS[XY] coordinates.  In the case of point scale
  45.     factor, it is multiplied by <currentpointsize> * .01 and becomes
  46.     the pointsize of the sequence to be emitted.
  47.  */
  48. /*          +-------------------------------- Troff character number
  49.         |
  50.             |    +--------------------------- N: standard fonts
  51.             |    |                            S: symbol font
  52.             |    |                            D: draw macro
  53.             |    |                            n: new font
  54.             |    |
  55.             |    |  +------------------------ X-shift
  56.             |    |  |                         Note: positive is right.
  57.             |    |  |
  58.             |    |  |  +--------------------- Y-shift
  59.             |    |  |  |                      Note: positive is up.
  60.             |    |  |  |
  61.             |    |  |  |  +------------------ Point scale factor
  62.             |    |  |  |  |
  63.             |    |  |  |  |   +-------------- Sequence
  64.             |    |  |  |  |   |
  65.             v    v  v  v  v   v */
  66.     /*  0*/    {N, 0, 0, 0, "h"},
  67.     /*  1*/    {N, 0, 0, 0, "t"},
  68.     /*  2*/    {N, 0, 0, 0, "n"},
  69.     /*  3*/    {N, 0, 0, 0, "m"},
  70.     /*  4*/    {N, 0, 0, 0, "l"},
  71.     /*  5*/    {N, 0, 0, 0, "i"},
  72.     /*  6*/    {N, 0, 0, 0, "z"},
  73.     /*  7*/    {N, 0, 0, 0, "s"},
  74.     /*  8*/    {N, 0, 0, 0, "d"},
  75.     /*  9*/    {N, 0, 0, 0, "b"},
  76.     /* 10*/    {N, 0, 0, 0, "x"},
  77.     /* 11*/    {N, 0, 0, 0, "f"},
  78.     /* 12*/    {N, 0, 0, 0, "j"},
  79.     /* 13*/    {N, 0, 0, 0, "u"},
  80.     /* 14*/    {N, 0, 0, 0, "k"},
  81.     /* 15*/    {N, 0, 0, 0, NOC},
  82.     /* 16*/    {N, 0, 0, 0, "p"},
  83.     /* 17*/    {D, 0, 0, 0, "do34em"},
  84.     /* 18*/    {N, 0, 0, 0, ";"},
  85.     /* 19*/    {N, 0, 0, 0, NOC},
  86.     /* 20*/    {N, 0, 0, 0, "a"},
  87.     /* 21*/    {N, 0, 0, 0, "_"},
  88.     /* 22*/    {N, 0, 0, 0, "c"},
  89.     /* 23*/    {N, 0, 0, 0, "`"},
  90.     /* 24*/    {N, 0, 0, 0, "e"},
  91.     /* 25*/    {N, 0, 0, 0, "'"},
  92.     /* 26*/    {N, 0, 0, 0, "o"},
  93.     /* 27*/    {D, 0, 0, 0, "do14"},
  94.     /* 28*/    {N, 0, 0, 0, "r"},
  95.     /* 29*/    {D, 0, 0, 0, "do12"},
  96.     /* 30*/    {N, 0, 0, 0, "v"},
  97.     /* 31*/    {N, 0, 0, 0, "-"},
  98.     /* 32*/    {N, 0, 0, 0, "w"},
  99.     /* 33*/    {N, 0, 0, 0, "q"},
  100.     /* 34*/    {N, 0, 0, 0, "/"},
  101.     /* 35*/    {N, 0, 0, 0, "."},
  102.     /* 36*/    {N, 0, 0, 0, "g"},
  103.     /* 37*/    {D, 0, 0, 0, "do34"},
  104.     /* 38*/    {N, 0, 0, 0, ","},
  105.     /* 39*/    {N, 0, 0, 0, "&"},
  106.     /* 40*/    {N, 0, 0, 0, "y"},
  107.     /* 41*/    {N, 0, 0, 0, NOC},
  108.     /* 42*/    {N, 0, 0, 0, "%"},
  109.     /* 43*/    {N, 0, 0, 0, NOC},
  110.     /* 44*/    {N, 0, 0, 0, "Q"},
  111.     /* 45*/    {N, 0, 0, 0, "T"},
  112.     /* 46*/    {N, 0, 0, 0, "O"},
  113.     /* 47*/    {N, 0, 0, 0, "H"},
  114.     /* 48*/    {N, 0, 0, 0, "N"},
  115.     /* 49*/    {N, 0, 0, 0, "M"},
  116.     /* 50*/    {N, 0, 0, 0, "L"},
  117.     /* 51*/    {N, 0, 0, 0, "R"},
  118.     /* 52*/    {N, 0, 0, 0, "G"},
  119.     /* 53*/    {N, 0, 0, 0, "I"},
  120.     /* 54*/    {N, 0, 0, 0, "P"},
  121.     /* 55*/    {N, 0, 0, 0, "C"},
  122.     /* 56*/    {N, 0, 0, 0, "V"},
  123.     /* 57*/    {N, 0, 0, 0, "E"},
  124.     /* 58*/    {N, 0, 0, 0, "Z"},
  125.     /* 59*/    {N, 0, 0, 0, "D"},
  126.     /* 60*/    {N, 0, 0, 0, "B"},
  127.     /* 61*/    {N, 0, 0, 0, "S"},
  128.     /* 62*/    {N, 0, 0, 0, "Y"},
  129.     /* 63*/    {N, 0, 0, 0, "F"},
  130.     /* 64*/    {N, 0, 0, 0, "X"},
  131.     /* 65*/    {N, 0, 0, 0, "A"},
  132.     /* 66*/    {N, 0, 0, 0, "W"},
  133.     /* 67*/    {N, 0, 0, 0, "J"},
  134.     /* 68*/    {N, 0, 0, 0, "U"},
  135.     /* 69*/    {N, 0, 0, 0, "K"},
  136.     /* 70*/    {N, 0, 0, 0, "0"},
  137.     /* 71*/    {N, 0, 0, 0, "1"},
  138.     /* 72*/    {N, 0, 0, 0, "2"},
  139.     /* 73*/    {N, 0, 0, 0, "3"},
  140.     /* 74*/    {N, 0, 0, 0, "4"},
  141.     /* 75*/    {N, 0, 0, 0, "5"},
  142.     /* 76*/    {N, 0, 0, 0, "6"},
  143.     /* 77*/    {N, 0, 0, 0, "7"},
  144.     /* 78*/    {N, 0, 0, 0, "8"},
  145.     /* 79*/    {N, 0, 0, 0, "9"},
  146.     /* 80*/    {N, 0, 0, 0, "*"},
  147.     /* 81*/    {N, 0, 0, 0, "\\261"},
  148.     /* 82*/    {N, 0, 0, 0, "\\256"},
  149.     /* 83*/    {N, 0, 0, 0, "\\257"},
  150.     /* 84*/    {D, 0, 0, 0, "doff"},
  151.     /* 85*/    {N, 0, 0, 0, "\\242"},
  152.     /* 86*/    {D, 0, 0, 0, "doFl"},
  153.     /* 87*/    {D, 0, 0, 0, "doFi"},
  154.     /* 88*/    {N, 0, 0, 0, "\\("},
  155.     /* 89*/    {N, 0, 0, 0, "\\)"},
  156.     /* 90*/    {N, 0, 0, 0, "["},
  157.     /* 91*/    {N, 0, 0, 0, "]"},
  158.     /* 92*/    {S, 0, 0, 0, "\\260"},
  159.     /* 93*/    {N, 0, 0, 0, "\\262"},
  160.     /* 94*/    {N, 0, 0, 0, "="},
  161.     /* 95*/    {S, 0, 0, 0, "\\322"},
  162.     /* 96*/    {N, 0, 0, 0, ":"},
  163.     /* 97*/    {N, 0, 0, 0, "+"},
  164.     /* 98*/    {N, 0, 0, 0, NOC},
  165.     /* 99*/    {N, 0, 0, 0, "!"},
  166.     /*100*/    {N, 0, 0, 0, "\\267"},
  167.     /*101*/    {N, 0, 0, 0, "?"},
  168.     /*102*/    {S, 0, 0, 0, "\\242"},
  169.     /*103*/    {N, -60, 0, 0, "|"},
  170.     /*104*/    {N, 0, 0, 0, NOC},
  171.     /*105*/    {S, 0, 0, 0, "\\323"},
  172.     /*106*/    {D, 0, 0, 0, "dosq"},
  173.     /*107*/    {N, 0, 0, 0, "$"},
  174.     };
  175.  
  176. struct troff2befont psSymFont[] = {
  177. /*          +-------------------------------- Troff character number
  178.         |
  179.             |    +--------------------------- N: standard fonts
  180.             |    |                            S: symbol font
  181.             |    |                            D: draw macro
  182.             |    |                            n: new font
  183.             |    |
  184.             |    |  +------------------------ X-shift (scaled by point)
  185.             |    |  |                         Note: positive is right.
  186.             |    |  |
  187.             |    |  |  +--------------------- Y-shift (scaled by point)
  188.             |    |  |  |                      Note: positive is up.
  189.             |    |  |  |
  190.             |    |  |  |  +------------------ Point scale factor
  191.             |    |  |  |  |
  192.             |    |  |  |  |   +-------------- Sequence
  193.             |    |  |  |  |   |
  194.             v    v  v  v  v   v */
  195.     /*  0*/    {S, 0, 0, 0, "\\171"},
  196.     /*  1*/    {S, 0, 0, 0, "\\161"},
  197.     /*  2*/    {S, 0, 0, 0, "\\156"},
  198.     /*  3*/    {S, 0, 0, 0, "\\155"},
  199.     /*  4*/    {S, 0, 0, 0, "\\154"},
  200.     /*  5*/    {S, 0, 0, 0, "\\151"},
  201.     /*  6*/    {S, 0, 0, 0, "\\172"},
  202.     /*  7*/    {S, 0, 0, 0, "\\163"},
  203.     /*  8*/    {S, 0, 0, 0, "\\144"},
  204.     /*  9*/    {S, 0, 0, 0, "\\142"},
  205.     /* 10*/    {S, 0, 0, 0, "\\170"},
  206.     /* 11*/    {S, 0, 0, 0, "\\150"},
  207.     /* 12*/    {S, 0, 0, 0, "\\146"},
  208.     /* 13*/    {S, 0, 0, 0, "\\165"},
  209.     /* 14*/    {S, 0, 0, 0, "\\153"},
  210.     /* 15*/    {S, 0, 0, 0, NOC},
  211.     /* 16*/    {S, 0, 0, 0, "\\160"},
  212.     /* 17*/    {N, 0, 0, 0, "@"},
  213.     /* 18*/    {S, 0, 0, 0, "\\257"},
  214.     /* 19*/    {S, 0, 0, 0, NOC},
  215.     /* 20*/    {S, 0, 0, 0, "\\141"},
  216.     /* 21*/    {S, 0, 0, 0, "\\174"},
  217.     /* 22*/    {S, 0, 0, 0, "\\143"},
  218.     /* 23*/    {N, 0, 0, 0, "\\042"},
  219.     /* 24*/    {S, 0, 0, 0, "\\145"},
  220.     /* 25*/    {S, 0, 0, 0, "\\075"},
  221.     /* 26*/    {S, 0, 0, 0, "\\157"},
  222.     /* 27*/    {S, 0, 0, 0, "\\254"},
  223.     /* 28*/    {S, 0, 0, 0, "\\162"},
  224.     /* 29*/    {S, 0, 0, 0, "\\255"},
  225.     /* 30*/    {S, 0, 0, 0, "\\164"},
  226.     /* 31*/    {4, 0, 0, 0, "O"},
  227.     /* 32*/    {N, 0, 0, 0, "\\134"},
  228.     /* 33*/    {S, 0, 0, 0, "\\131"},
  229.     /* 34*/    {D, 0, 0, 0, "BellSymbol"},
  230.     /* 35*/    {S, 0, 0, 0, "\\245"},
  231.     /* 36*/    {S, 0, 0, 0, "\\147"},
  232.     /* 37*/    {S, 0, 0, 0, "\\312"},
  233.     /* 38*/    {S, 0, 0, 0, "\\265"},
  234.     /* 39*/    {S, 0, 0, 0, "\\336"},
  235.     /* 40*/    {S, 0, 0, 0, "\\167"},
  236.     /* 41*/    {S, 0, 0, 0, NOC},
  237.     /* 42*/    {S, 0, 0, 0, "\\321"},
  238.     /* 43*/    {S, 0, 0, 0, NOC},
  239.     /* 44*/    {S, 0, 0, 0, "\\106"},
  240.     /* 45*/    {S, 0, 0, 0, "\\121"},
  241.     /* 46*/    {S, 0, 0, 0, "\\127"},
  242.     /* 47*/    {S, 0, 0, 0, "\\310"},
  243.     /* 48*/    {4, 0, 0, 0, "M"},
  244.     /* 49*/    {S, 0, 0, 0, "\\126"},
  245.     /* 50*/    {S, 0, 0, 0, "\\114"},
  246.     /* 51*/    {S, 0, 0, 0, "\\055"},
  247.     /* 52*/    {S, 0, 0, 0, "\\107"},
  248.     /* 53*/    {S, 0, 0, 0, "\\362"},
  249.     /* 54*/    {S, 0, 0, 0, "\\120"},
  250.     /* 55*/    {S, 0, 0, 0, "\\314"},
  251.     /* 56*/    {S, 0, 0, 0, "\\311"},
  252.     /* 57*/    {N, 0, 0, 0, "\\176"},
  253.     /* 58*/    {S, 0, 0, 0, "\\266"},
  254.     /* 59*/    {S, 0, 0, 0, "\\104"},
  255.     /* 60*/    {S, 0, 0, 0, "\\326"},
  256.     /* 61*/    {S, 0, 0, 0, "\\123"},
  257.     /* 62*/    {S, 0, 0, 0, "\\273"},
  258.     /* 63*/    {S, 0, 0, 0, "\\076"},
  259.     /* 64*/    {S, 0, 0, 0, "\\130"},
  260.     /* 65*/    {S, 0, 0, 0, "\\074"},
  261.     /* 66*/    {S, 0, 0, 0, "\\244"},
  262.     /* 67*/    {S, 0, 0, 0, "\\307"},
  263.     /* 68*/    {S, 0, 0, 0, "\\125"},
  264.     /* 69*/    {S, 0, 0, 0, "\\330"},
  265.     /* 70*/    {4, 0, 0, 0, "J"},
  266.     /* 71*/    {4, 0, 0, 0, "B"},
  267.     /* 72*/    {4, 0, 0, 0, "A"},
  268.     /* 73*/    {4, 0, 0, 0, "C"},
  269.     /* 74*/    {4, 0, 0, 0, "D"},
  270.     /* 75*/    {4, 0, 0, 0, "E"},
  271.     /* 76*/    {4, 0, 0, 0, "F"},
  272.     /* 77*/    {4, 0, 0, 0, "G"},
  273.     /* 78*/    {4, 0, 0, 0, "K"},
  274.     /* 79*/    {4, 0, 0, 0, "I"},
  275.     /* 80*/    {4, 0, 0, 0, "H"},
  276.     /* 81*/    {S, 0, 0, 0, "\\264"},
  277.     /* 82*/    {S, 0, 0, 0, "\\270"},
  278.     /* 83*/    {S, 0, 0, 0, "\\261"},
  279.     /* 84*/    {S, 0, 0, 0, "\\243"},
  280.     /* 85*/    {S, 0, 0, 0, "\\263"},
  281.     /* 86*/    {S, 0, 0, 0, "\\272"},
  282.     /* 87*/    {S, 0, 0, 0, "\\271"},
  283.     /* 88*/    {S, 0, 0, 0, "\\173"},
  284.     /* 89*/    {S, 0, 0, 0, "\\175"},
  285.     /* 90*/    {N, 0, 0, 0, "\\302"},
  286.     /* 91*/    {N, 0, 0, 0, "\\301"},
  287.     /* 92*/    {N, 0, 0, 0, "\\303"},
  288.     /* 93*/    {N, 0, 0, 0, "\\043"},
  289.     /* 94*/    {S, 0, 0, 0, "\\334"},
  290.     /* 95*/    {S, 0, 0, 0, "\\316"},
  291.     /* 96*/    {N, 0, 0, 0, "\\304"},
  292.     /* 97*/    {S, 0, 0, 0, "\\306"},
  293.     /* 98*/    {S, 0, 0, 0, NOC},
  294.     /* 99*/    {N, 0, 0, 0, "\\263"},
  295.     /*100*/    {4, 0, 0, 0, "L"},
  296.     /*101*/    {S, 0, 0, 0, "\\052"},
  297.     /*102*/    {S, 0, 0, 0, "\\315"},
  298.     /*103*/    {4, 0, 0, 0, "N"},
  299.     /*104*/    {S, 0, 0, 0, NOC},
  300.     /*105*/    {S, 0, 0, 0, "\\053"},
  301.     /*106*/    {S, 0, 0, 0, "\\256"},
  302.     /*107*/    {N, 0, 0, 0, "\\247"},
  303. };
  304.  
  305. psPage() {
  306.     if (!currentPage)
  307.     return;
  308.     printf("hits misses\n");
  309.     printf("PageSave restore\n");
  310.     printf("/misses exch def /hits exch def\n");
  311.     printf("ShowPage\n");
  312.     pagePending = 1;
  313. }
  314.  
  315. static
  316. doPageStart() {
  317.     currentPage++;
  318.     printf("%%%%Page: ? %d\n", currentPage);
  319. #ifdef    FORM
  320.     printf("/Form { %s } def\n",
  321.     Overlay[0] == '+' ? (Overlay[0] = '\0', Overlay+1) : Overlay);
  322. #endif
  323.     printf("/PageSave save def\n");
  324.     pagePending = 0;
  325.     printf("StartPage\n");
  326. }
  327.  
  328. psSetFont(font, points)
  329. int font, points; {
  330.     if (lastPoints != points || font != lastFont) {
  331.     struct fonttable *fp = &fonttable[font];
  332.     if (fp->fontSeq && *fp->fontSeq && !(fp->flags&USED)) {
  333.         char buffer[512];
  334.         int n;
  335.         FILE *f = fopen(fp->fontSeq, "r");
  336.         if (!f) {
  337.         fprintf(stderr, "%s: cannot open fontfile %s\n",
  338.             progname, fp->fontSeq);
  339.         } else {
  340.         DBP((D_BEND,"Downloading %s\n", fp->fontSeq));
  341.         while((n = fread(buffer, 1, sizeof(buffer), f)) > 0) {
  342.             fwrite(buffer, 1, n, stdout);
  343.         }
  344.         fclose(f);
  345.         }
  346.     }
  347.  
  348.     fp->flags |= USED;
  349. #ifdef    FONTMACRO
  350.     printf("/%s %d SetFont\n", fp->fontName, points);
  351. #else
  352.     printf("/%s dup /curFont exch def findfont\n",
  353.         fp->fontName);
  354.     printf("%d dup /curPoints exch def scalefont setfont\n", points);
  355. #endif
  356.     lastPoints = points;
  357.     lastFont = font;
  358.     }
  359. }
  360.  
  361. int indraw = 0;
  362.  
  363. psChar(x, y, font, points, troffChar, sequence)
  364. int x, y;
  365. int font, points, troffChar;
  366. register char *sequence; {
  367.     register int nx = TROFF2PSX(x), ny = TROFF2PSY(y);
  368.     register struct troff2befont *rp;
  369.  
  370.     if (pagePending) {
  371.     resetState();
  372.     doPageStart();
  373.     }
  374.  
  375.     if (font < 0) {
  376. #ifdef    TRY
  377.     if (!indraw) {
  378. #endif
  379.         printf("newpath\n");
  380.         emitnum(nx);
  381.         putchar(' ');
  382.         emitnum(ny);
  383.         printf(" moveto\n");
  384.         indraw = 1;
  385. #ifdef    TRY
  386.     }
  387. #endif
  388.     return;
  389. #ifdef    TRY
  390.     } else if (indraw) {
  391.     printf("stroke\n");
  392.     indraw = 0;
  393. #endif
  394.     }
  395.  
  396.     charCount++;
  397.  
  398.     DBP((D_BEND,"BEFORE (troffChar,x,y,font,points) = (%d,%d,%d,%d,%d)\n",
  399.     troffChar, x, y, font, points));
  400.     if (font == 3) {
  401.     rp = &be->besymfont[troffChar];
  402.     } else {
  403.     rp = &be->bestdfont[troffChar];
  404.     }
  405.  
  406.     switch(rp->t2b_font) {
  407.     /* Only fonts with "N" are subject to font translation */
  408.     case N:
  409.         if (font == 3)
  410.         font = 0;    /* Special chars are Courier */
  411.         else {
  412.         DBP((D_BEND,"psSetChar %d->%s (%s)\n", font,
  413.             xlatetable[font]->troffName,
  414.             xlatetable[font]->fontName));
  415.         font = xlatetable[font] - fonttable;
  416.         }
  417.         break;
  418.     case S:
  419.         font = 3;
  420.         break;
  421.     case D:
  422.         break;
  423.     default:
  424.         /* Typically used when the R and S fonts don't have the
  425.            character desired, so select the font via the index
  426.            in the fonts.?? file */
  427.         font = rp->t2b_font;
  428.         break;
  429.     }
  430.  
  431.     if (!sequence)
  432.     sequence = rp->t2b_charseq;
  433.  
  434.     if (!sequence) {
  435.     fprintf(stderr, "No coding for %d\n", troffChar);
  436.     return;
  437.     }
  438.  
  439.     /*    We're committed now - the "if" statements avoid floating
  440.     arithmetic on slow machines */
  441.  
  442.     if (rp->t2b_scale) points *= (.01 * rp->t2b_scale);
  443.     if (rp->t2b_xc) nx += points * (.01 * rp->t2b_xc);
  444.     if (rp->t2b_yc) ny += points * (.01 * rp->t2b_yc);
  445.  
  446.     psSetFont(font, points);
  447.  
  448.     DBP((D_BEND,"AFTER (sequence,x,y,font,points) = (%s,%d,%d,%d,%d)\n",
  449.     sequence, nx, ny, font, points));
  450.  
  451.     if (rp->t2b_font == D) {
  452.     emitnum(nx);
  453.     printf(" ");
  454.     emitnum(ny);
  455.     printf(" ");
  456.     printf("%s\n", sequence);
  457.     } else {
  458.     emitnum(nx);
  459.     if (lastYPos != ny) {
  460.         printf(" ");
  461.         emitnum(ny);
  462.         printf("(%s)Y\n", sequence);
  463.         lastYPos = ny;
  464.     } else
  465.         printf("(%s)X\n",sequence);
  466.     }
  467. }
  468.  
  469. /*    Specialized emit routine:
  470.     outputs number divided by PSSCALEFACTOR, rounded to the first
  471.     decimal place without using floats/double
  472.  */
  473. emitnum(val)
  474. register int val; {
  475.     register int neg;
  476.     if (val < 0) {
  477.     neg = 1;
  478.     val = -val;
  479.     } else {
  480.     neg = 0;
  481.     }
  482.     if (neg)
  483.     printf("-");
  484.     printf("%d", val / PSSCALEFACTOR);
  485.     val = ((val % PSSCALEFACTOR) * 10 /*+ (PSSCALEFACTOR / 2)*/) /
  486.     PSSCALEFACTOR;
  487.     if (val)
  488.     printf(".%d", val);
  489. }
  490.  
  491. extern char nodename[];
  492.  
  493. psProlog() {
  494.     extern char *ctime();
  495.     extern char *strchr();
  496.     char buffer[30];
  497.     FILE *library;
  498.     long curtime;
  499.  
  500.     currentPage = 0;
  501.     pagePending = 1;
  502.  
  503.     library = libopen(printer, "lib");
  504.  
  505.     time(&curtime);
  506.     strcpy(buffer, ctime(&curtime));
  507.     *strchr(buffer, '\n') = '\0';
  508.     getnodename();
  509.  
  510.     printf("%%!PS-Adobe-1.0\n");
  511.     printf("%%%%Title: (stdin)\n");
  512.     printf("%%%%Creator: %s %s\n", progname, shortversion);
  513.     printf("%%%%PsroffVersion: %s\n", version);
  514.     printf("%%%%CreationDate: %s\n", buffer);
  515.     printf("%%%%For: %s\n", username);
  516.     printf("%%%%Pages: (atend)\n");
  517.     printf("%%%%DocumentFonts: (atend)\n");
  518.     printf("%%%%EndComments\n");
  519.     printf("/GlobalSave save def\n");
  520.     printf("/hits 0 def /misses 0 def\n");
  521.     /* special backends (eg: psfig) need this */
  522.     printf("/resolution %d def\n", TROFFRESOLUTION);
  523. #ifndef    NOCHATTER
  524.     /* compatibility with behandler.ps */
  525.     printf("statusdict /jobname (%s@%s %s %s %s) def\n",
  526.     username, nodename, buffer, progname, shortversion);
  527.     printf("(%s@%s %s %s %s\\n) print\n", username, nodename, buffer,
  528.     progname, shortversion);
  529.     printf("flush\n");
  530. #endif
  531.     printf("usertime /btime exch def\n");
  532.     psXlate(library);
  533.     doprologs();
  534.     printf("%%%%EndProlog\n");
  535.     fclose(library);
  536. }
  537.  
  538. psEpilog() {
  539.     int i;
  540.     if (!currentPage)
  541.     return;
  542.     printf("%%%%Trailer\n");
  543.     if (metrics)
  544.     printf("%d metrics\n", charCount);
  545. #ifndef    NOCHATTER
  546.     printf("(Execution time (seconds): ) print\n");
  547.     printf("usertime btime sub 0.001 mul (          ) cvs print\n");
  548.     printf("(; Pages: %d) print\n", currentPage);
  549.     printf("(\\n) print\n");
  550.     printf("flush\n");
  551. #endif
  552.     printf("GlobalSave restore\n");
  553.     printf("%%%%DocumentFonts:");
  554.     for (i = 0; i < MAXFONTS; i++)
  555.     if (fonttable[i].flags&USED)
  556.         printf(" %s", fonttable[i].fontName);
  557.     printf("\n");
  558.     printf("%%%%Pages: %d\n", currentPage);
  559. #ifndef    NOCONTROLD
  560.     putchar('\004');
  561. #endif
  562. }
  563.  
  564. psXlate(library)
  565. FILE *library; {
  566.     char buf[512];
  567.     while (fgets(buf, sizeof(buf), library))
  568.     if (0 == strncmp(buf, "%%%", 3))
  569.         interp(&buf[3], psXlate, "ps");
  570.     else
  571.         fputs(buf, stdout);
  572. }
  573.  
  574. psOverlay(overlay)
  575. char *overlay; {
  576. #ifdef    FORM
  577.     strcpy(Overlay, overlay);
  578.     printf("%%%%%%Form set: %s\n", Overlay);
  579. #endif
  580. }
  581.  
  582. #ifdef    INSPECIAL
  583. psDraw(origX, origY, s)
  584. int origX, origY;
  585. register char *s; {
  586.     register int opcode, ctindex = 0, temp, neg;
  587.     /*static int curDX = -1, curDY = -1;*/
  588.     short int numbers[100];
  589.  
  590.     DBP((D_CAT, "psDraw: (%d,%d): %s\n", origX, origY, s));
  591.     /* Special invocation to get the newpath/moveto done */
  592.     psChar(origX, origY, -1, -1, (char*) NULL, (char*) NULL);
  593.     while(*s && isspace(*s)) s++;
  594.     opcode = *s;
  595.     neg = 1;
  596.     for (;*s;s++) {
  597.     if (isspace(*s))
  598.         continue;
  599.     else if (*s == '\\')
  600.         s += 3;
  601.     else if (*s == '-')
  602.         neg = -1;
  603.     else if (!isdigit(*s))
  604.         continue;
  605.     else {
  606.         temp = *s - '0';
  607.         while(isdigit(*(s+1)))
  608.         temp = temp * 10 + (*++s - '0');
  609.         numbers[ctindex++] = neg * temp;
  610.         neg = 1;
  611.     }
  612.     }
  613.     switch(opcode) {
  614.     case 'l':
  615.         DBP((D_CAT, "drawline: %d, %d\n", numbers[0], numbers[1]));
  616.         emitnum((int) numbers[0]);
  617.         putchar(' ');
  618.         emitnum((int) -numbers[1]);
  619.         printf(" rlineto\n");
  620.         break;
  621.     case 'a':
  622.         for (temp = 0; temp < 4; temp++) {
  623.         emitnum((int) ((temp % 2) ? -numbers[temp]: numbers[temp]));
  624.         putchar(' ');
  625.         }
  626.         printf("Arc\n");
  627.         break;
  628.     case 'c':
  629.         numbers[1] = numbers[0];
  630.     case 'e':
  631.         DBP((D_CAT, "drawellipse: %d, %d\n", numbers[0], numbers[1]));
  632.         emitnum((int) numbers[0]);
  633.         putchar(' ');
  634.         emitnum((int) numbers[1]);
  635.         printf(" Ellipse\n");
  636.         break;
  637.     case '~':
  638.         if (ctindex < 4) {
  639.         fprintf(stderr, "%s: too few points to spline: %s\n",
  640.             progname, s);
  641.         break;
  642.         }
  643.         fprintf(stderr, "%s: Don't support splines yet\n", progname);
  644.         /* Some of the following is inspired from tpscript.
  645.            First convert to RELATIVE to the starting point.
  646.            Further, There's a bug in PIC that returns negatively one
  647.            unit LESS than it went forward - fudge it here */
  648.         for (temp = 2; temp < ctindex; temp++) {
  649.         if (numbers[temp] < 0)
  650.             numbers[temp]--;
  651.         numbers[temp] += numbers[temp-2];
  652.         }
  653.         if (ctindex == 4) {
  654.         emitnum((int) numbers[0] / 2);
  655.         putchar(' ');
  656.         emitnum((int) -numbers[1] / 2);
  657.         putchar(' ');
  658.         emitnum((int) (numbers[0] + numbers[2]) / 2);
  659.         putchar(' ');
  660.         emitnum((int) -(numbers[1] + numbers[3])/ 2);
  661.         putchar(' ');
  662.         emitnum((int) numbers[2]);
  663.         putchar(' ');
  664.         emitnum((int) -numbers[3]);
  665.         printf(" rcurveto\n");
  666.         }
  667.         break;
  668.     default:
  669.         fprintf(stderr, "%s: invalid draw code %c\n", progname, opcode);
  670.         indraw = 0;
  671.         break;
  672.     }
  673.     printf("stroke\n");
  674. }
  675. #endif
  676. #endif /* PS */
  677.