home *** CD-ROM | disk | FTP | other *** search
- /* This file contains the iff device dependent subroutines for plplot */
- /* Tomas G Rokicki (Radical Eye Software), sometime in September 1989 */
-
- #include "plplot.h"
- #include <stdio.h>
- #ifdef AZTEC_C
- #define memset(ptr,val,len) setmem(ptr,len,val)
- extern char *calloc();
- #include <functions.h>
- #else
- #include <stdlib.h>
- #include <string.h>
- #endif
- #include <math.h>
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <devices/printer.h>
- #include <devices/prtbase.h>
-
- static FILE *OutFile;
-
- /* bitmap contains a pointer to an area of memory NBYTES in size */
- static short *bitmap;
-
- static bitmapx, bitmapy, xdpi, ydpi ;
- static int wordsperrow ;
- char *outname ;
-
- int getval(s)
- char *s ;
- {
- int m ;
-
- while (1) {
- printf(s) ;
- fflush(stdout) ;
- if (scanf("%d", &m) == 1 && m > 10 && m < 10000)
- return(m) ;
- printf("No value or value out of range; please try again\n") ;
- }
- }
-
- void iffquery(x, y, X, Y)
- int *x, *y, *X, *Y ;
- {
- if (xdpi == 0)
- xdpi = getval("Please enter desired horizontal IFF resolution (dpi): ") ;
- if (ydpi == 0)
- ydpi = getval("Please enter desired vertical IFF resolution (dpi) : ") ;
- if (bitmapx == 0)
- bitmapx = getval("Please enter desired horizontal IFF size in pixels : ") ;
- if (bitmapy == 0)
- bitmapy = getval("Please enter desired vertical IFF size in pixels : ") ;
- *x = xdpi ;
- *y = ydpi ;
- *X = bitmapx ;
- *Y = bitmapy ;
- }
-
- static char tempfile[100] ;
-
- void pliff(x1, y1, x2, y2, n)
- int x1, y1, x2, y2 ;
- char *n ;
- {
- if (x1)
- xdpi = x1 ;
- if (y1)
- ydpi = y1 ;
- if (x2)
- bitmapx = x2 ;
- if (y2)
- bitmapy = y2 ;
- if (n && *n) {
- strcpy(tempfile, n) ;
- outname = tempfile ;
- }
- }
-
- /* Opens the file for binary mode. */
-
- void iffini()
- {
- /* Allocate storage for bit map matrix */
- wordsperrow = (bitmapx + 15) / 16 ;
- if((bitmap = (short *)calloc(wordsperrow * 2,bitmapy)) == NULL)
- printf("Out of memory in call to calloc \n");
- }
-
- void iffopenfile()
- {
- char FileName[80];
-
- if (outname == 0 || outname[0] == 0) {
- printf("Enter IFF file name: ");
- scanf("%s",FileName);
- outname = FileName ;
- }
-
- if((OutFile = fopen(outname,"w")) == NULL) {
- printf("Error opening %s \n",outname);
- exit(1);
- }
- outname = 0 ;
- }
-
- /* Set IFF to test mode */
- void ifftex()
- {
- /* do nothing here */
- }
-
- /* Set IFF to graphics mode */
- void iffgra()
- {
- /* Do nothing here */
- }
-
- static int firstclear ;
-
- void iffwritefile() ;
-
- /* Print out page */
- void iffclr()
- {
- if (firstclear == 0) {
- firstclear = 1 ;
- memset((char *)bitmap,'\0',wordsperrow * (long)bitmapy * 2);
- return ;
- }
- iffopenfile() ;
- iffwritefile(bitmapx, bitmapy, wordsperrow, bitmap) ;
- memset((char *)bitmap,'\0',wordsperrow * (long)bitmapy * 2);
- fclose(OutFile) ;
- }
-
- /* Change color */
- void iffcol(colour)
- int colour;
- {
- }
-
- /* Function to draw the line in the bitmap */
- /* While not written in assembly, this should still be quite a bit faster */
- /* then the code it replaces from the DviJep driver. As a matter of fact, */
- /* it can be moved there painlessly. */
- void ifflin(x1,y1,x2,y2)
- register int x1,y1,x2,y2;
- {
- register short *p ;
- register unsigned int b ;
- register int t ;
- int d ;
- int nextrow ;
-
- if (x1 < 0 || x2 < 0 || x1 >= bitmapx || x2 >= bitmapx ||
- y1 < 0 || y2 < 0 || y1 >= bitmapy || y2 >= bitmapy) {
- printf("Error: line out of range: %d %d %d %d\n", x1, y1, x2, y2) ;
- exit(1) ;
- }
- /* we always want to go left to right. */
- if (x1 > x2) {
- t = x1 ; x1 = x2 ; x2 = t ;
- t = y1 ; y1 = y2 ; y2 = t ;
- }
- p = bitmap + y1 * (long)wordsperrow ;
- /* we always want to go `up'. */
- if (y2 > y1)
- nextrow = wordsperrow ;
- else {
- y2 = y1 * 2 - y2 ;
- nextrow = - wordsperrow ;
- }
- b = 1L << (15 - (x1 & 15)) ;
- p += (x1 >> 4) ;
- x2 -= x1 ;
- y2 -= y1 ;
- /* two routines, one for major in x, one for major in y */
- if (y2 > x2) {
- d = y2 ;
- t = x2 / 2 ;
- y1 = y2 ;
- while (y1 >= 0) {
- *p |= b ;
- p += nextrow ;
- t += x2 ;
- if (t >= d) {
- t -= d ;
- b >>= 1 ;
- if (b == 0) {
- b = 0x8000 ;
- p++ ;
- }
- }
- y1-- ;
- }
- } else {
- d = x2 ;
- t = y2 / 2 ;
- x1 = x2 ;
- while (x1 >= 0) {
- *p |= b ;
- b >>= 1 ;
- if (b == 0) {
- b = 0x8000 ;
- p++ ;
- }
- t += y2 ;
- if (t >= d) {
- t -= d ;
- p += nextrow ;
- }
- x1-- ;
- }
- }
- }
-
- /* Reset printer and close file */
- void ifftid()
- {
- iffclr();
- /* Reset Printer */
- free((void *)bitmap);
- }
- /*
- * Code we steal to write a black and white IFF file.
- */
- static struct iffhead {
- char formname[4] ;
- long formlen ; /* fill me in */
- char ilbmname[4] ;
- char bmhdname[4] ;
- long bmhdlen ;
- short w, h ; /* fill me in */
- long dummy0 ;
- char numplanes, masking, compression, pad1 ;
- short tc ;
- char xas, yas ;
- short pw, ph ;
- char cmapname[4] ;
- long cmaplen ;
- char r0, g0, b0, r1, g1, b1 ;
- char bodyname[4] ;
- long bodylen ; /* fill me in */
- } iffhead = { {'F','O','R','M'}, 0, {'I','L','B','M'}, {'B','M','H','D'}, 20,
- 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 320, 200, {'C','M','A','P'}, 6, 240, 240,
- 240, 0, 0, 0, {'B','O','D','Y'}, 0 } ;
- static long iffpos ;
- static short curbyte = -1 ;
- static short curcount = 0 ;
- static short runcount = 0 ;
- static void iffobyte(b)
- register int b ;
- {
- putc(b, OutFile) ;
- iffpos++ ;
- }
- char outchunk[256] ;
- static void iffoutbyte(b)
- register int b ;
- {
- register int i ;
-
- if (b == curbyte && runcount < 125) {
- runcount++ ;
- } else {
- if (runcount > 2) {
- if (curcount > 0) {
- iffobyte(curcount-1) ;
- for (i=0; i<curcount; i++)
- iffobyte(outchunk[i]) ;
- curcount = 0 ;
- }
- iffobyte(256 - runcount + 1) ;
- iffobyte(curbyte) ;
- curbyte = -1 ;
- runcount = 0 ;
- } else {
- while (runcount > 0) {
- outchunk[curcount++] = curbyte ;
- runcount-- ;
- }
- if (curcount > 110) {
- iffobyte(curcount-1) ;
- for (i=0; i<curcount; i++)
- iffobyte(outchunk[i]) ;
- curcount = 0 ;
- }
- }
- curbyte = b ;
- runcount = 1 ;
- }
- }
- void finishrow()
- {
- register int i ;
-
- if (runcount <= 2) {
- while (runcount > 0) {
- outchunk[curcount++] = curbyte ;
- runcount-- ;
- }
- }
- if (curcount > 0) {
- iffobyte(curcount-1) ;
- for (i=0; i<curcount; i++)
- iffobyte(outchunk[i]) ;
- curcount = 0 ;
- }
- if (runcount > 0) {
- iffobyte(256 - runcount + 1) ;
- iffobyte(curbyte) ;
- curbyte = -1 ;
- runcount = 0 ;
- }
- }
-
- /*
- * Finally we get into the nitty gritty of writing the stupid file.
- */
- static void iffwritefile(w, h, wpr, p)
- register int w, h, wpr ;
- register short *p ;
- {
- register int i, j ;
-
- fwrite((char *)&iffhead, 1, sizeof(struct iffhead), OutFile) ;
- iffpos = 0 ;
- for (j=0; j<h; j++) {
- for (i=wpr; i; i--, p++) {
- iffoutbyte((*p >> 8) & 255) ;
- iffoutbyte(*p & 255) ;
- }
- finishrow() ;
- }
- if (iffpos & 1)
- iffobyte(0) ;
- fseek(OutFile, 0L, 0) ;
- iffhead.w = w ;
- iffhead.h = h ;
- iffhead.pw = w ;
- iffhead.ph = h ;
- iffhead.formlen = iffpos + sizeof(struct iffhead) - 8 ;
- iffhead.bodylen = iffpos ;
- iffhead.xas = xdpi ;
- iffhead.yas = ydpi ;
- fwrite((char *)&iffhead, 1, sizeof(struct iffhead), OutFile) ;
- }
- /*
- * And, finally, the code to dump to Preferences.
- */
- #define Dmpport(a,b,c) dmpport(a,b,c)
- static union printerIO {
- struct IOStdReq ios ;
- struct IODRPReq iodrp ;
- struct IOPrtCmdReq iopc ;
- } *printerIO ;
- static struct PrinterData *PD ;
- static struct PrinterExtendedData *PED ;
- static struct MsgPort *replyport ;
- static long signal ;
- static short prtopen ;
- static struct RastPort rastport ;
- static struct BitMap Bitmap ;
- static short numrows ;
- static short dummycolors[] = { 0x0000, 0x0fff } ;
- static struct ColorMap dummyColorMap = { NULL, NULL, 2, (APTR)&dummycolors } ;
- /*
- * This is our main routine that talks to the printer device. It
- * just does a dumprastport().
- *
- * Note that a quality of `0' means to use the default quality set
- * by preferences.
- */
- static void doio() {
- register struct IODRPReq *ioreq ;
- long waitflags ;
-
- ioreq = &printerIO->iodrp ;
- SendIO(ioreq) ;
- while (1) {
- if (GetMsg(replyport) == NULL)
- waitflags = Wait((1L << replyport->mp_SigBit)) ;
- else
- break ;
- }
- }
- static void dmpport(flags, x, y)
- long flags ;
- int x, y ;
- {
- register struct IODRPReq *ioreq ;
-
- ioreq = &printerIO->iodrp ;
- ioreq->io_Command = PRD_DUMPRPORT ;
- ioreq->io_RastPort = &rastport ;
- ioreq->io_ColorMap = &dummyColorMap ;
- ioreq->io_Modes = 0 ;
- ioreq->io_SrcX = 0 ;
- ioreq->io_SrcY = 0 ;
- ioreq->io_SrcWidth = x ;
- ioreq->io_SrcHeight = y ;
- ioreq->io_DestCols = x ;
- ioreq->io_DestRows = y ;
- ioreq->io_Special = flags | SPECIAL_NOFORMFEED | SPECIAL_TRUSTME ;
- doio() ;
- }
- static void error(s)
- char *s ;
- {
- printf("Error: %s\n", s) ;
- exit(1) ;
- }
- void prefquery(x, y, X, Y)
- int *x, *y, *X, *Y ;
- {
- replyport = (struct MsgPort *)CreatePort("PlPlot.PIO", 0L) ;
- if (replyport == NULL)
- error("! couldn't open reply port") ;
- printerIO = (union printerIO *)
- AllocMem((long)sizeof(union printerIO), MEMF_CLEAR) ;
- if (printerIO == NULL)
- error("! couldn't allocate mem") ;
- if (OpenDevice("printer.device", 0L, printerIO, 0L) != NULL)
- error("! couldn't open printer.device") ;
- prtopen = 1 ;
- printerIO->ios.io_Message.mn_ReplyPort = replyport ;
- PD = (struct PrinterData *)printerIO->iodrp.io_Device ;
- /*
- * The user is full of shit with his settings of Preferences; we
- * override them all.
- */
- PD->pd_Preferences.PrintImage = IMAGE_NEGATIVE ;
- PD->pd_Preferences.PrintShade = SHADE_BW ;
- PD->pd_Preferences.PrintThreshold = 7 ;
- PD->pd_Preferences.PrintFlags = INTEGER_SCALING ;
- PED = &PD->pd_SegmentData->ps_PED ;
- /*
- * It's too bad we need to set up these ridiculous values just to get
- * the parameters for the selected printer . . .
- */
- Bitmap.BytesPerRow = 4 ;
- Bitmap.Rows = 600 ;
- Bitmap.Depth = 1 ;
- rastport.BitMap = &Bitmap ;
- dmpport((long)(SPECIAL_NOPRINT), 16, 504) ;
- numrows = PED->ped_NumRows ;
- xdpi = PED->ped_XDotsInch ;
- ydpi = PED->ped_YDotsInch ;
- bitmapx = PED->ped_MaxXDots ;
- bitmapy = ydpi * 10 ;
- *x = xdpi ;
- *y = ydpi ;
- *X = bitmapx ;
- *Y = bitmapy ;
- }
- void prefini() {
- /*
- * We are okay, so we allocate a nice chunk of memory for our bitmap.
- * This chunk of memory must be as wide as the widest page. Its height
- * must be a multiple of numrows, and we want it to be as large as
- * possible without taking away too much memory. More than about a fourth
- * of a page is wasted, though. So, for now we simply take a fourth of
- * a page, rounded up to a multiple of NumRows, and grab us a chunk of
- * memory.
- */
- iffini() ;
- /*
- * Now we set up and stuff our bitmap structure.
- */
- Bitmap.BytesPerRow = wordsperrow * 2 ;
- Bitmap.Rows = bitmapy ;
- Bitmap.Planes[0] = (PLANEPTR)bitmap ;
- }
- /*
- * How do we eject a page? I dunno. Let's pretend that a form
- * feed always works.
- */
- static void eject() {
- printerIO->ios.io_Command = PRD_RAWWRITE;
- printerIO->ios.io_Data = (APTR)"\014" ;
- printerIO->ios.io_Length = 1 ;
- doio() ;
- }
- /*
- * Now the dump routine.
- */
- void prefclr() {
- if (firstclear == 0) {
- firstclear = 1 ;
- memset((char *)bitmap,'\0',wordsperrow * (long)bitmapy * 2);
- return ;
- }
- dmpport(0L, bitmapx, bitmapy) ;
- eject() ;
- memset((char *)bitmap,'\0',wordsperrow * (long)bitmapy * 2);
- }
- /*
- * Here we free anything allocated in this file.
- */
- void preftid() {
- prefclr() ;
- free((void *)bitmap);
- if (prtopen) {
- CloseDevice(printerIO) ;
- prtopen = 0 ;
- }
- if (printerIO) {
- FreeMem(printerIO, (long)sizeof(union printerIO)) ;
- printerIO = NULL ;
- }
- if (replyport) {
- RemPort(replyport) ;
- DeletePort(replyport) ;
- replyport = NULL ;
- }
- }
-
- /*
- * This function `thickens' the lines by one pixel.
- */
- void plthicken() {
- register unsigned short *p ;
- register int i, j ;
-
- if (bitmap == NULL)
- return ;
- /* first we `thicken' horizontally. */
- p = (unsigned short *)bitmap ;
- for (j=0; j < bitmapy; j++) {
- for (i=1; i < wordsperrow; i++, p++)
- *p |= (*p << 1) | (p[1] >> 15) ;
- *p |= (*p << 1) ;
- p++ ;
- }
- /* next we `thicken' vertically. */
- p = (unsigned short *)bitmap ;
- for (j=1; j < bitmapy; j++)
- for (i=0; i<wordsperrow; i++, p++)
- *p |= p[wordsperrow] ;
- }
-