PLplot: ljiip.c Source File

PLplot 5.10.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
ljiip.c
Go to the documentation of this file.
1 // $Id: ljiip.c 11282 2010-10-28 16:26:09Z airwin $
2 //
3 // PLplot Laser Jet IIp device driver.
4 // Based on old LJII driver, modifications by Wesley Ebisuzaki
5 //
6 // DPI = 300, 150, 100 (dots per inch)
7 // default: Unix 300 dpi, MS-DOS 150 dpi
8 // higher = better output, more memory, longer to print
9 // GCMODE = 0, 2 (graphics compression mode)
10 // default: 2, old laser jets should use 0
11 // compression can speed up the printing up to 3x
12 //
13 //
14 #include "plDevs.h"
15
16 #ifdef PLD_ljiip
17
18 #include "plplotP.h"
19 #include "drivers.h"
20 #include <math.h>
21 #include <string.h>
22
23 #ifdef __GO32__ // dos386/djgpp
24 #ifdef MSDOS
25 #undef MSDOS
26 #endif
27 #endif
28
29 // Device info
30 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_ljiip =
31 "ljiip:LaserJet IIp/deskjet compressed graphics:0:ljiip:32:ljiip\n";
32
33 // Function prototypes
34
35 void plD_dispatch_init_ljiip( PLDispatchTable *pdt );
36
37 void plD_init_ljiip( PLStream * );
38 void plD_line_ljiip( PLStream *, short, short, short, short );
39 void plD_polyline_ljiip( PLStream *, short *, short *, PLINT );
40 void plD_eop_ljiip( PLStream * );
41 void plD_bop_ljiip( PLStream * );
42 void plD_tidy_ljiip( PLStream * );
43 void plD_state_ljiip( PLStream *, PLINT );
44 void plD_esc_ljiip( PLStream *, PLINT, void * );
45
46 static void setpoint( PLINT, PLINT );
47
48 // top level declarations
49
50 // GCMODE = graphics compression mode, 0=old laser jets, 2=ljiip or later
51 #define GCMODE 2
52
53 // DPI = dots per inch, more dots=better plot, more memory, more time
54 // possible DPI = 75, 100, 150, 300
55 // if DPI=300 then your machine must have a free 1Mb block of memory
56
57 #define DPI 300
58
59 #ifdef MSDOS
60 #undef DPI
61 #define DPI 150
62 #endif
63
64 #define OF pls->OutFile
65 #define CURX ( (long) ( DPI / 5 ) )
66 #define CURY ( (long) ( DPI / 7 ) )
67 #define XDOTS ( 376 * ( DPI / 50 ) ) // # dots across
68 #define YDOTS ( 500 * ( DPI / 50 ) ) // # dots down
69 #define JETX ( XDOTS - 1 )
70 #define JETY ( YDOTS - 1 )
71
72
73 #define BPROW ( XDOTS / 8L ) // # bytes across
74 #define MAX_WID 8 // max pen width in pixels
75 #define BPROW1 ( BPROW + ( MAX_WID + 7 ) / 8 ) // pen has width, make bitmap bigger
76 #define NBYTES BPROW1 * ( YDOTS + MAX_WID ) // total number of bytes
77
78 // Graphics control characters.
79
80 #define ESC 0x1b
81 #define FF 0x0c
82
83 static char mask[8] =
84 { '\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001' };
85
86 #ifndef MSDOS
87 #define _HUGE
88 #else
89 #define _HUGE _huge
90 #endif
91
92 static unsigned char _HUGE *bitmap; // memory area NBYTES in size
93
94 void plD_dispatch_init_ljiip( PLDispatchTable *pdt )
95 {
96 #ifndef ENABLE_DYNDRIVERS
97 pdt->pl_MenuStr = "LaserJet IIp/deskjet compressed graphics";
98 pdt->pl_DevName = "ljiip";
99 #endif
100 pdt->pl_type = plDevType_FileOriented;
101 pdt->pl_seq = 32;
102 pdt->pl_init = (plD_init_fp) plD_init_ljiip;
103 pdt->pl_line = (plD_line_fp) plD_line_ljiip;
104 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_ljiip;
105 pdt->pl_eop = (plD_eop_fp) plD_eop_ljiip;
106 pdt->pl_bop = (plD_bop_fp) plD_bop_ljiip;
107 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_ljiip;
108 pdt->pl_state = (plD_state_fp) plD_state_ljiip;
109 pdt->pl_esc = (plD_esc_fp) plD_esc_ljiip;
110 }
111
112 //--------------------------------------------------------------------------
113 // plD_init_ljiip()
114 //
115 // Initialize device.
116 //--------------------------------------------------------------------------
117
118 void
119 plD_init_ljiip( PLStream *pls )
120 {
121 PLDev *dev;
122
123 if ( pls->width == 0 ) // Is 0 if uninitialized
124 pls->width = DPI / 100;
125
126 // Initialize family file info
127
128 plFamInit( pls );
129
130 // Prompt for a file name if not already set
131
132 plOpenFile( pls );
133
134 // Allocate and initialize device-specific data
135
136 dev = plAllocDev( pls );
137
138 dev->xold = PL_UNDEFINED;
139 dev->yold = PL_UNDEFINED;
140 dev->xmin = 0;
141 dev->ymin = 0;
142
143 // number of pixels / mm
144
145 plP_setpxl( (PLFLT) ( DPI / 25.4 ), (PLFLT) ( DPI / 25.4 ) );
146
147 // Rotate by 90 degrees since portrait mode addressing is used
148
149 dev->xmin = 0;
150 dev->ymin = 0;
151 dev->xmax = JETY;
152 dev->ymax = JETX;
153 dev->xlen = dev->xmax - dev->xmin;
154 dev->ylen = dev->ymax - dev->ymin;
155
156 plP_setphy( dev->xmin, dev->xmax, dev->ymin, dev->ymax );
157
158 // If portrait mode is specified, then set up an additional rotation
159 // transformation with aspect ratio allowed to adjust via freeaspect.
160 // Default orientation is landscape (ORIENTATION == 3 or 90 deg rotation
161 // counter-clockwise from portrait). (Legacy PLplot used seascape
162 // which was equivalent to ORIENTATION == 1 or 90 deg clockwise rotation
163 // from portrait.)
164
165 if ( pls->portrait )
166 {
167 plsdiori( (PLFLT) ( 4 - ORIENTATION ) );
168 pls->freeaspect = 1;
169 }
170
171 // Allocate storage for bit map matrix
172
173 #ifdef MSDOS
174 if ( ( bitmap = (unsigned char _HUGE *)
175 halloc( (long) NBYTES, sizeof ( char ) ) ) == NULL )
176 plexit( "Out of memory in call to calloc" );
177 #else
178 if ( ( bitmap = (unsigned char *) calloc( NBYTES, sizeof ( char ) ) ) == NULL )
179 plexit( "Out of memory in call to calloc" );
180 #endif
181
182 // Reset Printer
183
184 fprintf( OF, "%cE", ESC );
185 }
186
187 //--------------------------------------------------------------------------
188 // plD_line_ljiip()
189 //
190 // Draw a line in the current color from (x1,y1) to (x2,y2).
191 //--------------------------------------------------------------------------
192
193 void
194 plD_line_ljiip( PLStream *pls, short x1a, short y1a, short x2a, short y2a )
195 {
196 PLDev *dev = (PLDev *) pls->dev;
197 int x1 = x1a, y1 = y1a, x2 = x2a, y2 = y2a;
198 int abs_dx, abs_dy, dx, dy, incx, incy;
199 int i, j, width, residual;
200 PLFLT tmp;
201
202 width = MIN( pls->width, MAX_WID );
203
204 // Take mirror image, since PCL expects (0,0) to be at top left
205
206 y1 = dev->ymax - ( y1 - dev->ymin );
207 y2 = dev->ymax - ( y2 - dev->ymin );
208
209 // Rotate by 90 degrees
210
211 plRotPhy( ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x1, &y1 );
212 plRotPhy( ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x2, &y2 );
213
214 dx = x2 - x1;
215 dy = y2 - y1;
216
217 if ( dx < 0 )
218 {
219 abs_dx = -dx;
220 incx = -1;
221 }
222 else
223 {
224 abs_dx = dx;
225 incx = 1;
226 }
227 if ( dy < 0 )
228 {
229 abs_dy = -dy;
230 incy = -1;
231 }
232 else
233 {
234 abs_dy = dy;
235 incy = 1;
236 }
237
238 // make pixel width narrower for diag lines
239
240 if ( abs_dy <= abs_dx )
241 {
242 if ( abs_dx == 0 )
243 tmp = 1.0;
244 else
245 tmp = 1.0 - (PLFLT) abs_dy / abs_dx;
246 }
247 else
248 {
249 tmp = 1.0 - (PLFLT) abs_dx / abs_dy;
250 }
251
252 width = floor( 0.5 + width * ( tmp * tmp * tmp * ( 1.0 - 0.707107 ) + 0.707107 ) );
253
254 if ( width < 1 )
255 width = 1;
256 if ( width > 1 )
257 {
258 for ( i = 0; i < width; i++ )
259 {
260 for ( j = 0; j < width; j++ )
261 {
262 setpoint( (PLINT) ( x1 + i ), (PLINT) ( y1 + j ) );
263 setpoint( (PLINT) ( x2 + i ), (PLINT) ( y2 + j ) );
264 }
265 }
266 }
267 if ( abs_dx >= abs_dy )
268 {
269 residual = -( abs_dx >> 1 );
270 if ( width == 1 )
271 {
272 for ( i = 0; i <= abs_dx; i++, x1 += incx )
273 {
274 setpoint( (PLINT) ( x1 ), (PLINT) ( y1 ) );
275 if ( ( residual += abs_dy ) >= 0 )
276 {
277 residual -= abs_dx;
278 y1 += incy;
279 }
280 }
281 }
282 else
283 {
284 for ( i = 0; i <= abs_dx; i++, x1 += incx )
285 {
286 for ( j = 0; j < width; j++ )
287 {
288 setpoint( (PLINT) ( x1 ), (PLINT) ( y1 + j ) );
289 setpoint( (PLINT) ( x1 + width - 1 ), (PLINT) ( y1 + j ) );
290 }
291 if ( ( residual += abs_dy ) >= 0 )
292 {
293 residual -= abs_dx;
294 y1 += incy;
295 }
296 }
297 }
298 }
299 else
300 {
301 residual = -( abs_dy >> 1 );
302 if ( width == 1 )
303 {
304 for ( i = 0; i <= abs_dy; i++, y1 += incy )
305 {
306 setpoint( (PLINT) ( x1 ), (PLINT) ( y1 ) );
307 if ( ( residual += abs_dx ) >= 0 )
308 {
309 residual -= abs_dy;
310 x1 += incx;
311 }
312 }
313 }
314 else
315 {
316 for ( i = 0; i <= abs_dy; i++, y1 += incy )
317 {
318 for ( j = 0; j < width; j++ )
319 {
320 setpoint( (PLINT) ( x1 + j ), (PLINT) ( y1 ) );
321 setpoint( (PLINT) ( x1 + j ), (PLINT) ( y1 + width - 1 ) );
322 }
323 if ( ( residual += abs_dx ) >= 0 )
324 {
325 residual -= abs_dy;
326 x1 += incx;
327 }
328 }
329 }
330 }
331 }
332
333 //--------------------------------------------------------------------------
334 // plD_polyline_ljiip()
335 //
336 // Draw a polyline in the current color.
337 //--------------------------------------------------------------------------
338
339 void
340 plD_polyline_ljiip( PLStream *pls, short *xa, short *ya, PLINT npts )
341 {
342 PLINT i;
343
344 for ( i = 0; i < npts - 1; i++ )
345 plD_line_ljiip( pls, xa[i], ya[i], xa[i + 1], ya[i + 1] );
346 }
347
348 //--------------------------------------------------------------------------
349 // plD_eop_ljiip()
350 //
351 // End of page.(prints it here).
352 //--------------------------------------------------------------------------
353
354 void
355 plD_eop_ljiip( PLStream *pls )
356 {
357 PLINT j;
358 unsigned char _HUGE *p;
359 #if GCMODE > 0
360 int i, iy, last, n, jmax;
361 unsigned char _HUGE t_buf[BPROW * 2];
362 unsigned char c;
363 #endif
364
365 // PCL III setup: ref. Deskjet Plus Printer Owner's Manual
366
367 fprintf( OF, "\033*rB" ); // end raster graphics
368 fprintf( OF, "\033*t%3dR", DPI ); // set DPI
369
370 #if GCMODE != 0
371 fprintf( OF, "\033*r%dS", XDOTS ); // raster width
372 fprintf( OF, "\033*b%1dM", GCMODE ); // graphics mode
373 #endif
374
375 // First move cursor to origin
376
377 fprintf( OF, "\033*p%ldX", CURX );
378 fprintf( OF, "\033*p%ldY", CURY );
379 fprintf( OF, "\033*r0A" ); // start graphics
380
381 // Write out raster data
382
383 #if GCMODE == 0
384 for ( j = 0, p = bitmap; j < YDOTS; j++, p += BPROW1 )
385 {
386 fprintf( OF, "\033*b>%dW", BPROW );
387 fwrite( p, BPROW, sizeof ( char ), OF );
388 }
389 #endif
390 #if GCMODE == 2
391 for ( iy = 0, p = bitmap; iy < YDOTS; iy++, p += BPROW1 )
392 {
393 // find last non-zero byte
394
395 last = BPROW - 1;
396 while ( last > 0 && p[last] == 0 )
397 last--;
398 last++;
399
400 // translate to mode 2, save results in t_buf[]
401
402 i = n = 0;
403 while ( i < last )
404 {
405 c = p[i];
406 jmax = i + 127;
407 jmax = last < jmax ? last : jmax;
408 if ( i < last - 2 && ( c == p[i + 1] ) && ( c == p[i + 2] ) )
409 {
410 j = i + 3;
411 while ( j < jmax && c == p[j] )
412 j++;
413 t_buf[n++] = ( i - j + 1 ) & 0xff;
414 t_buf[n++] = c;
415 i = j;
416 }
417 else
418 {
419 for ( j = i + 1; j < jmax; j++ )
420 {
421 if ( j < last - 2 && ( p[j] == p[j + 1] ) &&
422 ( p[j + 1] == p[j + 2] ) )
423 break;
424 }
425 t_buf[n++] = j - i - 1;
426 while ( i < j )
427 {
428 t_buf[n++] = p[i++];
429 }
430 }
431 }
432 fprintf( OF, "\033*b%dW", (int) n );
433 fwrite( t_buf, (int) n, sizeof ( char ), OF );
434 }
435 #endif
436
437 pls->bytecnt += NBYTES;
438
439 // End raster graphics and send Form Feed
440
441 fprintf( OF, "\033*rB" );
442 fprintf( OF, "%c", FF );
443
444 // Finally, clear out bitmap storage area
445
446 memset( (void *) bitmap, '\0', NBYTES );
447 }
448
449 //--------------------------------------------------------------------------
450 // plD_bop_ljiip()
451 //
452 // Set up for the next page.
453 // Advance to next family file if necessary (file output).
454 //--------------------------------------------------------------------------
455
456 void
457 plD_bop_ljiip( PLStream *pls )
458 {
459 if ( !pls->termin )
460 plGetFam( pls );
461
462 pls->page++;
463 }
464
465 //--------------------------------------------------------------------------
466 // plD_tidy_ljiip()
467 //
468 // Close graphics file or otherwise clean up.
469 //--------------------------------------------------------------------------
470
471 void
472 plD_tidy_ljiip( PLStream *pls )
473 {
474 // Reset Printer
475
476 fprintf( OF, "%cE", ESC );
477 plCloseFile( pls );
478 free( (char *) bitmap );
479 }
480
481 //--------------------------------------------------------------------------
482 // plD_state_ljiip()
483 //
484 // Handle change in PLStream state (color, pen width, fill attribute, etc).
485 //--------------------------------------------------------------------------
486
487 void
488 plD_state_ljiip( PLStream *pls, PLINT op )
489 {
490 }
491
492 //--------------------------------------------------------------------------
493 // plD_esc_ljiip()
494 //
495 // Escape function.
496 //--------------------------------------------------------------------------
497
498 void
499 plD_esc_ljiip( PLStream *pls, PLINT op, void *ptr )
500 {
501 }
502
503 //--------------------------------------------------------------------------
504 // setpoint()
505 //
506 // Sets a bit in the bitmap.
507 //--------------------------------------------------------------------------
508
509 static void
510 setpoint( PLINT x, PLINT y )
511 {
512 PLINT index;
513 index = x / 8 + y * BPROW1;
514 *( bitmap + index ) = *( bitmap + index ) | mask[x % 8];
515 }
516
517 #else
518 int
519 pldummy_ljiip()
520 {
521 return 0;
522 }
523
524 #endif // PLD_ljii