home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * rgep.c by Aaron Contorer for NCSA
- *
- * graphics routines for drawing on Epson printer
- * Input coordinate space = 0..4095 by 0..4095
- * MUST BE COMPILED WITH LARGE MEMORY MODEL!
- *
- */
-
- #include <stdio.h> /* used for debugging only */
- #include <stdlib.h>
- #ifdef MSC
- #ifdef __TURBOC__
- #include <alloc.h>
- #else
- #include <malloc.h>
- #endif
- #endif
- #ifdef MEMORY_DEBUG
- #include "memdebug.h"
- #endif
- #include "externs.h"
-
- #define TRUE 1
- #define FALSE 0
- #define INXMAX 4096
- #define INYMAX 4096
- #define SCRNXHI 719
- #define ROWS 90
- #define SCRNYHI 929
- #define LINEBYTE 930
- #define MAXRW 1 /* max. number of real windows */
-
- static int EPSactive; /* number of currently active window */
- static char EPSpbit[SCRNXHI+1];
- static unsigned char power2[8]={1,2,4,8,16,32,64,128};
- static char *EPSname="Epson, IBM, or compatible printer";
- static int EPSxmax=720;
- static int EPSymax=LINEBYTE;
- static int EPSbytes=80; /* number of bytes per line */
- static unsigned char *EPSram[ROWS];
- static void (*EPSoutfunc)(char c);
- static void signore(char c);
- static void EPSpoint(int x,int y);
- static void EPSdump(void );
- static void EPSsetup(void );
-
- /* Current status of an EPS window */
- struct EPSWIN
- {
- char inuse; /* true if window in use */
- int pencolor, rotation, size;
- int winbot,winleft,wintall,winwide;
- /* position of the window in virtual space */
- };
-
- static struct EPSWIN EPSwins[MAXRW];
-
- static void EPSsetup(void )
- /* prepare variables for use in other functions */
- {
- int x;
- EPSpbit[0]=128;
- EPSpbit[1]=64;
- EPSpbit[2]=32;
- EPSpbit[3]=16;
- EPSpbit[4]=8;
- EPSpbit[5]=4;
- EPSpbit[6]=2;
- EPSpbit[7]=1;
- for(x=8; x<=SCRNXHI; x++)
- EPSpbit[x]=EPSpbit[x&7];
- }
-
- void RGEPgmode() /* go into EPS graphics mode */
- {
- }
-
- void RGEPtmode() /* go into EPS text mode */
- {
- }
-
- void RGEPclrscr(w)
- int w;
- /*
- Clear the screen.
- */
- {
- if(w==EPSactive)
- EPSsetup();
- }
-
- int RGEPnewwin()
- /*
- Set up a new window; return its number.
- Returns -1 if cannot create window.
- */
- {
- int w=0;
- int x,y;
- for(x=0; x<ROWS; x++) {
- if((EPSram[x]=malloc(LINEBYTE))==NULL) { /* ran out of memory, free what we have now */
- for(; x>=0; x--)
- free(EPSram[x]);
- return(-1);
- } /* end if */
- for(y=0; y<LINEBYTE; y++)
- (EPSram[x])[y]=0;
- }
- while(w<MAXRW&&EPSwins[w].inuse)
- w++;
- if(w==MAXRW)
- return(-1); /* no windows available */
- EPSwins[w].pencolor=7;
- EPSwins[w].winbot=0;
- EPSwins[w].wintall=3120;
- EPSwins[w].winleft=0;
- EPSwins[w].winwide=4096;
- EPSwins[w].inuse=TRUE;
- return(w);
- }
-
- void RGEPclose(w)
- int w;
- {
- if(EPSactive==w) {
- RGEPclrscr(w);
- EPSactive=-1;
- }
- EPSdump();
- EPSwins[w].inuse=FALSE;
- }
-
- void RGEPpoint(w,x,y)
- int w,x,y;
- /* set pixel at location (x,y) -- no range checking performed */
- {
- int x2,y2; /* on-screen coordinates */
-
- if(w==EPSactive) {
- x2=(int)((long)x*EPSxmax/INXMAX);
- y2=(int)((long)y*EPSymax/INYMAX);
- EPSpoint(x2,y2);
- }
- }
-
- void RGEPpagedone(w)
- int w;
- /*
- Do whatever has to be done when the drawing is all done.
- (For printers, that means eject page.)
- */
- {
- EPSdump();
- w=w;
- }
-
- void RGEPdataline(w,data,count)
- int w,count;
- char *data;
- /*
- Copy 'count' bytes of data to screen starting at current
- cursor location.
- */
- {
- /* Function not supported yet. */
- w=w;
- data=data;
- count=count;
- }
-
- void RGEPpencolor(w,color)
- int w,color;
- /*
- Change pen color to the specified color.
- */
- {
- /* Function not supported. */
- w=w;
- color=color;
- }
-
- void RGEPcharmode(int w,int rotation,int size)
- /*
- Set description of future device-supported graphtext.
- Rotation=quadrant.
- */
- {
- /* No rotatable device-supported graphtext is available on EPS. */
- w=w;
- rotation=rotation;
- size=size;
- }
-
- /* Not yet supported: */
- void RGEPshowcur() {}
- void RGEPlockcur() {}
- void RGEPhidecur() {}
-
- static void EPSpoint(int x,int y)
- /*
- Set bit at x,y
- */
- {
- (EPSram[x>>3])[y]|=EPSpbit[x];
- }
-
- void RGEPdrawline(w,x0,y0,x1,y1)
- int w,x0,y0,x1,y1;
- /* draw a line from (x0,y0) to (x1,y1) */
- /* uses Bresenham's Line Algorithm */
- {
- int x,y,dx,dy,d,temp,
- dx2,dy2, /* 2dx and 2dy */
- direction; /* +1 or -1, used for slope */
- char transpose; /* true if switching x and y for vertical-ish line */
-
- if(w!=EPSactive)
- return;
- x0=(int)((long)x0*EPSxmax/INXMAX);
- y0=(int)((long)y0*EPSymax/INYMAX);
- x1=(int)((long)x1*EPSxmax/INXMAX);
- y1=(int)((long)y1*EPSymax/INYMAX);
-
- if(abs(y1-y0)>abs(x1-x0)) { /* transpose vertical-ish to horizontal-ish */
- temp=x1;
- x1=y1;
- y1=temp;
- temp=x0;
- x0=y0;
- y0=temp;
- transpose=TRUE;
- }
- else
- transpose=FALSE; /* make sure line is left to right */
- if(x1<x0) {
- temp=x1;
- x1=x0;
- x0=temp;
- temp=y1;
- y1=y0;
- y0=temp;
- }
- /* SPECIAL CASE: 1 POINT */
- if(x1==x0&&y1==y0) {
- EPSpoint(x1,y1);
- return;
- }
- /* ANY LINE > 1 POINT */
- x=x0;
- y=y0;
- dx=x1-x0;
- if(y1>=y0) {
- dy=y1-y0;
- direction=1;
- }
- else {
- dy=y0-y1;
- direction=-1;
- }
- dx2=dx<<1;
- dy2=dy<<1;
- d=(dy<<1)-dx;
- if(transpose) { /* CASE OF VERTICALISH (TRANSPOSED) LINES */
- while(x<=x1) {
- if(y>=0&&y<EPSxmax&&x>=0&&x<EPSymax)
- EPSpoint(y,x);
- while(d>=0) {
- y+=direction;
- d-=dx2;
- }
- d+=dy2;
- x++;
- }
- }
- else { /* CASE OF HORIZONTALISH LINES */
- while(x<=x1) {
- if(x>=0&&x<EPSxmax&&y>=0&&y<EPSymax)
- EPSpoint(x,y);
- while(d>=0){
- y+=direction;
- d-=dx2;
- }
- d+=dy2;
- x++;
- }
- } /* end horizontalish */
- } /* end RGEPdrawline() */
-
- void RGEPbell(w)
- int w; /* Ring bell in window w */
- {
- w=w;
- }
-
- char *RGEPdevname() /* return name of device that this RG supports */
- {
- return(EPSname);
- }
-
- static void signore(s)
- char s;
- /* Ignore the character pointer passed here. */
- {
- s=s;
- }
-
- void RGEPinit()
- /* initialize all RGEP variables */
- {
- int i;
- EPSsetup();
- for(i=0; i<MAXRW; i++)
- EPSwins[i].inuse=FALSE;
- EPSactive=-1;
- EPSoutfunc=signore;
- }
-
- void RGEPoutfunc(f)
- void (*f)(char );
- /*
- Specify the function that is to be called with pointers to all
- the printout strings.
- */
- {
- EPSoutfunc=f;
- }
-
- void RGEPuncover(w)
- int w;
- /*
- Make this window visible, hiding all others.
- Caller should follow this with clrscr and redraw to show the current
- contents of the window.
- */
- {
- EPSactive=w;
- }
-
- void RGEPinfo(int w,int a,int b,int c,int d,int v) {
-
- /* Needed for possible future functionality */
-
- w=w;
- a=a;
- b=b;
- c=c;
- d=d;
- v=v;
- }
-
- static void EPSdump(void )
- /*
- * Dump the contents of the buffer to the specified function.
- */
- {
- int x,y;
- int size=EPSymax*2;
-
- for(x=0;x<90;x++) { /* init graphics mode */
- (*EPSoutfunc)(033);
- (*EPSoutfunc)('L');
- (*EPSoutfunc)((char)(size&255));
- (*EPSoutfunc)((char)(size>>8)); /* send a line of bit image data */
- for(y=0; y<size; y++)
- (*EPSoutfunc)((EPSram[x]) [y]);
- /* go to next line */
- (*EPSoutfunc)(13);
- (*EPSoutfunc)(033);
- (*EPSoutfunc)('J');
- (*EPSoutfunc)(24);
- }
- (*EPSoutfunc)(12); /* form feed */
- }
-