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