Initial release of Maemo 5 port of gnuplot
[gnuplot] / term / hp500c.trm
1 /* Hello, Emacs, this is -*-C-*-
2  * $Id: hp500c.trm,v 1.17 2006/07/21 02:35:47 sfeam Exp $
3  *
4  */
5
6 /* GNUPLOT - hp500c.trm */
7
8 /*[
9  * Copyright 1990 - 1993, 1998, 2004
10  *
11  * Permission to use, copy, and distribute this software and its
12  * documentation for any purpose with or without fee is hereby granted,
13  * provided that the above copyright notice appear in all copies and
14  * that both that copyright notice and this permission notice appear
15  * in supporting documentation.
16  *
17  * Permission to modify the software is granted, but not the right to
18  * distribute the complete modified source code.  Modifications are to
19  * be distributed as patches to the released version.  Permission to
20  * distribute binaries produced by compiling modified sources is granted,
21  * provided you
22  *   1. distribute the corresponding source modifications from the
23  *    released version in the form of a patch file along with the binaries,
24  *   2. add special version identification to distinguish your version
25  *    in addition to the base release version number,
26  *   3. provide your name and address as the primary contact for the
27  *    support of your modified version, and
28  *   4. retain our contact information in regard to use of the base
29  *    software.
30  * Permission to distribute the released version of the source code along
31  * with corresponding source modifications in the form of a patch file is
32  * granted with same provisions 2 through 4 for binary distributions.
33  *
34  * This software is provided "as is" without express or implied warranty
35  * to the extent permitted by applicable law.
36 ]*/
37
38 /*
39  * This file is included by ../term.c.
40  *
41  * This terminal driver supports:
42  *  hpdj 500c
43  *
44  * AUTHORS
45  *  John Engels      -- \
46  *  Russell Lang     ----> HPLJII.trm
47  *  Maurice Castro   -- /
48  *  UdoHessenauer    ----> derived this version from the above one
49  *
50  * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
51  *
52  */
53
54 /* The following HP Deskjet500c  driver uses generic bit mapped graphics
55    routines from bitmap.c to build up a bit map in memory.  The driver
56    interchanges colomns and lines in order to access entire lines
57    easily and returns the lines to get bits in the right order :
58    (x,y) -> (y,XMAX-1-x). */
59 /* This interchange is done by calling b_makebitmap() with reversed
60    xmax and ymax, and then setting b_rastermode to TRUE.  b_setpixel()
61    will then perform the interchange before each pixel is plotted */
62 /* by John Engels JENGELS@BNANDP51.BITNET, inspired by the hpljet driver
63    of Jyrki Yli-Nokari */
64
65 /*
66  * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
67  */
68
69 #include "driver.h"
70
71 #ifdef TERM_REGISTER
72 register_term(hp500c)
73 #endif
74
75 #ifdef TERM_PROTO
76 TERM_PUBLIC void HP500C_options __PROTO((void));
77 TERM_PUBLIC void HP500C_init __PROTO((void));
78 TERM_PUBLIC void HP500C_reset __PROTO((void));
79 TERM_PUBLIC void HP500C_linetype __PROTO((int linetype));
80 TERM_PUBLIC void HP500C_graphics __PROTO((void));
81 TERM_PUBLIC void HP500C_text __PROTO((void));
82 /* default values for term_tbl */
83 #define HP500C_75PPI_XMAX (1920/4)
84 #define HP500C_75PPI_YMAX (1920/4)
85 #define HP500C_75PPI_HCHAR (1920/4/6)
86 #define HP500C_75PPI_VCHAR (1920/4/10)
87 #define HP500C_75PPI_VTIC 5
88 #define HP500C_75PPI_HTIC 5
89
90 #define GOT_HP500C_PROTO
91 #endif
92
93 #ifndef TERM_PROTO_ONLY
94 #ifdef TERM_BODY
95
96
97 /* We define 4 different print qualities : 300ppi, 150ppi, 100ppi and
98    75ppi.  (Pixel size = 1, 2, 3, 4 dots) */
99
100 #define HP500C_DPP (hpdj_dpp)   /* dots per pixel */
101 #define HP500C_PPI (300/HP500C_DPP)     /* pixel per inch */
102 /* make XMAX and YMAX a multiple of 8 */
103 #define HP500C_XMAX (8*(unsigned int)(xsize*1920/HP500C_DPP/8.0+0.9))
104 #define HP500C_YMAX (8*(unsigned int)(ysize*1920/HP500C_DPP/8.0+0.9))
105
106 /* Courier font with 6 lines per inch */
107 #define HP500C_VCHAR (HP500C_PPI/6)
108 /* Courier font with 10 caracters per inch */
109 #define HP500C_HCHAR (HP500C_PPI/10)
110
111
112 /* Save current cursor position */
113 #define HP500C_PUSH_CURSOR fputs("\033&f0S",gpoutfile)
114 /* Restore cursor position */
115 #define HP500C_POP_CURSOR fputs("\033&f1S",gpoutfile)
116
117 /* be sure to use courier font with 6lpi and 10cpi */
118 #define HP500C_COURIER fputs("\033(0N\033(s0p10.0h12.0v0s0b3T\033&l6D",gpoutfile)
119
120
121 static int HP_compress __PROTO((unsigned char *op, unsigned char *oe,
122                                unsigned char *cp));
123 static unsigned char HP_complement __PROTO((int c));
124 static int HP_compress_to_TIFF __PROTO((unsigned char *op, unsigned char *oe,
125                                        unsigned char *cp));
126 static int HP_nocompress __PROTO((unsigned char *op, unsigned char *oe,
127                                  unsigned char *cp));
128
129 static int hpdj_dpp = 4;
130 static int HP_COMP_MODE = 0;
131
132 /* bm_pattern not appropriate for 300ppi graphics */
133 #ifndef GOT_300_PATTERN
134 #define GOT_300_PATTERN
135 static unsigned int b_300ppi_pattern[] =
136 {
137     0xffff, 0x1111,
138     0xffff, 0x3333, 0x0f0f, 0x3f3f, 0x0fff, 0x00ff, 0x33ff
139 };
140 #endif
141
142
143 TERM_PUBLIC void
144 HP500C_options()
145 {
146     char opt[6];
147
148 #define HPDJCERROR "expecting dots per inch size 75, 100, 150 or 300 and/or compression method"
149     while (!END_OF_COMMAND) {
150         if (token[c_token].length > 4)
151             int_error(c_token, HPDJCERROR);
152
153         /* almost_equals() won't accept numbers - use strcmp() instead */
154         capture(opt, c_token, c_token, 6);
155         if (!strcmp(opt, "75")) {
156             hpdj_dpp = 4;
157             HP_COMP_MODE = 0;
158
159         } else if (!strcmp(opt, "100")) {
160             hpdj_dpp = 3;
161             HP_COMP_MODE = 0;
162         } else if (!strcmp(opt, "150")) {
163             hpdj_dpp = 2;
164             HP_COMP_MODE = 0;
165         } else if (!strcmp(opt, "300")) {
166             hpdj_dpp = 1;
167             HP_COMP_MODE = 0;
168         } else if (!strcmp(opt, "rle")) {
169             HP_COMP_MODE = 1;
170         } else if (!strcmp(opt, "tiff")) {
171             HP_COMP_MODE = 2;
172         }
173         c_token++;
174     }
175
176     term->xmax = HP500C_XMAX;
177     term->ymax = HP500C_YMAX;
178     switch (hpdj_dpp) {
179     case 1:
180         strcpy(term_options, "300");
181         term->v_tic = 15;
182         term->h_tic = 15;
183         break;
184     case 2:
185         strcpy(term_options, "150");
186         term->v_tic = 8;
187         term->h_tic = 8;
188         break;
189     case 3:
190         strcpy(term_options, "100");
191         term->v_tic = 6;
192         term->h_tic = 6;
193         break;
194     case 4:
195         strcpy(term_options, "75");
196         term->v_tic = 5;
197         term->h_tic = 5;
198         break;
199     }
200     switch (HP_COMP_MODE) {
201     case 0:
202         strcat(term_options, " no comp");
203         break;
204     case 1:
205         strcat(term_options, " RLE");
206         break;
207     case 2:
208         strcat(term_options, " TIFF");
209         break;
210     case 3:                     /* not implemented yet */
211         strcat(term_options, " Delta Row");
212         break;
213     }
214 }
215
216 TERM_PUBLIC void
217 HP500C_init()
218 {
219     /* HBB 980226: all changes to term-> fields *must* happen here, not
220      * in graphics() !*/
221     switch (hpdj_dpp) {
222     case 1:
223         b_charsize(FNT13X25);
224         term->v_char = FNT13X25_VCHAR;
225         term->h_char = FNT13X25_HCHAR;
226         break;
227     case 2:
228         b_charsize(FNT13X25);
229         term->v_char = FNT13X25_VCHAR;
230         term->h_char = FNT13X25_HCHAR;
231         break;
232     case 3:
233         b_charsize(FNT9X17);
234         term->v_char = FNT9X17_VCHAR;
235         term->h_char = FNT9X17_HCHAR;
236         break;
237     case 4:
238         b_charsize(FNT5X9);
239         term->v_char = FNT5X9_VCHAR;
240         term->h_char = FNT5X9_HCHAR;
241         break;
242     }
243 }
244
245 TERM_PUBLIC void
246 HP500C_reset()
247 {
248 #ifdef VMS
249     fflush_binary();
250 #endif
251 }
252
253
254
255 /* HP DeskJet 500c routines */
256
257 TERM_PUBLIC void
258 HP500C_linetype(int linetype)
259 {
260     if (linetype < 0)
261         linetype = 7;
262     else if (linetype >= 8) {
263         linetype %= 8;
264     }
265     switch (linetype) {
266     case 0:
267         linetype = 6;
268         break;
269     case 1:
270         linetype = 5;
271         break;
272     case 2:
273         linetype = 3;
274         break;
275     case 3:
276         linetype = 2;
277         break;
278     case 4:
279         linetype = 1;
280         break;
281     case 5:
282         linetype = 4;
283         break;
284     case 6:
285         linetype = 7;
286     }
287     b_setvalue(linetype);
288
289 }
290
291 #if 0
292 void
293 HP500C_point(unsigned int x, unsigned int y, int value)
294 {
295     HP500C_linetype(value);
296     do_point(x,y,value);
297 }
298 #endif
299
300 TERM_PUBLIC void
301 HP500C_graphics()
302 {
303     /* HBB 980226: moved block of code from here to init() */
304     /* rotate plot -90 degrees by reversing XMAX and YMAX and by
305        setting b_rastermode to TRUE */
306     b_makebitmap(HP500C_YMAX, HP500C_XMAX, 3);
307     b_rastermode = TRUE;
308 }
309
310 /*
311  * Run-length encoding for the DeskJet. We have pairs of <count>
312  * <what>, where count goes from 0 (meaning one count) to 255
313  * this might double the size of the image.
314  */
315
316 static int
317 HP_compress(unsigned char *op, unsigned char *oe, unsigned char *cp)
318 {
319     unsigned char *ce = cp;
320
321     while (op < oe) {
322         unsigned char prevchar;
323         unsigned char count;
324
325         prevchar = *op;         /* remember char */
326         count = 1;              /* its read the first time */
327
328         while (++op < oe && *op == prevchar && count < 255) {
329             /* set op to the next char */
330             count++;            /* and count it  */
331         }
332         *ce++ = --count;        /* were ready, so correct the count */
333         *ce++ = prevchar;       /* and store <what> */
334     }
335     *ce = 0;                    /* just to be safe   */
336     return ce - cp;             /* length of  cbufs */
337 }
338
339 static unsigned char
340 HP_complement(int c)
341 {
342     return (unsigned char) (256 - c);
343 }
344
345
346 static int
347 HP_compress_to_TIFF(
348     unsigned char *op,          /* original pointer */
349     unsigned char *oe,          /* end of orig string */
350     unsigned char *cp)          /* pointer for compressed data */
351 {
352     unsigned char *countposition;
353     unsigned char *ce = cp;
354
355     while (op < oe) {
356         unsigned char prevchar;
357         unsigned char count;
358
359         prevchar = *op;         /* gelesenes Zeichen aufbewaren */
360         count = 1;              /* bisher wurde es einmal gelesen */
361
362         while (++op < oe && *op == prevchar && count < 128) {
363             count++;
364         }
365         *ce = HP_complement(count - 1);
366         /* remember count for building blocks of literal bytes */
367         countposition = ce++;
368         *ce++ = prevchar;
369
370         if (count < 2) {
371             while (op < oe && (prevchar != *op || *op != *(op + 1))) {
372                 /* only use rle for at leat 3 equal bytes */
373                 *ce++ = *op;
374                 count++;
375                 prevchar = *op++;
376                 if (op > oe)
377                     puts("FATAL op> oe!!\n");
378             }
379             if (op < oe && prevchar == *op) {
380                 op--;
381                 count--;
382                 ce--;
383             }
384             *countposition = count - 1;
385         }
386     }
387     return ce - cp;
388
389 }
390
391 static int
392 HP_nocompress(
393     unsigned char *op,
394     unsigned char *oe,
395     unsigned char *cp)
396 {
397     unsigned char *ce = cp;
398
399     while (op < oe)
400         *ce++ = *op++;
401     return ce - cp;
402 }
403
404 /* 0 compression raster bitmap dump. Compatible with HP DeskJet 500
405    hopefully compatible with other HP Deskjet printers */
406
407 TERM_PUBLIC void
408 HP500C_text()
409 {
410     register int x, j, row, count = 0;
411     unsigned char *obuf, *oe, *cbuf, *ce;
412
413     if ((obuf = (unsigned char *) malloc(100 * b_psize)) == 0)
414         puts("FATAL!-- couldn't get enough memory for obuf");
415     if ((cbuf = (unsigned char *) malloc(400 * b_psize)) == 0)
416         puts("FATAL!-- couldn't get enough memory for cbuf");
417
418     oe = obuf;
419
420     fprintf(gpoutfile, "\
421 \033*t%dR\
422 \033*r1A\
423 \033*b%1dM\
424 \033*r%dS\
425 \033*r-3U",
426             HP500C_PPI,
427             HP_COMP_MODE,
428             b_ysize);
429
430     /* dump bitmap in raster mode */
431     for (x = b_xsize - 1; x >= 0; x--) {
432         row = (b_ysize / 8) - 1;
433         for (j = row; j >= 0; j--) {
434             *oe++ = (char) (*((*b_p)[j] + x));
435         }
436         switch (HP_COMP_MODE) {
437         case 2:
438             count = HP_compress_to_TIFF(obuf, oe, cbuf);
439             break;
440         case 1:
441             count = HP_compress(obuf, oe, cbuf);
442             break;
443         case 0:
444             count = HP_nocompress(obuf, oe, cbuf);
445             break;
446         }
447         fprintf(gpoutfile, "\033*b%dV", count);
448         ce = cbuf;
449         while (count--)
450             fputc(*ce++, gpoutfile);
451         oe = obuf;
452
453         for (j = row; j >= 0; j--) {
454             *oe++ = (char) (*((*b_p)[j + b_psize] + x));
455         }
456         switch (HP_COMP_MODE) {
457         case 2:
458             count = HP_compress_to_TIFF(obuf, oe, cbuf);
459             break;
460         case 1:
461             count = HP_compress(obuf, oe, cbuf);
462             break;
463         case 0:
464             count = HP_nocompress(obuf, oe, cbuf);
465             break;
466
467         }
468
469         fprintf(gpoutfile, "\033*b%dV", count);
470         ce = cbuf;
471         while (count--)
472             fputc(*ce++, gpoutfile);
473         oe = obuf;
474
475         for (j = row; j >= 0; j--) {
476             *oe++ = (char) (*((*b_p)[j + (2 * b_psize)] + x));
477         }
478         switch (HP_COMP_MODE) {
479         case 2:
480             count = HP_compress_to_TIFF(obuf, oe, cbuf);
481             break;
482         case 1:
483             count = HP_compress(obuf, oe, cbuf);
484             break;
485         case 0:
486             count = HP_nocompress(obuf, oe, cbuf);
487             break;
488         }
489         fprintf(gpoutfile, "\033*b%dW", count);
490         ce = cbuf;
491         while (count--)
492             fputc(*ce++, gpoutfile);
493         oe = obuf;
494
495     }
496     fputs("\033*rbC", gpoutfile);
497     free(cbuf);
498     free(obuf);
499     b_freebitmap();
500
501 #ifndef VMS
502     /* most vms spoolers add a formfeed character */
503     putc('\f', gpoutfile);
504 #endif /* !VMS */
505 }
506
507 #endif /* TERM_BODY */
508
509 #ifdef TERM_TABLE
510
511 TERM_TABLE_START(hp500c_driver)
512     "hp500c", "HP DeskJet 500c, [75 100 150 300] [rle tiff]",
513     HP500C_75PPI_XMAX, HP500C_75PPI_YMAX, HP500C_75PPI_VCHAR,
514     HP500C_75PPI_HCHAR, HP500C_75PPI_VTIC, HP500C_75PPI_HTIC, HP500C_options,
515     HP500C_init, HP500C_reset, HP500C_text, null_scale,
516     HP500C_graphics, b_move, b_vector, HP500C_linetype,
517     b_put_text, b_text_angle, null_justify_text, do_point,
518     do_arrow, set_font_null, 0, TERM_BINARY,
519     0, 0, b_boxfill
520 TERM_TABLE_END(hp500c_driver)
521
522 #undef LAST_TERM
523 #define LAST_TERM hp500c_driver
524
525 #endif /* TERM_TABLE */
526 #endif /* TERM_PROTO_ONLY */
527
528 #ifdef TERM_HELP
529 START_HELP(hp500c)
530 "1 hp500c",
531 "?commands set terminal hp500c",
532 "?set terminal hp500c",
533 "?set term hp500c",
534 "?terminal hp500c",
535 "?term hp500c",
536 "?hp500c",
537 " The `hp500c` terminal driver supports the Hewlett Packard HP DeskJet 500c.",
538 " It has options for resolution and compression.",
539 "",
540 " Syntax:",
541 "       set terminal hp500c {<res>} {<comp>}",
542 "",
543 " where `res` can be 75, 100, 150 or 300 dots per inch and `comp` can be \"rle\",",
544 " or \"tiff\".  Any other inputs are replaced by the defaults, which are 75 dpi",
545 " and no compression.  Rasterization at the higher resolutions may require a",
546 " large amount of memory."
547 END_HELP(hp500c)
548 #endif /* TERM_HELP */