#include #include /* for biosprint */ #include "grafprt.h" #include "arrays.h" #define MAXPRINTROWS 100 #define MAXCOLS 960 #define MAXROWS (MAXPRINTROWS * 16) /*--------------------------------------------------------------------*/ /* module grafprt.c in turbo c version 2.0, large code model. */ /* */ /* a set of graphics routines for high-resolution printer graphics */ /* on Epson FX, LX and other IBM Graphics Printer compatibles. */ /* */ /* sample usage: */ /* */ /* initgrafprt(); */ /* portrait(); */ /* frame(); */ /* defreg(0.0,1.0,0.5,2.0,200,860,700,1500); */ /* framxy(); */ /* prtlin(0.1,0.3,0.5,1.5,1); */ /* prntgr(0); */ /* */ /* released to the public domain by Gregory K. Landheim on January */ /* 1, 1989, (c) all rights reserved. anybody is authorized to use */ /* this code for any purpose whatsoever on the condition that they */ /* realize I assume absolutely no liability and give no warrantee */ /* for its use or performance. it is distributed "as is", and if */ /* you use it you assume full liability for its use. */ /* */ /*--------------------------------------------------------------------*/ /* */ /* initgrafprt() */ /* allocates arrays for bit map from the heap */ /* and initializes certain global variables. */ /* dismem() de-allocates arrays for bit map */ /* colorset() sets global Color for use by line drawing routines */ /* pset() plots a point in the bit map */ /* plank() blanks a point in the bit map */ /* prntgr() sends the graphics page (bit map) to the printer */ /* iprtln() draws a line in device integer coordinates */ /* frame() draws a boundary on the maximum plotting region */ /* framxy() draws a boundary around the real world region */ /* transf() transforms real world (x,y) to integer world (ix,iy) */ /* itransf() transforms int world (ix,iy) to plot device (ix,iy) */ /* defreg() defines correspondence between integer and real worlds */ /* prtlin() draws a line specified in real world coordinates */ /* */ /* a note about worlds: */ /* the real world is right-handed and rectangular and is expressed */ /* in floating point. */ /* the integer world is the right-handed and rectangular integer */ /* representation of the maximum pixel plotting domain of the */ /* plot device. */ /* the plot device is left-handed and rectangular. */ /* */ /* Printer page, Portrait mode: */ /* */ /* (0,1959)=[0,0] ------------------ [959,0]=(959,1599) */ /* | | */ /* [x,y] = printer | | */ /* coordinates | | */ /* | | */ /* (x,y) = integer world | | */ /* coordinates | | */ /* | | */ /* | | */ /* | | */ /* | | */ /* (0,0)=[0,1959] ------------------ [959,1599]=(959,0) */ /* */ /* */ /* Printer page, Landscape mode: */ /* */ /* [959,0] --------------------------------- [959,1599] */ /* (0,959) | | (1599,959) */ /* | | */ /* | | */ /* | | */ /* | | */ /* | | */ /* | | */ /* [0,0] --------------------------------- [0,1599] */ /* (0,0) (1599,0) */ /* */ /* defreg() is used to define a real world window within the */ /* integer world. the integer world coordinates used depend on */ /* whether you are in portrait or landscape mode. */ /* */ /*--------------------------------------------------------------------*/ int Arx,Ary; /* printer aspect ratio parameters */ int Maxwidth; /* pixel width of plot device */ int Maxheight; /* pixel height of plot device */ int Portrait = 1; /* flag, indicates whether to plot */ /* in portrait or landscape mode */ int Color = 1; /* color used for drawing lines */ unsigned char **Evenrow; /* buffer for printer pixel map */ unsigned char **Oddrow; /* buffer for printer pixel map */ float X_min, X_max, Y_min, Y_max; /* real world minima, maxima */ int IX_min, IX_max, IY_min, IY_max; /* integer world minima, maxima */ /* corresponding to real world minima and maxima */ float Dw,Dh; /* real world delta-x, delta-y */ int IDw,IDh; /* integer world delta-x, delta-y */ /* corresponding to real world delta-x and delta-y */ /*--------------------------------------------------------------------*/ /* */ /* void portrait() */ /* */ /* toggles global variable Portrait to indicate portrait mode */ /* plotting. */ /* */ /*--------------------------------------------------------------------*/ void portrait() { Portrait = 1; } /* void portrait() */ /*--------------------------------------------------------------------*/ /* */ /* void landscape() */ /* */ /* toggles global variable Portrait to indicate landscape mode */ /* plotting. */ /* */ /*--------------------------------------------------------------------*/ void landscape() { Portrait = 0; } /* void landscape() */ /*--------------------------------------------------------------------*/ /* */ /* int initgrafprt() */ /* */ /* Sets aside space in the heap for the printer bit map. The pixel */ /* data will be stored in two sets of MAXCOL global arrays, one set */ /* for the odd-numbered rows of pixels, and one for the even-numbered*/ /* rows of pixels. */ /* Since calloc() is called instead of malloc(), the arrays are */ /* initialized to zero. */ /* If the memory is successfully allocated, initgrafprt returns a */ /* value of 1, else 0. */ /* */ /* There must be about 188 kb of memory available for the bit map in */ /* order to call this routine successfully. */ /* */ /*--------------------------------------------------------------------*/ int initgrafprt() { /* prototype for alloc_2d_array() is in arrays.h */ Evenrow = (unsigned char **)alloc_2d_array(MAXCOLS,MAXPRINTROWS, sizeof(char *),sizeof(char)); if (!Evenrow) return(0); Oddrow = (unsigned char **)alloc_2d_array(MAXCOLS,MAXPRINTROWS, sizeof(char *),sizeof(char)); if (!Evenrow) return(0); Arx = 4; Ary = 5; Maxwidth = MAXCOLS - 1; Maxheight = MAXROWS - 1; return(1); } /* int initgrafprt() */ /*--------------------------------------------------------------------*/ /* */ /* void dismem() */ /* */ /* Disposes of space in the heap previously allocated for the printer*/ /* bit map allocated in function initgrafprt(). The pixel data */ /* was stored in two global arrays, one for the odd-numbered rows */ /* of pixels, and one for the even-numbered rows of pixels. */ /* */ /* In ordinary use, this routine should not be explicitly called */ /* except where it is called in prntgr(). If initgrafprt() is called */ /* and prntgr() is not called, be sure to call dismem() to dispose */ /* of the bit map memory from the heap. */ /* */ /*--------------------------------------------------------------------*/ void dismem() { free_2d_array((void **) Evenrow,MAXCOLS); free_2d_array((void **) Oddrow,MAXCOLS); } /* void dismem() */ /*--------------------------------------------------------------------*/ /* */ /* void far colorset(int color) */ /* */ /* sets global variable Color as flag for line drawing routines */ /* if color = 1, pset() is used, else pblank() */ /* */ /*--------------------------------------------------------------------*/ void far colorset(int color) { Color = color; } /* void colorset() */ /*--------------------------------------------------------------------*/ /* */ /* void pset(int x,int y) */ /* */ /* Writes the dot at position (x,y) into memory arrays (bit map). */ /* */ /* x must be less than or equal to Maxwidth. y must be less than or */ /* equal to Maxheight. Both x and y must be greater than or equal to */ /* 0. initgrafprt() must be called before pset() is called for the */ /* first time. */ /* */ /*--------------------------------------------------------------------*/ void pset(int x,int y) { static unsigned char o[8] = {128,64,32,16,8,4,2,1}; ((y % 2) == 0) ? (Evenrow[x][y >> 4] |= o[y % 16 >> 1]) : (Oddrow[x][y >> 4] |= o[y % 16 >> 1]); } /* void pset() */ /*--------------------------------------------------------------------*/ /* */ /* void pblank(int x,int y) */ /* */ /* Blanks the dot at position (x,y) in memory arrays (bit map). */ /* */ /* x must be less than or equal to Maxwidth. y must be less than or */ /* equal to Maxheight. Both x and y must be greater than or equal to */ /* 0. initgrafprt() must be called before pblank() is called for */ /* the first time. */ /* */ /*--------------------------------------------------------------------*/ void pblank(int x,int y) { static unsigned char a[8] = {127,191,223,239,247,251,253,254}; ((y % 2) == 0) ? (Evenrow[x][y >> 4] &= a[y % 16 >> 1]) : (Oddrow[x][y >> 4] &= a[y % 16 >> 1]); } /* void pblank() */ /*--------------------------------------------------------------------*/ /* */ /* void prntgr(int port) */ /* */ /* Lists the contents of the bit map to an Epson FX-80, LX-90, ALPS */ /* P2000, and other IBM Graphics Printer compatibles using double */ /* density graphics mode. */ /* */ /* port = printer port to be used, e.g. LPT1 = 0. */ /* */ /* The vertical high resolution is obtained by using the ESC 3 or */ /* 'Select n/216-Inch Line Spacing' command. */ /* */ /* REFERENCES: 'ALPS P2000/P2100 Printer User's Manual,' */ /* Copyright (C) 1986 by ALPS Electric Co., Ltd. */ /* */ /* 'Printer Interface Cartridge for the IBM PC and */ /* and Compatibles Operation Manual,' (C) 1985 by Epson */ /* Corporation, Nagano, Japan. */ /* */ /* "High-Resolution Printer Graphics," by Mark Bridger */ /* and Mark Goresky, BYTE, November 1985, pp 219-232. */ /* */ /* This routine will work only on an Epson LX or FX type printer, as */ /* well as the ALPS P2000 printer, and other IBM Graphics Printer */ /* compatibles. It should not be called unless a call has been made */ /* to initgrafprt(). */ /* */ /* biosprint() is used instead of fputc() to disable control-Z and */ /* other annoying characters that can screw up the printer stream. */ /* */ /*--------------------------------------------------------------------*/ void prntgr(int port) { int n1,n2; int i,j; /* n1 and n2 together give the number of graphics columns: */ n2 = MAXCOLS / 256; n1 = MAXCOLS % 256; /* loop through all the even-row odd-row lines: */ for (j=0; j