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