• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

ljiip.c

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

Generated on Wed Oct 12 2011 20:42:21 for PLplot by  doxygen 1.7.1