/* Hello, Emacs, this is -*-C-*- * $Id: rgip.trm,v 1.17 2006/07/21 02:35:48 sfeam Exp $ */ /* GNUPLOT - rgip.trm Uniplex graphics metafile */ /*[ * Copyright 1990 - 1993, 1998, 2004 * * Permission to use, copy, and distribute this software and its * documentation for any purpose with or without fee is hereby granted, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. * * Permission to modify the software is granted, but not the right to * distribute the complete modified source code. Modifications are to * be distributed as patches to the released version. Permission to * distribute binaries produced by compiling modified sources is granted, * provided you * 1. distribute the corresponding source modifications from the * released version in the form of a patch file along with the binaries, * 2. add special version identification to distinguish your version * in addition to the base release version number, * 3. provide your name and address as the primary contact for the * support of your modified version, and * 4. retain our contact information in regard to use of the base * software. * Permission to distribute the released version of the source code along * with corresponding source modifications in the form of a patch file is * granted with same provisions 2 through 4 for binary distributions. * * This software is provided "as is" without express or implied warranty * to the extent permitted by applicable law. ]*/ /* * This file is included by ../term.c. * * This terminal driver supports: * RGIP metafile * * AUTHORS * Hans Olav Eggestad * * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net). * */ /* * Original for direct RGIP Metafile output. */ /* * Max pixels for X and Y in one window is 10000. */ /* * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995) */ #include "driver.h" #ifdef TERM_REGISTER register_term(rgip) register_term(uniplex) #endif #ifdef TERM_PROTO TERM_PUBLIC void RGIP_init __PROTO((void)); TERM_PUBLIC void RGIP_graphics __PROTO((void)); TERM_PUBLIC void RGIP_text __PROTO((void)); TERM_PUBLIC void RGIP_linetype __PROTO((int lt)); TERM_PUBLIC void RGIP_move __PROTO((unsigned int x, unsigned int y)); TERM_PUBLIC void RGIP_vector __PROTO((unsigned int ux, unsigned int uy)); TERM_PUBLIC int RGIP_text_angle __PROTO((int ang)); TERM_PUBLIC int RGIP_justify_text __PROTO((enum JUSTIFY mode)); TERM_PUBLIC void RGIP_put_text __PROTO((unsigned int x, unsigned int y, const char *str)); TERM_PUBLIC void RGIP_reset __PROTO((void)); TERM_PUBLIC void RGIP_do_point __PROTO((unsigned int x, unsigned int y, int number)); TERM_PUBLIC void RGIP_options __PROTO((void)); #define RGIP_X_MAX 10000 #define RGIP_Y_MAX 6700 #define RGIP_FONTSIZE 1 #define RGIP_SC (300) #define RGIP_XMAX 9900 #define RGIP_YMAX 6600 #define RGIP_HTIC (100) #define RGIP_VTIC (100) #define RGIP_VCHAR (RGIP_FONTSIZE*RGIP_SC) #define RGIP_HCHAR (RGIP_VCHAR*3/7) #endif /* TERM_PROTO */ #ifndef TERM_PROTO_ONLY #ifdef TERM_BODY void RGIP_write_poly __PROTO((void)); static unsigned char *RGIP_cvts __PROTO((unsigned char *str, int *lcnt)); /* static void RGIP_setfont __PROTO((int sz)); */ #include #include #define RGIPDOTS 0 #define RGIPMARK 1 #define RGIPTEXT 2 #define RGIPLINE 3 #define RGIPPOLY 4 #define RGIP_MAX_POLY 250 static char *RGIP_Obj[6] = {"DOTS", "MARK", "TEXT", "LINE", "POLY"}; /* * RGIP fontsises range from 1 to 8 */ #define RGIP_FACES 3 #define RGIP_FSTYLES 4 #define RGIP_FSIZES 8 #define RGIP_HELVETICA 0 #define RGIP_TIMES 1 #define RGIP_COURIER 2 #define RGIP_LINE_WIDTHS 8 /* future, currently invisible and visible 0 and 1 */ #define RGIP_LINE_TYPES 8 #define RGIP_COLORS 16 #define RGIP_POINT_TYPES 8 static int RGIP_orgX; /* absolute-pixel-ORIgin of graph. */ static int RGIP_orgY; static int RGIP_orgx; /* absolute-pixel-ORIgin of current plot. */ static int RGIP_orgy; static int RGIP_posx; /* current drawing position (lines). */ static int RGIP_posy; /* static int RGIP_inplot; */ static int RGIP_xmax = RGIP_XMAX; /* width of graph in pixels. */ static int RGIP_ymax = RGIP_YMAX; /* height of graph in pixels. */ static int RGIP_winx = RGIP_XMAX; /* width of graph in pixels. */ static int RGIP_winy = RGIP_YMAX; /* height of graph in pixels. */ /* static int RGIP_blofs; */ /* BaseLine OFfSet from bounding box.*/ static int RGIP_angle = 0; /* 0 for horizontal text, 90 for vertical */ static int RGIP_portrait = 0; /* 0 for horizontal text, 90 for vertical */ static enum JUSTIFY RGIP_justify = LEFT; /* left/center/right */ static int RGIP_fface = 2; /* Times */ static int RGIP_ftype = 1; /* style roman */ static int RGIP_fontsize = RGIP_FONTSIZE; /* */ static int RGIP_tcol = 7; /* text color */ static int RGIP_lsty = 1; /* line style */ static int RGIP_lcol = 7; /* line color */ static int RGIP_lwid = 1; /* line width */ static int RGIP_fsty = 8; /* fill style */ static int RGIP_fcol = 8; /* fill color */ static int RGIP_mcol = 7; /* marker color */ static int RGIP_msty = 1; /* marker style */ static int RGIP_msize = 1; /* marker size */ static int RGIP_win_horiz = 1; static int RGIP_win_verti = 1; static int RGIP_plot_nr = 0; unsigned int RGIP_vecpos; unsigned int RGIP_xvector[RGIP_MAX_POLY]; unsigned int RGIP_yvector[RGIP_MAX_POLY]; static unsigned char *RGIP_cvts(); TERM_PUBLIC void RGIP_init() { register struct termentry *t = term; RGIP_posx = RGIP_posy = 0; if (RGIP_portrait) { RGIP_orgX = (RGIP_Y_MAX - RGIP_YMAX) / 2; RGIP_orgY = (RGIP_X_MAX - RGIP_XMAX) / 2; RGIP_xmax = RGIP_winx = (int) (RGIP_YMAX / RGIP_win_horiz); RGIP_ymax = RGIP_winy = (int) (RGIP_XMAX / RGIP_win_verti); } else { RGIP_orgX = (RGIP_X_MAX - RGIP_XMAX) / 2; RGIP_orgY = (RGIP_Y_MAX - RGIP_YMAX) / 2; RGIP_xmax = RGIP_winx = (int) (RGIP_XMAX / RGIP_win_horiz); RGIP_ymax = RGIP_winy = (int) (RGIP_YMAX / RGIP_win_verti); } t->xmax = (unsigned int) (RGIP_xmax); t->ymax = (unsigned int) (RGIP_ymax); RGIP_vecpos = 0; } TERM_PUBLIC void RGIP_graphics() { static int Gnr = 0; struct stat buf; unsigned char *p, fn[128]; int tmpx, tmpy; /* int xoff, yoff; */ if (RGIP_vecpos) { RGIP_write_poly(); } if (!Gnr || RGIP_plot_nr >= (RGIP_win_horiz * RGIP_win_verti)) { fstat(fileno(gpoutfile), &buf); if (S_ISREG(buf.st_mode)) { if (outstr && (p = (unsigned char *) strchr(outstr, 'X'))) { /* substitute X with graphnr */ if (!Gnr) { /* delete the base file */ unlink(outstr); /* should we close it first ? ? ? */ } else { fputs("%RI_GROUPEND\n", gpoutfile); fclose(gpoutfile); } *p = NUL; sprintf(fn, "%s%1d%s", outstr, ++Gnr, p + 1); if ((gpoutfile = fopen(fn, "w")) == (FILE *) NULL) { os_error(NO_CARET, "cannot reopen file with binary type; output unknown"); } *p = 'X'; /* put back X */ } } fprintf(gpoutfile, "\ %RGIP_METAFILE: 1.0a\n\ %RI_GROUPSTART\n\ 0 0 %d %d SetWindow\n\ 100 100 %d %d 10 1 7 1 8 BOX\n", (RGIP_portrait) ? RGIP_Y_MAX : RGIP_X_MAX, (RGIP_portrait) ? RGIP_X_MAX : RGIP_Y_MAX, (RGIP_portrait) ? RGIP_YMAX : RGIP_XMAX, (RGIP_portrait) ? RGIP_XMAX : RGIP_YMAX); RGIP_plot_nr = 0; } else { fputs("%RI_GROUPEND\n", gpoutfile); } fputs("%RI_GROUPSTART\n", gpoutfile); RGIP_plot_nr++; /* Gnr++; */ tmpx = RGIP_orgX + ((RGIP_plot_nr - 1) % RGIP_win_horiz) * RGIP_winx; tmpy = RGIP_orgY + ((RGIP_win_verti - 1) - (int) ((RGIP_plot_nr - 1) / RGIP_win_horiz)) * RGIP_winy; RGIP_orgx = tmpx + (int) ((RGIP_winx - RGIP_xmax) / 2); RGIP_orgy = tmpy + (int) ((RGIP_winy - RGIP_ymax) / 2); /* RGIP_linetype(-1); */ } TERM_PUBLIC void RGIP_text() { } TERM_PUBLIC void RGIP_linetype(int lt) { /* int pen, pattern; */ if (RGIP_vecpos) { RGIP_write_poly(); } if (lt <= LT_BLACK) { lt = 1; RGIP_lwid = 5; } else if (lt == LT_AXIS) { lt = 5; RGIP_lwid = 2; } else { RGIP_lwid = (int) (lt / RGIP_LINE_TYPES); if (RGIP_lwid < 1) RGIP_lwid = 1; RGIP_lwid *= 2; lt = (lt % RGIP_LINE_TYPES) + 1; } fputs("%RI_GROUPEND\n\ %RI_GROUPSTART\n", gpoutfile); /* RGIP_lsty = (lt == 0 || lt == 2) ? 1 : lt; */ RGIP_lsty = lt; } TERM_PUBLIC void RGIP_move(unsigned int x, unsigned int y) { /* fputs("%RI_GROUPEND\n", gpoutfile); fputs("%RI_GROUPSTART\n", gpoutfile); */ if (RGIP_vecpos) { RGIP_write_poly(); } RGIP_xvector[0] = x + RGIP_orgx; RGIP_yvector[0] = y + RGIP_orgy; RGIP_vecpos = 1; /* RGIP_posx = x; RGIP_posy = y; */ } TERM_PUBLIC void RGIP_vector(unsigned int ux, unsigned int uy) { /* store polygon-node */ RGIP_xvector[RGIP_vecpos] = ux + RGIP_orgx; RGIP_yvector[RGIP_vecpos] = uy + RGIP_orgy; RGIP_vecpos++; if (RGIP_vecpos >= RGIP_MAX_POLY) { RGIP_write_poly(); RGIP_xvector[RGIP_vecpos] = ux + RGIP_orgx; RGIP_yvector[RGIP_vecpos] = uy + RGIP_orgy; RGIP_vecpos++; } } void RGIP_write_poly() { register int i; putc('[', gpoutfile); for (i = 0; i < RGIP_vecpos; i++) { if (!(i % 8)) putc('\n', gpoutfile); fprintf(gpoutfile, " %1d\ %1d", RGIP_xvector[i], RGIP_yvector[i]); } RGIP_vecpos = 0; putc(']', gpoutfile); fprintf(gpoutfile, " %1d %d %1d %1d %1d %s\n", RGIP_lwid, RGIP_lsty, RGIP_lcol, RGIP_fsty, RGIP_fcol, RGIP_Obj[RGIPPOLY]); /* RGIP_posx = ux; RGIP_posy = uy; */ /* RGIP_move(ux, uy); */ } TERM_PUBLIC int RGIP_text_angle(int ang) { if (RGIP_vecpos) { RGIP_write_poly(); } if (RGIP_angle != ang) { RGIP_angle = ang; /* record for later use */ } return (TRUE); } TERM_PUBLIC int RGIP_justify_text(enum JUSTIFY mode) { if (RGIP_vecpos) { RGIP_write_poly(); } RGIP_justify = mode; return (TRUE); } static unsigned char * RGIP_cvts(unsigned char *str, int *lcnt) { unsigned char *cp1; unsigned char *cp2; static unsigned char *buf = NULL; int lc = 1; lc = 1; /* Free up old buffer, if there is one, get a new one. Since */ /* all transformations shorten the string, get a buffer that is */ /* the same size as the input string. */ if (buf != NULL) (void) free(buf); buf = (unsigned char *) gp_alloc(strlen(str), "converted label string"); /* Do the transformations. */ cp1 = str; cp2 = buf; while (strlen(cp1) > 0) { switch (*cp1) { case '\\': /* Escape sequence. */ if (*++cp1 == '\\') { /* Begin new line. */ *cp2++ = '\n'; lc++; break; } case '(': *cp2++ = '\\'; *cp2++ = '('; break; case ')': *cp2++ = '\\'; *cp2++ = ')'; break; /* Fall through to just copy next char out. */ default: *cp2++ = *cp1; break; } cp1++; } *cp2++ = '\n'; *cp2 = NUL; *lcnt = lc; return (buf); } TERM_PUBLIC void RGIP_put_text(unsigned int x, unsigned int y, const char *str) { register struct termentry *t = term; unsigned char *cvstr, *p; int xlines; /* lines */ if (RGIP_vecpos) { RGIP_write_poly(); } cvstr = RGIP_cvts(str, &xlines); x += RGIP_orgx, y += RGIP_orgy; if (!RGIP_angle) { /* horisontal */ y += (int) (t->v_char) * (xlines - 2) / 2; /* y += (t->v_char)*xlines; */ y += (int) (t->v_char) / 4; } else { x -= (int) (t->v_char) * (xlines - 2) / 2; x -= (int) (t->v_char) / 4; } while ((p = (unsigned char *) strchr(cvstr, '\n'))) { *p = '\0'; if (strlen(cvstr)) fprintf(gpoutfile, "%1d %1d %1d %1d (%s) %1d %1d %1d %1d %s\n", x, y, RGIP_justify, RGIP_angle, cvstr, RGIP_fface, RGIP_ftype, RGIP_fontsize, RGIP_tcol, RGIP_Obj[RGIPTEXT]); cvstr = ++p; if (RGIP_angle) { /* vertical */ x += (t->v_char); } else { y -= (t->v_char); } } } TERM_PUBLIC void RGIP_reset() { if (RGIP_vecpos) { RGIP_write_poly(); } fputs("%RI_GROUPEND\n", gpoutfile); /* fputs("%RI_GROUPEND\n", gpoutfile); */ } #if 0 /* HBB 20040619: found commented out --- why? */ RGIP_setfont(int sz) { RGIP_fontsize = (int) (sz); if ( RGIP_fontsize < 1 ) RGIP_fontsize = 1; term->v_char = RGIP_fontsize * RGIP_SC; term->h_char = RGIP_fontsize * RGIP_SC * 3 / 7; } #endif TERM_PUBLIC void RGIP_do_point(unsigned int x, unsigned int y, int number) { x += RGIP_orgx, y += RGIP_orgy; if (number < 0) { /* do dot */ fprintf(gpoutfile, "%1d %1d %1d %s\n", x, y, RGIP_mcol, RGIP_Obj[RGIPDOTS]); return; } RGIP_msty = (number % RGIP_POINT_TYPES) + 1; RGIP_msize = ((int) (number / RGIP_POINT_TYPES)) + 1; fprintf(gpoutfile, "%1d %1d %1d %1d %1d %s\n", x, y, RGIP_msize, RGIP_msty, RGIP_mcol, RGIP_Obj[RGIPMARK]); } TERM_PUBLIC void RGIP_options() { struct value a; while (!END_OF_COMMAND) { if (almost_equals(c_token, "p$ortrait")) { RGIP_portrait = TRUE; c_token++; } else if (almost_equals(c_token, "l$andscape")) { RGIP_portrait = FALSE; c_token++; } else if (equals(c_token, "[")) { /* windows spesified */ c_token++; /* if (RGIP_plot_nr>1) */ if (equals(c_token, "]")) { /* RGIP_page(); */ c_token++; continue; } if (END_OF_COMMAND) { int_error(c_token, "no. windows: [horizontal,vertical] expected"); } else if (!equals(c_token, ",")) { RGIP_win_horiz = (int) real(const_express(&a)); } if (!equals(c_token, ",")) int_error(c_token, "',' expected"); c_token++; if (!equals(c_token, "]")) { RGIP_win_verti = (int) real(const_express(&a)); } if (!equals(c_token, "]")) int_error(c_token, "expecting ']'"); c_token++; } else { /* We have font size specified */ RGIP_fontsize = (int) real(const_express(&a)); if (RGIP_fontsize < 1) RGIP_fontsize = 1; term->v_char = (unsigned int) (RGIP_fontsize * RGIP_SC); term->h_char = (unsigned int) (RGIP_fontsize * RGIP_SC * 3 / 7); } } sprintf(term_options, "%s %d [%1d,%1d]", (RGIP_portrait) ? "portrait" : "landscape", RGIP_fontsize, RGIP_win_horiz, RGIP_win_verti); } #endif /* TERM_BODY */ #ifdef TERM_TABLE TERM_TABLE_START(rgip_driver) "rgip", "RGIP metafile (Uniplex). Option: fontsize (1-8)", RGIP_XMAX, RGIP_YMAX, RGIP_VCHAR, RGIP_HCHAR, RGIP_VTIC, RGIP_HTIC, RGIP_options, RGIP_init, RGIP_reset, RGIP_text, null_scale, RGIP_graphics, RGIP_move, RGIP_vector, RGIP_linetype, RGIP_put_text, RGIP_text_angle, RGIP_justify_text, RGIP_do_point, do_arrow, set_font_null TERM_TABLE_END(rgip_driver) #undef LAST_TERM #define LAST_TERM rgip_driver TERM_TABLE_START(uniplex_driver) "uniplex", "RGIP metafile (Uniplex). Option: fontsize (1-8) (Same as rgip)", RGIP_XMAX, RGIP_YMAX, RGIP_VCHAR, RGIP_HCHAR, RGIP_VTIC, RGIP_HTIC, RGIP_options, RGIP_init, RGIP_reset, RGIP_text, null_scale, RGIP_graphics, RGIP_move, RGIP_vector, RGIP_linetype, RGIP_put_text, RGIP_text_angle, RGIP_justify_text, RGIP_do_point, do_arrow, set_font_null TERM_TABLE_END(uniplex_driver) #undef LAST_TERM #define LAST_TERM uniplex_driver #endif /* TERM_TABLE */ #endif /* TERM_PROTO_ONLY */ #ifdef TERM_HELP START_HELP(rgip) "1 rgip", "?commands set terminal rgip", "?set terminal rgip", "?set term rgip", "?terminal rgip", "?term rgip", "?rgip", "?commands set terminal uniplex", "?set terminal uniplex", "?set term uniplex", "?terminal uniplex", "?term uniplex", "?uniplex", " The `rgip` and `uniplex` terminal drivers support RGIP metafiles. They can", " combine several graphs on a single page, but only one page is allowed in a", " given output file.", "", " Syntax:", " set terminal rgip | uniplex {portrait | landscape}", " {[,]} {}", "", " permissible values for the font size are in the range 1--8, with the default", " being 1. The default layout is landscape. Graphs are placed on the page in", " a `horiz`x`vert` grid, which defaults to [1,1].", "", " Example:", " set terminal uniplex portrait [2,3]", "", " puts six graphs on a page in three rows of two in portrait orientation." END_HELP(rgip) #endif /* TERM_HELP */