/branches/tea/bindings/tk/plr.c
C | 560 lines | 308 code | 109 blank | 143 comment | 36 complexity | 8ef8e1e2ef671a4dcdf550074dffe233 MD5 | raw file
Possible License(s): LGPL-2.0, BSD-3-Clause-No-Nuclear-License-2014, Apache-2.0, GPL-2.0
- /* $Id: plr.c 1846 1995-09-22 16:04:16Z mjl $
- * $Log$
- * Revision 1.20 1995/09/22 16:04:12 mjl
- * Fixes to names of member variables of PLiodev structs.
- *
- * Revision 1.19 1995/03/16 23:08:06 mjl
- * The Copyright message was changed and general cleaning up done.
- *
- * Revision 1.18 1994/08/25 03:59:43 mjl
- * Fixed to properly update driver when cmap state is changed. Contributed
- * by Radey Shouman.
- *
- * Revision 1.17 1994/07/18 20:29:58 mjl
- * Fixed the escape function to pass ALL received escape commands.
- *
- * Revision 1.16 1994/06/30 18:43:02 mjl
- * Cleaning up to remove gcc -Wall warnings, and other miscellanea.
- */
- /*
- plr.c
- Copyright 1993, 1994, 1995
- Maurice LeBrun
- IFS, University of Texas at Austin
- This software may be freely copied, modified and redistributed under the
- terms of the GNU Library General Public License.
- There is no warranty or other guarantee of fitness of this software.
- It is provided solely "as is". The author(s) disclaim(s) all
- responsibility and liability with respect to this software's usage or
- its effect upon hardware or computer systems.
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- *
- * Support routines to render a PLplot byte stream, interpreting the PLplot
- * metacode.
- *
- * Although this code is duplicated to some extent by plrender and the
- * plot buffer redraw code (in plbuf.c), they are all different in some
- * significant ways, namely:
- *
- * - plrender must always retain backward compatibility code to
- * handle old metafiles, as well as stuff to support seeking.
- *
- * - plbuf by definition is redrawing on the same machine so no
- * special effort is necessary to make the byte stream portable,
- * also, only low-level graphics calls are used (grline, etc)
- *
- * The rendering code here must (by contrast to plbuf) use the high level
- * plot routines (as does plrender), to support local zooms as well as the
- * ability to dump the associated window into plot space to a file, but is
- * otherwise pretty minimal. A portable byte stream is used since network
- * communication over a socket may be used.
- *
- \*--------------------------------------------------------------------------*/
- /*
- #define DEBUG
- #define DEBUG_ENTER
- */
- #include "plserver.h"
- #include "plevent.h"
- #include "metadefs.h"
- /* Some wrapper macros to return (-1) on error */
- #define plr_rd(code) \
- if (code) { fprintf(stderr, \
- "Unable to read from %s in %s at line %d, bytecount %ld\n", \
- plr->iodev->typeName, __FILE__, __LINE__, plr->pdfs->bp); \
- return -1; }
- #define plr_cmd(code) \
- if ((code) == -1) return -1;
- /* Error termination */
- #define barf(msg) \
- { fprintf(stderr, "%s\nCommand code: %d, byte count: %ld\n", \
- msg, csave, plr->pdfs->bp); return -1; }
- /* Static function prototypes. */
- static int plr_process1 (PLRDev *plr, int c);
- static int plr_init (PLRDev *plr);
- static int plr_line (PLRDev *plr, int c);
- static int plr_eop (PLRDev *plr);
- static int plr_bop (PLRDev *plr);
- static int plr_state (PLRDev *plr);
- static int plr_esc (PLRDev *plr);
- static int plr_get (PLRDev *plr);
- static int plr_unget (PLRDev *plr, U_CHAR c);
- static int get_ncoords (PLRDev *plr, PLFLT *x, PLFLT *y, PLINT n);
- static int plresc_fill (PLRDev *plr);
- /* variables */
- static int csave = -1;
- static U_CHAR dum_uchar;
- static U_SHORT dum_ushort;
- static PLFLT x[PL_MAXPOLY], y[PL_MAXPOLY];
- /*--------------------------------------------------------------------------*\
- * plr_start()
- *
- * Set default state parameters before anyone else has a chance to.
- \*--------------------------------------------------------------------------*/
- void
- plr_start(PLRDev *plr)
- {
- dbug_enter("plr_start");
- plr->xmin = 0;
- plr->xmax = PIXELS_X - 1;
- plr->ymin = 0;
- plr->ymax = PIXELS_Y - 1;
- plr->xold = UNDEFINED;
- plr->yold = UNDEFINED;
- }
- /*--------------------------------------------------------------------------*\
- * plr_process()
- *
- * Read & process commands until plr->nbytes bytes have been read.
- \*--------------------------------------------------------------------------*/
- int
- plr_process(PLRDev *plr)
- {
- int c;
- dbug_enter("plr_process");
- while (plr->pdfs->bp < plr->nbytes) {
- plr_cmd( c = plr_get(plr) );
- csave = c;
- plr_cmd( plr_process1(plr, c) );
- }
- return 0;
- }
- /*--------------------------------------------------------------------------*\
- * plr_process1()
- *
- * Process a command. Note: because of line->polyline compression, this
- * may actually process an arbitrary number of LINE or LINETO commands.
- * Since the data buffer (fifo or socket) is only flushed after a complete
- * command, there should be no danger in rushing blindly ahead to execute
- * each plot command.
- \*--------------------------------------------------------------------------*/
- static int
- plr_process1(PLRDev *plr, int c)
- {
- switch (c) {
- case INITIALIZE:
- plr_cmd( plr_init(plr) );
- break;
- case LINE:
- case LINETO:
- case POLYLINE:
- plr_cmd( plr_line(plr, c) );
- break;
- case EOP:
- plr->at_eop = 1;
- plr_cmd( plr_eop(plr) );
- break;
- case BOP:
- plr->at_bop = 1;
- plr_cmd( plr_bop(plr) );
- break;
- case CHANGE_STATE:
- plr_cmd( plr_state(plr) );
- break;
- case ESCAPE:
- plr_cmd( plr_esc(plr) );
- break;
- default:
- fprintf(stderr, "plr_process1: Unrecognized command code %d\n", c);
- }
- return 0;
- }
- /*--------------------------------------------------------------------------*\
- * void plr_init()
- *
- * Handle initialization.
- \*--------------------------------------------------------------------------*/
- static int
- plr_init(PLRDev *plr)
- {
- char tk_magic[80], tk_version[80], tag[80];
- dbug_enter("plr_init");
- /* Read header info */
- plr_cmd( pdf_rd_header(plr->pdfs, tk_magic) );
- if (strcmp(tk_magic, PLSERV_HEADER))
- barf("plr_init: Invalid header");
- /* Read version field of header. We need to check that we can read the */
- /* byte stream, in case this is an old version of plserver. */
- plr_cmd( pdf_rd_header(plr->pdfs, tk_version) );
- if (strcmp(tk_version, PLSERV_VERSION) > 0) {
- fprintf(stderr,
- "Error: incapable of reading output of version %s.\n", tk_version);
- barf("plr_init: Please obtain a newer copy of plserver.");
- }
- /* Read tagged initialization info. */
- /* Overkill, but a no-brainer since plrender already uses this */
- for (;;) {
- plr_cmd( pdf_rd_header(plr->pdfs, tag) );
- if (*tag == '\0')
- break;
- if ( ! strcmp(tag, "xmin")) {
- plr_rd( pdf_rd_2bytes(plr->pdfs, &dum_ushort) );
- plr->xmin = dum_ushort;
- continue;
- }
- if ( ! strcmp(tag, "xmax")) {
- plr_rd( pdf_rd_2bytes(plr->pdfs, &dum_ushort) );
- plr->xmax = dum_ushort;
- continue;
- }
- if ( ! strcmp(tag, "ymin")) {
- plr_rd( pdf_rd_2bytes(plr->pdfs, &dum_ushort) );
- plr->ymin = dum_ushort;
- continue;
- }
- if ( ! strcmp(tag, "ymax")) {
- plr_rd( pdf_rd_2bytes(plr->pdfs, &dum_ushort) );
- plr->ymax = dum_ushort;
- continue;
- }
- if ( ! strcmp(tag, "width")) {
- plr_rd( pdf_rd_1byte(plr->pdfs, &dum_uchar) );
- plwid(dum_uchar);
- continue;
- }
- barf("plr_init: Unrecognized initialization tag.");
- }
- return 0;
- }
- /*--------------------------------------------------------------------------*\
- * plr_line()
- *
- * Draw a line or polyline.
- \*--------------------------------------------------------------------------*/
- static int
- plr_line(PLRDev *plr, int c)
- {
- int c1;
- U_SHORT npts;
- npts = 1;
- x[0] = plr->xold;
- y[0] = plr->yold;
- switch ((int) c) {
- case LINE:
- plr_cmd( get_ncoords(plr, x, y, 1) );
- case LINETO:
- for (;;) {
- plr_cmd( get_ncoords(plr, x + npts, y + npts, 1) );
- npts++;
- if (npts == PL_MAXPOLY || (plr->pdfs->bp == plr->nbytes))
- break;
- plr_cmd( c1 = plr_get(plr) );
- if (c1 != LINETO) {
- plr_cmd( plr_unget(plr, (U_CHAR) c1) );
- break;
- }
- }
- break;
- case POLYLINE:
- plr_rd( pdf_rd_2bytes(plr->pdfs, &npts) );
- plr_cmd( get_ncoords(plr, x, y, npts) );
- break;
- }
- plline(npts, x, y);
- plr->xold = x[npts - 1];
- plr->yold = y[npts - 1];
- return 0;
- }
- /*--------------------------------------------------------------------------*\
- * get_ncoords()
- *
- * Read n coordinate vectors.
- \*--------------------------------------------------------------------------*/
- #define plr_rdn(code) \
- if (code) { fprintf(stderr, \
- "Unable to read from %s in %s at line %d, bytecount %d\n\
- Bytes requested: %d\n", plr->iodev->typeName, __FILE__, __LINE__, \
- (int) plr->pdfs->bp, (int) 2*n); return -1; }
- static int
- get_ncoords(PLRDev *plr, PLFLT *x, PLFLT *y, PLINT n)
- {
- int i;
- short xs[PL_MAXPOLY], ys[PL_MAXPOLY];
- plr_rdn( pdf_rd_2nbytes(plr->pdfs, (U_SHORT *) xs, n) );
- plr_rdn( pdf_rd_2nbytes(plr->pdfs, (U_SHORT *) ys, n) );
- for (i = 0; i < n; i++) {
- x[i] = xs[i];
- y[i] = ys[i];
- }
- return 0;
- }
- /*--------------------------------------------------------------------------*\
- * plr_eop()
- *
- * Clear screen.
- \*--------------------------------------------------------------------------*/
- static int
- plr_eop(PLRDev *plr)
- {
- dbug_enter("plr_eop");
- pleop();
- return 0;
- }
- /*--------------------------------------------------------------------------*\
- * plr_bop()
- *
- * Page advancement.
- \*--------------------------------------------------------------------------*/
- static int
- plr_bop(PLRDev *plr)
- {
- dbug_enter("plr_bop");
- /* Advance and setup the page */
- plbop();
- plvpor(0., 1., 0., 1.);
- plwind(plr->xmin, plr->xmax, plr->ymin, plr->ymax);
- return 0;
- }
- /*--------------------------------------------------------------------------*\
- * plr_state()
- *
- * Handle change in PLStream state (color, pen width, fill attribute,
- * etc).
- \*--------------------------------------------------------------------------*/
- static int
- plr_state(PLRDev *plr)
- {
- U_CHAR op;
- int i;
- plr_rd( pdf_rd_1byte(plr->pdfs, &op) );
- switch (op) {
- case PLSTATE_WIDTH:{
- U_SHORT width;
- plr_rd( pdf_rd_2bytes(plr->pdfs, &width) );
- plwid(width);
- break;
- }
- case PLSTATE_COLOR0:{
- U_CHAR icol0, r, g, b;
- plr_rd( pdf_rd_1byte(plr->pdfs, &icol0) );
- if (icol0 == PL_RGB_COLOR) {
- plr_rd( pdf_rd_1byte(plr->pdfs, &r) );
- plr_rd( pdf_rd_1byte(plr->pdfs, &g) );
- plr_rd( pdf_rd_1byte(plr->pdfs, &b) );
- plrgb1(r, g, b);
- }
- else {
- plcol(icol0);
- }
- break;
- }
- case PLSTATE_COLOR1:{
- U_SHORT icol1;
- PLFLT col1;
- plr_rd( pdf_rd_2bytes(plr->pdfs, &icol1) );
- col1 = (double) icol1 / (double) plsc->ncol1;
- plcol1(col1);
- break;
- }
- case PLSTATE_FILL:{
- signed char patt;
- plr_rd( pdf_rd_1byte(plr->pdfs, (U_CHAR *) &patt) );
- plpsty(patt);
- break;
- }
- case PLSTATE_CMAP0:{
- U_CHAR ncol0;
- plr_rd( pdf_rd_1byte(plr->pdfs, &ncol0) );
- plsc->ncol0 = ncol0;
- for (i = 0; i < plsc->ncol0; i++) {
- plr_rd( pdf_rd_1byte(plr->pdfs, &plsc->cmap0[i].r) );
- plr_rd( pdf_rd_1byte(plr->pdfs, &plsc->cmap0[i].g) );
- plr_rd( pdf_rd_1byte(plr->pdfs, &plsc->cmap0[i].b) );
- }
- plP_state(PLSTATE_CMAP0);
- break;
- }
- case PLSTATE_CMAP1:{
- U_SHORT ncol1;
- plr_rd( pdf_rd_2bytes(plr->pdfs, &ncol1) );
- plsc->ncol1 = ncol1;
- for (i = 0; i < plsc->ncol1; i++) {
- plr_rd( pdf_rd_1byte(plr->pdfs, &plsc->cmap1[i].r) );
- plr_rd( pdf_rd_1byte(plr->pdfs, &plsc->cmap1[i].g) );
- plr_rd( pdf_rd_1byte(plr->pdfs, &plsc->cmap1[i].b) );
- }
- plP_state(PLSTATE_CMAP1);
- break;
- }
- }
- return 0;
- }
- /*--------------------------------------------------------------------------*\
- * plr_esc()
- *
- * Handle all escape functions.
- * Only those that require additional data to be read need to be
- * explicitly handled; the others are merely passed on to the actual
- * driver.
- \*--------------------------------------------------------------------------*/
- static int
- plr_esc(PLRDev *plr)
- {
- U_CHAR op;
- plr_rd( pdf_rd_1byte(plr->pdfs, &op) );
- switch (op) {
- case PLESC_FILL:
- plr_cmd( plresc_fill(plr) );
- break;
- default:
- pl_cmd((PLINT) op, NULL);
- break;
- }
- return 0;
- }
- /*--------------------------------------------------------------------------*\
- * plresc_fill()
- *
- * Fill polygon described in points pls->dev_x[] and pls->dev_y[].
- \*--------------------------------------------------------------------------*/
- static int
- plresc_fill(PLRDev *plr)
- {
- U_SHORT npts;
- dbug_enter("plresc_fill");
- plr_rd( pdf_rd_2bytes(plr->pdfs, &npts) );
- get_ncoords(plr, x, y, npts);
- plfill(npts, x, y);
- return 0;
- }
- /*--------------------------------------------------------------------------*\
- * plr_get()
- *
- * Read & return the next command
- \*--------------------------------------------------------------------------*/
- static int
- plr_get(PLRDev *plr)
- {
- int c;
- c = pdf_getc(plr->pdfs);
- if (c == EOF) {
- barf("plr_get: Unable to read character");
- }
- return c;
- }
- /*--------------------------------------------------------------------------*\
- * plr_unget()
- *
- * Push back the last command read.
- \*--------------------------------------------------------------------------*/
- static int
- plr_unget(PLRDev *plr, U_CHAR c)
- {
- if (pdf_ungetc(c, plr->pdfs) == EOF) {
- barf("plr_unget: Unable to push back character");
- }
- return 0;
- }