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

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>