1 /* Hello, Emacs, this is -*-C-*-
2 * $Id: dumb.trm,v 1.26.2.1 2008/08/16 18:11:53 sfeam Exp $
6 /* GNUPLOT - dumb.trm */
9 * Copyright 1991 - 1993, 1998, 2004 Thomas Williams, Colin Kelley
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.
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,
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
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.
34 * This software is provided "as is" without express or implied warranty
35 * to the extent permitted by applicable law.
39 * This file is included by ../term.c.
41 * This terminal driver supports:
45 * Francois Pinard, 91-04-03
46 * INTERNET: pinard@iro.umontreal.ca
48 * Ethan A Merritt Nov 2003
49 * Added support for enhanced text mode.
50 * Yes, this is frivolous, but it serves as an example for
51 * adding enhanced text to other terminals. You can disable
53 * #define NO_DUMB_ENHANCED_SUPPORT
55 * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
61 register_term(dumb_driver)
65 TERM_PUBLIC void DUMB_options __PROTO((void));
66 TERM_PUBLIC void DUMB_init __PROTO((void));
67 TERM_PUBLIC void DUMB_graphics __PROTO((void));
68 TERM_PUBLIC void DUMB_text __PROTO((void));
69 TERM_PUBLIC void DUMB_reset __PROTO((void));
70 TERM_PUBLIC void DUMB_linetype __PROTO((int linetype));
71 TERM_PUBLIC void DUMB_move __PROTO((unsigned int x, unsigned int y));
72 TERM_PUBLIC void DUMB_point __PROTO((unsigned int x, unsigned int y,
74 TERM_PUBLIC void DUMB_vector __PROTO((unsigned int x, unsigned int y));
75 TERM_PUBLIC void DUMB_put_text __PROTO((unsigned int x, unsigned int y,
77 TERM_PUBLIC void DUMB_arrow __PROTO((unsigned int sx, unsigned int sy,
78 unsigned int ex, unsigned int ey,
81 #ifndef NO_DUMB_ENHANCED_SUPPORT
82 /* To support "set term dumb enhanced" (don't ask why!) */
83 TERM_PUBLIC void ENHdumb_put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
84 TERM_PUBLIC void ENHdumb_OPEN __PROTO((char * fontname, double fontsize,
85 double base, TBOOLEAN widthflag, TBOOLEAN showflag,
87 TERM_PUBLIC void ENHdumb_FLUSH __PROTO((void));
89 #define ENHdumb_put_text NULL
96 #endif /* TERM_PROTO */
100 #define DUMB_AXIS_CONST '\1'
101 #define DUMB_BORDER_CONST '\2'
103 /* matrix of characters */
104 static char *dumb_matrix = NULL;
105 /* matrix of priority at each position */
106 static char *dumb_priority = NULL;
107 /* current character used to draw */
108 static char dumb_pen;
109 /* current X position */
111 /* current Y position */
113 static int dumb_xmax = DUMB_XMAX;
114 static int dumb_ymax = DUMB_YMAX;
115 static int dumb_feed = 1;
117 #define DUMB_PIXEL(x,y) dumb_matrix[dumb_xmax*(y)+(x)]
119 static void dumb_set_pixel __PROTO((int x, int y, int v, int p));
121 enum DUMB_id { DUMB_FEED, DUMB_NOFEED, DUMB_ENH, DUMB_NOENH, DUMB_SIZE, DUMB_OTHER };
123 static struct gen_table DUMB_opts[] =
125 { "f$eed", DUMB_FEED },
126 { "nof$eed", DUMB_NOFEED },
127 { "enh$anced", DUMB_ENH },
128 { "noe$nhanced", DUMB_NOENH },
129 { "size", DUMB_SIZE },
139 while (!END_OF_COMMAND) {
140 switch(lookup_table(&DUMB_opts[0],c_token)) {
149 #ifndef NO_DUMB_ENHANCED_SUPPORT
152 term->put_text = ENHdumb_put_text;
153 term->flags |= TERM_ENHANCED_TEXT;
157 term->put_text = DUMB_put_text;
158 term->flags &= ~TERM_ENHANCED_TEXT;
167 x = (int) real(const_express(&a));
168 if (!END_OF_COMMAND) {
169 if (equals(c_token,","))
171 y = (int) real(const_express(&a));
172 dumb_xmax = term->xmax = x;
173 dumb_ymax = term->ymax = y;
179 sprintf(term_options, "%sfeed %s %d %d",
180 dumb_feed ? "" : "no",
181 term->put_text == ENHdumb_put_text ? "enhanced" : "",
182 dumb_xmax, dumb_ymax);
187 dumb_set_pixel(int x, int y, int v, int p)
189 if ((unsigned) x <= dumb_xmax && /* ie x>=0 && x<=dumb_xmax */
190 (unsigned) y <= dumb_ymax &&
191 p > dumb_priority[dumb_xmax * y + x]) {
192 dumb_matrix[dumb_xmax * y + x] = v;
193 dumb_priority[dumb_xmax * y + x] = p;
204 dumb_matrix = gp_alloc((dumb_xmax+1) * (dumb_ymax+1) * 2, "dumb terminal");
206 dumb_priority = dumb_matrix + dumb_xmax * dumb_ymax;
214 char *pm = dumb_matrix, *pp = dumb_priority;
216 for (i = dumb_xmax * dumb_ymax; i > 0; i--) {
228 putc('\f', gpoutfile);
229 for (y = dumb_ymax - 1; y >= 0; y--) {
230 for (l = dumb_xmax; l > 0 && DUMB_PIXEL(l - 1, y) == ' '; l--);
231 for (x = 0; x < l; x++)
232 putc(DUMB_PIXEL(x, y), gpoutfile);
233 if (dumb_feed || y > 0)
234 putc('\n', gpoutfile);
250 DUMB_linetype(int linetype)
252 static char pen_type[7] = { '*', '#', '$', '%', '@', '&', '=' };
254 if (linetype == LT_BLACK)
255 dumb_pen = DUMB_BORDER_CONST;
256 else if (linetype == LT_AXIS)
257 dumb_pen = DUMB_AXIS_CONST;
258 else if (linetype <= LT_NODRAW)
261 linetype = linetype % 7;
262 dumb_pen = pen_type[linetype];
268 DUMB_move(unsigned int x, unsigned int y)
276 DUMB_point(unsigned int x, unsigned int y, int point)
278 dumb_set_pixel(x, y, point == -1 ? '.' : point % 26 + 'A', 4);
283 DUMB_vector(unsigned int arg_x, unsigned int arg_y)
285 int x = arg_x; /* we need signed int, since
286 * unsigned-signed=unsigned and */
287 int y = arg_y; /* abs and cast to double wouldn't work */
292 if (ABS(y - dumb_y) > ABS(x - dumb_x)) {
294 case DUMB_AXIS_CONST:
300 case DUMB_BORDER_CONST:
312 dumb_set_pixel(dumb_x, dumb_y, pen1, priority);
313 for (delta = 1; delta < ABS(y - dumb_y); delta++) {
314 dumb_set_pixel(dumb_x + (int) ((double) (x - dumb_x) *
315 delta / ABS(y - dumb_y) + 0.5),
316 dumb_y + delta * sign(y - dumb_y), pen, priority);
318 dumb_set_pixel(x, y, pen1, priority);
319 } else if (ABS(x - dumb_x) > ABS(y - dumb_y)) {
321 case DUMB_AXIS_CONST:
327 case DUMB_BORDER_CONST:
339 dumb_set_pixel(dumb_x, dumb_y, pen1, priority);
340 for (delta = 1; delta < ABS(x - dumb_x); delta++)
341 dumb_set_pixel(dumb_x + delta * sign(x - dumb_x),
343 (int) ((double) (y - dumb_y) * delta / ABS(x - dumb_x)
346 dumb_set_pixel(x, y, pen1, priority);
349 case DUMB_AXIS_CONST: /* zero length axis */
354 case DUMB_BORDER_CONST: /* zero length border */
364 for (delta = 0; delta <= ABS(x - dumb_x); delta++)
365 dumb_set_pixel(dumb_x + delta * sign(x - dumb_x),
366 dumb_y + delta * sign(y - dumb_y),
375 DUMB_put_text(unsigned int x, unsigned int y, const char *str)
379 length = strlen(str);
380 if (x + length > dumb_xmax)
381 x = GPMAX(0, dumb_xmax - length);
383 for (; x < dumb_xmax && *str; x++, str++)
384 dumb_set_pixel(x, y, *str, 5);
390 unsigned int sx, unsigned int sy,
391 unsigned int ex, unsigned int ey,
392 int head) /* ignored */
398 (void) head; /* dummy usage avoid compiler warnings */
399 saved_pen = dumb_pen;
408 dumb_pen = saved_pen;
414 #ifndef NO_DUMB_ENHANCED_SUPPORT
416 * The code from here on serves as an example of how to
417 * add enhanced text mode support to even a dumb driver.
420 static TBOOLEAN ENHdumb_opened_string;
421 static TBOOLEAN ENHdumb_show = TRUE;
422 static int ENHdumb_overprint = 0;
423 static TBOOLEAN ENHdumb_widthflag = TRUE;
424 static unsigned int ENHdumb_xsave, ENHdumb_ysave;
425 #define ENHdumb_fontsize 1
426 #define ENHdumb_font ""
427 static double ENHdumb_base;
432 double fontsize, double base,
433 TBOOLEAN widthflag, TBOOLEAN showflag,
436 /* There are two special cases:
437 * overprint = 3 means save current position
438 * overprint = 4 means restore saved position
440 if (overprint == 3) {
441 ENHdumb_xsave = dumb_x;
442 ENHdumb_ysave = dumb_y;
444 } else if (overprint == 4) {
445 DUMB_move(ENHdumb_xsave, ENHdumb_ysave);
450 if (!ENHdumb_opened_string) {
451 ENHdumb_opened_string = TRUE;
452 /* Start new text fragment */
453 enhanced_cur_text = &enhanced_text[0];
454 /* Scale fractional font height to vertical units of display */
455 ENHdumb_base = base * 2;
456 /* Keep track of whether we are supposed to show this string */
457 ENHdumb_show = showflag;
458 /* 0/1/2 no overprint / 1st pass / 2nd pass */
459 ENHdumb_overprint = overprint;
460 /* widthflag FALSE means do not update text position after printing */
461 ENHdumb_widthflag = widthflag;
462 /* Many drivers will need to do something about font selection here */
463 /* but dumb is dumb */
470 char *str = enhanced_text; /* The fragment to print */
471 int x = dumb_x; /* The current position */
474 if (ENHdumb_opened_string) {
475 *enhanced_cur_text = '\0';
478 /* print the string fragment, perhaps invisibly */
479 /* NB: base expresses offset from current y pos */
480 for (; x < dumb_xmax && *str; x++, str++)
482 dumb_set_pixel(x, dumb_y+ENHdumb_base, *str, 5);
484 if (!ENHdumb_widthflag)
485 /* don't update position */
487 else if (ENHdumb_overprint == 1)
488 /* First pass of overprint, leave position in center of fragment */
491 /* Normal case is to update position to end of fragment */
494 ENHdumb_opened_string = FALSE;
499 ENHdumb_put_text(unsigned int x, unsigned int y, const char *str)
501 /* If no enhanced text processing is needed, we can use the plain */
502 /* vanilla put_text() routine instead of this fancy recursive one. */
503 if (ignore_enhanced_text || !strpbrk(str, "{}^_@&~")) {
504 DUMB_put_text(x,y,str);
508 /* Set up global variables needed by enhanced_recursion() */
509 enhanced_fontscale = 1.0;
510 ENHdumb_opened_string = FALSE;
511 strncpy(enhanced_escape_format,"%c",sizeof(enhanced_escape_format));
515 /* Set the recursion going. We say to keep going until a
516 * closing brace, but we don't really expect to find one.
517 * If the return value is not the nul-terminator of the
518 * string, that can only mean that we did find an unmatched
519 * closing brace in the string. We increment past it (else
520 * we get stuck in an infinite loop) and try again.
522 while (*(str = enhanced_recursion((char *)str, TRUE,
523 ENHdumb_font, ENHdumb_fontsize,
524 0.0, TRUE, TRUE, 0))) {
525 (term->enhanced_flush)();
527 /* I think we can only get here if *str == '}' */
531 break; /* end of string */
533 /* else carry on and process the rest of the string */
536 #endif /* NO_DUMB_ENHANCED_SUPPORT */
538 #endif /* TERM_BODY */
541 TERM_TABLE_START(dumb_driver)
542 "dumb", "ascii art for anything that prints text",
543 DUMB_XMAX, DUMB_YMAX, 1, 1,
544 1, 1, DUMB_options, DUMB_init, DUMB_reset,
545 DUMB_text, null_scale, DUMB_graphics, DUMB_move, DUMB_vector,
546 DUMB_linetype, DUMB_put_text, null_text_angle,
547 null_justify_text, DUMB_point, DUMB_arrow, set_font_null,
550 NULL, NULL, NULL, NULL
552 , NULL, NULL, NULL, NULL, NULL
554 , NULL, NULL, NULL, NULL
558 #ifndef NO_DUMB_ENHANCED_SUPPORT
559 , ENHdumb_OPEN, ENHdumb_FLUSH, do_enh_writec
560 #endif /* NO_DUMB_ENHANCED_SUPPORT */
561 TERM_TABLE_END(dumb_driver)
564 #define LAST_TERM dumb_driver
566 #endif /* TERM_TABLE */
571 "?commands set terminal dumb",
572 "?set terminal dumb",
577 " The `dumb` terminal driver has an optional size specification and trailing",
578 " linefeed control.",
581 " set terminal dumb {[no]feed} {<xsize> <ysize>}",
582 #ifndef NO_DUMB_ENHANCED_SUPPORT
586 " where <xsize> and <ysize> set the size of the dumb terminals. Default is",
587 " 79 by 24. The last newline is printed only if `feed` is enabled.",
590 " set term dumb nofeed",
591 " set term dumb 79 49 # VGA screen---why would anyone do that?"
593 #endif /* TERM_HELP */