/* @(#)pscrdrv.c 17.1.1.1 (ESO-DMD) 01/25/02 17:33:38 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. Correspondence concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /* @(#)pscrdrv.c 17.1.1.1 (OAA-ASTRONET) 01/25/02 17:33:38 */ /* * HEADER : pscrdrv.c - Vers 3.6.010 - Jul 1994 - L. Fini, OAA * * * 010713 last modif KB * */ /*****************************************************************************/ /* AGL PostScript driver - L. Fini Jun 1987 */ /* - L. Fini Oct 1991 (Color support added) */ /* This driver is based on a FORTRAN version provided by Alco Blom for */ /* AGL V. 2.1 */ /* This driver allows selection of landscape(default) and Portrait mode by */ /* means of the USRAUX portion of the device definition string. */ /* Output orientation and size default to landscape A4. Different selection */ /* can be made when the first viewport is opened onto the device by means of */ /* format specifications characters with the following meanings: */ /* p : portrait */ /* l : landscape */ /* 3 : A3 */ /* 4 : A4 */ /* u : US-legal */ /* The selection characters are to be appendend to the device name, separa- */ /* ted by a point as in the following examples: */ /* iv=AG_VDEF("ps.p:",.......) selects portrait A4 */ /* or */ /* iv=AG_VDEF("ps.p4:",.......) selects portrait A4 */ /* iv=AG_VDEF("ps.pu:",.......) selects portrait US-legal */ /* iv=AG_VDEF("ps.3:",.......) selects portrait A3 */ /* or */ /* iv=AG_VDEF("ps.l3:",.......) selects landscape A3 */ /* (the characters: p,l,3,4,u can be put in any number and sequence. The */ /* last encountered only will take effect) */ #include #include #include #include #include /* */ /* The following entry points have been defined: */ /* */ /* Function Entry point */ /* */ /* Initialize AGLINPS0 */ /* Cursor en. AGLCUPS0 */ /* Erase AGLERPS0 */ /* Escape AGLESPS0 */ /* Polyline AGLPLPS0 */ /* Finish AGLTEPS0 */ /* Flush buff. AGLSEPS0 */ /* */ /* device parameters definition */ #define VERSCODE 36 /* Declare driver version */ #define A4 1 #define A3 2 #define USLEGAL 3 #define PSFLAGS SEPALPHA | EXECOMMND | SETBACKGR #define PSMAXLWIDTH 4 #define PSBLACK 0 /* Bot index and grayscale value */ #define PSWHITE 1 /* Bot index and grayscale value */ #define PSRED 2 #define PSGREEN 3 #define PSBLUE 4 #define PSYELLOW 5 #define PSMAGENTA 6 #define PSCYAN 7 #define TRUE 1 #define FALSE 0 #define CVTX(x) ((int)((x)*xfact))+1 #define CVTY(y) ((int)((y)*yfact))+1 /* To allow for good resolution with small file length the driver uses */ /* an arbitrary set of coordinates so that numbers are never greater than */ /* 10000 for A4 format. The PostScript scale factor is then used to adjust */ /* for standard PostScript coordinates (1/72 of an inch). The following */ /* values are the required conversion factors. */ /* US Legal Landscape mode --------------------------+ */ /* US Legal Portrait mode ---------------------+ | */ /* A3 Landscape mode -------------------+ | | */ /* A3 Portrait mode --------------+ | | | */ /* A4 Landscape mode -------+ | | | | */ /* A4 Portrait mode --+ | | | | | */ /* | | | | | | */ static float FACTC[6] = { 6908, 9999, 9999, 14908,7453, 9817 }; static float PSCMAXL[6]= { 19.0, 27.5, 27.5, 41.0, 20.5, 27.0 }; static float PSCLENG[6]= { 19.0, 27.5, 27.5, 41.0, 21.0, 27.0 }; static float PIXCM[6] = { 363.6364, 363.6364, 363.6364, 363.6364, 363.6364, 363.6364 }; static float CHARF[6] = { 13.889, /* Char. multip. */ 13.889, 13.889, 13.889, 13.889, 13.889 }; static FILE *filpt; static int id0, id1; static int Size,Sptx,Spty; static int rot,a4; static double xfact,yfact,xofst,yofst; static double xdim,ydim; static int page_touch; /* TRUE when current page has something into */ static int file_touch; /* TRUE when current file has something into */ static int cur_color; static int cur_backg; static int n_colors; static struct { float red; float green; float blue; } CTAB[8] = { /* PSBLACK */ { 0.0, 0.0, 0.0 }, /* PSWHITE */ { 1.0, 1.0, 1.0 }, /* PSRED */ { 1.0, 0.0, 0.0 }, /* PSGREEN */ { 0.0, 1.0, 0.0 }, /* PSBLUE */ { 0.0, 0.0, 1.0 }, /* PSYELLOW */ { 1.0, 1.0, 0.0 }, /* PSMAGENTA */ { 1.0, 0.0, 1.0 }, /* PSCYAN */ { 0.0, 1.0, 1.0 } }; static char *hd1 = "/cm { 28.34646 mul } def\n"; static char *hd2 = "1.0 cm 1.0 cm translate\n"; static char *hd3_us = "20.5 cm 0 cm translate\n90 rotate\n"; static char *hd3_a4 = "19.0 cm 0 cm translate\n90 rotate\n"; static char *hd3_a3 = "27.5 cm 0 cm translate\n90 rotate\n"; static char *hd4 = "0.077960552 0.077960552 scale\n"; static char *hd5 = "[] 0 setdash\n"; static char hd6[] = "1 6 mul setlinewidth\n"; static char *hd7 = "/m { moveto } def\n"; static char *hd8 = "/r { rlineto } def\n"; static char *hd9 = "/l { 8 { rlineto } repeat } def \n"; static char *hd10 = "/c { { rlineto } repeat } def\n"; static char *hd11 = "/s { stroke } def\n"; static char *hd12 = "/n { newpath } def\n"; static char *hd13 = "2 setlinejoin\n"; static char *hd14 = "% BEGINNING OF PLOT\n"; static void showpage(filpt) FILE *filpt; { static char *show = "showpage % END OF PAGE\n"; fputs(show,filpt); } void set_pscolor(color) /* set up a given color */ int color; { fprintf(filpt,"%f %f %f setrgbcolor\n",CTAB[color].red, CTAB[color].green, CTAB[color].blue ); } static void fill_area(xmin,xmax,ymin,ymax,color) int xmin,xmax; int ymin,ymax; int color; { set_pscolor(color); fprintf(filpt,"n %d %d moveto\n",xmin,ymin); fprintf(filpt,"%d %d lineto\n",xmax,ymin); fprintf(filpt,"%d %d lineto\n",xmax,ymax); fprintf(filpt,"%d %d lineto\n",xmin,ymax); fprintf(filpt,"closepath fill\n"); set_pscolor(cur_color); } /*---------------------------------------------------------------------------*/ void AGLINPS0 (AGLDVCOM) struct bufcom *AGLDVCOM; { static char *in00 = "%!PS-Adobe-3.0 EPSF-3.0\n"; static char *in01 = "%%BoundingBox: 28 28 "; static char *in01_a4 = "570 810\n"; static char *in01_a3 = "810 1208\n"; static char *in01_us = "604 795\n"; static char *in02 = "%! AGL PostScript driver file header - V 3.61\n"; static char *in03 = "%%EndComments\n"; extern void AG_DMSG(); char auxbuf[PHNAMLNG]; static char *filnam = "pscrplot"; char *pt; ERRCODE=AGLNOERR; switch((int)IBUFFR(0)) { /* Select function */ case 0: /* Hardware initialization */ file_touch=FALSE; page_touch=FALSE; strcpy(auxbuf,filnam); AG_NEWN(auxbuf); if(*auxbuf == '\0') { ERRCODE=DEVOPNSEV; return; } filpt=fopen(auxbuf,"w"); if (filpt==NULL) { AG_DMSG("Open error:",auxbuf); ERRCODE=DEVOPNSEV; return; } *hd6 = '1'; CHANNEL=0; rot = TRUE; /* Select default orientation */ Size=A4; /* Select default size */ pt=CHARBUF; while(*pt++); /* Skip device name */ while(*pt++); /* Skip SYSAUX info */ /* to Get USRAUX string */ while(*pt) { /* Scan selection string */ switch(TOUPPER(*pt)) { case 'P': /* select portrait mode */ rot = FALSE; break; case 'L': /* select landscape mode */ rot = TRUE; break; case '4': Size=A4; break; case 'U': Size=USLEGAL; break; case '3': Size=A3; break; } pt++; } if(rot) { /* Select rotation */ AG_DMSG("Mode:","Landscape"); id0 = 1; id1 = 0; } else { AG_DMSG("Mode:","Portrait"); id0 = 0; id1 = 1; } strcpy(CHARBUF,auxbuf); /* Copy filename to buffer */ AG_DMSG("Out to:",auxbuf); fputs(in00,filpt); fputs(in01,filpt); switch(Size) { /* Select size */ case A4: Sptx = id0; Spty = id1; AG_DMSG("Size:","A4"); fputs(in01_a4,filpt); break; case A3: Sptx = id0+2; Spty = id1+2; AG_DMSG("Size:","A3"); fputs(in01_a3,filpt); break; case USLEGAL: Sptx = id0+4; Spty = id1+4; AG_DMSG("Size:","US-legal"); fputs(in01_us,filpt); break; } fputs(in02,filpt); fputs(in03,filpt); fputs(hd1,filpt); fputs(hd2,filpt); if(rot) switch(Size) { /* Select size */ case A4: fputs(hd3_a4,filpt); break; case A3: fputs(hd3_a3,filpt); break; case USLEGAL: fputs(hd3_us,filpt); break; } fputs(hd4,filpt); fputs(hd5,filpt); fputs(hd6,filpt); fputs(hd7,filpt); fputs(hd8,filpt); fputs(hd9,filpt); fputs(hd10,filpt); fputs(hd11,filpt); fputs(hd12,filpt); fputs(hd13,filpt); fputs(hd14,filpt); xdim = (RBUFFR(id0)n_colors)) cur_color=PSBLACK; set_pscolor(cur_color); break; case 3: /* set line style */ ERRCODE=AGLNOERR; /* Not used since vers. 3.3 */ break; case 4: /* set line width */ ERRCODE=AGLNOERR; *auxbuf = *hd6; switch((int)IBUFFR(1)) { default: case 0: *hd6 = '1'; break; case 1: *hd6 = '2'; break; case 2: *hd6 = '3'; break; case 3: *hd6 = '4'; break; case 4: *hd6 = '5'; break; } if(*auxbuf != *hd6) fputs(hd6,filpt); break; case 6: /* Coordinate roundoff */ break; /* Unnecessary for high resol. devices */ } } static int cnt=0; static int xv[8], yv[8]; static void trace(filpt,xx,yy) FILE *filpt; int xx,yy; { xv[cnt]=xx; yv[cnt]=yy; cnt++; if (cnt==8) { do { cnt--; fprintf(filpt,"%d %d ", xv[cnt], yv[cnt]); } while(cnt); fprintf(filpt,"l\n"); cnt=0; } } static void trace_flush(filpt) FILE *filpt; { if (cnt>0) { if(cnt==1) fprintf(filpt,"%d %d r ",xv[0],yv[0]); else { int cnts=cnt; do { cnt--; fprintf(filpt,"%d %d ", xv[cnt], yv[cnt]); } while(cnt); fprintf(filpt,"%d c ",cnts); } } fprintf(filpt,"s\n"); cnt=0; } /*---------------------------------------------------------------------------*/ void AGLPLPS0(AGLDVCOM) struct bufcom *AGLDVCOM; { int n; float *vectx, *vecty; int xx,yy; int x0,y0; ERRCODE=AGLNOERR; n = NPOINTS; vectx = VECTX; vecty = VECTY; if(cur_color != cur_backg) { page_touch=TRUE; file_touch=TRUE; fprintf(filpt,"n %d %d m\n", /* Move to first point */ (x0=CVTX(*vectx++)), (y0=CVTY(*vecty++))); xx=CVTX(*vectx++)-x0; yy=CVTY(*vecty++)-y0; /* the usual trace_flush doesn't draw anything => missing point on the `i' char. so we make a 1x1 `filled' square */ if ((n == 2) && (xx == 0) && (yy == 0)) { yy = 1; fprintf(filpt,"%d %d ", xx,yy); xx = 1; yy = 0; fprintf(filpt,"%d %d ", xx,yy); xx = 0; yy = -1; fprintf(filpt,"%d %d ", xx,yy); xx = -1; yy = 0; fprintf(filpt,"%d %d ", xx,yy); xx = 1; yy = 1; fprintf(filpt,"%d %d ", xx,yy); xx = -1; yy = 0; fprintf(filpt,"%d %d ", xx,yy); xx = 1; yy = -1; fprintf(filpt,"%d %d ", xx,yy); fprintf(filpt,"7 c "); /* 7 line segments */ fprintf(filpt,"s\n"); } else { trace(filpt,xx,yy); /* Trace to second point */ x0 += xx; y0 += yy; n--; while(n-- > 1) { register int xn,yn; xn=CVTX(*vectx++); yn=CVTY(*vecty++); xx= xn-x0; yy= yn-y0; if((0!=xx)||(0!=yy)) { trace(filpt,xx,yy); x0 = xn; y0 = yn; } } } trace_flush(filpt); } } /*---------------------------------------------------------------------------*/ void AGLCUPS0(AGLDVCOM) struct bufcom *AGLDVCOM; { ERRCODE=UNSFEATINF; } /*---------------------------------------------------------------------------*/ void AGLERPS0(AGLDVCOM) struct bufcom *AGLDVCOM; { int xmin,xmax,ymin,ymax; ERRCODE=AGLNOERR; xmin = CVTX(RBUFFR(0)); xmax = CVTX(RBUFFR(1)); ymin = CVTY(RBUFFR(2)); ymax = CVTY(RBUFFR(3)); if((xmin==CVTX(0.0))&&(xmax==CVTX(1.0))&& /* Eject page, if the entire */ (ymin==CVTY(0.0))&&(ymax==CVTY(1.0)) ){ /* page is erased */ if(page_touch) { showpage(filpt); page_touch=FALSE; } } cur_backg = IBUFFR(0); if((cur_backg<0)||(cur_backg>n_colors)) cur_backg=PSWHITE; fill_area(xmin,xmax,ymin,ymax,cur_backg); } /*---------------------------------------------------------------------------*/ void AGLESPS0(AGLDVCOM) struct bufcom *AGLDVCOM; { ERRCODE=UNSFEATINF; } /*---------------------------------------------------------------------------*/ void AGLSEPS0(AGLDVCOM) struct bufcom *AGLDVCOM; { ERRCODE=AGLNOERR; } /*---------------------------------------------------------------------------*/ void AGLTEPS0(AGLDVCOM) struct bufcom *AGLDVCOM; { extern void AG_DMSG(); showpage(filpt); fclose(filpt); filpt=NULL; AG_DMSG("Out file","closed"); ERRCODE=AGLNOERR; CHANNEL=(-1); IBUFFR(0)= !file_touch; }