Annotation of OpenXM_contrib/gnuplot/term/rgip.trm, Revision 1.1.1.1
1.1 maekawa 1: /*
2: * $Id: rgip.trm,v 1.16 1998/04/14 00:18:06 drd Exp $
3: */
4:
5: /* GNUPLOT - rgip.trm Uniplex graphics metafile */
6:
7: /*[
8: * Copyright 1990 - 1993, 1998
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: * RGIP metafile
42: *
43: * AUTHORS
44: * Hans Olav Eggestad
45: *
46: * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
47: *
48: */
49:
50: /*
51: * Original for direct RGIP Metafile output.
52: */
53: /*
54: * Max pixels for X and Y in one window is 10000.
55: */
56: /*
57: * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
58: */
59:
60: #include "driver.h"
61:
62: #ifdef TERM_REGISTER
63: register_term(rgip)
64: register_term(uniplex)
65: #endif
66:
67: #ifdef TERM_PROTO
68: TERM_PUBLIC void RGIP_init __PROTO((void));
69: TERM_PUBLIC void RGIP_graphics __PROTO((void));
70: TERM_PUBLIC void RGIP_text __PROTO((void));
71: TERM_PUBLIC void RGIP_linetype __PROTO((int lt));
72: TERM_PUBLIC void RGIP_move __PROTO((unsigned int x, unsigned int y));
73: TERM_PUBLIC void RGIP_vector __PROTO((unsigned int ux, unsigned int uy));
74: TERM_PUBLIC int RGIP_text_angle __PROTO((int ang));
75: TERM_PUBLIC int RGIP_justify_text __PROTO((enum JUSTIFY mode));
76: TERM_PUBLIC void RGIP_put_text __PROTO((unsigned int x, unsigned int y, char *str));
77: TERM_PUBLIC void RGIP_reset __PROTO((void));
78: TERM_PUBLIC void RGIP_do_point __PROTO((unsigned int x, unsigned int y, int number));
79: TERM_PUBLIC void RGIP_options __PROTO((void));
80: #define RGIP_X_MAX 10000
81: #define RGIP_Y_MAX 6700
82:
83: #define RGIP_FONTSIZE 1
84: #define RGIP_SC (300)
85: #define RGIP_XMAX 9900
86: #define RGIP_YMAX 6600
87: #define RGIP_HTIC (100)
88: #define RGIP_VTIC (100)
89: #define RGIP_VCHAR (RGIP_FONTSIZE*RGIP_SC)
90: #define RGIP_HCHAR (RGIP_VCHAR*3/7)
91: #endif /* TERM_PROTO */
92:
93: #ifndef TERM_PROTO_ONLY
94: #ifdef TERM_BODY
95:
96:
97: void RGIP_write_poly __PROTO((void));
98: static unsigned char *RGIP_cvts __PROTO((unsigned char *str, int *lcnt));
99: /* static void RGIP_setfont __PROTO((int sz)); */
100:
101: #include <sys/types.h>
102: #include <sys/stat.h>
103:
104: #define RGIPDOTS 0
105: #define RGIPMARK 1
106: #define RGIPTEXT 2
107: #define RGIPLINE 3
108: #define RGIPPOLY 4
109: #define RGIP_MAX_POLY 250
110: static char *RGIP_Obj[6] =
111: {"DOTS", "MARK", "TEXT", "LINE", "POLY"};
112:
113: /*
114: * RGIP fontsises range from 1 to 8
115: */
116:
117: #define RGIP_FACES 3
118: #define RGIP_FSTYLES 4
119: #define RGIP_FSIZES 8
120: #define RGIP_HELVETICA 0
121: #define RGIP_TIMES 1
122: #define RGIP_COURIER 2
123: #define RGIP_LINE_WIDTHS 8 /* future, currently invisible and visible 0
124: and 1 */
125: #define RGIP_LINE_TYPES 8
126: #define RGIP_COLORS 16
127: #define RGIP_POINT_TYPES 8
128:
129:
130:
131:
132: static int RGIP_orgX; /* absolute-pixel-ORIgin of graph. */
133: static int RGIP_orgY;
134: static int RGIP_orgx; /* absolute-pixel-ORIgin of current plot. */
135: static int RGIP_orgy;
136: static int RGIP_posx; /* current drawing position (lines). */
137: static int RGIP_posy;
138: /* static int RGIP_inplot; */
139: static int RGIP_xmax = RGIP_XMAX; /* width of graph in pixels. */
140: static int RGIP_ymax = RGIP_YMAX; /* height of graph in pixels. */
141: static int RGIP_winx = RGIP_XMAX; /* width of graph in pixels. */
142: static int RGIP_winy = RGIP_YMAX; /* height of graph in pixels. */
143: /* static int RGIP_blofs; */ /* BaseLine OFfSet from bounding box.*/
144: static int RGIP_angle = 0; /* 0 for horizontal text, 90 for vertical */
145: static int RGIP_portrait = 0; /* 0 for horizontal text, 90 for vertical */
146: static enum JUSTIFY RGIP_justify = LEFT; /* left/center/right */
147: static int RGIP_fface = 2; /* Times */
148: static int RGIP_ftype = 1; /* style roman */
149: static int RGIP_fontsize = RGIP_FONTSIZE; /* */
150: static int RGIP_tcol = 7; /* text color */
151: static int RGIP_lsty = 1; /* line style */
152: static int RGIP_lcol = 7; /* line color */
153: static int RGIP_lwid = 1; /* line width */
154: static int RGIP_fsty = 8; /* fill style */
155: static int RGIP_fcol = 8; /* fill color */
156: static int RGIP_mcol = 7; /* marker color */
157: static int RGIP_msty = 1; /* marker style */
158: static int RGIP_msize = 1; /* marker size */
159:
160: static int RGIP_win_horiz = 1;
161: static int RGIP_win_verti = 1;
162: static int RGIP_plot_nr = 0;
163:
164: unsigned int RGIP_vecpos;
165: unsigned int RGIP_xvector[RGIP_MAX_POLY];
166: unsigned int RGIP_yvector[RGIP_MAX_POLY];
167: static unsigned char *RGIP_cvts();
168:
169:
170: TERM_PUBLIC void RGIP_init()
171: {
172: register struct termentry *t = term;
173:
174: RGIP_posx = RGIP_posy = 0;
175:
176: if (RGIP_portrait) {
177: RGIP_orgX = (RGIP_Y_MAX - RGIP_YMAX) / 2;
178: RGIP_orgY = (RGIP_X_MAX - RGIP_XMAX) / 2;
179: RGIP_xmax = RGIP_winx = (int) (RGIP_YMAX / RGIP_win_horiz);
180: RGIP_ymax = RGIP_winy = (int) (RGIP_XMAX / RGIP_win_verti);
181: } else {
182: RGIP_orgX = (RGIP_X_MAX - RGIP_XMAX) / 2;
183: RGIP_orgY = (RGIP_Y_MAX - RGIP_YMAX) / 2;
184: RGIP_xmax = RGIP_winx = (int) (RGIP_XMAX / RGIP_win_horiz);
185: RGIP_ymax = RGIP_winy = (int) (RGIP_YMAX / RGIP_win_verti);
186: }
187:
188: t->xmax = (unsigned int) (RGIP_xmax);
189: t->ymax = (unsigned int) (RGIP_ymax);
190:
191: RGIP_vecpos = 0;
192: }
193:
194: TERM_PUBLIC void RGIP_graphics()
195: {
196: static int Gnr = 0;
197: struct stat buf;
198: unsigned char *p, fn[128];
199:
200: int tmpx, tmpy;
201: /* int xoff, yoff; */
202:
203: if (RGIP_vecpos) {
204: RGIP_write_poly();
205: }
206: if (!Gnr || RGIP_plot_nr >= (RGIP_win_horiz * RGIP_win_verti)) {
207: fstat(fileno(gpoutfile), &buf);
208: if (S_ISREG(buf.st_mode)) {
209: if (outstr && (p = (unsigned char *) strchr(outstr, 'X'))) {
210: /* substitute X with graphnr */
211: if (!Gnr) { /* delete the base file */
212: unlink(outstr); /* should we close it first ? ? ? */
213: } else {
214: fputs("%RI_GROUPEND\n", gpoutfile);
215: fclose(gpoutfile);
216: }
217: *p = NUL;
218: sprintf(fn, "%s%1d%s", outstr, ++Gnr, p + 1);
219: if ((gpoutfile = fopen(fn, "w")) == (FILE *) NULL) {
220: os_error("cannot reopen file with binary type; output unknown",
221: NO_CARET);
222: }
223: *p = 'X'; /* put back X */
224: }
225: }
226: fprintf(gpoutfile, "\
227: %RGIP_METAFILE: 1.0a\n\
228: %RI_GROUPSTART\n\
229: 0 0 %d %d SetWindow\n\
230: 100 100 %d %d 10 1 7 1 8 BOX\n",
231: (RGIP_portrait) ? RGIP_Y_MAX : RGIP_X_MAX,
232: (RGIP_portrait) ? RGIP_X_MAX : RGIP_Y_MAX,
233: (RGIP_portrait) ? RGIP_YMAX : RGIP_XMAX,
234: (RGIP_portrait) ? RGIP_XMAX : RGIP_YMAX);
235: RGIP_plot_nr = 0;
236: } else {
237: fputs("%RI_GROUPEND\n", gpoutfile);
238: }
239: fputs("%RI_GROUPSTART\n", gpoutfile);
240: RGIP_plot_nr++;
241: /* Gnr++; */
242: tmpx = RGIP_orgX + ((RGIP_plot_nr - 1) % RGIP_win_horiz) * RGIP_winx;
243: tmpy = RGIP_orgY + ((RGIP_win_verti - 1) - (int) ((RGIP_plot_nr - 1) / RGIP_win_horiz)) * RGIP_winy;
244: RGIP_orgx = tmpx + (int) ((RGIP_winx - RGIP_xmax) / 2);
245: RGIP_orgy = tmpy + (int) ((RGIP_winy - RGIP_ymax) / 2);
246:
247:
248: /* RGIP_linetype(-1); */
249: }
250:
251: TERM_PUBLIC void RGIP_text()
252: {
253: }
254:
255: TERM_PUBLIC void RGIP_linetype(lt)
256: int lt;
257: {
258: /* int pen, pattern; */
259:
260: if (RGIP_vecpos) {
261: RGIP_write_poly();
262: }
263: /* -2: axis
264: * -1: border
265: * 0: arrow
266: * 1-7: graph
267: */
268: if (lt == -2) {
269: lt = 1;
270: RGIP_lwid = 5;
271: } else if (lt == -1) {
272: lt = 5;
273: RGIP_lwid = 2;
274: } else {
275: RGIP_lwid = (int) (lt / RGIP_LINE_TYPES);
276: if (RGIP_lwid < 1)
277: RGIP_lwid = 1;
278: RGIP_lwid *= 2;
279: lt = (lt % RGIP_LINE_TYPES) + 1;
280: }
281: fputs("%RI_GROUPEND\n\
282: %RI_GROUPSTART\n", gpoutfile);
283:
284: /* RGIP_lsty = (lt == 0 || lt == 2) ? 1 : lt; */
285:
286: RGIP_lsty = lt;
287: }
288:
289:
290: TERM_PUBLIC void RGIP_move(x, y)
291: unsigned int x, y;
292: {
293: /*
294: fputs("%RI_GROUPEND\n", gpoutfile);
295: fputs("%RI_GROUPSTART\n", gpoutfile);
296: */
297: if (RGIP_vecpos) {
298: RGIP_write_poly();
299: }
300: RGIP_xvector[0] = x + RGIP_orgx;
301: RGIP_yvector[0] = y + RGIP_orgy;
302: RGIP_vecpos = 1;
303: /*
304: RGIP_posx = x;
305: RGIP_posy = y;
306: */
307: }
308:
309:
310: TERM_PUBLIC void RGIP_vector(ux, uy)
311: unsigned int ux, uy;
312: {
313: /* store polygon-node */
314:
315: RGIP_xvector[RGIP_vecpos] = ux + RGIP_orgx;
316: RGIP_yvector[RGIP_vecpos] = uy + RGIP_orgy;
317: RGIP_vecpos++;
318: if (RGIP_vecpos >= RGIP_MAX_POLY) {
319: RGIP_write_poly();
320: RGIP_xvector[RGIP_vecpos] = ux + RGIP_orgx;
321: RGIP_yvector[RGIP_vecpos] = uy + RGIP_orgy;
322: RGIP_vecpos++;
323: }
324: }
325:
326: void RGIP_write_poly()
327: {
328: register int i;
329:
330: putc('[', gpoutfile);
331: for (i = 0; i < RGIP_vecpos; i++) {
332: if (!(i % 8))
333: putc('\n', gpoutfile);
334: fprintf(gpoutfile, " %1d\
335: %1d",
336: RGIP_xvector[i],
337: RGIP_yvector[i]);
338: }
339: RGIP_vecpos = 0;
340: putc(']', gpoutfile);
341:
342: fprintf(gpoutfile, " %1d %d %1d %1d %1d %s\n", RGIP_lwid, RGIP_lsty,
343: RGIP_lcol, RGIP_fsty, RGIP_fcol, RGIP_Obj[RGIPPOLY]);
344:
345: /*
346: RGIP_posx = ux;
347: RGIP_posy = uy;
348: */
349: /* RGIP_move(ux, uy); */
350: }
351:
352:
353: TERM_PUBLIC int RGIP_text_angle(ang)
354: int ang;
355: {
356: if (RGIP_vecpos) {
357: RGIP_write_poly();
358: }
359: if (RGIP_angle != ang) {
360: RGIP_angle = ang; /* record for later use */
361: }
362: return (TRUE);
363: }
364:
365: TERM_PUBLIC int RGIP_justify_text(mode)
366: enum JUSTIFY mode;
367: {
368: if (RGIP_vecpos) {
369: RGIP_write_poly();
370: }
371: RGIP_justify = mode;
372: return (TRUE);
373: }
374:
375: static unsigned char *RGIP_cvts(str, lcnt)
376: unsigned char *str;
377: int *lcnt; /* lines */
378: {
379: unsigned char *cp1;
380: unsigned char *cp2;
381: static unsigned char *buf = NULL;
382: int lc = 1;
383:
384: lc = 1;
385: /* Free up old buffer, if there is one, get a new one. Since */
386: /* all transformations shorten the string, get a buffer that is */
387: /* the same size as the input string. */
388:
389: if (buf != NULL)
390: (void) free(buf);
391: buf = (unsigned char *) gp_alloc(strlen(str), "converted label string");
392:
393: /* Do the transformations. */
394:
395: cp1 = str;
396: cp2 = buf;
397: while (strlen(cp1) > 0) {
398: switch (*cp1) {
399: case '\\': /* Escape sequence. */
400: if (*++cp1 == '\\') {
401: /* Begin new line. */
402: *cp2++ = '\n';
403: lc++;
404: break;
405: }
406: case '(':
407: *cp2++ = '\\';
408: *cp2++ = '(';
409: break;
410: case ')':
411: *cp2++ = '\\';
412: *cp2++ = ')';
413: break;
414: /* Fall through to just copy next char out. */
415:
416: default:
417: *cp2++ = *cp1;
418: break;
419: }
420: cp1++;
421: }
422:
423: *cp2++ = '\n';
424: *cp2 = NUL;
425: *lcnt = lc;
426: return (buf);
427: }
428:
429: TERM_PUBLIC void RGIP_put_text(x, y, str)
430: unsigned int x, y; /* reference point of string */
431: char *str; /* the text */
432: {
433: register struct termentry *t = term;
434: unsigned char *cvstr, *p;
435: int xlines; /* lines */
436:
437: if (RGIP_vecpos) {
438: RGIP_write_poly();
439: }
440: cvstr = RGIP_cvts(str, &xlines);
441:
442: x += RGIP_orgx,
443: y += RGIP_orgy;
444:
445: if (!RGIP_angle) { /* horisontal */
446: y += (int) (t->v_char) * (xlines - 2) / 2;
447: /* y += (t->v_char)*xlines; */
448: y += (int) (t->v_char) / 4;
449: } else {
450: x -= (int) (t->v_char) * (xlines - 2) / 2;
451: x -= (int) (t->v_char) / 4;
452: }
453:
454: while ((p = (unsigned char *) strchr(cvstr, '\n'))) {
455: *p = '\0';
456: if (strlen(cvstr))
457: fprintf(gpoutfile, "%1d %1d %1d %1d (%s) %1d %1d %1d %1d %s\n",
458: x, y, RGIP_justify, RGIP_angle * 90, cvstr, RGIP_fface,
459: RGIP_ftype, RGIP_fontsize, RGIP_tcol, RGIP_Obj[RGIPTEXT]);
460: cvstr = ++p;
461: if (RGIP_angle) { /* vertical */
462: x += (t->v_char);
463: } else {
464: y -= (t->v_char);
465: }
466: }
467: }
468:
469:
470: TERM_PUBLIC void RGIP_reset()
471: {
472: if (RGIP_vecpos) {
473: RGIP_write_poly();
474: }
475: fputs("%RI_GROUPEND\n", gpoutfile);
476: /* fputs("%RI_GROUPEND\n", gpoutfile); */
477: }
478:
479: /* static void
480: RGIP_setfont(sz)
481: int sz;
482: {
483: RGIP_fontsize = (int) (sz);
484: if ( RGIP_fontsize < 1 ) RGIP_fontsize = 1;
485: term->v_char = (unsigned int)(RGIP_fontsize*RGIP_SC);
486: term->h_char = (unsigned int)(RGIP_fontsize*RGIP_SC*3/7);
487: }
488: */
489:
490: TERM_PUBLIC void RGIP_do_point(x, y, number)
491: unsigned int x, y;
492: int number;
493: {
494:
495: x += RGIP_orgx,
496: y += RGIP_orgy;
497:
498: if (number < 0) { /* do dot */
499: fprintf(gpoutfile, "%1d %1d %1d %s\n",
500: x, y, RGIP_mcol, RGIP_Obj[RGIPDOTS]);
501: return;
502: }
503: RGIP_msty = (number % RGIP_POINT_TYPES) + 1;
504: RGIP_msize = ((int) (number / RGIP_POINT_TYPES)) + 1;
505:
506: fprintf(gpoutfile, "%1d %1d %1d %1d %1d %s\n",
507: x, y, RGIP_msize, RGIP_msty, RGIP_mcol, RGIP_Obj[RGIPMARK]);
508: }
509:
510: TERM_PUBLIC void RGIP_options()
511: {
512: struct value a;
513:
514: while (!END_OF_COMMAND) {
515: if (almost_equals(c_token, "p$ortrait")) {
516: RGIP_portrait = TRUE;
517: c_token++;
518: } else if (almost_equals(c_token, "l$andscape")) {
519: RGIP_portrait = FALSE;
520: c_token++;
521: } else if (equals(c_token, "[")) { /* windows spesified */
522: c_token++;
523: /* if (RGIP_plot_nr>1) */
524: if (equals(c_token, "]")) {
525: /* RGIP_page(); */
526: c_token++;
527: continue;
528: }
529: if (END_OF_COMMAND) {
530: int_error("no. windows: [horizontal,vertical] expected", c_token);
531: } else if (!equals(c_token, ",")) {
532: RGIP_win_horiz = (int) real(const_express(&a));
533: }
534: if (!equals(c_token, ","))
535: int_error("',' expected", c_token);
536: c_token++;
537: if (!equals(c_token, "]")) {
538: RGIP_win_verti = (int) real(const_express(&a));
539: }
540: if (!equals(c_token, "]"))
541: int_error("expecting ']'", c_token);
542: c_token++;
543: } else {
544: /* We have font size specified */
545: RGIP_fontsize = (int) real(const_express(&a));
546: if (RGIP_fontsize < 1)
547: RGIP_fontsize = 1;
548: term->v_char = (unsigned int) (RGIP_fontsize * RGIP_SC);
549: term->h_char = (unsigned int) (RGIP_fontsize * RGIP_SC * 3 / 7);
550: }
551: }
552: sprintf(term_options, "%s %d [%1d,%1d]",
553: (RGIP_portrait) ? "portrait" : "landscape",
554: RGIP_fontsize, RGIP_win_horiz, RGIP_win_verti);
555: }
556:
557: #endif /* TERM_BODY */
558:
559: #ifdef TERM_TABLE
560:
561: TERM_TABLE_START(rgip_driver)
562: "rgip", "RGIP metafile (Uniplex). Option: fontsize (1-8)",
563: RGIP_XMAX, RGIP_YMAX, RGIP_VCHAR, RGIP_HCHAR,
564: RGIP_VTIC, RGIP_HTIC, RGIP_options, RGIP_init, RGIP_reset,
565: RGIP_text, null_scale, RGIP_graphics, RGIP_move,
566: RGIP_vector, RGIP_linetype, RGIP_put_text, RGIP_text_angle,
567: RGIP_justify_text, RGIP_do_point, do_arrow, set_font_null
568: TERM_TABLE_END(rgip_driver)
569:
570: #undef LAST_TERM
571: #define LAST_TERM rgip_driver
572:
573: TERM_TABLE_START(uniplex_driver)
574: "uniplex", "RGIP metafile (Uniplex). Option: fontsize (1-8) (Same as rgip)",
575: RGIP_XMAX, RGIP_YMAX, RGIP_VCHAR, RGIP_HCHAR,
576: RGIP_VTIC, RGIP_HTIC, RGIP_options, RGIP_init, RGIP_reset,
577: RGIP_text, null_scale, RGIP_graphics, RGIP_move,
578: RGIP_vector, RGIP_linetype, RGIP_put_text, RGIP_text_angle,
579: RGIP_justify_text, RGIP_do_point, do_arrow, set_font_null
580: TERM_TABLE_END(uniplex_driver)
581:
582: #undef LAST_TERM
583: #define LAST_TERM uniplex_driver
584:
585: #endif /* TERM_TABLE */
586: #endif /* TERM_PROTO_ONLY */
587:
588: #ifdef TERM_HELP
589: START_HELP(rgip)
590: "1 rgip",
591: "?commands set terminal rgip",
592: "?set terminal rgip",
593: "?set term rgip",
594: "?terminal rgip",
595: "?term rgip",
596: "?rgip",
597: "?commands set terminal uniplex",
598: "?set terminal uniplex",
599: "?set term uniplex",
600: "?terminal uniplex",
601: "?term uniplex",
602: "?uniplex",
603: " The `rgip` and `uniplex` terminal drivers support RGIP metafiles. They can",
604: " combine several graphs on a single page, but only one page is allowed in a",
605: " given output file.",
606: "",
607: " Syntax:",
608: " set terminal rgip | uniplex {portrait | landscape}",
609: " {[<horiz>,<vert>]} {<fontsize>}",
610: "",
611: " permissible values for the font size are in the range 1--8, with the default",
612: " being 1. The default layout is landscape. Graphs are placed on the page in",
613: " a `horiz`x`vert` grid, which defaults to [1,1].",
614: "",
615: " Example:",
616: " set terminal uniplex portrait [2,3]",
617: "",
618: " puts six graphs on a page in three rows of two in portrait orientation."
619: END_HELP(rgip)
620: #endif /* TERM_HELP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>