
by moving needed C source to src/plot and building during `make', but stripping out the copies of gd, png, and zlib; instead, hook a dc<%>-based back end into plot
267 lines
6.8 KiB
C
267 lines
6.8 KiB
C
/*
|
|
Device driver whose handlers are inplemented in Racket
|
|
using dc<%>.
|
|
*/
|
|
|
|
#include "plDevs.h"
|
|
#include "plplotP.h"
|
|
#include "drivers.h"
|
|
|
|
/* Device info */
|
|
char* plD_DEVICE_INFO_dc = "dc:dc<%>:0:dc:50:dc";
|
|
|
|
void plD_init_dc (PLStream *);
|
|
void plD_line_dc (PLStream *, short, short, short, short);
|
|
void plD_polyline_dc (PLStream *, short *, short *, PLINT);
|
|
void plD_eop_dc (PLStream *);
|
|
void plD_eop_jpeg (PLStream *);
|
|
void plD_bop_dc (PLStream *);
|
|
void plD_tidy_dc (PLStream *);
|
|
void plD_state_dc (PLStream *, PLINT);
|
|
void plD_esc_dc (PLStream *, PLINT, void *);
|
|
|
|
typedef struct {
|
|
void *p;
|
|
void (*drawLine)(void *p, short x1a, short y1a, short x2a, short y2a);
|
|
void (*drawLines)(void *p, short *xa, short *ya, PLINT npts);
|
|
void (*fillPoly)(void *p, short *xa, short *ya, PLINT npts);
|
|
void (*setWidth)(void *p, int w);
|
|
void (*setColor)(void *p, short i);
|
|
void (*setColorRGB)(void *p, short r, short g, short b);
|
|
void (*startPage)(void *p);
|
|
void (*endPage)(void *p);
|
|
void (*endDoc)(void *p);
|
|
} dc_Dev;
|
|
|
|
void plD_dispatch_init_dc( PLDispatchTable *pdt )
|
|
{
|
|
pdt->pl_MenuStr = "drawing context";
|
|
pdt->pl_DevName = "dc<%>";
|
|
pdt->pl_type = plDevType_FileOriented;
|
|
pdt->pl_seq = 50;
|
|
pdt->pl_init = (plD_init_fp) plD_init_dc;
|
|
pdt->pl_line = (plD_line_fp) plD_line_dc;
|
|
pdt->pl_polyline = (plD_polyline_fp) plD_polyline_dc;
|
|
pdt->pl_eop = (plD_eop_fp) plD_eop_dc;
|
|
pdt->pl_bop = (plD_bop_fp) plD_bop_dc;
|
|
pdt->pl_tidy = (plD_tidy_fp) plD_tidy_dc;
|
|
pdt->pl_state = (plD_state_fp) plD_state_dc;
|
|
pdt->pl_esc = (plD_esc_fp) plD_esc_dc;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* plD_init_dc_Dev()
|
|
*
|
|
\*--------------------------------------------------------------------------*/
|
|
|
|
static void
|
|
plD_init_dc_Dev(PLStream *pls)
|
|
{
|
|
/* Allocate and initialize device-specific data */
|
|
dc_Dev *dev;
|
|
|
|
if (pls->dev != NULL)
|
|
free((void *) pls->dev);
|
|
|
|
pls->dev = calloc(1, (size_t) sizeof(dc_Dev));
|
|
if (pls->dev == NULL)
|
|
plexit("plD_init_dc_Dev: Out of memory.");
|
|
|
|
dev = (dc_Dev *) pls->dev;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*\
|
|
* plD_init_dc()
|
|
*
|
|
* Initialize device.
|
|
\*----------------------------------------------------------------------*/
|
|
|
|
void plD_init_dc(PLStream *pls)
|
|
{
|
|
dc_Dev *dev;
|
|
|
|
pls->termin = 0; /* Not an interactive device */
|
|
pls->icol0 = 1;
|
|
pls->bytecnt = 0;
|
|
pls->page = 0;
|
|
pls->dev_fill0 = 1; /* Can do solid fills */
|
|
|
|
if (!pls->colorset)
|
|
pls->color = 1; /* Is a color device */
|
|
|
|
/* Initialize family file info */
|
|
plFamInit(pls);
|
|
|
|
/* Allocate and initialize device-specific data */
|
|
plD_init_dc_Dev(pls);
|
|
dev=(dc_Dev *)pls->dev;
|
|
|
|
if (pls->xlength <= 0 || pls->ylength <=0)
|
|
{
|
|
/* use default width, height of 800x600 if not specifed by -geometry option
|
|
* or plspage */
|
|
plspage(0., 0., 800, 600, 0, 0);
|
|
}
|
|
|
|
pls->graphx = GRAPHICS_MODE;
|
|
|
|
if (pls->xdpi<=0)
|
|
{
|
|
/* This corresponds to a typical monitor resolution of 4 pixels/mm. */
|
|
plspage(4.*25.4, 4.*25.4, 0, 0, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
pls->ydpi=pls->xdpi; /* Set X and Y dpi's to the same value */
|
|
}
|
|
/* Convert DPI to pixels/mm */
|
|
plP_setpxl(1*pls->xdpi/25.4,1*pls->ydpi/25.4);
|
|
|
|
plP_setphy(0, 1*(pls->xlength - 1), 0, 1*(pls->ylength - 1));
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*\
|
|
* plD_line_dc()
|
|
*
|
|
* Draw a line in the current color from (x1,y1) to (x2,y2).
|
|
\*----------------------------------------------------------------------*/
|
|
|
|
void
|
|
plD_line_dc(PLStream *pls, short x1a, short y1a, short x2a, short y2a)
|
|
{
|
|
dc_Dev *dev=(dc_Dev *)pls->dev;
|
|
|
|
if (dev->drawLine)
|
|
dev->drawLine(dev->p, x1a, y1a, x2a, y2a);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*\
|
|
* plD_polyline_dc()
|
|
*
|
|
* Draw a polyline in the current color.
|
|
\*----------------------------------------------------------------------*/
|
|
|
|
void
|
|
plD_polyline_dc(PLStream *pls, short *xa, short *ya, PLINT npts)
|
|
{
|
|
dc_Dev *dev=(dc_Dev *)pls->dev;
|
|
|
|
if (dev->drawLines)
|
|
dev->drawLines(dev->p, xa, ya, npts);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------*\
|
|
* fill_polygon()
|
|
*
|
|
* Fill polygon described in points pls->dev_x[] and pls->dev_y[].
|
|
\*----------------------------------------------------------------------*/
|
|
|
|
static void
|
|
fill_polygon(PLStream *pls)
|
|
{
|
|
dc_Dev *dev=(dc_Dev *)pls->dev;
|
|
|
|
if (dev->fillPoly)
|
|
dev->fillPoly(dev->p, pls->dev_x, pls->dev_y, pls->dev_npts);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------*\
|
|
* plD_state_dc()
|
|
*
|
|
* Handle change in PLStream state (color, pen width, fill attribute, etc).
|
|
\*----------------------------------------------------------------------*/
|
|
|
|
void
|
|
plD_state_dc(PLStream *pls, PLINT op)
|
|
{
|
|
dc_Dev *dev=(dc_Dev *)pls->dev;
|
|
|
|
switch (op) {
|
|
|
|
case PLSTATE_WIDTH:
|
|
if (dev->setWidth)
|
|
dev->setWidth(dev->p, pls->width);
|
|
break;
|
|
|
|
case PLSTATE_COLOR0:
|
|
|
|
if (pls->icol0 == PL_RGB_COLOR) {
|
|
if (dev->setColorRGB)
|
|
dev->setColorRGB(dev->p, pls->curcolor.r, pls->curcolor.g, pls->curcolor.b);
|
|
} else {
|
|
if (dev->setColor)
|
|
dev->setColor(dev->p, pls->icol0);
|
|
}
|
|
break;
|
|
|
|
case PLSTATE_COLOR1:
|
|
if (dev->setColorRGB)
|
|
dev->setColorRGB(dev->p, pls->curcolor.r, pls->curcolor.g, pls->curcolor.b);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------*\
|
|
* plD_esc_dc()
|
|
*
|
|
* Escape function.
|
|
\*----------------------------------------------------------------------*/
|
|
|
|
void plD_esc_dc(PLStream *pls, PLINT op, void *ptr)
|
|
{
|
|
switch (op) {
|
|
|
|
case PLESC_FILL: /* fill */
|
|
fill_polygon(pls);
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*\
|
|
* plD_bop_dc()
|
|
*
|
|
* Set up for the next page.
|
|
* Advance to next family file if necessary (file output).
|
|
\*----------------------------------------------------------------------*/
|
|
|
|
void plD_bop_dc(PLStream *pls)
|
|
{
|
|
dc_Dev *dev=(dc_Dev *)pls->dev;
|
|
|
|
if (dev->startPage)
|
|
dev->startPage(dev->p);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*\
|
|
* plD_tidy_dc()
|
|
*
|
|
* Close graphics file or otherwise clean up.
|
|
\*----------------------------------------------------------------------*/
|
|
|
|
void plD_tidy_dc(PLStream *pls)
|
|
{
|
|
dc_Dev *dev=(dc_Dev *)pls->dev;
|
|
|
|
if (dev->endDoc)
|
|
dev->endDoc(dev->p);
|
|
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*\
|
|
* plD_eop_dc()
|
|
*
|
|
* End of page.
|
|
\*----------------------------------------------------------------------*/
|
|
|
|
void plD_eop_dc(PLStream *pls)
|
|
{
|
|
dc_Dev *dev=(dc_Dev *)pls->dev;
|
|
|
|
if (dev->endPage)
|
|
dev->endPage(dev->p);
|
|
}
|