[BACK]Return to mif.trm CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot / term

Annotation of OpenXM_contrib/gnuplot/term/mif.trm, Revision 1.1.1.2

1.1       maekawa     1: /*
1.1.1.2 ! maekawa     2:  * $Id: mif.trm,v 1.11 1999/01/12 14:04:11 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: /* 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>