home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / VOGLE.ZIP / VOGLE / DRIVERS / PS.C < prev    next >
C/C++ Source or Header  |  2000-02-11  |  11KB  |  695 lines

  1.  
  2. #define VOGLE 1
  3. /*
  4.  * The next bit is site and UNIX specific...
  5.  */
  6.  
  7. /*
  8.  * Some more bug fixes from  ralf@physik3.gwdg.de (Ralf Fassel)
  9.  * regarding %%Pages and devname .... 28/03/94
  10.  */
  11.  
  12. #include <stdio.h>
  13. #ifdef VOGLE
  14. #include "vogle.h"
  15. #else
  16. #include "vogl.h"
  17. #endif
  18.  
  19. typedef struct {
  20.     float    r, g, b;
  21. } Coltab;
  22.  
  23. static Coltab    *coltab;
  24. extern char    *vallocate();
  25.  
  26. extern FILE    *_voutfile();
  27.  
  28. static int    ps_first_time = 1, drawn = 0,
  29.         curcol = 0,            /* black */
  30.         pslstx = -1, pslsty = -1,    /* last (x, y) drawn */
  31.         colour = 0, page;
  32.  
  33. /*
  34.  * gray scale map for our standard colours
  35.  */
  36. static float    graymap[8] = {
  37.             0.0,
  38.             0.30,
  39.             0.59,
  40.             0.89,
  41.             0.11,
  42.             0.41,
  43.             0.70,
  44.             0.99
  45. };
  46.  
  47. static FILE    *fp;
  48.  
  49. /*
  50.  * noop
  51.  *
  52.  *    do nothing but return -1
  53.  */
  54. static int
  55. noop()
  56. {
  57.     return(-1);
  58. }
  59. /*
  60.  * PS_color
  61.  *
  62.  *    change the grey value of the ink
  63.  */
  64. static int
  65. PS_color(col)
  66.     int    col;
  67. {
  68.     curcol = col;
  69.     if (colour) {
  70.         curcol %= 256;
  71.         fprintf(fp, "%3.2f %3.2f %3.2f c\n", coltab[curcol].r, coltab[curcol].g, coltab[curcol].b);
  72.         return(0);
  73.     }
  74.  
  75.     if (col > 7)
  76.         return(0);
  77.  
  78.  
  79. #ifdef GREY_LINES
  80.     fprintf(fp, "%3.2f g\n", graymap[curcol]);
  81. #endif
  82.  
  83.     return(0);
  84. }
  85.  
  86. /*
  87.  * PS_mapcolor
  88.  *
  89.  *    Set our values in our pseudo colour map.
  90.  */
  91. static int
  92. PS_mapcolor(indx, r, g, b)
  93.     int    indx, r, g, b;
  94. {
  95.     if (colour && indx < 256 && indx >= 0) {
  96.         coltab[indx].r = r / 255.0;
  97.         coltab[indx].g = g / 255.0;
  98.         coltab[indx].b = b / 255.0;
  99.     }
  100.  
  101.     return(0);
  102. }
  103.  
  104. /*
  105.  * PS_common_init
  106.  *
  107.  *     Initialization that is common to both layouts
  108.  */
  109. static int
  110. PS_common_init()
  111. {
  112.  
  113.     vdevice.depth = colour ? 8 : 1;
  114.  
  115.     /*    Set other line drawing parameters    */
  116.  
  117.     fprintf(fp, "2 setlinewidth\n1 setlinejoin\n1 setlinecap\n");
  118.  
  119.     /*    Speed up symbol font handling    */
  120.  
  121.     fprintf(fp, "/sf /Courier findfont def\n");
  122.  
  123.     /*    Move    */
  124.  
  125.     fprintf(fp, "/m /moveto load def\n");
  126.  
  127.     /*    Draw    */
  128.  
  129.     fprintf(fp, "/d { lineto currentpoint stroke moveto } def\n");
  130.  
  131.     /*    Polygon Draw    */
  132.  
  133.     fprintf(fp, "/p /lineto load def\n");
  134.  
  135.     /*    Set character height    */
  136.  
  137.     fprintf(fp, "/h { sf exch scalefont setfont } def\n");
  138.  
  139.     /*    Show character string    */
  140.  
  141.     fprintf(fp, "/s /show load def\n");
  142.  
  143.     /*    Set gray scale    */
  144.  
  145.     fprintf(fp, "/g /setgray load def\n");
  146.  
  147.     if (colour) {
  148.         fprintf(fp, "/c /setrgbcolor load def\n");
  149.         coltab = (Coltab *)vallocate(256 * sizeof(Coltab));
  150.         PS_mapcolor(0, 0, 0, 0);
  151.         PS_mapcolor(1, 255, 0, 0);
  152.         PS_mapcolor(2, 0, 255, 0);
  153.         PS_mapcolor(3, 255, 255, 0);
  154.         PS_mapcolor(4, 0, 0, 255);
  155.         PS_mapcolor(5, 255, 0, 255);
  156.         PS_mapcolor(6, 0, 255, 255);
  157.         PS_mapcolor(7, 255, 255, 255);
  158.     }
  159.  
  160.     /*    Set a default font height    */
  161.     
  162.     fprintf(fp, "22 h\n");
  163.  
  164.     return(1);
  165. }
  166.  
  167. /*
  168.  * PS_init
  169.  *
  170.  *    set up the postcript environment. Returns 1 on success.
  171.  */
  172. static int
  173. PS_init()
  174. {
  175.     fp = _voutfile();
  176.  
  177.     if (!ps_first_time)
  178.         return(1);
  179.  
  180.     page = 1;
  181.     fputs("%!PS-Adobe-2.0 EPSF-1.2\n", fp);
  182.     fputs("%%BoundingBox: 74 96 528 728\n", fp);
  183.     fprintf(fp, "%%%%Page: %d %d\n", page, page);
  184.     fputs("%%EndComments\n", fp);
  185.     fprintf(fp, "72 300 div dup scale\n90 rotate\n400 -2200 translate\n");
  186.  
  187.     vdevice.sizeSy = 1890; 
  188.     vdevice.sizeSx = 2634; 
  189.     vdevice.sizeX = vdevice.sizeY = 1890; 
  190.  
  191.     PS_common_init();
  192.  
  193.     return (1);
  194. }
  195.  
  196. /*
  197.  * PSP_init
  198.  *
  199.  *    set up the postscript (Portrait) environment. Returns 1 on success.
  200.  */
  201. static int
  202. PSP_init()
  203. {
  204.     fp = _voutfile();
  205.  
  206.     if (!ps_first_time)
  207.         return(1);
  208.  
  209.     page = 1;
  210.     fputs("%!PS-Adobe-2.0 EPSF-1.2\n", fp);
  211.     fputs("%%BoundingBox: 72 96 526 728\n", fp);
  212.     fprintf(fp, "%%%%Page: %d %d\n", page, page);
  213.     fputs("%%EndComments\n", fp);
  214.  
  215.     fprintf(fp, "72 300 div dup scale\n300 400 translate\n");
  216.  
  217.     vdevice.sizeSy = 2634; 
  218.     vdevice.sizeSx = 1890; 
  219.     vdevice.sizeX = vdevice.sizeY = 1890; 
  220.  
  221.     PS_common_init();
  222.  
  223.     return (1);
  224. }
  225.  
  226. /*
  227.  * PS_exit
  228.  *
  229.  *    do a showpage and close the output file if neccessary.
  230.  */
  231. static int
  232. PS_exit()
  233. {
  234.     fputs("showpage\n", fp);
  235.     fputs("%%Trailer\n", fp);
  236.     fflush(fp);
  237.  
  238.     if (fp != stdout)
  239.         fclose(fp);
  240.  
  241.     /*
  242.      * Bug fix from brett@kirk.es.go.dlr.de (Bernward Bretthauer)
  243.      */
  244.     ps_first_time = 1;
  245.     drawn = 0;
  246.     curcol = 0;            /* black */
  247.     pslstx = pslsty = -1;
  248.     colour = 0;
  249.  
  250.     return(0);
  251. }
  252.  
  253. /*
  254.  * PS_draw
  255.  *
  256.  *    draw to an x, y point.
  257.  */
  258. static int
  259. PS_draw(x, y)
  260.     int    x, y;
  261. {
  262.     if (pslstx != vdevice.cpVx || pslsty != vdevice.cpVy)
  263.         fprintf(fp, "%d %d m\n", vdevice.cpVx, vdevice.cpVy);
  264.  
  265.     fprintf(fp, "%d %d d\n", x, y);
  266.     pslstx = x;
  267.     pslsty = y;
  268.     drawn = 1;
  269.  
  270.     return(0);
  271. }
  272.  
  273. static int
  274. PS_pnt(x, y)
  275.     int    x, y;
  276. {
  277.     fprintf(fp, "%d %d m\n", x, y);
  278.     fprintf(fp, "%d %d d\n", x, y);
  279.  
  280.     return(0);
  281. }
  282.  
  283.  
  284. /*
  285.  * PS_font
  286.  *
  287.  * load in small or large - could be improved.
  288.  */
  289. static int
  290. PS_font(font)
  291.     char    *font;
  292. {
  293.     if (strcmp(font, "small") == 0) {
  294.         vdevice.hwidth = 11.0;
  295.         vdevice.hheight = vdevice.hwidth * 1.833;
  296.         fprintf(fp, "%d h\n", (int)vdevice.hheight);
  297.     } else if (strcmp(font, "large") == 0) {
  298.         vdevice.hwidth = 22.0;
  299.         vdevice.hheight = vdevice.hwidth * 1.833;
  300.         fprintf(fp, "%d h\n", (int)vdevice.hheight);
  301.  
  302.     } else
  303.         return(0);
  304.  
  305.     return(1);
  306. }
  307.  
  308. /*
  309.  * PS_clear
  310.  *
  311.  *    flush the current page without resetting the graphics state of the
  312.  * laser printer.
  313.  */
  314. static int
  315. PS_clear()
  316. {
  317.     if (drawn) {
  318.         fprintf(fp, "gsave showpage grestore\n");
  319.         /* This is the end of the page, not of the document. */
  320.         /*  ralf@physik3.gwdg.de (Ralf Fassel) */
  321.         fputs("%%PageTrailer\n", fp);
  322.         page++;
  323.         fprintf(fp, "%%%%Page: %d %d\n", page, page);
  324.     }
  325.  
  326.     drawn = 0;
  327.  
  328.     return(0);
  329. }
  330.  
  331.     
  332. /*
  333.  * PS_char
  334.  *
  335.  *    output a character making sure that a '\' is sent first when
  336.  * appropriate.
  337.  */
  338. static int
  339. PS_char(c)
  340.     char    c;
  341. {
  342.     if (pslstx != vdevice.cpVx || pslsty != vdevice.cpVy)
  343.         fprintf(fp, "%d %d m\n", vdevice.cpVx, vdevice.cpVy);
  344.  
  345.     fprintf(fp, "(");
  346.  
  347.     switch(c) {
  348.     case '(':
  349.         fprintf(fp, "\\(");
  350.         break;
  351.     case ')':
  352.         fprintf(fp, "\\)");
  353.         break;
  354.     case '\\':
  355.         fprintf(fp, "\\");
  356.         break;
  357.     default:
  358.         fprintf(fp, "%c",c);
  359.     }
  360.  
  361.     fprintf(fp,") s \n");
  362.  
  363.     drawn = 1;
  364.     pslstx = pslsty = -1;
  365.  
  366.     return(0);
  367. }
  368.  
  369. /*
  370.  * PS_string
  371.  *
  372.  *    output a string one char at a time.
  373.  */
  374. static int
  375. PS_string(s)
  376.     char    *s;
  377. {
  378.     char    c;
  379.  
  380.     if (pslstx != vdevice.cpVx || pslsty != vdevice.cpVy)
  381.         fprintf(fp, "%d %d m\n", vdevice.cpVx, vdevice.cpVy);
  382.  
  383.     fprintf(fp, "(");
  384.     while ((c = *s++))
  385.         switch(c) {
  386.         case '(':
  387.             fprintf(fp, "\\(");
  388.             break;
  389.         case ')':
  390.             fprintf(fp, "\\)");
  391.             break;
  392.         case '\\':
  393.             fprintf(fp, "\\");
  394.             break;
  395.         default:
  396.         fprintf(fp, "%c",c);
  397.         }
  398.  
  399.     fprintf(fp,") s \n");
  400.     drawn = 1;
  401.     pslstx = pslsty = -1;
  402.  
  403.     return(0);
  404. }
  405.  
  406. /*
  407.  * PS_fill
  408.  *
  409.  *      fill a polygon
  410.  */
  411. static int
  412. PS_fill(n, x, y)
  413.     int     n, x[], y[];
  414. {
  415.     int     i;
  416.  
  417.  
  418.     fprintf(fp, "newpath \n");
  419.  
  420.     fprintf(fp, "%d %d m\n", x[0], y[0]);
  421.  
  422.     for (i = 1; i < n; i++)
  423.         fprintf(fp, "%d %d p\n", x[i], y[i]);
  424.  
  425.     fprintf(fp, "closepath\n");
  426.  
  427.     if (!colour)
  428.         fprintf(fp, "%3.2f g\n", graymap[curcol]);
  429.  
  430.     fprintf(fp, "fill\n");
  431.  
  432.     if (!colour)
  433.         fprintf(fp, "0 g\n");
  434.  
  435.     vdevice.cpVx = x[n - 1];
  436.     vdevice.cpVy = y[n - 1];
  437.  
  438.     pslstx = pslsty = -1;        /* fill destroys current path */
  439.  
  440.     return(0);
  441. }
  442.  
  443. #ifndef VOGLE
  444. /*
  445.  * Set the line width...
  446.  */
  447. static int
  448. PS_setlw(w)
  449.     int    w;
  450. {
  451.     fprintf(fp, "%d setlinewidth\n", w * 2 + 1);
  452.  
  453.     return(0);
  454. }
  455.  
  456. /*
  457.  * Set the line style...
  458.  */
  459. static int
  460. PS_setls(lss)
  461.     int    lss;
  462. {
  463.     unsigned ls = lss;
  464.     int    i, d, a, b, offset;
  465.  
  466.     if (ls == 0xffff) {
  467.         fprintf(fp, "[] 0 setdash\n");
  468.         return;
  469.     }
  470.  
  471.     fputc('[', fp);
  472.  
  473.     for (i = 0; i < 16; i++)    /* Over 16 bits */
  474.         if ((ls & (1 << i)))
  475.             break;
  476.  
  477.     offset = i;
  478.  
  479. #define    ON    1
  480. #define    OFF    0
  481.         
  482.     a = b = OFF;
  483.     if (ls & (1 << 0))
  484.         a = b = ON;
  485.  
  486.     d = 0;
  487.     for (i = 0; i < 16; i++) {    /* Over 16 bits */
  488.         if (ls & (1 << i))
  489.             a = ON;
  490.         else
  491.             a = OFF;
  492.  
  493.         if (a != b) {
  494.             b = a;
  495.             fprintf(fp, "%d ", d * 2 + 1);
  496.             d = 0;
  497.         }
  498.  
  499.         d++;
  500.     }
  501.  
  502.     fprintf(fp, "] %d setdash\n", offset);
  503.  
  504.     return(0);
  505. }
  506.  
  507. #else
  508. /*
  509.  * Set the line width...
  510.  */
  511. static int
  512. PS_setlw(w)
  513.     int    w;
  514. {
  515.     if (w == 0)
  516.         w = 2;
  517.     else if (w == 1)
  518.         w = 4;
  519.  
  520.     fprintf(fp, "%d setlinewidth\n", w);
  521.  
  522.     return(0);
  523. }
  524. #endif
  525.  
  526. static DevEntry psdev = {
  527.     "postscript",
  528.     "large",
  529.     "small",
  530.     noop,
  531.     PS_char,
  532.     noop,
  533.     PS_clear,
  534.     PS_color,
  535.     PS_draw,
  536.     PS_exit,
  537.     PS_fill,
  538.     PS_font,
  539.     noop,
  540.     noop,
  541.     PS_init,
  542.     noop,
  543.     PS_mapcolor,
  544. #ifndef VOGLE
  545.     PS_setls,
  546. #endif
  547.     PS_setlw,
  548.     PS_string,
  549.     noop,
  550.     noop
  551. };
  552.  
  553. /*
  554.  * _CPS_devcpy
  555.  *
  556.  *    copy the postscript device into vdevice.dev.
  557.  *     Set it so we can use colours.
  558.  */
  559. int
  560. _CPS_devcpy()
  561. {
  562.     vdevice.dev = psdev;
  563.     vdevice.dev.devname = "cps";
  564.     colour = 1;
  565.  
  566.     return(0);
  567. }
  568.  
  569. /*
  570.  * _PS_devcpy
  571.  *
  572.  *    copy the postscript device into vdevice.dev.
  573.  */
  574. int
  575. _PS_devcpy()
  576. {
  577.     vdevice.dev = psdev;
  578.  
  579.     return(0);
  580. }
  581.  
  582. /*
  583.  * _PSP_devcpy
  584.  *
  585.  *    copy the postscript portrait device into vdevice.dev.
  586.  */
  587. int
  588. _PSP_devcpy()
  589. {
  590.     vdevice.dev = psdev;
  591.     vdevice.dev.Vinit = PSP_init;
  592.     vdevice.dev.devname = "ppostscript";
  593.  
  594.     return(0);
  595. }
  596.  
  597. /*
  598.  * _PCPS_devcpy
  599.  *
  600.  *    copy the portrait postscript device into vdevice.dev.
  601.  *     Set it so we can use colours.
  602.  */
  603. int
  604. _PCPS_devcpy()
  605. {
  606.     vdevice.dev = psdev;
  607.     vdevice.dev.Vinit = PSP_init;
  608.     vdevice.dev.devname = "pcps";
  609.     colour = 1;
  610.  
  611.     return(0);
  612. }
  613.  
  614.  
  615. #ifdef LASERWRITER
  616.  
  617. /*
  618.  * LASER_init
  619.  *
  620.  *    set up the postcript environment. Returns 1 on success.
  621.  *    Opens pipe direct to lpr -Plw
  622.  */
  623. static int
  624. LASER_init()
  625. {
  626.     fp = popen("lpr -Plw", "w");
  627.     if (!fp) {
  628.         fprintf(stderr, "Couldn't open pipe to lpr command.\n");
  629.         exit(1);
  630.     }
  631.  
  632.     page = 1;
  633.  
  634.     if (!ps_first_time)
  635.         return(1);
  636.  
  637.     fputs("%!PS-Adobe-2.0 EPSF-1.2\n", fp);
  638.     fputs("%%BoundingBox: 74 96 528 728\n", fp);
  639.     fprintf(fp, "%%%%Page: %d %d\n", page, page);
  640.     fputs("%%EndComments\n", fp);
  641.     fprintf(fp, "72 300 div dup scale\n90 rotate\n400 -2200 translate\n");
  642.  
  643.     vdevice.sizeSy = 1890; 
  644.     vdevice.sizeSx = 2634; 
  645.     vdevice.sizeX = vdevice.sizeY = 1890; 
  646.  
  647.     PS_common_init();
  648.  
  649.     return (1);
  650. }
  651.  
  652. /*
  653.  * LASER_exit
  654.  *
  655.  *    do a showpage and close the output file if neccessary.
  656.  */
  657. static int
  658. LASER_exit()
  659. {
  660.     fprintf(fp, "showpage\n");
  661.     fprintf(fp, "%%Trailer\n");
  662.     fflush(fp);
  663.  
  664.     pclose(fp);
  665.  
  666.     /*
  667.      * Bug fix from brett@kirk.es.go.dlr.de (Bernward Bretthauer)
  668.      */
  669.     ps_first_time = 1;
  670.     drawn = 0;
  671.     curcol = 0;            /* black */
  672.     pslstx = pslsty = -1;
  673.     colour = 0;
  674.  
  675.     return(0);
  676. }
  677.  
  678. /*
  679.  * _LASER_devcpy
  680.  *
  681.  *    copy the postscript portrait device into vdevice.dev.
  682.  */
  683. int
  684. _LASER_devcpy()
  685. {
  686.     vdevice.dev = psdev;
  687.     vdevice.dev.Vinit = LASER_init;
  688.     vdevice.dev.Vexit = LASER_exit;
  689.     vdevice.dev.devname = "laser";
  690.     colour = 1;    /* If you have a colour printer */
  691.  
  692.     return(0);
  693. }
  694. #endif
  695.