PLplot
5.10.0
|
00001 // PLplot Laser Jet IIp device driver. 00002 // Based on old LJII driver, modifications by Wesley Ebisuzaki 00003 // 00004 // DPI = 300, 150, 100 (dots per inch) 00005 // default: Unix 300 dpi, MS-DOS 150 dpi 00006 // higher = better output, more memory, longer to print 00007 // GCMODE = 0, 2 (graphics compression mode) 00008 // default: 2, old laser jets should use 0 00009 // compression can speed up the printing up to 3x 00010 // 00011 // 00012 #include "plDevs.h" 00013 00014 #ifdef PLD_ljiip 00015 00016 #include "plplotP.h" 00017 #include "drivers.h" 00018 #include <math.h> 00019 #include <string.h> 00020 00021 #ifdef __GO32__ // dos386/djgpp 00022 #ifdef MSDOS 00023 #undef MSDOS 00024 #endif 00025 #endif 00026 00027 // Device info 00028 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_ljiip = 00029 "ljiip:LaserJet IIp/deskjet compressed graphics:0:ljiip:32:ljiip\n"; 00030 00031 // Function prototypes 00032 00033 void plD_dispatch_init_ljiip( PLDispatchTable *pdt ); 00034 00035 void plD_init_ljiip( PLStream * ); 00036 void plD_line_ljiip( PLStream *, short, short, short, short ); 00037 void plD_polyline_ljiip( PLStream *, short *, short *, PLINT ); 00038 void plD_eop_ljiip( PLStream * ); 00039 void plD_bop_ljiip( PLStream * ); 00040 void plD_tidy_ljiip( PLStream * ); 00041 void plD_state_ljiip( PLStream *, PLINT ); 00042 void plD_esc_ljiip( PLStream *, PLINT, void * ); 00043 00044 static void setpoint( PLINT, PLINT ); 00045 00046 // top level declarations 00047 00048 // GCMODE = graphics compression mode, 0=old laser jets, 2=ljiip or later 00049 #define GCMODE 2 00050 00051 // DPI = dots per inch, more dots=better plot, more memory, more time 00052 // possible DPI = 75, 100, 150, 300 00053 // if DPI=300 then your machine must have a free 1Mb block of memory 00054 00055 #define DPI 300 00056 00057 #ifdef MSDOS 00058 #undef DPI 00059 #define DPI 150 00060 #endif 00061 00062 #define OF pls->OutFile 00063 #define CURX ( (long) ( DPI / 5 ) ) 00064 #define CURY ( (long) ( DPI / 7 ) ) 00065 #define XDOTS ( 376 * ( DPI / 50 ) ) // # dots across 00066 #define YDOTS ( 500 * ( DPI / 50 ) ) // # dots down 00067 #define JETX ( XDOTS - 1 ) 00068 #define JETY ( YDOTS - 1 ) 00069 00070 00071 #define BPROW ( XDOTS / 8L ) // # bytes across 00072 #define MAX_WID 8 // max pen width in pixels 00073 #define BPROW1 ( BPROW + ( MAX_WID + 7 ) / 8 ) // pen has width, make bitmap bigger 00074 #define NBYTES BPROW1 * ( YDOTS + MAX_WID ) // total number of bytes 00075 00076 // Graphics control characters. 00077 00078 #define ESC 0x1b 00079 #define FF 0x0c 00080 00081 static char mask[8] = 00082 { '\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001' }; 00083 00084 #ifndef MSDOS 00085 #define _HUGE 00086 #else 00087 #define _HUGE _huge 00088 #endif 00089 00090 static unsigned char _HUGE *bitmap; // memory area NBYTES in size 00091 00092 void plD_dispatch_init_ljiip( PLDispatchTable *pdt ) 00093 { 00094 #ifndef ENABLE_DYNDRIVERS 00095 pdt->pl_MenuStr = "LaserJet IIp/deskjet compressed graphics"; 00096 pdt->pl_DevName = "ljiip"; 00097 #endif 00098 pdt->pl_type = plDevType_FileOriented; 00099 pdt->pl_seq = 32; 00100 pdt->pl_init = (plD_init_fp) plD_init_ljiip; 00101 pdt->pl_line = (plD_line_fp) plD_line_ljiip; 00102 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_ljiip; 00103 pdt->pl_eop = (plD_eop_fp) plD_eop_ljiip; 00104 pdt->pl_bop = (plD_bop_fp) plD_bop_ljiip; 00105 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_ljiip; 00106 pdt->pl_state = (plD_state_fp) plD_state_ljiip; 00107 pdt->pl_esc = (plD_esc_fp) plD_esc_ljiip; 00108 } 00109 00110 //-------------------------------------------------------------------------- 00111 // plD_init_ljiip() 00112 // 00113 // Initialize device. 00114 //-------------------------------------------------------------------------- 00115 00116 void 00117 plD_init_ljiip( PLStream *pls ) 00118 { 00119 PLDev *dev; 00120 00121 if ( pls->width == 0 ) // Is 0 if uninitialized 00122 pls->width = DPI / 100; 00123 00124 // Initialize family file info 00125 00126 plFamInit( pls ); 00127 00128 // Prompt for a file name if not already set 00129 00130 plOpenFile( pls ); 00131 00132 // Allocate and initialize device-specific data 00133 00134 dev = plAllocDev( pls ); 00135 00136 dev->xold = PL_UNDEFINED; 00137 dev->yold = PL_UNDEFINED; 00138 dev->xmin = 0; 00139 dev->ymin = 0; 00140 00141 // number of pixels / mm 00142 00143 plP_setpxl( (PLFLT) ( DPI / 25.4 ), (PLFLT) ( DPI / 25.4 ) ); 00144 00145 // Rotate by 90 degrees since portrait mode addressing is used 00146 00147 dev->xmin = 0; 00148 dev->ymin = 0; 00149 dev->xmax = JETY; 00150 dev->ymax = JETX; 00151 dev->xlen = dev->xmax - dev->xmin; 00152 dev->ylen = dev->ymax - dev->ymin; 00153 00154 plP_setphy( dev->xmin, dev->xmax, dev->ymin, dev->ymax ); 00155 00156 // If portrait mode is specified, then set up an additional rotation 00157 // transformation with aspect ratio allowed to adjust via freeaspect. 00158 // Default orientation is landscape (ORIENTATION == 3 or 90 deg rotation 00159 // counter-clockwise from portrait). (Legacy PLplot used seascape 00160 // which was equivalent to ORIENTATION == 1 or 90 deg clockwise rotation 00161 // from portrait.) 00162 00163 if ( pls->portrait ) 00164 { 00165 plsdiori( (PLFLT) ( 4 - ORIENTATION ) ); 00166 pls->freeaspect = 1; 00167 } 00168 00169 // Allocate storage for bit map matrix 00170 00171 #ifdef MSDOS 00172 if ( ( bitmap = (unsigned char _HUGE *) 00173 halloc( (long) NBYTES, sizeof ( char ) ) ) == NULL ) 00174 plexit( "Out of memory in call to calloc" ); 00175 #else 00176 if ( ( bitmap = (unsigned char *) calloc( NBYTES, sizeof ( char ) ) ) == NULL ) 00177 plexit( "Out of memory in call to calloc" ); 00178 #endif 00179 00180 // Reset Printer 00181 00182 fprintf( OF, "%cE", ESC ); 00183 } 00184 00185 //-------------------------------------------------------------------------- 00186 // plD_line_ljiip() 00187 // 00188 // Draw a line in the current color from (x1,y1) to (x2,y2). 00189 //-------------------------------------------------------------------------- 00190 00191 void 00192 plD_line_ljiip( PLStream *pls, short x1a, short y1a, short x2a, short y2a ) 00193 { 00194 PLDev *dev = (PLDev *) pls->dev; 00195 int x1 = x1a, y1 = y1a, x2 = x2a, y2 = y2a; 00196 int abs_dx, abs_dy, dx, dy, incx, incy; 00197 int i, j, width, residual; 00198 PLFLT tmp; 00199 00200 width = MIN( pls->width, MAX_WID ); 00201 00202 // Take mirror image, since PCL expects (0,0) to be at top left 00203 00204 y1 = dev->ymax - ( y1 - dev->ymin ); 00205 y2 = dev->ymax - ( y2 - dev->ymin ); 00206 00207 // Rotate by 90 degrees 00208 00209 plRotPhy( ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x1, &y1 ); 00210 plRotPhy( ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x2, &y2 ); 00211 00212 dx = x2 - x1; 00213 dy = y2 - y1; 00214 00215 if ( dx < 0 ) 00216 { 00217 abs_dx = -dx; 00218 incx = -1; 00219 } 00220 else 00221 { 00222 abs_dx = dx; 00223 incx = 1; 00224 } 00225 if ( dy < 0 ) 00226 { 00227 abs_dy = -dy; 00228 incy = -1; 00229 } 00230 else 00231 { 00232 abs_dy = dy; 00233 incy = 1; 00234 } 00235 00236 // make pixel width narrower for diag lines 00237 00238 if ( abs_dy <= abs_dx ) 00239 { 00240 if ( abs_dx == 0 ) 00241 tmp = 1.0; 00242 else 00243 tmp = 1.0 - (PLFLT) abs_dy / abs_dx; 00244 } 00245 else 00246 { 00247 tmp = 1.0 - (PLFLT) abs_dx / abs_dy; 00248 } 00249 00250 width = floor( 0.5 + width * ( tmp * tmp * tmp * ( 1.0 - 0.707107 ) + 0.707107 ) ); 00251 00252 if ( width < 1 ) 00253 width = 1; 00254 if ( width > 1 ) 00255 { 00256 for ( i = 0; i < width; i++ ) 00257 { 00258 for ( j = 0; j < width; j++ ) 00259 { 00260 setpoint( (PLINT) ( x1 + i ), (PLINT) ( y1 + j ) ); 00261 setpoint( (PLINT) ( x2 + i ), (PLINT) ( y2 + j ) ); 00262 } 00263 } 00264 } 00265 if ( abs_dx >= abs_dy ) 00266 { 00267 residual = -( abs_dx >> 1 ); 00268 if ( width == 1 ) 00269 { 00270 for ( i = 0; i <= abs_dx; i++, x1 += incx ) 00271 { 00272 setpoint( (PLINT) ( x1 ), (PLINT) ( y1 ) ); 00273 if ( ( residual += abs_dy ) >= 0 ) 00274 { 00275 residual -= abs_dx; 00276 y1 += incy; 00277 } 00278 } 00279 } 00280 else 00281 { 00282 for ( i = 0; i <= abs_dx; i++, x1 += incx ) 00283 { 00284 for ( j = 0; j < width; j++ ) 00285 { 00286 setpoint( (PLINT) ( x1 ), (PLINT) ( y1 + j ) ); 00287 setpoint( (PLINT) ( x1 + width - 1 ), (PLINT) ( y1 + j ) ); 00288 } 00289 if ( ( residual += abs_dy ) >= 0 ) 00290 { 00291 residual -= abs_dx; 00292 y1 += incy; 00293 } 00294 } 00295 } 00296 } 00297 else 00298 { 00299 residual = -( abs_dy >> 1 ); 00300 if ( width == 1 ) 00301 { 00302 for ( i = 0; i <= abs_dy; i++, y1 += incy ) 00303 { 00304 setpoint( (PLINT) ( x1 ), (PLINT) ( y1 ) ); 00305 if ( ( residual += abs_dx ) >= 0 ) 00306 { 00307 residual -= abs_dy; 00308 x1 += incx; 00309 } 00310 } 00311 } 00312 else 00313 { 00314 for ( i = 0; i <= abs_dy; i++, y1 += incy ) 00315 { 00316 for ( j = 0; j < width; j++ ) 00317 { 00318 setpoint( (PLINT) ( x1 + j ), (PLINT) ( y1 ) ); 00319 setpoint( (PLINT) ( x1 + j ), (PLINT) ( y1 + width - 1 ) ); 00320 } 00321 if ( ( residual += abs_dx ) >= 0 ) 00322 { 00323 residual -= abs_dy; 00324 x1 += incx; 00325 } 00326 } 00327 } 00328 } 00329 } 00330 00331 //-------------------------------------------------------------------------- 00332 // plD_polyline_ljiip() 00333 // 00334 // Draw a polyline in the current color. 00335 //-------------------------------------------------------------------------- 00336 00337 void 00338 plD_polyline_ljiip( PLStream *pls, short *xa, short *ya, PLINT npts ) 00339 { 00340 PLINT i; 00341 00342 for ( i = 0; i < npts - 1; i++ ) 00343 plD_line_ljiip( pls, xa[i], ya[i], xa[i + 1], ya[i + 1] ); 00344 } 00345 00346 //-------------------------------------------------------------------------- 00347 // plD_eop_ljiip() 00348 // 00349 // End of page.(prints it here). 00350 //-------------------------------------------------------------------------- 00351 00352 void 00353 plD_eop_ljiip( PLStream *pls ) 00354 { 00355 PLINT j; 00356 unsigned char _HUGE *p; 00357 #if GCMODE > 0 00358 int i, iy, last, n, jmax; 00359 unsigned char _HUGE t_buf[BPROW * 2]; 00360 unsigned char c; 00361 #endif 00362 00363 // PCL III setup: ref. Deskjet Plus Printer Owner's Manual 00364 00365 fprintf( OF, "\033*rB" ); // end raster graphics 00366 fprintf( OF, "\033*t%3dR", DPI ); // set DPI 00367 00368 #if GCMODE != 0 00369 fprintf( OF, "\033*r%dS", XDOTS ); // raster width 00370 fprintf( OF, "\033*b%1dM", GCMODE ); // graphics mode 00371 #endif 00372 00373 // First move cursor to origin 00374 00375 fprintf( OF, "\033*p%ldX", CURX ); 00376 fprintf( OF, "\033*p%ldY", CURY ); 00377 fprintf( OF, "\033*r0A" ); // start graphics 00378 00379 // Write out raster data 00380 00381 #if GCMODE == 0 00382 for ( j = 0, p = bitmap; j < YDOTS; j++, p += BPROW1 ) 00383 { 00384 fprintf( OF, "\033*b>%dW", BPROW ); 00385 fwrite( p, BPROW, sizeof ( char ), OF ); 00386 } 00387 #endif 00388 #if GCMODE == 2 00389 for ( iy = 0, p = bitmap; iy < YDOTS; iy++, p += BPROW1 ) 00390 { 00391 // find last non-zero byte 00392 00393 last = BPROW - 1; 00394 while ( last > 0 && p[last] == 0 ) 00395 last--; 00396 last++; 00397 00398 // translate to mode 2, save results in t_buf[] 00399 00400 i = n = 0; 00401 while ( i < last ) 00402 { 00403 c = p[i]; 00404 jmax = i + 127; 00405 jmax = last < jmax ? last : jmax; 00406 if ( i < last - 2 && ( c == p[i + 1] ) && ( c == p[i + 2] ) ) 00407 { 00408 j = i + 3; 00409 while ( j < jmax && c == p[j] ) 00410 j++; 00411 t_buf[n++] = ( i - j + 1 ) & 0xff; 00412 t_buf[n++] = c; 00413 i = j; 00414 } 00415 else 00416 { 00417 for ( j = i + 1; j < jmax; j++ ) 00418 { 00419 if ( j < last - 2 && ( p[j] == p[j + 1] ) && 00420 ( p[j + 1] == p[j + 2] ) ) 00421 break; 00422 } 00423 t_buf[n++] = j - i - 1; 00424 while ( i < j ) 00425 { 00426 t_buf[n++] = p[i++]; 00427 } 00428 } 00429 } 00430 fprintf( OF, "\033*b%dW", (int) n ); 00431 fwrite( t_buf, (int) n, sizeof ( char ), OF ); 00432 } 00433 #endif 00434 00435 pls->bytecnt += NBYTES; 00436 00437 // End raster graphics and send Form Feed 00438 00439 fprintf( OF, "\033*rB" ); 00440 fprintf( OF, "%c", FF ); 00441 00442 // Finally, clear out bitmap storage area 00443 00444 memset( (void *) bitmap, '\0', NBYTES ); 00445 } 00446 00447 //-------------------------------------------------------------------------- 00448 // plD_bop_ljiip() 00449 // 00450 // Set up for the next page. 00451 // Advance to next family file if necessary (file output). 00452 //-------------------------------------------------------------------------- 00453 00454 void 00455 plD_bop_ljiip( PLStream *pls ) 00456 { 00457 if ( !pls->termin ) 00458 plGetFam( pls ); 00459 00460 pls->page++; 00461 } 00462 00463 //-------------------------------------------------------------------------- 00464 // plD_tidy_ljiip() 00465 // 00466 // Close graphics file or otherwise clean up. 00467 //-------------------------------------------------------------------------- 00468 00469 void 00470 plD_tidy_ljiip( PLStream *pls ) 00471 { 00472 // Reset Printer 00473 00474 fprintf( OF, "%cE", ESC ); 00475 plCloseFile( pls ); 00476 free( (char *) bitmap ); 00477 } 00478 00479 //-------------------------------------------------------------------------- 00480 // plD_state_ljiip() 00481 // 00482 // Handle change in PLStream state (color, pen width, fill attribute, etc). 00483 //-------------------------------------------------------------------------- 00484 00485 void 00486 plD_state_ljiip( PLStream *pls, PLINT op ) 00487 { 00488 } 00489 00490 //-------------------------------------------------------------------------- 00491 // plD_esc_ljiip() 00492 // 00493 // Escape function. 00494 //-------------------------------------------------------------------------- 00495 00496 void 00497 plD_esc_ljiip( PLStream *pls, PLINT op, void *ptr ) 00498 { 00499 } 00500 00501 //-------------------------------------------------------------------------- 00502 // setpoint() 00503 // 00504 // Sets a bit in the bitmap. 00505 //-------------------------------------------------------------------------- 00506 00507 static void 00508 setpoint( PLINT x, PLINT y ) 00509 { 00510 PLINT index; 00511 index = x / 8 + y * BPROW1; 00512 *( bitmap + index ) = *( bitmap + index ) | mask[x % 8]; 00513 } 00514 00515 #else 00516 int 00517 pldummy_ljiip() 00518 { 00519 return 0; 00520 } 00521 00522 #endif // PLD_ljii