[net.sources] Gnuplot V1.1 HP laserjet driver FIXED

jty@topelius.UUCP (03/23/87)

cat <<'---- CUT HERE'
The HP laserjet driver I posted to net a while ago had
(at least) one bug: It will not plot correctly on
a 16 bit int - machine (like PC) due to an overflow.

Also it used calloc() rather heavily: the allocated
raster/page was >400KB and it didn't fit in the PC memory.

Now here is a new version where the raster uses 52K
and the overflow bug is fixed.

This version is in the form of a diff to the ORIGINAL distributed
V1.1 gnuplot term.c. There are also some fixes to the distributed
HP26 driver.

This has been tested in HP 9500 HP-UX and
HP Vectra PC (IBM PC clone) PC-DOS w/Microsoft-C 4.0

Patch and enjoy.

The following term.c.diff is done by
$ diff term.c.orig term.c >term.c.diff

PS.
Whoever invented the ".. rejected because you included too much..."
in inews, should be [censored]
---- CUT HERE
: To unbundle, sh this file
echo '  24 -rw-rw-r--   1 jty      intrin     11796 Mar  3 12:25 term.c.diff' 1>&2
sed 's/^\.//' >term.c.diff <<'END-OF-term.c.diff'
.123a124,549
.> #ifdef HPLJET
.> #define RASTER
.> #define RASTERTIGHT
.> #endif /* HPLJET */
.> 
.> #ifdef RASTER
.> /*
.> ** General raster plotting routines.
.> ** Raster routines written and copyrighted 1987 by
.> ** Jyrki Yli-Nokari (jty@intrin.UUCP)
.> ** Intrinsic, Ltd.
.> ** 
.> ** You may use this code for anything you like as long as
.> ** you are not selling it and the credit is given and
.> ** this message retained.
.> **
.> ** The plotting area is defined as a huge raster.
.> ** The raster is stored in a dynamically allocated pixel array r_p
.> **
.> ** The raster is allocated (and initialized to zero) with
.> ** r_makeraster(xsize, ysize)
.> ** and freed with r_freeraster()
.> **
.> ** Valid (unsigned) coordinates range from zero to (xsize-1,ysize-1)
.> **
.> ** Plotting is done via r_move(x, y) and r_draw(x, y, value) functions,
.> ** where the point (x,y) is the target to go from the current point
.> ** and value is the value (of type pixel) to be stored in every pixel.
.> **
.> ** Internally all plotting goes through r_setpixel(x, y, val).
.> ** If you want different plotting styles (like OR, XOR...), use "value"
.> ** in r_draw() to mark different styles and change r_setpixel() accordingly.
.> **
.> ** If RASTERTIGHT is defined, the raster is stored as one bit/pixel to
.> ** save (PC) memory. RASTERTIGHT assumes that the type pixel is 8 bits.
.> */
.> 
.> #define IN(i,size)	((unsigned)i < (unsigned)size)
.> typedef char pixel;	/* the type of one pixel in raster */
.> typedef pixel *raster[];	/* the raster */
.> 
.> static raster *r_p;	/* global pointer to raster */
.> static unsigned r_currx, r_curry;	/* the current coordinates */
.> static unsigned r_xsize, r_ysize;	/* the size of the raster */
.> 
.> char *calloc();
.> void free();
.> 
.> /*
.> ** set pixel (x, y, val) to value val (this can be 1/0 or a color number).
.> */
.> void
.> r_setpixel(x, y, val)
.> unsigned x, y;
.> pixel val;
.> {
.> 	if (IN(x, r_xsize) && IN(y, r_ysize)) {
.> #ifdef RASTERTIGHT
.> 		if (val) {
.> 			*((*r_p)[y] + (x >> 3)) |= 1 << (x & 7);
.> 		} else {
.> 			*((*r_p)[y] + (x >> 3)) &= ~(1 << (x & 7));
.> 		}
.> #else
.> 		*(((*r_p)[y]) + x) = val;
.> #endif
.> 	}
.> #ifdef RASTERDEBUG
.> 	else {
.> 		fprintf(stderr, "Warning: setpixel(%d, %d, %d) out of bounds\n", x, y, val);
.> 	}
.> #endif
.> }
.> 
.> /*
.> ** get pixel (x,y) value
.> */
.> pixel
.> r_getpixel(x, y)
.> unsigned x, y;
.> {
.> 	if (IN(x, r_xsize) && IN(y, r_ysize)) {
.> #ifdef RASTERTIGHT
.> 		return ((*((*r_p)[y] + (x >> 3)) & (1 << (x & 7))) != 0);
.> #else
.> 		return *(((*r_p)[y]) + x);
.> #endif
.> 	} else {
.> #ifdef RASTERDEBUG
.> 		fprintf(stderr, "Warning: getpixel(%d,%d) out of bounds\n", x, y);
.> #endif
.> 		return 0;
.> 	}
.> }
.> 
.> /*
.> ** allocate the raster
.> */
.> void
.> r_makeraster(x, y)
.> unsigned x, y;
.> {
.> 	register unsigned j;
.> 	
.> 	/* allocate row pointers */
.> 	if ((r_p = (raster *)calloc(y, sizeof(pixel *))) == (raster *)0) {
.> 		fprintf(stderr, "Raster buffer allocation failure\n");
.> 		exit(1);
.> 	}
.> #ifdef RASTERTIGHT
.> #define XITEMS	x
.> #else
.> #define XITEMS	(x >> 3)
.> #endif
.> 	for (j = 0; j < y; j++) {
.> 		if (((*r_p)[j] = (pixel *)calloc(XITEMS, sizeof(pixel))) == (pixel *)0) {
.> 			fprintf(stderr, "Raster buffer allocation failure\n");
.> 			exit(1);
.> 		}
.> 	}
.> 	r_xsize = x; r_ysize = y;
.> 	r_currx = r_curry = 0;
.> }
.> 	
.> /*
.> ** plot a line from (x0,y0) to (x1,y1) with color val.
.> */
.> void
.> r_plot(x0, y0, x1, y1, val)
.> unsigned x0, y0, x1, y1;
.> pixel val;
.> {
.> 	unsigned hx, hy, i;
.> 	int e, dx, dy;
.> 
.> 	hx = abs((int)(x1 - x0));
.> 	hy = abs((int)(y1 - y0));
.> 	dx = (x1 > x0) ? 1 : -1;
.> 	dy = (y1 > y0) ? 1 : -1;
.> 	
.> 	if (hx > hy) {
.> 		/*
.> 		** loop over x-axis
.> 		*/
.> 		e = hy + hy - hx;
.> 		for (i = 0; i <= hx; i++) {
.> 			r_setpixel(x0, y0, val);
.> 			if (e > 0) {
.> 				y0 += dy;
.> 				e += hy + hy - hx - hx;
.> 			} else {
.> 				e += hy + hy;
.> 			}
.> 			x0 += dx;
.> 		}
.> 	} else {
.> 		/*
.> 		** loop over y-axis
.> 		*/
.> 		e = hx + hx - hy;
.> 		for (i = 0; i <= hy; i++) {
.> 			r_setpixel(x0, y0, val);
.> 			if (e > 0) {
.> 				x0 += dx;
.> 				e += hx + hx - hy - hy;
.> 			} else {
.> 				e += hx + hx;
.> 			}
.> 			y0 += dy;
.> 		}
.> 	}
.> }
.> 
.> /*
.> ** move to (x,y)
.> */
.> void
.> r_move(x, y)
.> unsigned x, y;
.> {
.> 	r_currx = x;
.> 	r_curry = y;
.> }
.> 
.> /*
.> ** draw to (x,y) with color val
.> ** (move pen down)
.> */
.> void
.> r_draw(x, y, val)
.> unsigned x, y;
.> pixel val;
.> {
.> 	r_plot(r_currx, r_curry, x, y, val);
.> 	r_currx = x;
.> 	r_curry = y;
.> }
.> 
.> /*
.> ** free the allocated raster
.> */
.> void
.> r_freeraster()
.> {
.> 	int y;
.> 
.> 	for (y = 0; y < r_ysize; y++) {
.> 		free((char *)(*r_p)[y]);
.> 	}
.> 	free((char *)r_p);
.> }
.> #endif /* RASTER */
.> 
.> #ifdef HPLJET
.> /*
.> ** Hewlett-Packard Laserjet
.> ** Driver written and copyrighted 1987 by
.> ** Jyrki Yli-Nokari (jty@intrin.UUCP)
.> ** Intrinsic, Ltd.
.> ** 
.> ** You may use this code for anything you like as long as
.> ** you are not selling it and the credit is given and
.> ** this message retained.
.> */
.> 
.> /*
.> ** NOTE:
.> ** When sending the plot to the laserjet there must be absolutely
.> ** NO character translation done by the operating system.
.> ** Normally, in UNIX, the (operating system) terminal driver
.> ** translates newlines to CR/LF pairs. This is called the "cooked mode".
.> ** Some operating systems might add CR/LF pairs if they think there
.> ** is a too long line. ALL THIS IS STRICTLY PROHIBITED.
.> ** ALL DATA TO THE LASERJET MUST BE SENT WHEN THE LINE IS IN RAW MODE.
.> **
.> 
.> /*
.> ** The laserjet math is a pain since we have to deal with
.> ** decipoints (720/inch), dots (300/inch), pixels (100-300/inch),
.> ** characters (10/inch horiz., 6/inch vertic.) and the size of
.> ** the plottable surface in A4 (about 7.8 inches horizontally).
.> ** On top of this we also support different plot sizes!
.> */
.> 
.> #define HPLJET_PIXSIZE	(hpljet_pixel)
.> 		/* Laserjet pixel size in laserjet minimum dots */
.> #define HPLJET_PPI (300/HPLJET_PIXSIZE)
.> 		/* Laserjet raster scaling factor, Pixels Per Inch */
.> #define HPLJET_WIDTH 5600
.> 		/* ~ Number of horizontal decipoints in A4 */
.> #define HPLJET_IN2DP(x) (720*(x))
.> 		/* convert INches TO DeciPoints */
.> #define HPLJET_PX2DP(x) (HPLJET_IN2DP(x)/HPLJET_PPI)
.> 		/* convert PiXels TO DeciPoints */
.> #define HPLJET_HC2DP(x) (72*(x))
.> 		/* convert Horizontal Characters TO DeciPoints */
.> #define HPLJET_VC2DP(x) (120*(x))
.> 		/* convert Vertical Characters TO DeciPoints */
.> #define HPLJET_LMARG ((HPLJET_WIDTH - HPLJET_PX2DP(HPLJETXMAX))/2)
.> 		/* Picture left margin in decipoints */
.> #define HPLJET_RMARG ((HPLJET_WIDTH + HPLJET_PX2DP(HPLJETXMAX))/2)
.> 		/* Picture right margin in decipoints */
.> #define HPLJETXMAX 640
.> 		/* Number of pixels in X-axis */
.> #define HPLJETYMAX 640
.> 		/* Number of pixels in Y-axis */
.> #define HPLJETXLAST (HPLJETXMAX - 1)
.> 		/* Last valid X-pixel value */
.> #define HPLJETYLAST (HPLJETYMAX - 1)
.> 		/* Last valid Y-pixel value */
.> 
.> #define HPLJETVCHAR	(HPLJET_PPI/6)
.> 		/* Vertical pixel size of the character font */
.> #define HPLJETHCHAR	(HPLJET_PPI/10)
.> 		/* Horizontal pixel size of the character font */
.> #define HPLJET1VCHAR	(300/6)
.> 		/* Vertical pixel size of the character font */
.> #define HPLJET1HCHAR	(300/10)
.> 		/* Horizontal pixel size of the character font */
.> #define HPLJET2VCHAR	(150/6)
.> 		/* Vertical pixel size of the character font */
.> #define HPLJET2HCHAR	(150/10)
.> 		/* Horizontal pixel size of the character font */
.> #define HPLJET3VCHAR	(100/6)
.> 		/* Vertical pixel size of the character font */
.> #define HPLJET3HCHAR	(100/10)
.> 		/* Horizontal pixel size of the character font */
.> /*
.> ** (I guess) VTIC and HTIC are used as
.> ** "small units that look like equal length".
.> ** They determine (at least) the length of "bars" in axises and
.> ** the size of plotting symbols.
.> */
.> #define HPLJETVTIC		6
.> #define HPLJETHTIC		6
.> 
.> /*
.> ** We use laserjet1, laserjet2 and laserjet3 for different
.> ** pixel sizes of the picture (1 is the smallest).
.> ** The size of the text, however, remains the same.
.> ** These three terminal types use mostly the same
.> ** functions, only the init-function determines the size of the picture.
.> ** Also, the h_char and v_char are different, but they are
.> ** not used.
.> */
.> 
.> /*
.> ** Initialize (once) for graphics
.> */
.> static int hpljet_pixel = 3;
.> 
.> HPLJET1init()
.> {
.> 	hpljet_pixel = 1;
.> }
.> 
.> HPLJET2init()
.> {
.> 	hpljet_pixel = 2;
.> }
.> 
.> HPLJET3init()
.> {
.> 	hpljet_pixel = 3;
.> }
.> 
.> HPLJETmove(x, y)
.> {
.> 	r_move((unsigned)x, (unsigned)y);
.> }
.> 
.> HPLJETvector(x, y)
.> {
.> 	r_draw((unsigned)x, (unsigned)y, (pixel)1);
.> }
.> 
.> /*
.> ** Enter graphics mode:
.> **	- allocate raster buffer
.> **	- set resolution
.> */
.> HPLJETgraphics()
.> {
.> 	r_makeraster(HPLJETXMAX, HPLJETYMAX);
.> 	fprintf(outfile,"\033*t%dR", HPLJET_PPI);
.> /*	                             1
.> **	1. Set resolution pixels/inch
.> */
.> }
.> 
.> /*
.> ** (re-)enter text mode,
.> ** output raster and deallocate it.
.> */
.> HPLJETtext()
.> {
.> 	int x, y;
.> 	unsigned v, i;
.> 
.> 	fprintf(outfile, "\033&a%dH\033&a%dV", HPLJET_LMARG, HPLJET_VC2DP(2));
.> 	fprintf(outfile, "\033*r1A");
.> 	for (y = r_ysize-1; y >= 0; y--) {
.> 		fprintf(outfile, "\033*b%dW", r_xsize/8);
.> 		for (x = 0; x < r_xsize; x += 8) {
.> 			v = 0;
.> 			for (i = 0; i < 8; i++) {
.> 				v = (v << 1) | r_getpixel((unsigned)x + i, (unsigned)y);
.> 			}
.> 			putc((char)v, outfile);
.> 		}
.> 	}
.> 	r_freeraster();
.> 	fprintf(outfile, "\033*rB\f");
.> }
.> 
.> /*
.> ** Select line type [-2:8]
.> ** line types:
.> **	-2 = border line
.> **	-1 = x/y axis line
.> **	0-8 = function plot lines.
.> **	Dummy function here.
.> */
.> HPLJETlinetype(linetype)
.> int linetype;
.> {
.> }
.> 
.> /*
.> ** Put text "str" to the lower right corner of the screen.
.> ** "row" is the row number [0:1].
.> ** Actually in the laserjet, put the text above the upper right corner.
.> */
.> HPLJETlrput_text(row,str)
.> unsigned int row;
.> char *str;
.> {
.> 	
.> 	fprintf(outfile, "\033&a%dH\033&a%dV",
.> 	        HPLJET_RMARG - HPLJET_HC2DP(strlen(str)), HPLJET_VC2DP(row));
.> 	fputs(str, outfile);
.> }
.> 
.> /*
.> ** Put text "str" to the upper left corner of the screen.
.> ** "row" is the (serial) number of function to be plotted.
.> ** Actually in the laserjet, put the text under the lower left corner.
.> */
.> HPLJETulput_text(row,str)
.> unsigned int row;
.> char *str;
.> {
.> 	fprintf(outfile, "\033&a%dH\033&a%dV",
.> 	        HPLJET_LMARG,
.> 	        HPLJET_VC2DP(row+3)+HPLJET_PX2DP(HPLJETYMAX));
.> 	fputs(str, outfile);
.> }
.> 
.> /*
.> ** RETURN to normal mode (exit gnuplot)
.> */
.> HPLJETreset()
.> {
.> }
.> #endif /* HPLJET */
.> 
.786,787c1212,1213
.< #define HP26_VTIC	(HP26_YMAX/70)		
.< #define HP26_HTIC	(HP26_XMAX/75)		
.---
.> #define HP26_VTIC	4
.> #define HP26_HTIC	4
.822,823c1248,1249
.< 						SOLID,	/* axes */
.< 						DOTS,	/* plot 0 */
.---
.> 						DOTS,	/* axes */
.> 						SOLID,	/* plot 0 */
.830c1256
.< 						SOLID,	/* plot 7 */
.---
.> 						DOTS,	/* plot 7 */
.858d1283
.< 	HP26_move(HP26_XMAX-HP26_HTIC*2,HP26_VTIC*2+HP26_VCHAR*row);
.1640a2066,2080
.> #ifdef HPLJET
.> 	,{"laserjet1",HPLJETXMAX,HPLJETYMAX,HPLJET1VCHAR, HPLJET1HCHAR, HPLJETVTIC,
.> 		HPLJETHTIC, HPLJET1init,HPLJETreset, HPLJETtext, HPLJETgraphics, 
.> 		HPLJETmove, HPLJETvector,HPLJETlinetype,HPLJETlrput_text,
.> 		HPLJETulput_text, line_and_point}
.> 	,{"laserjet2",HPLJETXMAX,HPLJETYMAX,HPLJET2VCHAR, HPLJET2HCHAR, HPLJETVTIC, 
.> 		HPLJETHTIC, HPLJET2init,HPLJETreset, HPLJETtext, HPLJETgraphics, 
.> 		HPLJETmove, HPLJETvector,HPLJETlinetype,HPLJETlrput_text,
.> 		HPLJETulput_text, line_and_point}
.> 	,{"laserjet3",HPLJETXMAX,HPLJETYMAX,HPLJET3VCHAR, HPLJET3HCHAR, HPLJETVTIC, 
.> 		HPLJETHTIC, HPLJET3init,HPLJETreset, HPLJETtext, HPLJETgraphics, 
.> 		HPLJETmove, HPLJETvector,HPLJETlinetype,HPLJETlrput_text,
.> 		HPLJETulput_text, line_and_point}
.> #endif
.> 
END-OF-term.c.diff
exit 0
-- 
Jyrki Yli-Nokari, Intrinsic Oy, SF-33100 Tampere, FINLAND

USENET:      INTERNET:      BITNET:          FUNET:        TELEPHONE:
intrin!jty   jty@intrin.FI  YLI at FINTUTA   TTKKLK::YLI   +358 31 132800