[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.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>