/usr/bin/gnuplot symlinks packageing problems were fixed gor gnuplot-x11
[gnuplot] / term / imagen.trm
1 /* Hello, Emacs, this is -*-C-*-
2  * $Id: imagen.trm,v 1.20 2006/07/21 02:35:47 sfeam Exp $
3  */
4
5 /* GNUPLOT - imagen.trm */
6
7 /*[
8  * Copyright 1990 - 1993, 1998, 2004
9  *
10  * Permission to use, copy, and distribute this software and its
11  * documentation for any purpose with or without fee is hereby granted,
12  * provided that the above copyright notice appear in all copies and
13  * that both that copyright notice and this permission notice appear
14  * in supporting documentation.
15  *
16  * Permission to modify the software is granted, but not the right to
17  * distribute the complete modified source code.  Modifications are to
18  * be distributed as patches to the released version.  Permission to
19  * distribute binaries produced by compiling modified sources is granted,
20  * provided you
21  *   1. distribute the corresponding source modifications from the
22  *    released version in the form of a patch file along with the binaries,
23  *   2. add special version identification to distinguish your version
24  *    in addition to the base release version number,
25  *   3. provide your name and address as the primary contact for the
26  *    support of your modified version, and
27  *   4. retain our contact information in regard to use of the base
28  *    software.
29  * Permission to distribute the released version of the source code along
30  * with corresponding source modifications in the form of a patch file is
31  * granted with same provisions 2 through 4 for binary distributions.
32  *
33  * This software is provided "as is" without express or implied warranty
34  * to the extent permitted by applicable law.
35 ]*/
36
37 /*
38  * This file is included by ../term.c.
39  *
40  * This terminal driver supports:
41  *   Imagen laser printers
42  *
43  * AUTHORS
44  *   Paul E. McKenney, David Kotz
45  *   Rewritten/extended by:
46  *      Hans Olav Eggestad
47  * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
48  *
49  */
50
51 /*
52  * Original for direct Imagen output (but retaining many of the
53  * LaTeX extensions) by Paul E. McKenney, 1989.
54  * Further modified by David Kotz to fit into gnuplot 2.0.
55  * Information Science and Technology Division, SRI International,
56  * 333 Ravenswood Ave, Menlo Park, CA 94025.
57  * Mail to mckenney@sri.com.
58  */
59 /*
60  * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
61  */
62
63 #include "driver.h"
64
65 #ifdef TERM_REGISTER
66 register_term(imagen)
67 #endif
68
69 #ifdef TERM_PROTO
70 TERM_PUBLIC void IMAGEN_init __PROTO((void));
71 TERM_PUBLIC void IMAGEN_graphics __PROTO((void));
72 TERM_PUBLIC void IMAGEN_options __PROTO((void));
73 TERM_PUBLIC void IMAGEN_text __PROTO((void));
74 TERM_PUBLIC void IMAGEN_linetype __PROTO((int lt));
75 TERM_PUBLIC void IMAGEN_move __PROTO((unsigned int x, unsigned int y));
76 TERM_PUBLIC void IMAGEN_vector __PROTO((unsigned int ux, unsigned int uy));
77 TERM_PUBLIC int IMAGEN_text_angle __PROTO((int ang));
78 TERM_PUBLIC int IMAGEN_justify_text __PROTO((enum JUSTIFY mode));
79 TERM_PUBLIC void IMAGEN_put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
80 TERM_PUBLIC void IMAGEN_reset __PROTO((void));
81 #define IMAGEN_PTS_PER_INCH (300)
82 #define IMAGEN_XMAX (IMAGEN_PTS_PER_INCH * 11)  /* 10.0 inches */
83 #define IMAGEN_YMAX (IMAGEN_PTS_PER_INCH * 78 / 10)     /* 7.5 inches */
84 #define IMAGEN_HTIC (20)
85 #define IMAGEN_VTIC (20)
86 #define IMAGEN_VCHAR (IMAGEN_FONTSIZE*5)
87 #define IMAGEN_HCHAR (IMAGEN_VCHAR/2)
88 #endif /* TERM_PROTO */
89
90 #ifndef TERM_PROTO_ONLY
91 #ifdef TERM_BODY
92
93 static void IM_page __PROTO((void));
94 static void IMAGEN_draw_path __PROTO((void));
95 static void IMAGEN_setpos __PROTO((int ux, int uy));
96 static unsigned char *IMAGEN_cvts __PROTO((unsigned char *str, int *width, int *height));
97 static void IMAGEN_putwd __PROTO((unsigned int w));
98 static void IMAGEN_createfamily __PROTO((char *c, int sz));
99 static void IMAGEN_setfont __PROTO((int sz));
100 static void IMP_set_draw_pattern __PROTO((int pattern, int sz));
101 static void IMAGEN_mapsinit __PROTO((void));
102 static void IMAGEN_createmap __PROTO((int name, unsigned short *map));
103
104
105 /*
106 #ifndef __malloc_h
107 #include <malloc.h>
108 #endif
109 */
110 #include "impcodes.h"
111
112 /* default is landscape */
113 #define IMAGEN_A4_H  (IMAGEN_PTS_PER_INCH * 83 / 10)
114 #define IMAGEN_A4_W  (IMAGEN_PTS_PER_INCH * 116 / 10)
115
116 /* width in current orientation */
117 static int IMAGEN_Xmax = IMAGEN_XMAX;
118 static int IMAGEN_Ymax = IMAGEN_YMAX;
119
120 #define IMAGEN_FONTSIZE 12
121 #define IMAGEN_FONT "cour"
122
123
124 static unsigned short IMP_gmap[128];
125 static unsigned char IMP_chmap[256];
126
127 static int IMAGEN_page_h = IMAGEN_A4_H;
128 static int IMAGEN_page_w = IMAGEN_A4_W;
129 static int IM_win_horiz = 1;
130 static int IM_win_verti = 1;
131 static int IM_plot_nr = 0;
132
133 static int IMAGEN_fontsize = IMAGEN_FONTSIZE;
134 static int IMAGEN_familytable[36];
135 static int IMAGEN_orgX;         /* absolute-pixel-ORIgin of graph page. */
136 static int IMAGEN_orgY;
137 static int IMAGEN_orgx;         /* absolute-pixel-ORIgin of current graph. */
138 static int IMAGEN_orgy;
139 static int IMAGEN_posx;         /* current drawing position (lines).    */
140 static int IMAGEN_posy;
141 /* static int IMAGEN_inplot; */
142 static int IMAGEN_xmax = IMAGEN_XMAX;   /* width of graph in pixels.    */
143 static int IMAGEN_ymax = IMAGEN_YMAX;   /* height of graph in pixels.   */
144 static int IMAGEN_winx = IMAGEN_XMAX;   /* width of window in pixels.   */
145 static int IMAGEN_winy = IMAGEN_YMAX;   /* height of window in pixels.  */
146 static int IMAGEN_hchar;        /* Height of CHAR in current font.      */
147 static int IMAGEN_wchar;        /* Width of CHAR in current font.       */
148 static int IMAGEN_blofs;        /* BaseLine OFfSet from bounding box.   */
149 static int IMAGEN_angle = -1;   /* 0 for horizontal text, 1 for vertical */
150 static int IMAGEN_portrait;     /* 0 for landscape */
151 static enum JUSTIFY IMAGEN_justify = LEFT;      /* left/center/right */
152
153 #define STOREPATH 100
154 static unsigned int IM_xvector[STOREPATH]; /* draw path vector of x values */
155 static unsigned int IM_yvector[STOREPATH]; /* draw path vector of y values */
156 static unsigned int IM_veclen;  /* length of allocated path vector */
157 static unsigned int IM_vecpos = 0; /* current pos in vector */
158
159 /* char IMPdrpattern[10][10] = { {0}, {30,10,0}, {0}, {10,30,0}, {2,20,0},
160         {20,10,0}, {30,20,10,20,0}, {30,20,4,10,10,10,4,20,0}, {40,20,0}, {30,15,4,15,0}
161 };
162 */
163
164 static char IMPdrpattern[10][10] =
165 {
166 /* -2 */ {0},
167 /* -1 */ {1, 8, 0},
168 /*  0 */ {0},
169 /*  1 */ {16, 4, 0},
170 /*  2 */ {3, 8, 0},
171 /*  3 */ {8, 8, 0},
172 /*  4 */ {16, 6, 3, 6, 0},
173 /*  5 */ {16, 6, 8, 6, 0},
174 /*  6 */ {16, 4, 1, 4, 8, 4, 1, 4, 0},
175 /*  7 */ {16, 4, 1, 8, 1, 4, 0}
176 };
177
178 enum IMAGEN_id { IMAGEN_PORTRAIT, IMAGEN_LANDSCAPE, IMAGEN_OTHER };
179
180 static struct gen_table IMAGEN_opts[] =
181 {
182     { "p$ortrait", IMAGEN_PORTRAIT },
183     { "l$andscape", IMAGEN_LANDSCAPE },
184     { NULL, IMAGEN_OTHER }
185 };
186
187 TERM_PUBLIC void
188 IMAGEN_options()
189 {
190     struct value a;
191
192     while (!END_OF_COMMAND) {
193         switch(lookup_table(&IMAGEN_opts[0],c_token)) {
194         case IMAGEN_PORTRAIT:
195             IMAGEN_portrait = TRUE;
196             IMAGEN_page_h = IMAGEN_A4_W;
197             IMAGEN_page_w = IMAGEN_A4_H;
198             IMAGEN_Xmax = IMAGEN_YMAX;
199             IMAGEN_Ymax = IMAGEN_XMAX;
200             c_token++;
201             break;
202         case IMAGEN_LANDSCAPE:
203             IMAGEN_portrait = FALSE;
204             c_token++;
205             break;
206         case IMAGEN_OTHER:
207         default:
208             if (equals(c_token, "[")) { /* windows spesified */
209                 c_token++;
210                 /* if (IM_plot_nr>1) */
211                 if (equals(c_token, "]")) {
212                     IM_page();
213                     c_token++;
214                     break;
215                 }
216                 if (END_OF_COMMAND) {
217                     int_error(c_token, "no. windows: [horizontal,vertical] expected");
218                 } else if (!equals(c_token, ",")) {
219                     IM_win_horiz = (int) real(const_express(&a));
220                 }
221                 if (!equals(c_token, ","))
222                     int_error(c_token, "',' expected");
223                 c_token++;
224                 if (!equals(c_token, "]")) {
225                     IM_win_verti = (int) real(const_express(&a));
226                 }
227                 if (!equals(c_token, "]"))
228                     int_error(c_token, "expecting ']'");
229                 c_token++;
230             } else {
231                 /* We have font size specified */
232                 IMAGEN_fontsize = (int) real(const_express(&a));
233                 if (IMAGEN_fontsize < 8)
234                     IMAGEN_fontsize = 8;
235                 if (IMAGEN_fontsize > 15)
236                     IMAGEN_fontsize = 15;
237             }
238         }
239     }
240     sprintf(term_options, "%d %s [%1d,%1d]", IMAGEN_fontsize, (IMAGEN_portrait) ? "portrait" :
241             "landscape", IM_win_horiz, IM_win_verti);
242 }
243
244
245 TERM_PUBLIC void
246 IMAGEN_init()
247 {
248     register struct termentry *t = term;
249     /* char font[10];   */  /* font name */
250
251     IMAGEN_posx = IMAGEN_posy = 0;
252
253     IMAGEN_orgX = (IMAGEN_page_w - IMAGEN_Xmax) / 2;
254     IMAGEN_orgY = (IMAGEN_page_h - IMAGEN_Ymax) / 2;
255
256     IMAGEN_xmax = IMAGEN_winx = (int) (IMAGEN_Xmax / IM_win_horiz);
257     IMAGEN_ymax = IMAGEN_winy = (int) (IMAGEN_Ymax / IM_win_verti);
258
259     t->xmax = (unsigned int) (IMAGEN_xmax);
260     t->ymax = (unsigned int) (IMAGEN_ymax);
261
262     fputs("@document(language impress, paper a4)", gpoutfile);
263
264     if (IMAGEN_portrait) {
265         putc(imP_SET_ABS_V, gpoutfile);
266         IMAGEN_putwd(3520);
267     }
268     putc(imP_SET_HV_SYSTEM, gpoutfile);
269     putc(((IMAGEN_portrait ? 3 : 0) << 5) | (3 << 3) | (IMAGEN_portrait ? 0 : 5), gpoutfile);
270
271     /* sprintf(font, "cour%02d", IMAGEN_FONTSIZE); */
272     IMAGEN_mapsinit();
273     IMAGEN_createmap(1, IMP_gmap);
274     /* IMAGEN_createfamily(font, IMAGEN_FONTSIZE); */
275     IMAGEN_setfont(IMAGEN_fontsize);
276
277     IMAGEN_text_angle(0);
278
279     putc(imP_SET_ABS_H, gpoutfile);
280     IMAGEN_putwd(0);
281     putc(imP_SET_ABS_V, gpoutfile);
282     IMAGEN_putwd(0);
283
284     IMAGEN_linetype(LT_AXIS);
285     /*
286        if ((IM_xvector = (unsigned int *) malloc(STOREPATH*sizeof(int))) == NULL) {
287        fputs("Imagendriver: Unable to allocate memory for draw path\n", stderr);
288        exit(1);
289        }
290        if ((IM_yvector = (unsigned int *) malloc(STOREPATH*sizeof(int))) == NULL) {
291        fputs("Imagendriver: Unable to allocate memory for draw path\n", stderr);
292        exit(1);
293        }
294      */
295     IM_veclen = STOREPATH;
296     IM_vecpos = 0;
297 }
298
299 static void
300 IM_page()
301 {
302     if (IM_vecpos) {
303         /* fprintf(stderr,"graphics, draw path\n"); */
304         IMAGEN_draw_path();
305     }
306     putc(imP_ENDPAGE, gpoutfile);
307 }
308
309 TERM_PUBLIC void
310 IMAGEN_graphics()
311 {
312     int tmpx, tmpy;
313 /*    int xoff, yoff; */
314
315     if (IM_vecpos) {
316         /* fprintf(stderr,"graphics, draw path\n"); */
317         IMAGEN_draw_path();
318     }
319     if (IM_plot_nr >= (IM_win_horiz * IM_win_verti)) {
320         IM_page();
321         IM_plot_nr = 0;
322     }
323     IM_plot_nr++;
324     tmpx = IMAGEN_orgX + ((IM_plot_nr - 1) % IM_win_horiz) * IMAGEN_winx;
325     tmpy = IMAGEN_orgY + ((IM_win_verti - 1) - (int) ((IM_plot_nr - 1) / IM_win_horiz)) * IMAGEN_winy;
326     IMAGEN_orgx = tmpx + (int) ((IMAGEN_winx - IMAGEN_xmax) / 2);
327     IMAGEN_orgy = tmpy + (int) ((IMAGEN_winy - IMAGEN_ymax) / 2);
328 }
329
330
331 TERM_PUBLIC void
332 IMAGEN_text()
333 {
334 }
335
336
337 #define DRAW_PATTERNS 6
338
339
340 TERM_PUBLIC void
341 IMAGEN_linetype(int lt)
342 {
343     static int lastlinetype = -10;
344     int pen /*, pattern */ ;
345
346     if (IM_vecpos) {
347         /* fprintf(stderr,"move, draw path\n"); */
348         IMAGEN_draw_path();
349     }
350
351     if (lt < -2)
352         lt = LT_BLACK;
353
354     if (lt == LT_BLACK) {
355         pen = 4;
356     } else {
357         pen = (int) (lt / 8) * 2;
358         if (pen <= 0)
359             pen = 1;
360     }
361     lt = (lt % 8) + 2;
362
363     if (lastlinetype == lt)
364         return;
365
366     lastlinetype = lt;
367
368     putc(imP_SET_PEN, gpoutfile);
369     putc(pen, gpoutfile);
370     IMP_set_draw_pattern(lt, pen);
371 }
372
373
374 TERM_PUBLIC void
375 IMAGEN_move(unsigned int x, unsigned int y)
376 {
377     if (IM_vecpos) {
378         /* fprintf(stderr,"move, draw path\n"); */
379         IMAGEN_draw_path();
380     }
381     IM_xvector[0] = x + IMAGEN_orgx;
382     IM_yvector[0] = y + IMAGEN_orgy;
383     /* fprintf(stderr,"Ny vector: startpos: %1d %1d\n",IM_xvector[0],IM_yvector[0]); */
384     IM_vecpos = 1;
385     /*
386        IMAGEN_posx = x;
387        IMAGEN_posy = y;
388      */
389 }
390
391 TERM_PUBLIC void
392 IMAGEN_vector(unsigned int ux, unsigned int uy)
393 {
394     /* void IMAGEN_draw_path(); */
395
396     /* Store path. */
397     IM_xvector[IM_vecpos] = ux + IMAGEN_orgx;
398     IM_yvector[IM_vecpos] = uy + IMAGEN_orgy;
399     /* fprintf(stderr,"Ny node: nr: %1d; %1d %1d\n",IM_vecpos,IM_xvector[IM_vecpos],IM_yvector[IM_vecpos]);  */
400     IM_vecpos++;
401     if (IM_vecpos >= IM_veclen) {
402         IMAGEN_draw_path();
403         IM_xvector[0] = ux + IMAGEN_orgx;
404         IM_yvector[0] = uy + IMAGEN_orgy;
405         IM_vecpos = 1;
406     }
407 }
408
409 static void
410 IMAGEN_draw_path()
411 {
412 /*    unsigned int pos; */
413     register int i;
414
415     putc(imP_CREATE_PATH, gpoutfile);
416     IMAGEN_putwd(IM_vecpos);
417     for (i = 0; i < IM_vecpos; i++) {
418         /*
419            IMAGEN_putwd(IM_xvector[i] + IMAGEN_orgx);
420            IMAGEN_putwd(IM_yvector[i] + IMAGEN_orgy);
421          */
422         IMAGEN_putwd(IM_xvector[i]);
423         IMAGEN_putwd(IM_yvector[i]);
424     }
425     IM_vecpos = 0;
426     /* Draw path with black pen. */
427
428     putc(imP_DRAW_PATH, gpoutfile);
429     putc(15, gpoutfile);
430
431     /* Set current position to end of line. */
432
433     /* IMAGEN_move(ux, uy); */
434 }
435
436 static void
437 IMAGEN_setpos(int ux, int uy)
438 {
439     /* Set x and y position (for text), also set beginning-of-line. */
440
441     putc(imP_SET_ABS_H, gpoutfile);
442     IMAGEN_putwd(ux + IMAGEN_orgx);
443     putc(imP_SET_ABS_V, gpoutfile);
444     IMAGEN_putwd(uy + IMAGEN_orgy);
445     putc(imP_SET_BOL, gpoutfile);
446     if (IMAGEN_angle == 1)
447         IMAGEN_putwd(uy + IMAGEN_orgx);         /* vertical */
448     else
449         IMAGEN_putwd(ux + IMAGEN_orgx);         /* horizontal */
450 }
451
452 TERM_PUBLIC int
453 IMAGEN_text_angle(int ang)
454 {
455     if (IM_vecpos) {
456         /* fprintf(stderr,"text_angle, draw path\n"); */
457         IMAGEN_draw_path();
458     }
459     if (IMAGEN_angle != ang) {
460         IMAGEN_angle = ang;     /* record for later use */
461         putc(imP_SET_ADV_DIRS, gpoutfile);
462         putc(ang == 0 ? 0 : 7, gpoutfile);      /* 0=>horiz : 7=>vert */
463     }
464     return (TRUE);
465 }
466
467 TERM_PUBLIC int
468 IMAGEN_justify_text(enum JUSTIFY mode)
469 {
470     if (IM_vecpos) {
471         /* fprintf(stderr,"justify_text, draw path\n"); */
472         IMAGEN_draw_path();
473     }
474     IMAGEN_justify = mode;
475     return (TRUE);
476 }
477
478 static unsigned char *
479 IMAGEN_cvts(unsigned char *str, int *width, int *height)
480 {
481     unsigned char *cp1;
482     unsigned char *cp2;
483     static unsigned char *buf = NULL;
484     int h;
485     int maxw;
486     int w;
487
488     /* Free up old buffer, if there is one, get a new one.  Since       */
489     /* all transformations shorten the string, get a buffer that is     */
490     /* the same size as the input string.                               */
491
492     if (buf != NULL)
493         (void) free(buf);
494     buf = (unsigned char *) gp_alloc(strlen((char *) str)+2, "converted label string");
495
496     /* Do the transformations. */
497
498     cp1 = str;
499     cp2 = buf;
500     h = 1;
501     maxw = 0;
502     w = 0;
503     while (strlen((char *) cp1) > 0) {
504         switch (*cp1) {
505         case ' ':               /* Space character. */
506             *cp2++ = imP_SP;
507             w++;
508             break;
509
510         case '\\':              /* Escape sequence. */
511             if (*++cp1 == '\\') {
512                 /* Begin new line. */
513                 h++;
514                 if (w > maxw)
515                     maxw = w;
516                 w = 0;
517                 *cp2++ = '\n';
518                 /* *cp2++ = imP_CRLF; */
519                 break;
520             }
521             /* Fall through to just copy next char out. */
522
523         default:
524             /* *cp2++ = *cp1; */
525             *cp2++ = IMP_chmap[*cp1];
526             w++;
527             break;
528         }
529         cp1++;
530     }
531
532     *cp2++ = '\n';
533     *cp2 = '\0';
534     if (w > maxw)
535         maxw = w;
536
537     if (height != NULL)
538         *height = IMAGEN_angle ?
539             IMAGEN_wchar * maxw :
540             IMAGEN_hchar * h;
541     if (width != NULL)
542         *width = IMAGEN_angle ?
543             IMAGEN_hchar * h :
544             IMAGEN_wchar * maxw;
545     return (buf);
546 }
547
548 TERM_PUBLIC void
549 IMAGEN_put_text(unsigned int x, unsigned int y, const char str[])
550 {
551     unsigned char *cvstr, *p;
552     int height;
553     int width;
554     int sx, sy;
555
556     if (IM_vecpos) {
557         /* fprintf(stderr,"put_text, draw path\n"); */
558         IMAGEN_draw_path();
559     }
560     cvstr = IMAGEN_cvts((unsigned char *) str, &width, &height);
561
562     if (IMAGEN_angle) {         /* vertical */
563         /* x += IMAGEN_hchar; */
564         x -= width / 2 - IMAGEN_hchar;
565         /* y -= height/2; */
566     } else                      /* horizontal */
567         y += height / 2 - IMAGEN_hchar;
568
569     while ((p = (unsigned char *) strchr((char *) cvstr, '\n'))) {
570         *p = '\0';
571         sx = x;
572         sy = y;
573         if (IMAGEN_angle)
574             sx = x - IMAGEN_blofs;
575         else
576             sy = y + IMAGEN_blofs;
577
578         width = strlen((char *) cvstr) * IMAGEN_wchar;
579
580         switch (IMAGEN_justify) {
581         case LEFT:
582             break;
583         case CENTRE:
584             if (IMAGEN_angle) {
585                 sy = y - width / 2;
586             } else {
587                 sx = x - width / 2;
588             }
589             break;
590             /*x -= width/2; break; */
591         case RIGHT:
592             if (IMAGEN_angle) {
593                 sy = y - width;
594             } else {
595                 sx = x - width;
596             }
597             break;
598             /* x -= width; break; */
599         }
600
601         IMAGEN_setpos(sx, sy);
602         fputs((char *) cvstr, gpoutfile);
603         cvstr = ++p;
604         if (IMAGEN_angle) {     /* vertical */
605             x += IMAGEN_hchar;
606         } else {
607             y -= IMAGEN_hchar;
608         }
609
610     }
611 }
612
613 TERM_PUBLIC void
614 IMAGEN_reset()
615 {
616     if (IM_vecpos) {
617         /* fprintf(stderr,"reset, draw path\n"); */
618         IMAGEN_draw_path();
619     }
620     putc(imP_EOF, gpoutfile);
621 }
622
623 static void
624 IMAGEN_putwd(unsigned int w)
625 {
626     /* fprintf(stderr,"%1u\n",w); */
627     putc(w >> 8, gpoutfile);
628     putc(w, gpoutfile);
629 }
630
631 static void
632 IMAGEN_createfamily(char *c, int sz)
633 {
634
635     putc(imP_CREATE_FAMILY_TABLE, gpoutfile);
636     putc(sz, gpoutfile);
637     putc(1, gpoutfile);
638     putc(1, gpoutfile);
639     /* putc(0, gpoutfile); */
640     fputs(c, gpoutfile);
641     putc(0, gpoutfile);
642 }
643
644 static void
645 IMAGEN_setfont(int sz)
646 {
647     char font[20];
648
649     if (!IMAGEN_familytable[sz]) {
650         sprintf(font, "%s%02d", IMAGEN_FONT, sz);
651         IMAGEN_createfamily(font, sz);
652         IMAGEN_familytable[sz] = sz;
653     }
654     IMAGEN_hchar = sz * 5;
655     IMAGEN_wchar = IMAGEN_hchar / 2;
656     IMAGEN_blofs = IMAGEN_hchar / 3;
657     term->v_char = IMAGEN_hchar;
658     term->h_char = IMAGEN_wchar;
659     putc(imP_SET_FAMILY, gpoutfile);
660     putc(sz, gpoutfile);
661     putc(imP_SET_SP, gpoutfile);
662     IMAGEN_putwd(IMAGEN_wchar);
663     putc(imP_SET_IL, gpoutfile);
664     IMAGEN_putwd(IMAGEN_hchar);
665 }
666
667 static void
668 IMP_set_draw_pattern(int pattern, int sz)
669 {
670     int i /*,j */ ;
671     putc(imP_SET_DRAW_PATTERN, gpoutfile);
672     putc(0, gpoutfile);
673     putc(imP_SET_DRAW_PATTERN, gpoutfile);
674     /* if ( strlen(IMPdrpattern[pattern]) == 1 ) {
675        putc(type,gpoutfile);
676        return;
677        } */
678     putc(strlen(IMPdrpattern[pattern]), gpoutfile);
679     for (i = 0; i < strlen(IMPdrpattern[pattern]); i++) {
680         IMAGEN_putwd(IMPdrpattern[pattern][i] * sz);
681     }
682 }
683
684
685 static void
686 IMAGEN_mapsinit()
687 {
688
689     register int i /*, j */ ;
690
691     for (i = 32; i < 127; i++) {
692         IMP_gmap[i] = i;
693     }
694     IMP_gmap[1] = 225;
695     IMP_gmap[2] = 233;
696     IMP_gmap[3] = 61736;
697     IMP_gmap[4] = 241;
698     IMP_gmap[5] = 249;
699     IMP_gmap[6] = 61864;
700     IMP_gmap[7] = 162;
701     IMP_gmap[8] = 163;
702     IMP_gmap[9] = 164;
703     IMP_gmap[10] = 165;
704     IMP_gmap[11] = 167;
705     IMP_gmap[12] = 171;
706     IMP_gmap[13] = 182;
707     IMP_gmap[14] = 61346;
708     IMP_gmap[15] = 191;
709     IMP_gmap[16] = 187;
710     IMP_gmap[17] = 188;
711     IMP_gmap[18] = 189;
712     IMP_gmap[19] = 190;
713     IMP_gmap[20] = 210;
714     IMP_gmap[21] = 211;
715     IMP_gmap[22] = 251;
716     IMP_gmap[23] = 61232;
717     IMP_gmap[24] = 212;
718     IMP_gmap[25] = 137;
719     IMP_gmap[26] = 176;
720     IMP_gmap[27] = 161;
721     IMP_gmap[28] = 139;
722     IMP_gmap[29] = 133;
723     IMP_gmap[30] = 140;
724     IMP_gmap[31] = 61249;
725     IMP_gmap[32] = 8738;
726     IMP_gmap[34] = 186;
727     IMP_gmap[36] = 164;
728     IMP_gmap[39] = 185;
729     IMP_gmap[127] = 61286;
730
731     /* for (i=1;i<127;i++) fprintf(stderr,"%d -> %d\n",i,IMP_gmap[i]); */
732
733     for (i = 32; i <= 127; i++) {
734         IMP_chmap[i] = i;
735     }
736     for (i = 128; i <= 255; i++) {
737         IMP_chmap[i] = 128;     /* first map all non printable chars to SPACE */
738     }
739
740     IMP_chmap[161] = 27;
741     IMP_chmap[162] = 7;
742     IMP_chmap[163] = 8;
743     IMP_chmap[164] = 120;
744     IMP_chmap[165] = 10;
745     IMP_chmap[166] = 124;
746     IMP_chmap[167] = 11;
747     IMP_chmap[168] = 25;
748     IMP_chmap[169] = 21;
749     IMP_chmap[170] = 45;
750     IMP_chmap[171] = 12;
751     IMP_chmap[172] = 83;
752     IMP_chmap[173] = 45;
753     IMP_chmap[174] = 20;
754     IMP_chmap[175] = 126;
755     IMP_chmap[176] = 26;
756     IMP_chmap[177] = 12;
757     IMP_chmap[178] = 1;
758     IMP_chmap[179] = 2;
759     IMP_chmap[180] = 29;
760     IMP_chmap[181] = 52;
761     IMP_chmap[182] = 13;
762     IMP_chmap[183] = 5;
763     IMP_chmap[184] = 28;
764     IMP_chmap[185] = 3;
765     IMP_chmap[186] = 45;
766     IMP_chmap[187] = 16;
767     IMP_chmap[188] = 17;
768     IMP_chmap[189] = 18;
769     IMP_chmap[190] = 19;
770     IMP_chmap[191] = 15;
771     IMP_chmap[192] = 65;
772     IMP_chmap[193] = 65;
773     IMP_chmap[194] = 65;
774     IMP_chmap[195] = 65;
775     IMP_chmap[196] = 65;
776     IMP_chmap[197] = 3;
777     IMP_chmap[198] = 1;
778     IMP_chmap[199] = 67;
779     IMP_chmap[200] = 69;
780     IMP_chmap[201] = 69;
781     IMP_chmap[202] = 69;
782     IMP_chmap[203] = 69;
783     IMP_chmap[204] = 73;
784     IMP_chmap[205] = 73;
785     IMP_chmap[206] = 73;
786     IMP_chmap[207] = 73;
787     IMP_chmap[208] = 68;
788     IMP_chmap[209] = 78;
789     IMP_chmap[210] = 79;
790     IMP_chmap[211] = 79;
791     IMP_chmap[212] = 79;
792     IMP_chmap[213] = 79;
793     IMP_chmap[214] = 79;
794     IMP_chmap[215] = 13;
795     IMP_chmap[216] = 2;
796     IMP_chmap[217] = 85;
797     IMP_chmap[218] = 85;
798     IMP_chmap[219] = 85;
799     IMP_chmap[220] = 85;
800     IMP_chmap[221] = 89;
801     IMP_chmap[222] = 32;
802     IMP_chmap[223] = 22;
803     IMP_chmap[224] = 97;
804     IMP_chmap[225] = 97;
805     IMP_chmap[226] = 97;
806     IMP_chmap[227] = 97;
807     IMP_chmap[228] = 97;
808     IMP_chmap[229] = 6;
809     IMP_chmap[230] = 4;
810     IMP_chmap[231] = 99;
811     IMP_chmap[232] = 101;
812     IMP_chmap[233] = 101;
813     IMP_chmap[234] = 101;
814     IMP_chmap[235] = 101;
815     IMP_chmap[236] = 105;
816     IMP_chmap[237] = 105;
817     IMP_chmap[238] = 105;
818     IMP_chmap[239] = 105;
819     IMP_chmap[240] = 100;
820     IMP_chmap[241] = 110;
821     IMP_chmap[242] = 111;
822     IMP_chmap[243] = 111;
823     IMP_chmap[244] = 111;
824     IMP_chmap[245] = 111;
825     IMP_chmap[246] = 111;
826     IMP_chmap[247] = 10;
827     IMP_chmap[248] = 5;
828     IMP_chmap[249] = 117;
829     IMP_chmap[250] = 117;
830     IMP_chmap[251] = 117;
831     IMP_chmap[252] = 117;
832     IMP_chmap[253] = 121;
833     IMP_chmap[254] = 32;
834     IMP_chmap[255] = 121;
835 }
836
837 static void
838 IMAGEN_createmap(int name, unsigned short *map)
839 {
840     register int i, j;
841     unsigned char s[4], *p;
842
843     p = s;
844     *p++ = imP_CREATE_MAP;
845     *p++ = name;
846     j = 0;
847     for (i = 0; i < 127; i++) {
848         if (map[i])
849             j++;
850     }
851     *p = j;
852     for (i = 0; i < 3; i++)
853         putc(s[i], gpoutfile);
854
855     s[3] = 1;
856     for (j = 0; j < 127; j++) {
857         if (map[j]) {
858             p = s;
859             *p++ = j;
860             *p++ = map[j] >> 8;
861             *p = map[j] & 255;
862             for (i = 0; i < 4; i++)
863                 putc(s[i], gpoutfile);
864         }
865     }
866 }
867
868 #endif /* TERM_BODY */
869
870 #ifdef TERM_TABLE
871
872 TERM_TABLE_START(imagen_driver)
873     "imagen", "Imagen laser printer",
874     IMAGEN_XMAX, IMAGEN_YMAX, IMAGEN_VCHAR, IMAGEN_HCHAR,
875     IMAGEN_VTIC, IMAGEN_HTIC, IMAGEN_options, IMAGEN_init, IMAGEN_reset,
876     IMAGEN_text, null_scale, IMAGEN_graphics, IMAGEN_move,
877     IMAGEN_vector, IMAGEN_linetype, IMAGEN_put_text, IMAGEN_text_angle,
878     IMAGEN_justify_text, line_and_point, do_arrow, set_font_null
879 TERM_TABLE_END(imagen_driver)
880
881 #undef LAST_TERM
882 #define LAST_TERM imagen_driver
883
884 #endif /* TERM_TABLE */
885 #endif /* TERM_PROTO_ONLY */
886
887 #ifdef TERM_HELP
888 START_HELP(imagen)
889 "1 imagen",
890 "?commands set terminal imagen",
891 "?set terminal imagen",
892 "?set term imagen",
893 "?terminal imagen",
894 "?term imagen",
895 "?imagen",
896 " The `imagen` terminal driver supports Imagen laser printers.  It is capable",
897 " of placing multiple graphs on a single page.",
898 "",
899 " Syntax:",
900 "       set terminal imagen {<fontsize>} {portrait | landscape}",
901 "                           {[<horiz>,<vert>]}",
902 "",
903 " where `fontsize` defaults to 12 points and the layout defaults to `landscape`.",
904 " `<horiz>` and `<vert>` are the number of graphs in the horizontal and",
905 " vertical directions; these default to unity.",
906 "",
907 " Example:",
908 "       set terminal imagen portrait [2,3]",
909 "",
910 " puts six graphs on the page in three rows of two in portrait orientation."
911 END_HELP(imagen)
912 #endif