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