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

Annotation of OpenXM_contrib/gnuplot/term/latex.trm, Revision 1.1

1.1     ! maekawa     1: /*
        !             2:  * $Id: latex.trm,v 1.63 1998/04/14 00:17:53 drd Exp $
        !             3:  *
        !             4:  */
        !             5:
        !             6: /* GNUPLOT - latex.trm */
        !             7:
        !             8: /*[
        !             9:  * Copyright 1990 - 1993, 1998
        !            10:  *
        !            11:  * Permission to use, copy, and distribute this software and its
        !            12:  * documentation for any purpose with or without fee is hereby granted,
        !            13:  * provided that the above copyright notice appear in all copies and
        !            14:  * that both that copyright notice and this permission notice appear
        !            15:  * in supporting documentation.
        !            16:  *
        !            17:  * Permission to modify the software is granted, but not the right to
        !            18:  * distribute the complete modified source code.  Modifications are to
        !            19:  * be distributed as patches to the released version.  Permission to
        !            20:  * distribute binaries produced by compiling modified sources is granted,
        !            21:  * provided you
        !            22:  *   1. distribute the corresponding source modifications from the
        !            23:  *    released version in the form of a patch file along with the binaries,
        !            24:  *   2. add special version identification to distinguish your version
        !            25:  *    in addition to the base release version number,
        !            26:  *   3. provide your name and address as the primary contact for the
        !            27:  *    support of your modified version, and
        !            28:  *   4. retain our contact information in regard to use of the base
        !            29:  *    software.
        !            30:  * Permission to distribute the released version of the source code along
        !            31:  * with corresponding source modifications in the form of a patch file is
        !            32:  * granted with same provisions 2 through 4 for binary distributions.
        !            33:  *
        !            34:  * This software is provided "as is" without express or implied warranty
        !            35:  * to the extent permitted by applicable law.
        !            36: ]*/
        !            37:
        !            38: /*
        !            39:  * This file is included by ../term.c.
        !            40:  *
        !            41:  * This terminal driver supports:
        !            42:  *   LaTeX pictures (latex).
        !            43:  *   LaTeX pictures with emTeX specials (emtex).
        !            44:  *
        !            45:  * AUTHORS
        !            46:  *   David Kotz, Russell Lang
        !            47:  *
        !            48:  * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
        !            49:  *
        !            50:  */
        !            51:
        !            52: /* modified to optimize use of \rule for long lines */
        !            53: /* TLDC: modified to have nice line types */
        !            54:
        !            55: /* the following LATEX driver has been modified by
        !            56:    Russell Lang, eln272v@monu1.cc.monash.oz from the
        !            57:    GnuTeX 1.3 driver by David Kotz, David.Kotz@Dartmouth.edu.
        !            58:    Since then it has been further extended by David Kotz.
        !            59:    EmTeX driver by Russell Lang. */
        !            60:
        !            61: /*  9 Dec 1992  LATEX_put_text rewritten to handle \\ newlines
        !            62:                 Daniel S. Lewart (d-lewart@uiuc.edu) */
        !            63:
        !            64: /* Since it took me a little while to figure out what is happening,
        !            65:  * I may as well write it down.
        !            66:  *  There are three length scales of interest: inches, points
        !            67:  * and dots. inches are obvious. points are the usual typesetting
        !            68:  * thing (ie approx 72 points per inch). This driver works in
        !            69:  * units of dots, which corresponds to pixels on a 300 DPI printer.
        !            70:  * We do a \setlength{unitlength}{...pt} to make teX work in
        !            71:  * terms of dots.  The ... is called LATEX_UNIT in here.
        !            72:  *   The reason I had to get involved in all of this is because
        !            73:  * font size (in pts) was not being scaled up by DOTS_PER_POINT
        !            74:  * - drd, Sept 1996
        !            75:  */
        !            76:
        !            77: #include "driver.h"
        !            78:
        !            79: #ifdef TERM_REGISTER
        !            80: register_term(latex)
        !            81: #ifdef EMTEX
        !            82: register_term(emtex)
        !            83: #endif
        !            84: #endif
        !            85:
        !            86: #ifdef TERM_PROTO
        !            87: TERM_PUBLIC void LATEX_options __PROTO((void));
        !            88: TERM_PUBLIC void LATEX_init __PROTO((void));
        !            89: TERM_PUBLIC void LATEX_graphics __PROTO((void));
        !            90: TERM_PUBLIC void LATEX_text __PROTO((void));
        !            91: TERM_PUBLIC void LATEX_put_text __PROTO((unsigned int x, unsigned int y, char str[]));
        !            92: TERM_PUBLIC void LATEX_linetype __PROTO((int linetype));
        !            93: TERM_PUBLIC void LATEX_move __PROTO((unsigned int x, unsigned int y));
        !            94: TERM_PUBLIC void LATEX_point __PROTO((unsigned int x, unsigned int y, int number));
        !            95: TERM_PUBLIC void LATEX_vector __PROTO((unsigned int ux, unsigned int uy));
        !            96: TERM_PUBLIC void LATEX_arrow __PROTO((unsigned int sx, unsigned int sy, unsigned int ex, unsigned int ey, TBOOLEAN head));
        !            97: TERM_PUBLIC int LATEX_justify_text __PROTO((enum JUSTIFY mode));
        !            98: TERM_PUBLIC int LATEX_text_angle __PROTO((int ang));
        !            99: TERM_PUBLIC void LATEX_reset __PROTO((void));
        !           100:
        !           101: #ifdef EMTEX
        !           102: TERM_PUBLIC void EMTEX_init __PROTO((void));
        !           103: TERM_PUBLIC void EMTEX_reset __PROTO((void));
        !           104: TERM_PUBLIC void EMTEX_text __PROTO((void));
        !           105: #endif
        !           106:
        !           107: #define TINY_STEP 0.5          /* tiny steps for high quality lines */
        !           108:
        !           109: #define LATEX_PTS_PER_INCH (72.27)
        !           110: #define DOTS_PER_INCH (300)    /* resolution of printer we expect to use */
        !           111: #define LATEX_UNIT (LATEX_PTS_PER_INCH/DOTS_PER_INCH)  /* dot size in pt */
        !           112:
        !           113: /* 5 inches wide by 3 inches high (default) */
        !           114: #define LATEX_XMAX (5*DOTS_PER_INCH)   /* (LATEX_PTS_PER_INCH/LATEX_UNIT*5.0) */
        !           115: #define LATEX_YMAX (3*DOTS_PER_INCH)   /* (LATEX_PTS_PER_INCH/LATEX_UNIT*3.0) */
        !           116:
        !           117: #define LATEX_HTIC (5*DOTS_PER_INCH/72)                /* (5 pts) */
        !           118: #define LATEX_VTIC (5*DOTS_PER_INCH/72)                /* (5 pts) */
        !           119: #define LATEX_HCHAR (DOTS_PER_INCH*53/10/72)   /* (5.3 pts) */
        !           120: #define LATEX_VCHAR (DOTS_PER_INCH*11/72)      /* (11 pts) */
        !           121: #endif
        !           122:
        !           123:
        !           124: #ifndef TERM_PROTO_ONLY
        !           125: #ifdef TERM_BODY
        !           126:
        !           127: static int LATEX_posx;
        !           128: static int LATEX_posy;
        !           129: static int LATEX_fontsize = 10;
        !           130: static char LATEX_font[MAX_ID_LEN+1] = "cmr";
        !           131: static enum JUSTIFY latex_justify = LEFT;
        !           132: static int latex_angle = 0;
        !           133:
        !           134: /* Default line-drawing character */
        !           135: /* the definition of plotpoint varies with linetype */
        !           136: #define LATEX_DOT "\\usebox{\\plotpoint}"
        !           137: #define LATEX_TINY_DOT "\\rule{1pt}{1pt}"      /* for dots plot style */
        !           138:
        !           139: /* POINTS */
        !           140: #define LATEX_POINT_TYPES 12   /* we supply more point types */
        !           141: static char GPFAR *GPFAR LATEX_points[] =
        !           142: {
        !           143:     "\\raisebox{-.8pt}{\\makebox(0,0){$\\Diamond$}}",
        !           144:     "\\makebox(0,0){$+$}",
        !           145:     "\\raisebox{-.8pt}{\\makebox(0,0){$\\Box$}}",
        !           146:     "\\makebox(0,0){$\\times$}",
        !           147:     "\\makebox(0,0){$\\triangle$}",
        !           148:     "\\makebox(0,0){$\\star$}",
        !           149:     "\\circle{12}", "\\circle{18}", "\\circle{24}",
        !           150:     "\\circle*{12}", "\\circle*{18}", "\\circle*{24}"
        !           151: };
        !           152:
        !           153: /* LINES */
        !           154: static float LATEX_size = 0;   /* current thick of line in points */
        !           155: static float LATEX_dotspace = 0;       /* current dotspace of line in points */
        !           156: #define LATEX_LINE_TYPES 6     /* number of line types below */
        !           157: #define LATEX_THIN_LINE 0      /* the thinnest solid line type */
        !           158: static struct {
        !           159:     float size;                        /* size of dot, or thick of line in points */
        !           160:     float dotspace;            /* inter-dot space in points; 0 for lines */
        !           161: } GPFAR LATEX_lines[] =
        !           162:
        !           163: {
        !           164:     {0.4, 0.0},                        /* thin solid line */
        !           165:     {0.4, 5.0},                        /* thin dotted line */
        !           166:     {0.8, 0.0},                        /* thick solid line */
        !           167:     {1.0, 5.0},                        /* thick dotted line */
        !           168:     {1.2, 0.0},                        /* Thick solid line */
        !           169:     {1.0, 10.0},               /* thick widely dotted line */
        !           170: };
        !           171:
        !           172: /* for drawing dotted and solid lines */
        !           173: static void LATEX_dot_line __PROTO((int x1, int x2, int y1, int y2));
        !           174: static void LATEX_solid_line __PROTO((int x1, int x2, int y1, int y2));
        !           175: static void LATEX_rule __PROTO((int code, double x, double y, double width, double height));
        !           176: static void LATEX_flushdot __PROTO((void));
        !           177: #define LATEX_flushrule() LATEX_rule(2, 0.,0.,0.,0.)   /* flush old rule */
        !           178: static TBOOLEAN LATEX_moved = TRUE;    /* pen is up after move */
        !           179: static float LATEX_dotsize;    /* size of LATEX_DOT in units */
        !           180: static TBOOLEAN LATEX_needsdot = FALSE;                /* does dotted line need termination? */
        !           181:
        !           182: #ifdef EMTEX
        !           183: TBOOLEAN emtex = FALSE;                /* not currently using emtex */
        !           184: static void
        !           185: EMTEX_solid_line __PROTO((int x1, int x2, int y1, int y2));
        !           186: #endif
        !           187:
        !           188: /* ARROWS */
        !           189: /* the set of non-vertical/non-horizontal LaTeX vector slopes */
        !           190: /* except negatives - they are handled specially */
        !           191: static struct vslope {
        !           192:     int dx, dy;
        !           193: } GPFAR LATEX_slopes[] =
        !           194:
        !           195: {
        !           196:     {1, 1},
        !           197:     {1, 2},
        !           198:     {1, 3},
        !           199:     {1, 4},
        !           200:     {2, 1},
        !           201:     {2, 3},
        !           202:     {3, 1},
        !           203:     {3, 2},
        !           204:     {3, 4},
        !           205:     {4, 1},
        !           206:     {4, 3},
        !           207:     {0, 0}                     /* terminator */
        !           208: };
        !           209:
        !           210: /* figure out the best arrow */
        !           211: void best_latex_arrow __PROTO((int, int, int, int, int, TBOOLEAN));
        !           212:
        !           213: TERM_PUBLIC void LATEX_options()
        !           214: {
        !           215:     if (!END_OF_COMMAND) {
        !           216:        if (almost_equals(c_token, "c$ourier")) {
        !           217:            strcpy(LATEX_font, "cmtt");
        !           218:            c_token++;
        !           219:        } else if (almost_equals(c_token, "r$oman")) {
        !           220:            strcpy(LATEX_font, "cmr");
        !           221:            c_token++;
        !           222:        } else if (almost_equals(c_token, "d$efault")) {
        !           223:            strcpy(LATEX_font, "cmr");
        !           224:            LATEX_fontsize = 10;
        !           225:            c_token++;
        !           226:        }
        !           227:     }
        !           228:     if (!END_OF_COMMAND) {
        !           229:        struct value a;
        !           230:        LATEX_fontsize = (int) real(const_express(&a));
        !           231:     }
        !           232:     /* tell gnuplot core about char. sizes. Horizontal spacing
        !           233:      * is about half the text pointsize
        !           234:      */
        !           235:     term->v_char = (unsigned int) (LATEX_fontsize * DOTS_PER_INCH / 72);
        !           236:     term->h_char = (unsigned int) (LATEX_fontsize * DOTS_PER_INCH / 144);
        !           237:
        !           238:     sprintf(term_options, "%s %d", LATEX_font[2] == 't' ? "courier" : "roman",
        !           239:            LATEX_fontsize);
        !           240: }
        !           241:
        !           242:
        !           243: TERM_PUBLIC void LATEX_init()
        !           244: {
        !           245: #ifdef EMTEX
        !           246:     emtex = FALSE;
        !           247: #endif
        !           248:     LATEX_posx = LATEX_posy = 0;
        !           249:
        !           250:     fprintf(gpoutfile, "\
        !           251: %% GNUPLOT: LaTeX picture\n\
        !           252: \\setlength{\\unitlength}{%fpt}\n\
        !           253: \\ifx\\plotpoint\\undefined\\newsavebox{\\plotpoint}\\fi\n",
        !           254:            LATEX_UNIT);
        !           255:
        !           256:     LATEX_linetype(-1);
        !           257:     LATEX_size = 0;
        !           258: }
        !           259:
        !           260: TERM_PUBLIC void LATEX_graphics()
        !           261: {
        !           262:     register struct termentry *t = term;
        !           263:
        !           264:     /* bounding box */
        !           265:     int xscale = xsize * t->xmax;
        !           266:     int yscale = ysize * t->ymax;
        !           267:
        !           268:     fprintf(gpoutfile, "\
        !           269: \\begin{picture}(%d,%d)(0,0)\n\
        !           270: \\font\\gnuplot=%s10 at %dpt\n\
        !           271: \\gnuplot\n",
        !           272:            xscale, yscale,
        !           273:            LATEX_font, LATEX_fontsize);
        !           274: }
        !           275:
        !           276:
        !           277: TERM_PUBLIC void LATEX_text()
        !           278: {
        !           279:     LATEX_flushrule();
        !           280:     LATEX_flushdot();
        !           281:     fputs("\\end{picture}\n", gpoutfile);
        !           282:     LATEX_posx = LATEX_posy = 0;       /* current position */
        !           283:     LATEX_moved = TRUE;                /* pen is up after move */
        !           284: }
        !           285:
        !           286: TERM_PUBLIC void LATEX_linetype(linetype)
        !           287: int linetype;
        !           288: {
        !           289:     float size;
        !           290:
        !           291:     if (linetype >= LATEX_LINE_TYPES)
        !           292:        linetype %= LATEX_LINE_TYPES;
        !           293:
        !           294: #ifdef EMTEX
        !           295:     if (!emtex)
        !           296: #endif
        !           297:        LATEX_flushrule();
        !           298:     LATEX_flushdot();
        !           299:
        !           300:     /* Find the new desired line thickness. */
        !           301:     /* negative linetypes (for axes) use a thin line */
        !           302:     /* only relevant for drawing axes/border in 3d */
        !           303:     size = (linetype >= 0 ? LATEX_lines[linetype].size
        !           304:            : LATEX_lines[LATEX_THIN_LINE].size);
        !           305:
        !           306:     /* If different from current size, redefine \plotpoint */
        !           307:     if (size != LATEX_size) {
        !           308:        fprintf(gpoutfile,
        !           309:                "\\sbox{\\plotpoint}{\\rule[%.3fpt]{%.3fpt}{%.3fpt}}%%\n",
        !           310:                -size / 2, size, size);
        !           311: #ifdef EMTEX
        !           312:        if (emtex)              /* change line width */
        !           313:            fprintf(gpoutfile, "\\special{em:linewidth %.1fpt}%%\n", size);
        !           314: #endif
        !           315:     }
        !           316:     LATEX_size = size;
        !           317:     LATEX_dotsize = size / LATEX_UNIT;
        !           318:     LATEX_dotspace = (linetype >= 0) ? LATEX_lines[linetype].dotspace : 0;
        !           319:     LATEX_moved = TRUE;                /* reset */
        !           320: }
        !           321:
        !           322: TERM_PUBLIC void LATEX_move(x, y)
        !           323: unsigned int x, y;
        !           324: {
        !           325:     LATEX_flushdot();
        !           326:
        !           327:     LATEX_posx = x;
        !           328:     LATEX_posy = y;
        !           329:     LATEX_moved = TRUE;                /* reset */
        !           330: }
        !           331:
        !           332:
        !           333: TERM_PUBLIC void LATEX_point(x, y, number) /* version of line_and_point */
        !           334: unsigned int x, y;
        !           335: int number;                    /* type of point */
        !           336: {
        !           337:     LATEX_move(x, y);
        !           338:
        !           339:     /* Print the character defined by 'number'; number < 0 means
        !           340:        to use a dot, otherwise one of the defined points. */
        !           341:     fprintf(gpoutfile, "\\put(%d,%d){%s}\n", x, y,
        !           342:            (number < 0 ? LATEX_TINY_DOT
        !           343:             : LATEX_points[number % LATEX_POINT_TYPES]));
        !           344: }
        !           345:
        !           346:
        !           347: TERM_PUBLIC void LATEX_vector(ux, uy)
        !           348: unsigned int ux, uy;
        !           349: {
        !           350:     if (LATEX_dotspace == 0.0) {
        !           351:        /* solid line */
        !           352: #ifdef EMTEX
        !           353:        if (emtex)
        !           354:            EMTEX_solid_line(LATEX_posx, (int) ux, LATEX_posy, (int) uy);
        !           355:        else
        !           356: #endif
        !           357:            LATEX_solid_line(LATEX_posx, (int) ux, LATEX_posy, (int) uy);
        !           358:     } else
        !           359:        /* dotted line */
        !           360:        LATEX_dot_line(LATEX_posx, (int) ux, LATEX_posy, (int) uy);
        !           361:
        !           362:     LATEX_posx = ux;
        !           363:     LATEX_posy = uy;
        !           364: }
        !           365:
        !           366: static void LATEX_solid_line(x1, x2, y1, y2)
        !           367: int x1, x2, y1, y2;
        !           368: {
        !           369:     float slope;
        !           370:     int inc;
        !           371:     float dx, dy, x, y;
        !           372:     float offset, length;
        !           373:     int code;                  /* possibly combine with previous rule */
        !           374:
        !           375:     /* we draw a solid line using the current line thickness (size) */
        !           376:     /* we do it with lots of \\rules */
        !           377:
        !           378:     if (x1 == x2 && y1 == y2) {        /* zero-length line - just a dot */
        !           379:        if (LATEX_moved) {
        !           380:            LATEX_flushrule();
        !           381:            /* plot a dot */
        !           382:            fprintf(gpoutfile, "\\put(%u,%u){%s}\n", x1, y1, LATEX_DOT);
        !           383:        }
        !           384:     } else {
        !           385:        code = (LATEX_moved ? 0 : 1);   /* no combine after move */
        !           386:        LATEX_moved = FALSE;
        !           387:        if (x1 == x2)           /* vertical line - special case */
        !           388:            LATEX_rule(code, (double) x1, (double) y1,
        !           389:                       LATEX_dotsize, (double) y2 - y1);
        !           390:        else if (y1 == y2)      /* horizontal line - special case */
        !           391:            LATEX_rule(code, (double) x1, (double) y1, (double) x2 - x1,
        !           392:                       LATEX_dotsize);
        !           393:        else {
        !           394:            dx = (float) x2 - x1;
        !           395:            dy = (float) y2 - y1;
        !           396:            slope = dy / dx;
        !           397:            if (ABS(slope) <= 1.0) {
        !           398:                /* longer than high */
        !           399:                x = GPMIN(ABS(dx), (0.25 + 1.0 / ABS(slope)) * LATEX_dotsize);
        !           400:                offset = sign(dy) * GPMIN(LATEX_dotsize, ABS(dy));
        !           401:                dy = dy - offset;
        !           402:                length = x * LATEX_UNIT;
        !           403:                inc = (x == ABS(dx) ? 1 : GPMAX(1, ABS(dy) / TINY_STEP + 0.5));
        !           404:                if (inc == 1) {
        !           405:                    fprintf(gpoutfile, "\\put(%u,%.2f){\\rule{%.3fpt}{%.3fpt}}\n",
        !           406:                            (x2 >= x1 ? x1 : x2), ((float) y1 + y2 - LATEX_dotsize) / 2,
        !           407:                            length, LATEX_dotsize * LATEX_UNIT);
        !           408:                } else {
        !           409:                    dy = dy / inc;
        !           410:                    dx = (dx - sign(dx) * x) / (inc - 1);
        !           411:                    fprintf(gpoutfile,
        !           412:                            "\\multiput(%.2f,%.2f)(%.3f,%.3f){%u}{\\rule{%.3fpt}{%.3fpt}}\n",
        !           413:                            (dx >= 0.0 ? (float) x1 : x1 - x),
        !           414:                            (float) y1 - (ABS(dy) - offset) / 2,
        !           415:                            dx, dy, inc, length, ABS(dy) * LATEX_UNIT);
        !           416:                }
        !           417: /* done with one section, now smooth it */
        !           418:                x = x / 2;
        !           419:                dx = sign(dx) * x;
        !           420:                dx = (float) x2 - x1 - dx;
        !           421:                dy = (float) y2 - y1;
        !           422:                fprintf(gpoutfile, "\\multiput(%.2f,%.2f)(%.3f,%.3f){2}{\\rule{%.3fpt}{%.3fpt}}\n",
        !           423:                        (dx >= 0.0 ? (float) x1 : x1 - x), (float) y1 - LATEX_dotsize / 2,
        !           424:                        dx, dy, x * LATEX_UNIT, LATEX_dotsize * LATEX_UNIT);
        !           425:                LATEX_moved = TRUE;
        !           426:            } else {
        !           427:                /* higher than long */
        !           428:                y = GPMIN(ABS(dy), (0.25 + ABS(slope)) * LATEX_dotsize);
        !           429:                offset = sign(dx) * GPMIN(LATEX_dotsize, ABS(dx));
        !           430:                dx = dx - offset;
        !           431:                length = y * LATEX_UNIT;
        !           432:                inc = (y == ABS(dy) ? 1 : GPMAX(1, ABS(dx) / TINY_STEP + 0.5));
        !           433:                if (inc == 1) {
        !           434:                    fprintf(gpoutfile, "\\put(%.2f,%u){\\rule{%.3fpt}{%.3fpt}}\n",
        !           435:                            ((float) x1 + x2 - LATEX_dotsize) / 2, (y2 >= y1 ? y1 : y2),
        !           436:                            LATEX_dotsize * LATEX_UNIT, length);
        !           437:                } else {
        !           438:                    dx = dx / inc;
        !           439:                    dy = (dy - sign(dy) * y) / (inc - 1);
        !           440:                    fprintf(gpoutfile,
        !           441:                            "\\multiput(%.2f,%.2f)(%.3f,%.3f){%u}{\\rule{%.3fpt}{%.3fpt}}\n",
        !           442:                            (float) x1 - (ABS(dx) - offset) / 2,
        !           443:                            (dy >= 0 ? (float) y1 : y1 - y),
        !           444:                            dx, dy, inc, ABS(dx) * LATEX_UNIT, length);
        !           445:                }
        !           446: /* done with one section, now smooth it */
        !           447:                y = y / 2;
        !           448:                dx = (float) x2 - x1;
        !           449:                dy = sign(dy) * y;
        !           450:                dy = (float) y2 - y1 - dy;
        !           451:                fprintf(gpoutfile, "\\multiput(%.2f,%.2f)(%.3f,%.3f){2}{\\rule{%.3fpt}{%.3fpt}}\n",
        !           452:                        (float) x1 - LATEX_dotsize / 2, (dy >= 0.0 ? (float) y1 : y1 - y),
        !           453:                        dx, dy, LATEX_dotsize * LATEX_UNIT, y * LATEX_UNIT);
        !           454:                LATEX_moved = TRUE;
        !           455:            }
        !           456:        }
        !           457:     }
        !           458: }
        !           459:
        !           460: /* Draw a \rule. Width or height may be negative; we can correct.
        !           461:  * The rule is never output immediately. The previous rule is output
        !           462:  * as-is if code is 0, and the previous rule is
        !           463:  * combined with the current rule (if possible) if code is 1.
        !           464:  * The previous rule is output, and the new one ignored, if code is 2.
        !           465:  */
        !           466: static void LATEX_rule(code, x, y, width, height)
        !           467: int code;                      /* how do we treat this rule? */
        !           468: double x, y;
        !           469: double width;
        !           470: double height;
        !           471: {
        !           472:     static float lastx, lasty;
        !           473:     static float lastw, lasth;
        !           474:     static TBOOLEAN isvalid = FALSE;   /* is 'last' data valid? */
        !           475:     TBOOLEAN combine = (code == 1);
        !           476:     TBOOLEAN flush = (code == 2);
        !           477:
        !           478:     if (!flush)
        !           479:        if (width == 0 || height == 0)
        !           480:            return;             /* ignore this rule */
        !           481:
        !           482:     if (isvalid && combine) {
        !           483:        /* try to combine new rule with old rule */
        !           484:        if ((int) lastx == (int) x && lastw == width) {         /* vertical rule */
        !           485:            if (lasth * height >= 0) {  /* same sign */
        !           486:                lasth += height;
        !           487:                return;
        !           488:            }
        !           489:        } else if ((int) lasty == (int) y && lasth == height) {         /* horiz rule */
        !           490:            if (lastw * width >= 0) {   /* same sign */
        !           491:                lastw += width;
        !           492:                return;
        !           493:            }
        !           494:        }
        !           495:        /* oh well, output last and remember the new one */
        !           496:     }
        !           497:     if (isvalid) {
        !           498:        /* output the rule */
        !           499:        if (lastw < 0) {
        !           500:            lastx += lastw;
        !           501:            lastw = -lastw;
        !           502:        }
        !           503:        if (lasth < 0) {
        !           504:            lasty += lasth;
        !           505:            lasth = -lasth;
        !           506:        }
        !           507:        /* if very small use canned dot */
        !           508:        if (lastw < LATEX_dotsize || lasth < LATEX_dotsize)
        !           509:            fprintf(gpoutfile, "\\put(%.1f,%.1f){%s}\n",
        !           510:                    lastx, lasty, LATEX_DOT);
        !           511:        else
        !           512:            fprintf(gpoutfile, "\\put(%.1f,%.1f){\\rule[%.3fpt]{%.3fpt}{%.3fpt}}\n",
        !           513:                    lastx, lasty, -LATEX_dotsize * LATEX_UNIT / 2,
        !           514:                    lastw * LATEX_UNIT, lasth * LATEX_UNIT);
        !           515:     }
        !           516:     if (flush) {
        !           517:        isvalid = FALSE;
        !           518:     } else {
        !           519:        lastx = x;
        !           520:        lasty = y;
        !           521:        lastw = width;
        !           522:        lasth = height;
        !           523:        isvalid = TRUE;
        !           524:     }
        !           525: }
        !           526:
        !           527: static void LATEX_dot_line(x1, x2, y1, y2)
        !           528: int x1, x2, y1, y2;
        !           529: {
        !           530:     static float LATEX_left;   /* fraction of space left after last dot */
        !           531:
        !           532:     /* we draw a dotted line using the current dot spacing */
        !           533:
        !           534:     if (LATEX_moved)
        !           535:        LATEX_left = 1.0;       /* reset after a move */
        !           536:
        !           537:     /* zero-length line? */
        !           538:     if (x1 == x2 && y1 == y2) {
        !           539:        if (LATEX_moved)
        !           540:            /* plot a dot */
        !           541:            fprintf(gpoutfile, "\\put(%u,%u){%s}\n", x1, y1, LATEX_DOT);
        !           542:     } else {
        !           543:        float dotspace = LATEX_dotspace / LATEX_UNIT;
        !           544:        float x, y;             /* current position */
        !           545:        float xinc, yinc;       /* increments */
        !           546:        float slope;            /* slope of line */
        !           547:        float lastx = -1;       /* last x point plotted */
        !           548:        float lasty = -1;       /* last y point plotted */
        !           549:        int numdots = 0;        /* number of dots in this section */
        !           550:
        !           551:        /* first, figure out increments for x and y */
        !           552:        if (x2 == x1) {
        !           553:            xinc = 0.0;
        !           554:            yinc = (y2 - y1 > 0) ? dotspace : -dotspace;
        !           555:        } else {
        !           556:            slope = ((float) y2 - y1) / ((float) x2 - x1);
        !           557:            xinc = dotspace / sqrt(1 + slope * slope) * sign(x2 - x1);
        !           558:            yinc = slope * xinc;
        !           559:        }
        !           560:
        !           561:        /* now draw the dotted line */
        !           562:        /* we take into account where we last placed a dot */
        !           563:        for (x = x1 + xinc * (1 - LATEX_left), y = y1 + yinc * (1 - LATEX_left);
        !           564:             (x2 - x) * xinc >= 0 && (y2 - y) * yinc >= 0;      /* same sign or zero */
        !           565:             lastx = x, x += xinc,
        !           566:             lasty = y, y += yinc)
        !           567:            numdots++;
        !           568:        if (numdots == 1)
        !           569:            fprintf(gpoutfile, "\\put(%.2f,%.2f){%s}\n",
        !           570:                    lastx, lasty, LATEX_DOT);
        !           571:        else if (numdots > 0)
        !           572:            fprintf(gpoutfile, "\\multiput(%u,%u)(%.3f,%.3f){%u}{%s}\n",
        !           573:                    x1, y1, xinc, yinc, numdots, LATEX_DOT);
        !           574:
        !           575:        /* how much is left over, as a fraction of dotspace? */
        !           576:        if (xinc != 0.0)        /* xinc must be nonzero */
        !           577:            if (lastx >= 0)
        !           578:                LATEX_left = ABS(x2 - lastx) / ABS(xinc);
        !           579:            else
        !           580:                LATEX_left += ABS(x2 - x1) / ABS(xinc);
        !           581:        else if (lasty >= 0)
        !           582:            LATEX_left = ABS(y2 - lasty) / ABS(yinc);
        !           583:        else
        !           584:            LATEX_left += ABS(y2 - y1) / ABS(yinc);
        !           585:     }
        !           586:
        !           587:     LATEX_needsdot = (LATEX_left > 0);
        !           588:
        !           589:     LATEX_moved = FALSE;
        !           590: }
        !           591:
        !           592: static void LATEX_flushdot()
        !           593: {
        !           594:     if (LATEX_needsdot)
        !           595:        fprintf(gpoutfile, "\\put(%d,%d){%s}\n",
        !           596:                LATEX_posx, LATEX_posy, LATEX_DOT);
        !           597:     LATEX_needsdot = FALSE;
        !           598: }
        !           599:
        !           600: TERM_PUBLIC void LATEX_arrow(sx, sy, ex, ey, head)
        !           601: unsigned int sx, sy, ex, ey;
        !           602: TBOOLEAN head;
        !           603: {
        !           604:     best_latex_arrow(sx, sy, ex, ey, 1, head);
        !           605:
        !           606:     LATEX_posx = ex;
        !           607:     LATEX_posy = ey;
        !           608: }
        !           609:
        !           610: void best_latex_arrow(sx, sy, ex, ey, who, head)
        !           611: int sx, sy, ex, ey;            /* start and end points */
        !           612: int who;                       /* 1=LATEX, 2=EEPIC */
        !           613: TBOOLEAN head;
        !           614: {
        !           615:     int dx = ex - sx;
        !           616:     int dy = ey - sy;
        !           617:     float m;                   /* slope of line */
        !           618:     float arrowslope;          /* slope of arrow */
        !           619:     float minerror = 0;                /* best-case error */
        !           620:     struct vslope *slope;      /* one of the slopes */
        !           621:     struct vslope *bestslope;  /* the slope with min error */
        !           622:
        !           623:     /* We try to draw a real arrow (ie, \vector). If we can't get
        !           624:        * a slope that is close, we draw a bent arrow.
        !           625:      */
        !           626:
        !           627:     if (dx == 0) {
        !           628:        /* vertical arrow */
        !           629:        fprintf(gpoutfile, "\\put(%d,%d){\\%s(0,%d){%d}}\n",
        !           630:                sx, sy, head ? "vector" : "line",
        !           631:                sign(ey - sy), ABS(ey - sy));
        !           632:     } else if (dy == 0) {
        !           633:        /* horizontal arrow */
        !           634:        fprintf(gpoutfile, "\\put(%d,%d){\\%s(%d,0){%d}}\n",
        !           635:                sx, sy, head ? "vector" : "line",
        !           636:                sign(ex - sx), ABS(ex - sx));
        !           637:     } else {
        !           638:        /* Slanted arrow. We'll give it a try.
        !           639:         * we try to find the closest-slope arrowhead.
        !           640:         */
        !           641:        bestslope = NULL;
        !           642:        minerror = 0;           /* to shut up turbo C */
        !           643:        m = ABS((float) dy / dx);       /* the slope we want */
        !           644:        for (slope = LATEX_slopes; slope->dx != 0.0; slope++) {
        !           645:            /* find the slope of the arrow */
        !           646:            arrowslope = (float) slope->dy / slope->dx;
        !           647:            if (bestslope == NULL || ABS(m - arrowslope) < minerror) {
        !           648:                minerror = ABS(m - arrowslope);
        !           649:                bestslope = slope;
        !           650:            }
        !           651:        }
        !           652:
        !           653:        /* now we have the best slope arrow */
        !           654:        /* maybe it's exactly the right slope! */
        !           655:        if (minerror == 0.0)    /* unlikely but possible */
        !           656:            fprintf(gpoutfile, "\\put(%d,%d){\\%s(%d,%d){%d}}\n",
        !           657:                    sx, sy, head ? "vector" : "line",
        !           658:                    bestslope->dx * sign(ex - sx), bestslope->dy * sign(ey - sy),
        !           659:                    ABS(ex - sx));
        !           660:        else {
        !           661:            /* we draw the line the usual way, with thin lines */
        !           662: #ifdef EMTEX
        !           663:            if (emtex) {
        !           664:                LATEX_linetype(LATEX_THIN_LINE);
        !           665:                EMTEX_solid_line(sx, ex, sy, ey);
        !           666:            } else
        !           667: #endif
        !           668:            if (who == 1) {
        !           669:                LATEX_linetype(LATEX_THIN_LINE);
        !           670:                LATEX_solid_line(sx, ex, sy, ey);
        !           671:            }
        !           672: #ifdef EEPIC
        !           673:            else {
        !           674:                EEPIC_move(sx, sy);
        !           675:                EEPIC_vector(ex, ey);
        !           676:            }
        !           677: #endif /* EEPIC */
        !           678:            /* and then draw an arrowhead (a short vector) there */
        !           679:            if (head)
        !           680:                fprintf(gpoutfile, "\\put(%d,%d){\\vector(%d,%d){0}}\n",
        !           681:                        ex, ey,
        !           682:                        bestslope->dx * sign(ex - sx), bestslope->dy * sign(ey - sy));
        !           683:        }
        !           684:     }
        !           685: }
        !           686:
        !           687: TERM_PUBLIC void LATEX_put_text(x, y, str)
        !           688: unsigned int x, y;             /* reference point of string */
        !           689: char str[];                    /* the text */
        !           690: {
        !           691:     static char *justify[] =
        !           692:     {"[l]", "", "[r]"};
        !           693:     int flag, i;
        !           694:
        !           695:     /* ignore empty strings */
        !           696:     if (str[0] == NUL)
        !           697:        return;
        !           698:
        !           699:     for (flag = FALSE, i = 0; str[i] && !flag;)
        !           700:        flag = (str[i++] == '\\') && (str[i++] == '\\');
        !           701:
        !           702:     fprintf(gpoutfile, "\\put(%d,%d)", x, y);
        !           703:     if ((str[0] == '{') || (str[0] == '[')) {
        !           704:        fprintf(gpoutfile, "{\\makebox(0,0)%s}\n", str);
        !           705:     } else if (flag)
        !           706:        fprintf(gpoutfile, "{\\makebox(0,0)%s{\\shortstack{%s}}}\n",
        !           707:                justify[latex_justify], str);
        !           708:     else
        !           709:        fprintf(gpoutfile, "{\\makebox(0,0)%s{%s}}\n",
        !           710:                justify[latex_justify], str);
        !           711: }
        !           712:
        !           713: TERM_PUBLIC int LATEX_justify_text(mode)
        !           714: enum JUSTIFY mode;
        !           715: {
        !           716:     latex_justify = mode;
        !           717:     return (TRUE);
        !           718: }
        !           719:
        !           720: TERM_PUBLIC int LATEX_text_angle(ang)
        !           721: int ang;
        !           722: {
        !           723:     /* we can't really write text vertically, but this will
        !           724:        put the ylabel centred at the left of the plot, and
        !           725:        then we'll make a \shortstack */
        !           726:     latex_angle = ang;
        !           727:     return (TRUE);
        !           728: }
        !           729:
        !           730: TERM_PUBLIC void LATEX_reset()
        !           731: {
        !           732:     LATEX_posx = LATEX_posy = 0;       /* current position */
        !           733:     LATEX_moved = TRUE;                /* pen is up after move */
        !           734: }
        !           735:
        !           736:
        !           737: #ifdef EMTEX
        !           738:
        !           739: TERM_PUBLIC void EMTEX_init()
        !           740: {
        !           741:     emtex = TRUE;
        !           742:     LATEX_posx = LATEX_posy = 0;
        !           743:     fprintf(gpoutfile, "\
        !           744: %% GNUPLOT: LaTeX picture with emtex specials\n\
        !           745: \\setlength{\\unitlength}{%fpt}\n\
        !           746: \\ifx\\plotpoint\\undefined\\newsavebox{\\plotpoint}\\fi\n",
        !           747:            LATEX_UNIT);
        !           748:     LATEX_linetype(-1);
        !           749: }
        !           750:
        !           751:
        !           752: TERM_PUBLIC void EMTEX_reset()
        !           753: {
        !           754:     emtex = FALSE;
        !           755:     LATEX_posx = LATEX_posy = 0;
        !           756: }
        !           757:
        !           758:
        !           759: TERM_PUBLIC void EMTEX_text()
        !           760: {
        !           761:     fputs("\\end{picture}\n", gpoutfile);
        !           762: }
        !           763:
        !           764:
        !           765: static void EMTEX_solid_line(x1, x2, y1, y2)
        !           766: int x1, x2, y1, y2;
        !           767: {
        !           768:     /* emtex special solid line */
        !           769:     if (LATEX_moved)
        !           770:        fprintf(gpoutfile, "\\put(%d,%d){\\special{em:moveto}}\n", x1, y1);
        !           771:     if ((x1 != x2) || (y1 != y2))
        !           772:        fprintf(gpoutfile, "\\put(%d,%d){\\special{em:lineto}}\n", x2, y2);
        !           773:     LATEX_posx = x2;
        !           774:     LATEX_posy = y2;
        !           775:     LATEX_moved = FALSE;
        !           776: }
        !           777:
        !           778:
        !           779: #endif /* EMTEX */
        !           780:
        !           781: #endif /* TERM_BODY */
        !           782: #endif /* TERM_PROTO_ONLY */
        !           783:
        !           784: #ifdef TERM_TABLE
        !           785:
        !           786: TERM_TABLE_START(latex_driver)
        !           787:     "latex", "LaTeX picture environment",
        !           788:     LATEX_XMAX, LATEX_YMAX, LATEX_VCHAR, LATEX_HCHAR,
        !           789:     LATEX_VTIC, LATEX_HTIC, LATEX_options, LATEX_init, LATEX_reset,
        !           790:     LATEX_text, null_scale, LATEX_graphics, LATEX_move, LATEX_vector,
        !           791:     LATEX_linetype, LATEX_put_text, LATEX_text_angle,
        !           792:     LATEX_justify_text, LATEX_point, LATEX_arrow, set_font_null
        !           793: TERM_TABLE_END(latex_driver)
        !           794:
        !           795: #undef LAST_TERM
        !           796: #define LAST_TERM latex_driver
        !           797:
        !           798:
        !           799: #ifdef EMTEX
        !           800: TERM_TABLE_START(emtex_driver)
        !           801:     "emtex", "LaTeX picture environment with emTeX specials",
        !           802:     LATEX_XMAX, LATEX_YMAX, LATEX_VCHAR, LATEX_HCHAR,
        !           803:     LATEX_VTIC, LATEX_HTIC, LATEX_options, EMTEX_init, EMTEX_reset,
        !           804:     EMTEX_text, null_scale, LATEX_graphics, LATEX_move, LATEX_vector,
        !           805:     LATEX_linetype, LATEX_put_text, LATEX_text_angle,
        !           806:     LATEX_justify_text, LATEX_point, LATEX_arrow, set_font_null
        !           807: TERM_TABLE_END(emtex_driver)
        !           808:
        !           809: #undef LAST_TERM
        !           810: #define LAST_TERM emtex_driver
        !           811:
        !           812: #endif /* EMTEX */
        !           813: #endif /* TERM_TABLE */
        !           814:
        !           815:
        !           816: #ifdef TERM_HELP
        !           817: START_HELP(latex)
        !           818: "1 latex",
        !           819: "?commands set terminal emtex",
        !           820: "?set terminal emtex",
        !           821: "?set term emtex",
        !           822: "?terminal emtex",
        !           823: "?term emtex",
        !           824: "?latex",
        !           825: "?commands set terminal latex",
        !           826: "?set terminal latex",
        !           827: "?set term latex",
        !           828: "?terminal latex",
        !           829: "?term latex",
        !           830: "?emtex",
        !           831: " The `latex` and `emtex` drivers allow two options.",
        !           832: "",
        !           833: " Syntax:",
        !           834: "       set terminal latex | emtex {courier | roman} {<fontsize>}",
        !           835: "",
        !           836: " `fontsize` may be any size you specify.  The default is 10-point Roman.",
        !           837: "",
        !           838: " Unless your driver is capable of building fonts at any size (e.g. dvips),",
        !           839: " stick to the standard 10, 11 and 12 point sizes.",
        !           840: "",
        !           841: " METAFONT users beware: METAFONT does not like odd sizes.",
        !           842: "",
        !           843: " All drivers for LaTeX offer a special way of controlling text positioning:",
        !           844: " If any text string begins with '{', you also need to include a '}' at the",
        !           845: " end of the text, and the whole text will be centered both horizontally",
        !           846: " and vertically by LaTeX. --- If the text string begins with '[', you need",
        !           847: " to continue it with: a position specification (up to two out of t,b,l,r),",
        !           848: " ']{', the text itself, and finally, '}'. The text itself may be anything",
        !           849: " LaTeX can typeset as an LR-box. \\rule{}{}'s may help for best positioning.",
        !           850: "",
        !           851: " Examples:",
        !           852: " About label positioning:",
        !           853: " Use gnuplot defaults (mostly sensible, but sometimes not really best):",
        !           854: "        set title '\\LaTeX\\ -- $ \\gamma $'",
        !           855: " Force centering both horizontally and vertically:",
        !           856: "        set label '{\\LaTeX\\ -- $ \\gamma $}' at 0,0",
        !           857: " Specify own positioning (top here):",
        !           858: "        set xlabel '[t]{\\LaTeX\\ -- $ \\gamma $}'",
        !           859: " The other label -- account for long ticlabels:",
        !           860: "        set ylabel '[r]{\\LaTeX\\ -- $ \\gamma $\\rule{7mm}{0pt}'"
        !           861: END_HELP(latex)
        !           862: #endif /* TERM_TABLE */

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