PLplot  5.10.0
ljiip.c
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines