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