Annotation of OpenXM_contrib/gnuplot/term/mif.trm, Revision 1.1.1.3
1.1 maekawa 1: /*
1.1.1.3 ! ohara 2: * $Id: mif.trm,v 1.11.2.2 2002/12/11 19:24:27 lhecking Exp $
1.1 maekawa 3: */
4: /* GNUPLOT -- mif.trm */
5:
6: /*[
7: * Copyright 1992, 1993, 1998
8: *
9: * Permission to use, copy, and distribute this software and its
10: * documentation for any purpose with or without fee is hereby granted,
11: * provided that the above copyright notice appear in all copies and
12: * that both that copyright notice and this permission notice appear
13: * in supporting documentation.
14: *
15: * Permission to modify the software is granted, but not the right to
16: * distribute the complete modified source code. Modifications are to
17: * be distributed as patches to the released version. Permission to
18: * distribute binaries produced by compiling modified sources is granted,
19: * provided you
20: * 1. distribute the corresponding source modifications from the
21: * released version in the form of a patch file along with the binaries,
22: * 2. add special version identification to distinguish your version
23: * in addition to the base release version number,
24: * 3. provide your name and address as the primary contact for the
25: * support of your modified version, and
26: * 4. retain our contact information in regard to use of the base
27: * software.
28: * Permission to distribute the released version of the source code along
29: * with corresponding source modifications in the form of a patch file is
30: * granted with same provisions 2 through 4 for binary distributions.
31: *
32: * This software is provided "as is" without express or implied warranty
33: * to the extent permitted by applicable law.
34: ]*/
35:
36: /*
37: * This file is included by ../term.c.
38: *
39: * This terminal driver was developed for
40: * gnuplot for unix version 3.0 (patchlevel 1)
41: * gnuplot for unix version 3.2 (patchlevel 2)
42: *
43: * This terminal driver supports:
44: * Frame Maker MIF format version 3.00
45: *
46: * Options for this terminal driver (set terminal mif [options]):
47: * colour / Draw primitives with line types >= 0 in colour (sep. 2-7)
48: * monochrome Draw primitives in black (sep. 0)
49: *
50: * polyline / Draw lines as continous curves
51: * vectors Draw lines as collections of vectors
52: *
53: * help / ? Print short usage description on stderr
54: *
55: * Properties for this terminal driver:
56: * -Gnuplot size of worksheet: MIF_XMAX * MIF_YMAX
57: * -Unit in MIF output: cm
58: * -Plot primitives with the same pen will
59: * be grouped in the same MIF group.
60: * -Plot primitives with line types >= 0
61: * will as default be drawn in colour.
62: * -Lines are plotted as collections of
63: * vectors, or as continous lines (default)
64: * -Plot primitives in a plot will be in a
65: * Frame in MIF. Several plot Frames will
66: * be collected in one large Frame.
67: * -Point size of MIF output characters: MIF_PSIZE
68: * -Used font for MIF output characters: Times
69: * -Supports vertical text
70: * -points and dots as characters
71: * -character formats for TextLines
72: *
73: * AUTHORS:
74: * Olof Franksson, Physics IV, KTH, S-100 44 Stockholm, Sweden
75: *
76: * NEW TERMINAL FORMAT: David C. Schooley
77:
78: * COMMENTS:
79: * Send comments and/or suggestions to olof@fysik4.kth.se
80: *
81: * CHANGES:
82: * Changed to new terminal format 9/29/95 schooley@ee.gatech.edu
83: * Changed order of routine declarations. olof@fysik4.kth.se
84: * Changed mechanism for pen pattern selection. kssingvo@immd4.informatik.uni-erlangen.de
85: * Support for vertical text. kssingvo@immd4.informatik.uni-erlangen.de
86: * Fixed plot bug for "set size XS,YS", XS/YS > 1. olof@fysik4.kth.se
87: *
88: */
89:
90: #include "driver.h"
91:
92: #ifdef TERM_REGISTER
93: register_term(mif)
94: #endif
95:
96:
97:
98: #ifdef TERM_PROTO
99: TERM_PUBLIC void MIF_init __PROTO((void));
100: TERM_PUBLIC void MIF_graphics __PROTO((void));
101: TERM_PUBLIC void MIF_text __PROTO((void));
102: TERM_PUBLIC void MIF_linetype __PROTO((int linetype));
103: TERM_PUBLIC void MIF_move __PROTO((unsigned int x, unsigned int y));
104: TERM_PUBLIC void MIF_vector __PROTO((unsigned int x, unsigned int y));
105: TERM_PUBLIC void MIF_put_text __PROTO((unsigned int x, unsigned int y, char *str));
106: TERM_PUBLIC int MIF_text_angle __PROTO((int ang));
107: TERM_PUBLIC void MIF_reset __PROTO((void));
108: TERM_PUBLIC void MIF_options __PROTO((void));
109: TERM_PUBLIC int MIF_justify_text __PROTO((enum JUSTIFY mode));
110: TERM_PUBLIC void MIF_point __PROTO((unsigned int x, unsigned int y, int number));
111:
112: /** Coordinates **/
113: /* The cast to float is not necessary because we are dividing by a float */
114: /* On OSK the cast to a float is not allowed in a constant expression wich */
115: /* is used by the declaration and initialization of mif_line */
116: /* Converts gnuplot units to MIF units */
117: #define GNP_TO_MIF(P) ((P) / 1000.0)
118: /* Basic unit: 0.01 mm (15cm -> 15*10*100=15000) */
119: #define MIF_XMAX 15000
120: /* Basic unit: 0.01 mm (10cm -> 10*10*100=10000) */
121: #define MIF_YMAX 10000
122:
123: #define MIF_XLAST (MIF_XMAX - 1)
124: #define MIF_YLAST (MIF_YMAX - 1)
125:
126: static int insert_mif_line __PROTO((double fx, double fy));
127: static int proc_group_id __PROTO((int group_id));
128: static void free_mif_line __PROTO((void));
129: static void put_mif_line __PROTO((void));
130: static void MIF_set_font __PROTO((char *));
131: static void mif_put_point __PROTO((unsigned int x, unsigned int y, int np));
132:
133: #ifndef cfree
134: # define cfree free
135: #endif
136:
137: /* Declared in ../setshow.c */
138: extern char term_options[];
139:
140: static struct mif_line { /* Line point structure specification */
141: float fpos_x; /* Line point X coordinate */
142: float fpos_y; /* Y coordinate */
143: struct mif_line *next; /* Pointer to next line point */
144: struct mif_line *prev; /* Pointer to previous line point */
145: } mif_line =
146: { /* Current position structure. Adjust for orign. Local for this file. */
147: GNP_TO_MIF(0),
148: GNP_TO_MIF(MIF_YLAST),
149: &mif_line,
150: &mif_line
151: };
152:
153: /** Characters **/
154: #define MIF_PSIZE 9 /* Point size of used characters */
155:
156: #define MIF_VCHAR (MIF_YMAX/31) /* Distance between rows (a guess) */
157: #define MIF_HCHAR (MIF_XMAX/95) /* Distance between characters (a guess) */
158:
159: /** Scale marks **/
160: #define MIF_VTIC (MIF_YMAX/150) /* Size of scale mark (vert) */
161: #define MIF_HTIC (MIF_XMAX/225) /* Size of scale mark (hor) */
162:
163: /** Drawing properties **/
164: static char mif_justify[64]; /* How to justify the used text */
165: static char mif_pen[64], mif_pen_width[64], mif_separation[64]; /* How to plot */
166:
167: #define MIF_TEXT_HOR 0
168: #define MIF_TEXT_VER 1
169: static int mif_text_ang = MIF_TEXT_HOR; /* Rotation angle of text */
170:
171: #define MIF_NPENS 16 /* Number of MIF pen types */
172: static int mif_pentype = 0; /* Pen type to use. Also used to create groups for graphics */
173: #define MIF_PEN_TO_GROUP(P) ( 1 + (P) ) /* Map pen type to group number. Must be >= 1 */
174:
175: static int mif_pattern_table[MIF_NPENS] =
176: { /* Table, which pattern should be used for drawing */
177: 0, /* border */
178: 1, /* not used */
179: 2, 3, 4, 8, 12, 13, /* other lines: functions, data, ... (5 is used for grid; 6,7 is (nearly) invisible) */
180: 5, /* grid */
181: 9, 10, 11, 12, 13, 14, 15 /* not used */
182: };
183:
184: /** MIF groups administration **/
185: #define MIF_NGROUP_ID 20
186: static struct mif_group_id {
187: int group_existance;
188: /* This group id should generate a MIF group */
189: #define MIF_GROUP_EXISTS 1
190: /* This group id should not generate a MIF group */
191: #define MIF_GROUP_NOT_EXISTS 0
192:
193: int group_id;
194: #define MIF_INVALID_GROUP_ID 0 /* An invalid MIF group ID */
195:
196: } mif_group_id[MIF_NGROUP_ID]; /* List of used group ID:s and corresponding MIF groups existance */
197:
198: /** Semaphores **/
199: static int mif_initialized = 0; /* != 0 when output is active */
200: static int mif_in_frame = 0; /* != 0 when inside a plot frame */
201: static int mif_frameno = -1; /* Current frame number */
202: static int mif_colour = TRUE; /* == TRUE when colour should be used */
203: static int mif_polyline = TRUE; /* == TRUE when lines are drawn as continous curves */
204:
205: struct mpt { /* point definition structure */
206: int chr; /* character for point */
207: float x_offset, y_offset; /* offset for vertical positioning */
208: char *font; /* font */
209: };
210:
211: char zgnuplot[] = "ZGnuplot"; /* character formats */
212: char zgnuplotp[] = "ZGnuplotP";
213: char zgnuplotd[] = "ZGnuplotD";
214: char *mif_font = NULL; /* actual character format */
215:
216: struct mpt mpt[POINT_TYPES + 1] =
217: { /* point definition data */
218: {'.', 0.000, 0.005, zgnuplotd, /* dot */ },
219:
220: {'G', 0.002, 0.084, zgnuplotp, /* diamond */ },
221: {';', 0.002, 0.084, zgnuplotp, /* plus */ },
222: {'n', 0.002, 0.084, zgnuplotp, /* box */ },
223: {'5', 0.002, 0.084, zgnuplotp, /* X */ },
224: {'s', 0.002, 0.062, zgnuplotp, /* triangle */ },
225: {'K', 0.005, 0.075, zgnuplotp, /* star */ },
226: };
227:
228: /* diamond is offset 0, dot is offset -1 */
229: struct mpt *mif_point = &(mpt[1]);
230:
231: #endif
232:
233:
234: #ifndef TERM_PROTO_ONLY
235: #ifdef TERM_BODY
236:
237:
238: /** Declaration of routine/s for internal use **/
239: static int insert_mif_line __PROTO((double fx, double fy));
240: static int proc_group_id __PROTO((int group_id));
241:
242: /** Routine/s **/
243:
244: /* Called when this terminal type is set in order to parse options */
245: TERM_PUBLIC void MIF_options()
246: {
247: if (!END_OF_COMMAND) {
248: /* Colour options */
249: if (!END_OF_COMMAND && almost_equals(c_token, "m$onochrome")) { /* Compare up to $ */
250: mif_colour = FALSE;
251: c_token++;
252: }
253: if (!END_OF_COMMAND && (almost_equals(c_token, "c$olor")
254: || almost_equals(c_token, "c$olour"))) { /* Compare up to $ */
255: mif_colour = TRUE;
256: c_token++;
257: }
258: /* Curve options */
259: if (!END_OF_COMMAND && almost_equals(c_token, "v$ectors")) { /* Compare up to $ */
260: mif_polyline = FALSE;
261: c_token++;
262: }
263: if (!END_OF_COMMAND && almost_equals(c_token, "p$olyline")) { /* Compare up to $ */
264: mif_polyline = TRUE;
265: c_token++;
266: }
267: /* Short help */
268: if (!END_OF_COMMAND &&
269: (almost_equals(c_token, "h$elp") ||
270: almost_equals(c_token, "?$"))) { /* Compare up to $ */
271: fprintf(stderr, "\
272: Usage: set terminal mif [options]\n\
273: \toptions:\n\
274: \t\tcolour / Draw primitives with line types >= 0 in colour (sep. 2-7)\n\
275: \t\tmonochrome Draw primitives in black (sep. 0)\n\n\
276: \t\tpolyline / Draw lines as continous curves\n\
277: \t\tvectors Draw lines as collections of vectors\n\n\
278: \t\thelp / ? Print short usage description on stderr\n");
279:
280: c_token++;
281: }
282: }
283: sprintf(term_options, "%s %s", (mif_colour == TRUE) ? "colour" : "monochrome",
284: (mif_polyline == TRUE) ? "polyline" : "vectors");
285: }
286:
287: /* Deallocate the used line structure elements */
288: static void free_mif_line()
289: {
290: struct mif_line *tline;
291:
292: while (mif_line.prev != &mif_line) {
293: /* Unlink */
294: tline = mif_line.prev;
295: mif_line.prev = mif_line.prev->prev;
296: mif_line.prev->next = &mif_line;
297:
298: /* Deallocate */
299: free(tline);
300: }
301:
302: /* Make sure that the list will be empty */
303: mif_line.prev = &mif_line;
304: mif_line.next = &mif_line;
305: }
306:
307: /* Draw the pending line. Change current position. */
308: static void put_mif_line()
309: {
310: int np, i;
311: struct mif_line *tline;
312:
313: /* Process if inside a Frame */
314: if (mif_initialized != 0 && mif_in_frame != 0) {
315:
316: /* Count the number of available points */
317: for (tline = mif_line.next, np = 1; tline != &mif_line; tline = tline->next, np++);
318:
319: /* Draw line (at least two points) */
320: if (np >= 2) {
321:
322: /* Line preamble */
323: fprintf(gpoutfile, "\t<PolyLine <GroupID %d> %s %s %s\n",
324: MIF_PEN_TO_GROUP(mif_pentype), mif_pen, mif_pen_width, mif_separation);
325:
326: /* Draw the line elements */
327: fprintf(gpoutfile, "\t\t<NumPoints %d> ", np);
328: for (i = 0, tline = &mif_line; i < np; i++, tline = tline->next) {
329: if (i % 4 == 0)
330: fputs("\n\t\t", gpoutfile);
331: fprintf(gpoutfile, "<Point %.3f %.3f> ",
332: tline->fpos_x, tline->fpos_y);
333: }
334:
335: /* Line post amble */
336: fputs("\n\t>\n", gpoutfile);
337:
338: /* Register the used group ID */
339: proc_group_id(MIF_PEN_TO_GROUP(mif_pentype));
340:
341: /* Avoid to redraw this. The MIF system should remember it. */
342: mif_pen[0] = '\0';
343: mif_pen_width[0] = '\0';
344: mif_separation[0] = '\0';
345:
346: /* Move current position to end of line */
347: mif_line.fpos_x = mif_line.prev->fpos_x;
348: mif_line.fpos_y = mif_line.prev->fpos_y;
349:
350: /* Restore the line */
351: free_mif_line();
352: }
353: } /* Line processed */
354: }
355:
356:
357: /* Draw a point */
358: static void mif_put_point(x, y, np)
359: unsigned int x, y;
360: int np;
361: {
362: /* Process if inside a Frame */
363: if (mif_initialized != 0 && mif_in_frame != 0) {
364:
365: /* Draw pending line */
366: if (mif_polyline == TRUE)
367: put_mif_line();
368:
369: /* Adjust current position for text-graphics alignment */
370: MIF_move(x, y);
371:
372: /* center text */
373: MIF_justify_text(CENTRE);
374:
375: /* Draw the point */
376: fprintf(gpoutfile, "\t<TextLine <GroupID %d>\n",
377: MIF_PEN_TO_GROUP(mif_pentype));
378:
379: MIF_set_font(mif_point[np].font);
380:
381: fprintf(gpoutfile, "\t\t<TLOrigin %.3f %.3f> %s <String `%c'>\n",
382: mif_line.fpos_x + mif_point[np].x_offset,
383: mif_line.fpos_y + mif_point[np].y_offset,
384: mif_justify,
385: mif_point[np].chr);
386: fputs("\t>\n", gpoutfile);
387:
388: /* Register the used group ID */
389: proc_group_id(MIF_PEN_TO_GROUP(mif_pentype));
390:
391: /* Avoid to redraw this. The MIF system should remember it. */
392: mif_justify[0] = '\0';
393:
394: } /* Point processed */
395: }
396:
397:
398: /*
399: * draw points
400: */
401: TERM_PUBLIC void MIF_point(x, y, number)
402: unsigned int x, y;
403: int number;
404: {
405: if (number < 0) { /* dot */
406: number = -1;
407: } else { /* point */
408: number %= POINT_TYPES;
409: }
410: mif_put_point(x, y, number);
411: }
412:
413:
414: /* Set up a MIF output file */
415: TERM_PUBLIC void MIF_init()
416: {
417: int i;
418:
419: /* Process if not inside a MIF file and Frame */
420: if (mif_initialized == 0 && mif_in_frame == 0) {
421: /* Tell this terminal driver that the output is initialized and no current frames are processed */
422: mif_initialized = 1;
423: mif_in_frame = 0;
424:
425: /* Reset internal position */
426: free_mif_line();
427: mif_line.fpos_x = GNP_TO_MIF(0);
428: mif_line.fpos_y = GNP_TO_MIF(MIF_YLAST);
429:
430: /* Reset drawing properties strings */
431: mif_pen[0] = '\0';
432: mif_pen_width[0] = '\0';
433: mif_separation[0] = '\0';
434:
435: MIF_justify_text(LEFT);
436:
437: /* Reset group ID generator */
438: for (i = 0; i < MIF_NGROUP_ID; i++) {
439: mif_group_id[i].group_id = MIF_INVALID_GROUP_ID;
440: mif_group_id[i].group_existance = MIF_GROUP_NOT_EXISTS;
441: }
442:
443: /* Identify ourselves */
444: /*bs show borders */
445: /* Setup a default environment to use */
446: fprintf(gpoutfile, "\
447: <MIFFile 3.00> # Generated by gnuplot version %s patchlevel %s; identifies this as a MIF file\n\
448: #\n\
449: # show borders\n\
450: <Document\n<DBordersOn Yes>\n>\n\
451: # Set a default pen pattern, pen width, unit and font for subsequent objects\n\
452: <Pen 0>\n\
453: <Fill 15>\n\
454: <PenWidth 0.5 pt>\n\
455: <Separation 0>\n\
456: <Units Ucm>\n\
457: <FontCatalog\n\
458: \t<Font <FTag `%s'><FFamily `Times'><FSize %d><FPlain Yes>>\n\
459: \t<Font <FTag `%s'><FFamily `ZapfDingbats'><FSize 7.0 pt><FPlain Yes>>\n\
460: \t<Font <FTag `%s'><FFamily `Symbol'><FSize 5.0 pt><FPlain Yes>>\n\
461: >\n\
462: #\n",
1.1.1.3 ! ohara 463: gnuplot_version, gnuplot_patchlevel,
1.1 maekawa 464: zgnuplot, MIF_PSIZE,
465: zgnuplotp,
466: zgnuplotd);
467: } /* MIF file created */
468: }
469:
470: /* Finish of a MIF output file */
471: TERM_PUBLIC void MIF_reset()
472: {
473: /* Process if inside a MIF file and not inside a Frame */
474: if (mif_initialized != 0 && mif_in_frame == 0) {
475: /* Finish off the MIF file */
476: fputs("\
477: #\n\
478: # End of MIFFile\n", gpoutfile);
479:
480: /* Tell this terminal driver that the output is finished */
481: mif_initialized = 0;
482:
483: /* bs: reset frame number */
484: mif_frameno = -1;
485:
486: } /* MIF file finished */
487: }
488:
489: /* Start plotting a Frame (-> graphics mode) */
490: TERM_PUBLIC void MIF_graphics()
491: {
492: int i;
493:
494: /* Process if not inside a Frame */
495: if (mif_initialized != 0 && mif_in_frame == 0) {
496: /* Tell that this terminal driver is working with a plot frame */
497: mif_in_frame = 1;
498:
499: /* Update frame number */
500: mif_frameno++;
501:
502: /* Set current position */
503: free_mif_line();
504: mif_line.fpos_x = GNP_TO_MIF(0);
505: mif_line.fpos_y = GNP_TO_MIF(MIF_YLAST);
506:
507: /* Set drawing properties */
508: mif_pen[0] = '\0';
509: mif_pen_width[0] = '\0';
510: mif_separation[0] = '\0';
511:
512: MIF_justify_text(LEFT);
513:
514: /* Reset group ID generator */
515: for (i = 0; i < MIF_NGROUP_ID; i++) {
516: mif_group_id[i].group_id = MIF_INVALID_GROUP_ID;
517: mif_group_id[i].group_existance = MIF_GROUP_NOT_EXISTS;
518: }
519:
520: /* Frame preamble */
521: fprintf(gpoutfile, "\
522: #\n\
523: # Frame number %d with plot of graphics\n\
524: <Frame\n\
525: \t<Pen 15>\n\
526: \t<Fill 15>\n\
527: \t<PenWidth 0.5 pt>\n\
528: \t<Separation 0>\n\
529: \t<BRect 2.000 %.3f %.3f %.3f>\n\
530: \t<NSOffset 0.000>\n\
531: \t<BLOffset 0.000>\n",
532: mif_frameno,
533: ((float) mif_frameno) * GNP_TO_MIF(MIF_YMAX + 100),
534: GNP_TO_MIF(MIF_XMAX), GNP_TO_MIF(MIF_YMAX));
535: } /* Frame created */
536: }
537:
538: /* Stop plotting a Frame (-> text mode) */
539: TERM_PUBLIC void MIF_text()
540: {
541: int i;
542:
543: /* Process if inside a Frame */
544: if (mif_initialized != 0 && mif_in_frame != 0) {
545:
546: /* Draw pending line */
547: if (mif_polyline == TRUE)
548: put_mif_line();
549:
550: /* Group the used plot primitives */
551: fputs("\
552: \t#\n\
553: \t# Group the the objects in groups to make the chart easier to manipulate\n\
554: \t# after it's imported into FrameMaker.\n", gpoutfile);
555:
556: for (i = 0; i < MIF_NGROUP_ID; i++) {
557: if (mif_group_id[i].group_id != MIF_INVALID_GROUP_ID &&
558: mif_group_id[i].group_existance == MIF_GROUP_EXISTS) {
559: fprintf(gpoutfile, "\
560: \t<Group\n\
561: \t\t<ID %d>\n\
562: \t>\n", mif_group_id[i].group_id);
563: }
564: }
565:
566: /* Frame post amble */
567: fprintf(gpoutfile, "\
568: >\n\
569: # End of Frame number %d\n\
570: #\n",
571: mif_frameno);
572:
573: /* Tell that this terminal driver is not working with a plot frame */
574: mif_in_frame = 0;
575: } /* Frame finshed */
576: }
577:
578: /* Select type of line in grapics */
579: /* NOTE: actually written to output the first time a primitive
580: * is drawn AFTER this call */
581: TERM_PUBLIC void MIF_linetype(linetype)
582: /* -2=border, -1=X/Y-axis, 0-13=lines, and 14-=mapped back */
583: int linetype;
584: {
585: /* Process if inside a Frame */
586: if (mif_initialized != 0 && mif_in_frame != 0) {
587:
588: /* Draw pending line */
589: if (mif_polyline == TRUE)
590: put_mif_line();
591:
592: /* Translate gnuplot pen types to MIF pen types */
593: if (linetype < 0) { /* Special lines */
594: if (linetype == -1) {
595: mif_pentype = 8 + MIF_NPENS; /* -1 */
596: if (mif_colour == TRUE)
597: sprintf(mif_separation, " <Separation 0> ");
598: } else {
599: mif_pentype = 0 + MIF_NPENS; /* -2 or less */
600: if (mif_colour == TRUE)
601: sprintf(mif_separation, " <Separation 0> ");
602: }
603: sprintf(mif_pen_width, " <PenWidth 1.0 pt> ");
604: } else { /* Normal lines */
605: mif_pentype = (linetype) % MIF_NPENS; /* 0-(MIF_NPENS-1) */
606: sprintf(mif_pen_width, " <PenWidth 0.1 pt> ");
607: if (mif_colour == TRUE)
608: sprintf(mif_separation, " <Separation %d> ", 2 + (mif_pentype % 6)); /* 2-7 */
609: }
610:
611: /* Set pen type */
612: sprintf(mif_pen, " <Pen %d> ", mif_pattern_table[mif_pentype % MIF_NPENS]);
613:
614: } /* Primitive processed */
615: }
616:
617: /* Draw the text horisontally or vertically (90 degrees counterclockwise) */
618: TERM_PUBLIC int MIF_text_angle(ang)
619: int ang;
620: {
621: if (ang != 0)
622: mif_text_ang = MIF_TEXT_VER;
623: else
624: mif_text_ang = MIF_TEXT_HOR;
625:
626: return (TRUE);
627: }
628:
629: /* Justify following text lines (MIF_put_text()) relative to the insertion point */
630: TERM_PUBLIC int MIF_justify_text(mode)
631: /* NOTE: actually written to output in text primitives which are
632: * drawn AFTER this call */
633: enum JUSTIFY mode;
634: {
635: int rval = TRUE;
636:
637: /* Process if inside a Frame */
638: if (mif_initialized != 0 && mif_in_frame != 0) {
639: switch (mode) {
640: case LEFT:
641: sprintf(mif_justify, " <TLAlignment Left> ");
642: break;
643: case CENTRE:
644: sprintf(mif_justify, " <TLAlignment Center> ");
645: break;
646: case RIGHT:
647: sprintf(mif_justify, " <TLAlignment Right> ");
648: break;
649: default:
650: rval = FALSE;
651: break;
652: }
653:
654: }
655: /* Primitive processed */
656: else {
657: rval = FALSE;
658: }
659:
660: return (rval);
661: }
662:
663: /* Draw a vector from current position to (x, y) and change current position. */
664: /* NOTE: actually written to output the first time another primitive
665: * is called AFTER this call */
666: TERM_PUBLIC void MIF_vector(x, y)
667: unsigned int x, y;
668: {
669: /* Process if inside a Frame */
670: if (mif_initialized != 0 && mif_in_frame != 0) {
671:
672: /* Setup the vector as a part of the line */
673: insert_mif_line(GNP_TO_MIF(x), GNP_TO_MIF(MIF_YLAST - (int) y));
674:
675: /* Draw pending line -> vector */
676: if (mif_polyline == FALSE)
677: put_mif_line();
678:
679: } /* Vector processed */
680: }
681:
682: /* Move current position */
683: TERM_PUBLIC void MIF_move(x, y)
684: unsigned int x, y;
685: {
686: /* Process if inside a Frame */
687: if (mif_initialized != 0 && mif_in_frame != 0) {
688:
689: /* Draw pending line */
690: if (mif_polyline == TRUE)
691: put_mif_line();
692:
693: mif_line.fpos_x = GNP_TO_MIF(x);
694: mif_line.fpos_y = GNP_TO_MIF(MIF_YLAST - (int) y);
695: }
696: }
697:
698:
699: /* set font */
700: static void MIF_set_font(font)
701: char *font;
702: {
703: if (font != mif_font) {
704: fprintf(gpoutfile, "\t\t<Font\n\t\t\t<FTag `%s'>\n\t\t>\n", font);
705: mif_font = font;
706: }
707: }
708:
709:
710: /* Draw the text string str at (x, y). Adjust according to MIF_justify_text().
711: * Change current position. */
712: TERM_PUBLIC void MIF_put_text(x, y, str)
713: unsigned int x, y;
714: char str[];
715: {
716: /* Process if inside a Frame */
717: if (mif_initialized != 0 && mif_in_frame != 0) {
718:
719: /* Draw pending line */
720: if (mif_polyline == TRUE)
721: put_mif_line();
722:
723: /* Adjust current position for text-graphics alignment */
724: MIF_move(x, y - MIF_VCHAR / 5);
725:
726: if (strlen(str) > 0) {
727:
728: /* Draw the text */
729: fprintf(gpoutfile, "\t<TextLine <GroupID %d> %s %s %s\n",
730: MIF_PEN_TO_GROUP(mif_pentype), mif_pen,
731: mif_pen_width, mif_separation);
732:
733: MIF_set_font(zgnuplot);
734:
735: fprintf(gpoutfile, "\
736: \t\t<TLOrigin %.3f %.3f> %s %s <String `%s'>\n\
737: \t>\n",
738: mif_line.fpos_x, mif_line.fpos_y, mif_justify,
739: (mif_text_ang == MIF_TEXT_VER) ? "<Angle 90>" : "",
740: str);
741:
742: /* Register the used group ID */
743: proc_group_id(MIF_PEN_TO_GROUP(mif_pentype));
744:
745: /* Avoid to redraw this. The MIF system should remember it. */
746: mif_pen[0] = '\0';
747: mif_pen_width[0] = '\0';
748: mif_separation[0] = '\0';
749:
750: mif_justify[0] = '\0'; /* Independent of linetype */
751: }
752: } /* Text processed */
753: }
754:
755:
756: /* Insert one point in the line */
757: static int insert_mif_line(fx, fy)
758: double fx, fy;
759: {
760: int rval = TRUE;
761:
762: if ((mif_line.prev->next = (struct mif_line *) gp_alloc(sizeof(struct mif_line),
763: "MIF driver")) != (struct mif_line *) NULL) {
764: /* Link */
765: mif_line.prev->next->next = &mif_line;
766: mif_line.prev->next->prev = mif_line.prev;
767: mif_line.prev = mif_line.prev->next;
768:
769: /* Fill */
770: mif_line.prev->fpos_x = fx;
771: mif_line.prev->fpos_y = fy;
772:
773: rval = TRUE;
774: } else { /* Failed to allocate */
775: /* Relink */
776: mif_line.prev->next = &mif_line;
777:
778: rval = FALSE;
779: }
780:
781: return (rval);
782: }
783:
784: /* Register group ID. Update group ID existance. */
785: /* Returns: 1 group_id belongs to a MIF group
786: 0 group_id does not belong to a MIF group
787: -1 not inside a Frame
788: -2 group ID list is full
789: */
790: static int proc_group_id(group_id)
791: int group_id;
792: {
793: int i, rval = 0;
794:
795: /* Process if inside a Frame */
796: if (mif_initialized != 0 && mif_in_frame != 0) {
797:
798: /* Find out the group ID, or a free group ID slot index. */
799: for (i = 0; i < MIF_NGROUP_ID &&
800: mif_group_id[i].group_id != MIF_INVALID_GROUP_ID &&
801: mif_group_id[i].group_id != group_id;
802: i++) {
803: /* Don't check the group_existance variable */
804: }
805:
806: if (i < MIF_NGROUP_ID) {
807: if (mif_group_id[i].group_id == MIF_INVALID_GROUP_ID) {
808: /* Register as new group ID for eventual use as MIF group */
809: mif_group_id[i].group_id = group_id;
810: mif_group_id[i].group_existance = MIF_GROUP_NOT_EXISTS;
811: } else {
812: /* If second use of this group ID -> create a new MIF group */
813: if (mif_group_id[i].group_id == group_id) {
814: mif_group_id[i].group_existance = MIF_GROUP_EXISTS;
815: /* NOTE: a group MUST have at least two members. */
816: rval = 1;
817: }
818: }
819: } else {
820: rval = -2; /* No place for this group ID in the list */
821: }
822:
823: }
824: /* Group ID processed */
825: else {
826: rval = -1; /* Not inside a Frame */
827: }
828:
829: /* Return MIF group status */
830: return (rval);
831: }
832:
833:
834: #endif
835:
836:
837: #ifdef TERM_TABLE
838:
839: TERM_TABLE_START(mif_driver)
840: "mif", "Frame maker MIF 3.00 format",
841: MIF_XMAX, MIF_YMAX, MIF_VCHAR, MIF_HCHAR,
842: MIF_VTIC, MIF_HTIC, MIF_options, MIF_init, MIF_reset,
843: MIF_text, null_scale, MIF_graphics, MIF_move, MIF_vector,
844: MIF_linetype, MIF_put_text, MIF_text_angle,
845: MIF_justify_text, MIF_point, do_arrow, set_font_null
846: TERM_TABLE_END(mif_driver)
847:
848: #undef LAST_TERM
849: #define LAST_TERM mif_driver
850:
851: #endif
852: #endif /* TERM_PROTO_ONLY */
853:
854: #ifdef TERM_HELP
855: START_HELP(mif)
856: "1 mif",
857: "?commands set terminal mif",
858: "?set terminal mif",
859: "?set term mif",
860: "?terminal mif",
861: "?term mif",
862: "?mif",
863: " The `mif` terminal driver produces Frame Maker MIF format version 3.00. It",
864: " plots in MIF Frames with the size 15*10 cm, and plot primitives with the same",
865: " pen will be grouped in the same MIF group. Plot primitives in a `gnuplot`",
866: " page will be plotted in a MIF Frame, and several MIF Frames are collected in",
867: " one large MIF Frame. The MIF font used for text is \"Times\".",
868: "",
869: " Several options may be set in the MIF 3.00 driver.",
870: "",
871: " Syntax:",
872: " set terminal mif {colour | monochrome} {polyline | vectors}",
873: " {help | ?}",
874: "",
875: " `colour` plots lines with line types >= 0 in colour (MIF sep. 2--7) and",
876: " `monochrome` plots all line types in black (MIF sep. 0).",
877: " `polyline` plots curves as continuous curves and `vectors` plots curves as",
878: " collections of vectors.",
879: " `help` and `?` print online help on standard error output---both print a",
1.1.1.3 ! ohara 880: " short description of the usage; `help` also lists the options.",
1.1 maekawa 881: "",
882: " Examples:",
883: " set term mif colour polylines # defaults",
884: " set term mif # defaults",
885: " set term mif vectors",
886: " set term mif help"
887: END_HELP(mif)
888: #endif /* TERM_HELP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>