home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / maths / plplot / plplot_2 / drivers / tk / plr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-25  |  12.8 KB  |  556 lines

  1. /* $Id: plr.c,v 1.18 1994/08/25 03:59:43 mjl Exp $
  2.  * $Log: plr.c,v $
  3.  * Revision 1.18  1994/08/25  03:59:43  mjl
  4.  * Fixed to properly update driver when cmap state is changed.  Contributed
  5.  * by Radey Shouman.
  6.  *
  7.  * Revision 1.17  1994/07/18  20:29:58  mjl
  8.  * Fixed the escape function to pass ALL received escape commands.
  9.  *
  10.  * Revision 1.16  1994/06/30  18:43:02  mjl
  11.  * Cleaning up to remove gcc -Wall warnings, and other miscellanea.
  12. */
  13.  
  14. /*
  15.     plr.c
  16.  
  17.     Copyright 1993
  18.     Maurice LeBrun
  19.     IFS, University of Texas at Austin
  20.  
  21.     This software may be freely copied, modified and redistributed without
  22.     fee provided that this copyright notice is preserved intact on all
  23.     copies and modified copies.
  24.  
  25.     There is no warranty or other guarantee of fitness of this software.
  26.     It is provided solely "as is". The author(s) disclaim(s) all
  27.     responsibility and liability with respect to this software's usage or
  28.     its effect upon hardware or computer systems.
  29.  
  30.  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  31.  *
  32.  * Support routines to render a PLPLOT byte stream, interpreting the PLPLOT
  33.  * metacode.  
  34.  *
  35.  * Although this code is duplicated to some extent by plrender and the
  36.  * plot buffer redraw code (in plbuf.c), they are all different in some
  37.  * significant ways, namely:
  38.  *
  39.  *    - plrender must always retain backward compatibility code to 
  40.  *      handle old metafiles, as well as stuff to support seeking.
  41.  *
  42.  *    - plbuf by definition is redrawing on the same machine so no 
  43.  *      special effort is necessary to make the byte stream portable,
  44.  *      also, only low-level graphics calls are used (grline, etc)
  45.  *
  46.  * The rendering code here must (by contrast to plbuf) use the high level
  47.  * plot routines (as does plrender), to support local zooms as well as the
  48.  * ability to dump the associated window into plot space to a file, but is
  49.  * otherwise pretty minimal.  A portable byte stream is used since network
  50.  * communication over a socket may be used.
  51.  *
  52. \*----------------------------------------------------------------------*/
  53.  
  54. /*
  55. #define DEBUG
  56. #define DEBUG_ENTER
  57. */
  58.  
  59. #include "plserver.h"
  60. #include "plevent.h"
  61. #include "metadefs.h"
  62.  
  63. /* Some wrapper macros to return (-1) on error */
  64.  
  65. #define plr_rd(code) \
  66. if (code) { fprintf(stderr, \
  67.         "Unable to read from %s in %s at line %d, bytecount %ld\n", \
  68.         plr->iodev->typename, __FILE__, __LINE__, plr->pdfs->bp); \
  69.         return(-1); }
  70.  
  71. #define plr_cmd(code) \
  72. if ((code) == -1) return(-1);
  73.  
  74. /* Error termination */
  75.  
  76. #define barf(msg) \
  77. { fprintf(stderr, "%s\nCommand code: %d, byte count: %ld\n", \
  78.       msg, csave, plr->pdfs->bp); return(-1); }
  79.  
  80. /* Static function prototypes. */
  81.  
  82. static int    plr_process1     (PLRDev *plr, int c);
  83. static int    plr_init    (PLRDev *plr);
  84. static int    plr_line    (PLRDev *plr, int c);
  85. static int    plr_eop        (PLRDev *plr);
  86. static int    plr_bop     (PLRDev *plr);
  87. static int    plr_state    (PLRDev *plr);
  88. static int    plr_esc        (PLRDev *plr);
  89. static int    plr_get        (PLRDev *plr);
  90. static int    plr_unget    (PLRDev *plr, U_CHAR c);
  91. static int    get_ncoords    (PLRDev *plr, PLFLT *x, PLFLT *y, PLINT n);
  92. static int    plresc_fill    (PLRDev *plr);
  93.  
  94. /* variables */
  95.  
  96. static int    csave = -1;
  97. static U_CHAR    dum_uchar;
  98. static U_SHORT    dum_ushort;
  99. static PLFLT    x[PL_MAXPOLY], y[PL_MAXPOLY];
  100.  
  101. /*----------------------------------------------------------------------*\
  102.  * plr_start()
  103.  *
  104.  * Set default state parameters before anyone else has a chance to.
  105. \*----------------------------------------------------------------------*/
  106.  
  107. void
  108. plr_start(PLRDev *plr)
  109. {
  110.     dbug_enter("plr_start");
  111.  
  112.     plr->xmin = 0;
  113.     plr->xmax = PIXELS_X - 1;
  114.     plr->ymin = 0;
  115.     plr->ymax = PIXELS_Y - 1;
  116.  
  117.     plr->xold = UNDEFINED;
  118.     plr->yold = UNDEFINED;
  119. }
  120.  
  121. /*----------------------------------------------------------------------*\
  122.  * plr_process()
  123.  *
  124.  * Read & process commands until plr->nbytes bytes have been read.
  125. \*----------------------------------------------------------------------*/
  126.  
  127. int
  128. plr_process(PLRDev *plr)
  129. {
  130.     int c;
  131.  
  132.     dbug_enter("plr_process");
  133.  
  134.     while (plr->pdfs->bp < plr->nbytes) {
  135.     plr_cmd( c = plr_get(plr) );
  136.     csave = c;
  137.     plr_cmd( plr_process1(plr, c) );
  138.     }
  139.     return 0;
  140. }
  141.  
  142. /*----------------------------------------------------------------------*\
  143.  * plr_process1()
  144.  *
  145.  * Process a command.  Note: because of line->polyline compression, this
  146.  * may actually process an arbitrary number of LINE or LINETO commands.
  147.  * Since the data buffer (fifo or socket) is only flushed after a complete
  148.  * command, there should be no danger in rushing blindly ahead to execute
  149.  * each plot command.
  150. \*----------------------------------------------------------------------*/
  151.  
  152. static int
  153. plr_process1(PLRDev *plr, int c)
  154. {
  155.     switch (c) {
  156.  
  157.     case INITIALIZE:
  158.     plr_cmd( plr_init(plr) );
  159.     break;
  160.  
  161.     case LINE:
  162.     case LINETO:
  163.     case POLYLINE:
  164.     plr_cmd( plr_line(plr, c) );
  165.     break;
  166.  
  167.     case EOP:
  168.     plr->at_eop = 1;
  169.     plr_cmd( plr_eop(plr) );
  170.     break;
  171.  
  172.     case BOP:
  173.     plr->at_bop = 1;
  174.     plr_cmd( plr_bop(plr) );
  175.     break;
  176.  
  177.     case CHANGE_STATE:
  178.     plr_cmd( plr_state(plr) );
  179.     break;
  180.  
  181.     case ESCAPE:
  182.     plr_cmd( plr_esc(plr) );
  183.     break;
  184.  
  185.     default:
  186.     fprintf(stderr, "plr_process1: Unrecognized command code %d\n", c);
  187.     }
  188.  
  189.     return 0;
  190. }
  191.  
  192. /*----------------------------------------------------------------------*\
  193.  * void plr_init()
  194.  *
  195.  * Handle initialization.
  196. \*----------------------------------------------------------------------*/
  197.  
  198. static int
  199. plr_init(PLRDev *plr)
  200. {
  201.     char tk_magic[80], tk_version[80], tag[80];
  202.  
  203.     dbug_enter("plr_init");
  204.  
  205. /* Read header info */
  206.  
  207.     plr_cmd( pdf_rd_header(plr->pdfs, tk_magic) );
  208.     if (strcmp(tk_magic, PLSERV_HEADER))
  209.     barf("plr_init: Invalid header");
  210.  
  211. /* Read version field of header.  We need to check that we can read the */
  212. /* byte stream, in case this is an old version of plserver. */
  213.  
  214.     plr_cmd( pdf_rd_header(plr->pdfs, tk_version) );
  215.     if (strcmp(tk_version, PLSERV_VERSION) > 0) {
  216.     fprintf(stderr,
  217.         "Error: incapable of reading output of version %s.\n", tk_version);
  218.     barf("plr_init: Please obtain a newer copy of plserver.");
  219.     }
  220.  
  221. /* Read tagged initialization info. */
  222. /* Overkill, but a no-brainer since plrender already uses this */
  223.  
  224.     for (;;) {
  225.     plr_cmd( pdf_rd_header(plr->pdfs, tag) );
  226.     if (*tag == '\0')
  227.         break;
  228.  
  229.     if ( ! strcmp(tag, "xmin")) {
  230.         plr_rd( pdf_rd_2bytes(plr->pdfs, &dum_ushort) );
  231.         plr->xmin = dum_ushort;
  232.         continue;
  233.     }
  234.  
  235.     if ( ! strcmp(tag, "xmax")) {
  236.         plr_rd( pdf_rd_2bytes(plr->pdfs, &dum_ushort) );
  237.         plr->xmax = dum_ushort;
  238.         continue;
  239.     }
  240.  
  241.     if ( ! strcmp(tag, "ymin")) {
  242.         plr_rd( pdf_rd_2bytes(plr->pdfs, &dum_ushort) );
  243.         plr->ymin = dum_ushort;
  244.         continue;
  245.     }
  246.  
  247.     if ( ! strcmp(tag, "ymax")) {
  248.         plr_rd( pdf_rd_2bytes(plr->pdfs, &dum_ushort) );
  249.         plr->ymax = dum_ushort;
  250.         continue;
  251.     }
  252.  
  253.     if ( ! strcmp(tag, "width")) {
  254.         plr_rd( pdf_rd_1byte(plr->pdfs, &dum_uchar) );
  255.         plwid(dum_uchar);
  256.         continue;
  257.     }
  258.  
  259.     barf("plr_init: Unrecognized initialization tag.");
  260.     }
  261.  
  262.     return 0;
  263. }
  264.  
  265. /*----------------------------------------------------------------------*\
  266.  * plr_line()
  267.  *
  268.  * Draw a line or polyline.
  269. \*----------------------------------------------------------------------*/
  270.  
  271. static int
  272. plr_line(PLRDev *plr, int c)
  273. {
  274.     int c1;
  275.     U_SHORT npts;
  276.  
  277.     npts = 1;
  278.     x[0] = plr->xold;
  279.     y[0] = plr->yold;
  280.  
  281.     switch ((int) c) {
  282.  
  283.     case LINE:
  284.     plr_cmd( get_ncoords(plr, x, y, 1) );
  285.  
  286.     case LINETO:
  287.     for (;;) {
  288.         plr_cmd( get_ncoords(plr, x + npts, y + npts, 1) );
  289.  
  290.         npts++;
  291.         if (npts == PL_MAXPOLY || (plr->pdfs->bp == plr->nbytes))
  292.         break;
  293.  
  294.         plr_cmd( c1 = plr_get(plr) );
  295.         if (c1 != LINETO) {
  296.         plr_cmd( plr_unget(plr, (U_CHAR) c1) );
  297.         break;
  298.         }
  299.     }
  300.     break;
  301.  
  302.     case POLYLINE:
  303.     plr_rd( pdf_rd_2bytes(plr->pdfs, &npts) );
  304.     plr_cmd( get_ncoords(plr, x, y, npts) );
  305.     break;
  306.     }
  307.  
  308.     plline(npts, x, y);
  309.  
  310.     plr->xold = x[npts - 1];
  311.     plr->yold = y[npts - 1];
  312.  
  313.     return 0;
  314. }
  315.  
  316. /*----------------------------------------------------------------------*\
  317.  * get_ncoords()
  318.  *
  319.  * Read n coordinate vectors.
  320. \*----------------------------------------------------------------------*/
  321.  
  322. #define plr_rdn(code) \
  323. if (code) { fprintf(stderr, \
  324. "Unable to read from %s in %s at line %d, bytecount %d\n\
  325. Bytes requested: %d\n", plr->iodev->typename, __FILE__, __LINE__, \
  326. (int) plr->pdfs->bp, (int) 2*n); return(-1); }
  327.  
  328. static int
  329. get_ncoords(PLRDev *plr, PLFLT *x, PLFLT *y, PLINT n)
  330. {
  331.     int i;
  332.     short xs[PL_MAXPOLY], ys[PL_MAXPOLY];
  333.  
  334.     plr_rdn( pdf_rd_2nbytes(plr->pdfs, (U_SHORT *) xs, n) );
  335.     plr_rdn( pdf_rd_2nbytes(plr->pdfs, (U_SHORT *) ys, n) );
  336.  
  337.     for (i = 0; i < n; i++) {
  338.     x[i] = xs[i];
  339.     y[i] = ys[i];
  340.     }
  341.     return 0;
  342. }
  343.  
  344. /*----------------------------------------------------------------------*\
  345.  * plr_eop()
  346.  *
  347.  * Clear screen.
  348. \*----------------------------------------------------------------------*/
  349.  
  350. static int
  351. plr_eop(PLRDev *plr)
  352. {
  353.     dbug_enter("plr_eop");
  354.  
  355.     pleop();
  356.     return 0;
  357. }
  358.  
  359. /*----------------------------------------------------------------------*\
  360.  * plr_bop()
  361.  *
  362.  * Page advancement.
  363. \*----------------------------------------------------------------------*/
  364.  
  365. static int
  366. plr_bop(PLRDev *plr)
  367. {
  368.     dbug_enter("plr_bop");
  369.  
  370. /* Advance and setup the page */
  371.  
  372.     plbop();
  373.     plvpor(0., 1., 0., 1.);
  374.     plwind(plr->xmin, plr->xmax, plr->ymin, plr->ymax);
  375.  
  376.     return 0;
  377. }
  378.  
  379. /*----------------------------------------------------------------------*\
  380.  * plr_state()
  381.  *
  382.  * Handle change in PLStream state (color, pen width, fill attribute,
  383.  * etc).
  384. \*----------------------------------------------------------------------*/
  385.  
  386. static int
  387. plr_state(PLRDev *plr)
  388. {
  389.     U_CHAR op;
  390.     int i;
  391.  
  392.     plr_rd( pdf_rd_1byte(plr->pdfs, &op) );
  393.  
  394.     switch (op) {
  395.  
  396.     case PLSTATE_WIDTH:{
  397.     U_SHORT width;
  398.  
  399.     plr_rd( pdf_rd_2bytes(plr->pdfs, &width) );
  400.  
  401.     plwid(width);
  402.     break;
  403.     }
  404.  
  405.     case PLSTATE_COLOR0:{
  406.     U_CHAR icol0, r, g, b;
  407.  
  408.     plr_rd( pdf_rd_1byte(plr->pdfs, &icol0) );
  409.  
  410.     if (icol0 == PL_RGB_COLOR) {
  411.         plr_rd( pdf_rd_1byte(plr->pdfs, &r) );
  412.         plr_rd( pdf_rd_1byte(plr->pdfs, &g) );
  413.         plr_rd( pdf_rd_1byte(plr->pdfs, &b) );
  414.         plrgb1(r, g, b);
  415.     }
  416.     else {
  417.         plcol(icol0);
  418.     }
  419.     break;
  420.     }
  421.  
  422.     case PLSTATE_COLOR1:{
  423.     U_SHORT icol1;
  424.     PLFLT col1;
  425.  
  426.     plr_rd( pdf_rd_2bytes(plr->pdfs, &icol1) );
  427.     col1 = (double) icol1 / (double) plsc->ncol1;
  428.     plcol1(col1);
  429.     break;
  430.     }
  431.  
  432.     case PLSTATE_FILL:{
  433.     signed char patt;
  434.  
  435.     plr_rd( pdf_rd_1byte(plr->pdfs, (U_CHAR *) &patt) );
  436.     plpsty(patt);
  437.     break;
  438.     }
  439.  
  440.     case PLSTATE_CMAP0:{
  441.     U_CHAR ncol0;
  442.  
  443.     plr_rd( pdf_rd_1byte(plr->pdfs, &ncol0) );
  444.     plsc->ncol0 = ncol0;
  445.     for (i = 0; i < plsc->ncol0; i++) {
  446.         plr_rd( pdf_rd_1byte(plr->pdfs, &plsc->cmap0[i].r) );
  447.         plr_rd( pdf_rd_1byte(plr->pdfs, &plsc->cmap0[i].g) );
  448.         plr_rd( pdf_rd_1byte(plr->pdfs, &plsc->cmap0[i].b) );
  449.     }
  450.     plP_state(PLSTATE_CMAP0);
  451.     break;
  452.     }
  453.  
  454.     case PLSTATE_CMAP1:{
  455.     U_SHORT ncol1;
  456.  
  457.     plr_rd( pdf_rd_2bytes(plr->pdfs, &ncol1) );
  458.     plsc->ncol1 = ncol1;
  459.     for (i = 0; i < plsc->ncol1; i++) {
  460.         plr_rd( pdf_rd_1byte(plr->pdfs, &plsc->cmap1[i].r) );
  461.         plr_rd( pdf_rd_1byte(plr->pdfs, &plsc->cmap1[i].g) );
  462.         plr_rd( pdf_rd_1byte(plr->pdfs, &plsc->cmap1[i].b) );
  463.     }
  464.     plP_state(PLSTATE_CMAP1);
  465.     break;
  466.     }
  467.     }
  468.  
  469.     return 0;
  470. }
  471.  
  472. /*----------------------------------------------------------------------*\
  473.  * plr_esc()
  474.  *
  475.  * Handle all escape functions.
  476.  * Only those that require additional data to be read need to be
  477.  * explicitly handled; the others are merely passed on to the actual
  478.  * driver. 
  479. \*----------------------------------------------------------------------*/
  480.  
  481. static int
  482. plr_esc(PLRDev *plr)
  483. {
  484.     U_CHAR op;
  485.  
  486.     plr_rd( pdf_rd_1byte(plr->pdfs, &op) );
  487.  
  488.     switch (op) {
  489.  
  490.     case PLESC_FILL:
  491.     plr_cmd( plresc_fill(plr) );
  492.     break;
  493.  
  494.     default:
  495.         pl_cmd((PLINT) op, NULL);
  496.     break;
  497.     }
  498.  
  499.     return 0;
  500. }
  501.  
  502. /*----------------------------------------------------------------------*\
  503.  * plresc_fill()
  504.  *
  505.  * Fill polygon described in points pls->dev_x[] and pls->dev_y[].
  506. \*----------------------------------------------------------------------*/
  507.  
  508. static int
  509. plresc_fill(PLRDev *plr)
  510. {
  511.     U_SHORT npts;
  512.  
  513.     dbug_enter("plresc_fill");
  514.  
  515.     plr_rd( pdf_rd_2bytes(plr->pdfs, &npts) );
  516.     get_ncoords(plr, x, y, npts);
  517.     plfill(npts, x, y);
  518.  
  519.     return 0;
  520. }
  521.  
  522. /*----------------------------------------------------------------------*\
  523.  * plr_get()
  524.  *
  525.  * Read & return the next command
  526. \*----------------------------------------------------------------------*/
  527.  
  528. static int
  529. plr_get(PLRDev *plr)
  530. {
  531.     int c;
  532.  
  533.     c = pdf_getc(plr->pdfs);
  534.     if (c == EOF) {
  535.     barf("plr_get: Unable to read character");
  536.     }
  537.  
  538.     return c;
  539. }
  540.  
  541. /*----------------------------------------------------------------------*\
  542.  * plr_unget()
  543.  *
  544.  * Push back the last command read.
  545. \*----------------------------------------------------------------------*/
  546.  
  547. static int
  548. plr_unget(PLRDev *plr, U_CHAR c)
  549. {
  550.     if (pdf_ungetc(c, plr->pdfs) == EOF) {
  551.     barf("plr_unget: Unable to push back character");
  552.     }
  553.  
  554.     return 0;
  555. }
  556.