1 /* Hello, Emacs, this is -*-C-*-
2 * $Id: latex.trm,v 1.30.2.2 2007/05/27 05:15:28 sfeam Exp $
6 /* GNUPLOT - latex.trm */
9 * Copyright 1990 - 1993, 1998, 2004
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.
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,
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
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.
34 * This software is provided "as is" without express or implied warranty
35 * to the extent permitted by applicable law.
39 * This file is included by ../term.c.
41 * This terminal driver supports:
42 * LaTeX pictures (latex).
43 * LaTeX pictures with emTeX specials (emtex).
46 * David Kotz, Russell Lang
48 * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
52 /* modified to optimize use of \rule for long lines */
53 /* TLDC: modified to have nice line types */
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. */
61 /* 9 Dec 1992 LATEX_put_text rewritten to handle \\ newlines
62 Daniel S. Lewart (d-lewart@uiuc.edu) */
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
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, const 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, int 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));
102 TERM_PUBLIC void EMTEX_init __PROTO((void));
103 TERM_PUBLIC void EMTEX_reset __PROTO((void));
104 TERM_PUBLIC void EMTEX_text __PROTO((void));
108 TERM_PUBLIC void EEPIC_move __PROTO((unsigned int x, unsigned int y));
109 TERM_PUBLIC void EEPIC_vector __PROTO((unsigned int ux, unsigned int uy));
112 #define TINY_STEP 0.5 /* tiny steps for high quality lines */
114 #define LATEX_PTS_PER_INCH (72.27)
115 #define DOTS_PER_INCH (300) /* resolution of printer we expect to use */
116 #define LATEX_UNIT (LATEX_PTS_PER_INCH/DOTS_PER_INCH) /* dot size in pt */
118 /* 5 inches wide by 3 inches high (default) */
119 #define LATEX_XMAX (5*DOTS_PER_INCH) /* (LATEX_PTS_PER_INCH/LATEX_UNIT*5.0) */
120 #define LATEX_YMAX (3*DOTS_PER_INCH) /* (LATEX_PTS_PER_INCH/LATEX_UNIT*3.0) */
122 #define LATEX_HTIC (5*DOTS_PER_INCH/72) /* (5 pts) */
123 #define LATEX_VTIC (5*DOTS_PER_INCH/72) /* (5 pts) */
124 #define LATEX_HCHAR (DOTS_PER_INCH*53/10/72) /* (5.3 pts) */
125 #define LATEX_VCHAR (DOTS_PER_INCH*11/72) /* (11 pts) */
129 #ifndef TERM_PROTO_ONLY
132 static int LATEX_posx;
133 static int LATEX_posy;
134 static int LATEX_fontsize = 10;
135 static char LATEX_font[MAX_ID_LEN+1] = "doc";
136 static enum JUSTIFY latex_justify = LEFT;
137 static int latex_angle = 0;
139 static TBOOLEAN latex_explicit_size = FALSE;
140 static size_units latex_explicit_units = INCHES;
142 /* Default line-drawing character */
143 /* the definition of plotpoint varies with linetype */
144 #define LATEX_DOT "\\usebox{\\plotpoint}"
145 #define LATEX_TINY_DOT "\\rule{1pt}{1pt}" /* for dots plot style */
148 #define LATEX_POINT_TYPES 12 /* we supply more point types */
150 static const char GPFAR *GPFAR LATEX_points[] = {
151 "\\raisebox{-.8pt}{\\makebox(0,0){$\\Diamond$}}",
152 "\\makebox(0,0){$+$}",
153 "\\raisebox{-.8pt}{\\makebox(0,0){$\\Box$}}",
154 "\\makebox(0,0){$\\times$}",
155 "\\makebox(0,0){$\\triangle$}",
156 "\\makebox(0,0){$\\star$}",
157 "\\circle{12}", "\\circle{18}", "\\circle{24}",
158 "\\circle*{12}", "\\circle*{18}", "\\circle*{24}"
162 static float LATEX_size = 0; /* current thick of line in points */
163 static float LATEX_dotspace = 0; /* current dotspace of line in points */
164 #define LATEX_LINE_TYPES 6 /* number of line types below */
165 #define LATEX_THIN_LINE 0 /* the thinnest solid line type */
167 float size; /* size of dot, or thick of line in points */
168 float dotspace; /* inter-dot space in points; 0 for lines */
169 } GPFAR LATEX_lines[] =
172 {0.4, 0.0}, /* thin solid line */
173 {0.4, 5.0}, /* thin dotted line */
174 {0.8, 0.0}, /* thick solid line */
175 {1.0, 5.0}, /* thick dotted line */
176 {1.2, 0.0}, /* Thick solid line */
177 {1.0, 10.0}, /* thick widely dotted line */
180 /* for drawing dotted and solid lines */
181 static void LATEX_dot_line __PROTO((int x1, int x2, int y1, int y2));
182 static void LATEX_solid_line __PROTO((int x1, int x2, int y1, int y2));
183 static void LATEX_rule __PROTO((int code, double x, double y, double width, double height));
184 static void LATEX_flushdot __PROTO((void));
185 #define LATEX_flushrule() LATEX_rule(2, 0.,0.,0.,0.) /* flush old rule */
186 static TBOOLEAN LATEX_moved = TRUE; /* pen is up after move */
187 static float LATEX_dotsize; /* size of LATEX_DOT in units */
188 static TBOOLEAN LATEX_needsdot = FALSE; /* does dotted line need termination? */
191 static TBOOLEAN emtex = FALSE; /* not currently using emtex */
192 static void EMTEX_solid_line __PROTO((int x1, int x2, int y1, int y2));
196 /* the set of non-vertical/non-horizontal LaTeX vector slopes */
197 /* except negatives - they are handled specially */
198 static struct vslope {
200 } GPFAR LATEX_slopes[] =
214 {0, 0} /* terminator */
217 /* figure out the best arrow */
218 static void best_latex_arrow __PROTO((int, int, int, int, int, int));
220 enum LATEX_id { LATEX_COURIER, LATEX_ROMAN, LATEX_DEFAULT, LATEX_SIZE, LATEX_OTHER };
222 static struct gen_table LATEX_opts[] =
224 { "c$ourier", LATEX_COURIER },
225 { "r$oman", LATEX_ROMAN },
226 { "d$efault", LATEX_DEFAULT },
227 { "si$ze", LATEX_SIZE },
228 { NULL, LATEX_OTHER }
236 latex_explicit_size = FALSE;
238 while (!END_OF_COMMAND) {
239 switch(lookup_table(&LATEX_opts[0],c_token)) {
241 strcpy(LATEX_font, "cmtt");
245 strcpy(LATEX_font, "cmr");
249 strcpy(LATEX_font, "doc");
254 float xmax_t = 5., ymax_t = 3.;
256 latex_explicit_size = TRUE;
257 latex_explicit_units = parse_term_size(&xmax_t, &ymax_t, INCHES);
258 term->xmax = xmax_t * DOTS_PER_INCH/72;
259 term->ymax = ymax_t * DOTS_PER_INCH/72;
265 LATEX_fontsize = (int) real(const_express(&a));
269 /* tell gnuplot core about char. sizes. Horizontal spacing
270 * is about half the text pointsize
272 term->v_char = (unsigned int) (LATEX_fontsize * DOTS_PER_INCH / 72);
273 term->h_char = (unsigned int) (LATEX_fontsize * DOTS_PER_INCH / 144);
275 if (strcmp(LATEX_font, "doc")==0)
276 strncpy(term_options, "(document specific font)",MAX_LINE_LEN);
278 sprintf(term_options, "%s %d",
279 LATEX_font[2] == 't' ? "courier" : "roman", LATEX_fontsize);
281 if (latex_explicit_size) {
282 if (latex_explicit_units == CM)
283 sprintf(&(term_options[strlen(term_options)]), "size %.2fcm, %.2fcm ",
284 2.54*(float)term->xmax/(DOTS_PER_INCH),
285 2.54*(float)term->ymax/(DOTS_PER_INCH));
287 sprintf(&(term_options[strlen(term_options)]), "size %.2fin, %.2fin ",
288 (float)term->xmax/(DOTS_PER_INCH),
289 (float)term->ymax/(DOTS_PER_INCH));
301 LATEX_posx = LATEX_posy = 0;
303 fprintf(gpoutfile, "\
304 %% GNUPLOT: LaTeX picture\n\
305 \\setlength{\\unitlength}{%fpt}\n\
306 \\ifx\\plotpoint\\undefined\\newsavebox{\\plotpoint}\\fi\n",
309 LATEX_linetype(LT_AXIS);
318 /* set size of canvas */
319 if (!latex_explicit_size) {
320 term->xmax = LATEX_XMAX;
321 term->ymax = LATEX_YMAX;
325 xscale = xsize * term->xmax;
326 yscale = ysize * term->ymax;
328 fprintf(gpoutfile, "\\begin{picture}(%d,%d)(0,0)\n", xscale, yscale);
329 if (strcmp(LATEX_font, "doc") != 0) {
330 fprintf(gpoutfile, "\
331 \\font\\gnuplot=%s10 at %dpt\n\
333 LATEX_font, LATEX_fontsize);
343 fputs("\\end{picture}\n", gpoutfile);
344 LATEX_posx = LATEX_posy = 0; /* current position */
345 LATEX_moved = TRUE; /* pen is up after move */
349 LATEX_linetype(int linetype)
353 if (linetype >= LATEX_LINE_TYPES)
354 linetype %= LATEX_LINE_TYPES;
362 /* Find the new desired line thickness. */
363 /* negative linetypes (for axes) use a thin line */
364 /* only relevant for drawing axes/border in 3d */
365 size = (linetype >= 0 ? LATEX_lines[linetype].size
366 : LATEX_lines[LATEX_THIN_LINE].size);
368 /* If different from current size, redefine \plotpoint */
369 if (size != LATEX_size) {
371 "\\sbox{\\plotpoint}{\\rule[%.3fpt]{%.3fpt}{%.3fpt}}%%\n",
372 -size / 2, size, size);
374 if (emtex) /* change line width */
375 fprintf(gpoutfile, "\\special{em:linewidth %.1fpt}%%\n", size);
379 LATEX_dotsize = size / LATEX_UNIT;
380 LATEX_dotspace = (linetype >= 0) ? LATEX_lines[linetype].dotspace : 0;
381 LATEX_moved = TRUE; /* reset */
385 LATEX_move(unsigned int x, unsigned int y)
391 LATEX_moved = TRUE; /* reset */
396 LATEX_point(unsigned int x, unsigned int y, int number)
400 /* Print the character defined by 'number'; number < 0 means
401 to use a dot, otherwise one of the defined points. */
402 fprintf(gpoutfile, "\\put(%d,%d){%s}\n", x, y,
403 (number < 0 ? LATEX_TINY_DOT
404 : LATEX_points[number % LATEX_POINT_TYPES]));
409 LATEX_vector(unsigned int ux, unsigned int uy)
411 if (LATEX_dotspace == 0.0) {
415 EMTEX_solid_line(LATEX_posx, (int) ux, LATEX_posy, (int) uy);
418 LATEX_solid_line(LATEX_posx, (int) ux, LATEX_posy, (int) uy);
421 LATEX_dot_line(LATEX_posx, (int) ux, LATEX_posy, (int) uy);
428 LATEX_solid_line(int x1, int x2, int y1, int y2)
433 float offset, length;
434 int code; /* possibly combine with previous rule */
436 /* we draw a solid line using the current line thickness (size) */
437 /* we do it with lots of \\rules */
439 if (x1 == x2 && y1 == y2) { /* zero-length line - just a dot */
443 fprintf(gpoutfile, "\\put(%u,%u){%s}\n", x1, y1, LATEX_DOT);
446 code = (LATEX_moved ? 0 : 1); /* no combine after move */
448 if (x1 == x2) /* vertical line - special case */
449 LATEX_rule(code, (double) x1, (double) y1,
450 LATEX_dotsize, (double) y2 - y1);
451 else if (y1 == y2) /* horizontal line - special case */
452 LATEX_rule(code, (double) x1, (double) y1, (double) x2 - x1,
455 dx = (float) x2 - x1;
456 dy = (float) y2 - y1;
458 if (ABS(slope) <= 1.0) {
459 /* longer than high */
460 x = GPMIN(ABS(dx), (0.25 + 1.0 / ABS(slope)) * LATEX_dotsize);
461 offset = sign(dy) * GPMIN(LATEX_dotsize, ABS(dy));
463 length = x * LATEX_UNIT;
464 inc = (x == ABS(dx) ? 1 : GPMAX(1, ABS(dy) / TINY_STEP + 0.5));
466 fprintf(gpoutfile, "\\put(%u,%.2f){\\rule{%.3fpt}{%.3fpt}}\n",
467 (x2 >= x1 ? x1 : x2), ((float) y1 + y2 - LATEX_dotsize) / 2,
468 length, LATEX_dotsize * LATEX_UNIT);
471 dx = (dx - sign(dx) * x) / (inc - 1);
473 "\\multiput(%.2f,%.2f)(%.3f,%.3f){%u}{\\rule{%.3fpt}{%.3fpt}}\n",
474 (dx >= 0.0 ? (float) x1 : x1 - x),
475 (float) y1 - (ABS(dy) - offset) / 2,
476 dx, dy, inc, length, ABS(dy) * LATEX_UNIT);
478 /* done with one section, now smooth it */
481 dx = (float) x2 - x1 - dx;
482 dy = (float) y2 - y1;
483 fprintf(gpoutfile, "\\multiput(%.2f,%.2f)(%.3f,%.3f){2}{\\rule{%.3fpt}{%.3fpt}}\n",
484 (dx >= 0.0 ? (float) x1 : x1 - x), (float) y1 - LATEX_dotsize / 2,
485 dx, dy, x * LATEX_UNIT, LATEX_dotsize * LATEX_UNIT);
488 /* higher than long */
489 y = GPMIN(ABS(dy), (0.25 + ABS(slope)) * LATEX_dotsize);
490 offset = sign(dx) * GPMIN(LATEX_dotsize, ABS(dx));
492 length = y * LATEX_UNIT;
493 inc = (y == ABS(dy) ? 1 : GPMAX(1, ABS(dx) / TINY_STEP + 0.5));
495 fprintf(gpoutfile, "\\put(%.2f,%u){\\rule{%.3fpt}{%.3fpt}}\n",
496 ((float) x1 + x2 - LATEX_dotsize) / 2, (y2 >= y1 ? y1 : y2),
497 LATEX_dotsize * LATEX_UNIT, length);
500 dy = (dy - sign(dy) * y) / (inc - 1);
502 "\\multiput(%.2f,%.2f)(%.3f,%.3f){%u}{\\rule{%.3fpt}{%.3fpt}}\n",
503 (float) x1 - (ABS(dx) - offset) / 2,
504 (dy >= 0 ? (float) y1 : y1 - y),
505 dx, dy, inc, ABS(dx) * LATEX_UNIT, length);
507 /* done with one section, now smooth it */
509 dx = (float) x2 - x1;
511 dy = (float) y2 - y1 - dy;
512 fprintf(gpoutfile, "\\multiput(%.2f,%.2f)(%.3f,%.3f){2}{\\rule{%.3fpt}{%.3fpt}}\n",
513 (float) x1 - LATEX_dotsize / 2, (dy >= 0.0 ? (float) y1 : y1 - y),
514 dx, dy, LATEX_dotsize * LATEX_UNIT, y * LATEX_UNIT);
521 /* Draw a \rule. Width or height may be negative; we can correct.
522 * The rule is never output immediately. The previous rule is output
523 * as-is if code is 0, and the previous rule is
524 * combined with the current rule (if possible) if code is 1.
525 * The previous rule is output, and the new one ignored, if code is 2.
529 int code, /* how do we treat this rule? */
534 static float lastx, lasty;
535 static float lastw, lasth;
536 static TBOOLEAN isvalid = FALSE; /* is 'last' data valid? */
537 TBOOLEAN combine = (code == 1);
538 TBOOLEAN flush = (code == 2);
541 if (width == 0 || height == 0)
542 return; /* ignore this rule */
544 if (isvalid && combine) {
545 /* try to combine new rule with old rule */
546 if ((int) lastx == (int) x && lastw == width) { /* vertical rule */
547 if (lasth * height >= 0) { /* same sign */
551 } else if ((int) lasty == (int) y && lasth == height) { /* horiz rule */
552 if (lastw * width >= 0) { /* same sign */
557 /* oh well, output last and remember the new one */
560 /* output the rule */
569 /* if very small use canned dot */
570 if (lastw < LATEX_dotsize || lasth < LATEX_dotsize)
571 fprintf(gpoutfile, "\\put(%.1f,%.1f){%s}\n",
572 lastx, lasty, LATEX_DOT);
574 fprintf(gpoutfile, "\\put(%.1f,%.1f){\\rule[%.3fpt]{%.3fpt}{%.3fpt}}\n",
575 lastx, lasty, -LATEX_dotsize * LATEX_UNIT / 2,
576 lastw * LATEX_UNIT, lasth * LATEX_UNIT);
590 LATEX_dot_line(int x1, int x2, int y1, int y2)
592 static float LATEX_left; /* fraction of space left after last dot */
594 /* we draw a dotted line using the current dot spacing */
597 LATEX_left = 1.0; /* reset after a move */
599 /* zero-length line? */
600 if (x1 == x2 && y1 == y2) {
603 fprintf(gpoutfile, "\\put(%u,%u){%s}\n", x1, y1, LATEX_DOT);
605 float dotspace = LATEX_dotspace / LATEX_UNIT;
606 float x, y; /* current position */
607 float xinc, yinc; /* increments */
608 float slope; /* slope of line */
609 float lastx = -1; /* last x point plotted */
610 float lasty = -1; /* last y point plotted */
611 int numdots = 0; /* number of dots in this section */
613 /* first, figure out increments for x and y */
616 yinc = (y2 - y1 > 0) ? dotspace : -dotspace;
618 slope = ((float) y2 - y1) / ((float) x2 - x1);
619 xinc = dotspace / sqrt(1 + slope * slope) * sign(x2 - x1);
623 /* now draw the dotted line */
624 /* we take into account where we last placed a dot */
625 for (x = x1 + xinc * (1 - LATEX_left), y = y1 + yinc * (1 - LATEX_left);
626 (x2 - x) * xinc >= 0 && (y2 - y) * yinc >= 0; /* same sign or zero */
627 lastx = x, x += xinc,
628 lasty = y, y += yinc)
631 fprintf(gpoutfile, "\\put(%.2f,%.2f){%s}\n",
632 lastx, lasty, LATEX_DOT);
633 else if (numdots > 0)
634 fprintf(gpoutfile, "\\multiput(%u,%u)(%.3f,%.3f){%u}{%s}\n",
635 x1, y1, xinc, yinc, numdots, LATEX_DOT);
637 /* how much is left over, as a fraction of dotspace? */
638 if (xinc != 0.0) { /* xinc must be nonzero */
640 LATEX_left = ABS(x2 - lastx) / ABS(xinc);
642 LATEX_left += ABS(x2 - x1) / ABS(xinc);
645 LATEX_left = ABS(y2 - lasty) / ABS(yinc);
647 LATEX_left += ABS(y2 - y1) / ABS(yinc);
650 LATEX_needsdot = (LATEX_left > 0);
659 fprintf(gpoutfile, "\\put(%d,%d){%s}\n",
660 LATEX_posx, LATEX_posy, LATEX_DOT);
661 LATEX_needsdot = FALSE;
666 unsigned int sx, unsigned int sy,
667 unsigned int ex, unsigned int ey,
670 best_latex_arrow(sx, sy, ex, ey, 1, head);
678 int sx, int sy, int ex, int ey, /* start and end points */
679 int who, /* 1=LATEX, 2=EEPIC */
684 float m; /* slope of line */
685 float arrowslope; /* slope of arrow */
686 float minerror = 0; /* best-case error */
687 struct vslope *slope; /* one of the slopes */
688 struct vslope *bestslope; /* the slope with min error */
690 /* We try to draw a real arrow (ie, \vector). If we can't get
691 * a slope that is close, we draw a bent arrow.
696 fprintf(gpoutfile, "\\put(%d,%d){\\%s(0,%d){%d}}\n",
697 sx, sy, head ? "vector" : "line",
698 sign(ey - sy), ABS(ey - sy));
699 } else if (dy == 0) {
700 /* horizontal arrow */
701 fprintf(gpoutfile, "\\put(%d,%d){\\%s(%d,0){%d}}\n",
702 sx, sy, head ? "vector" : "line",
703 sign(ex - sx), ABS(ex - sx));
705 /* Slanted arrow. We'll give it a try.
706 * we try to find the closest-slope arrowhead.
709 minerror = 0; /* to shut up turbo C */
710 m = ABS((float) dy / dx); /* the slope we want */
711 for (slope = LATEX_slopes; slope->dx != 0.0; slope++) {
712 /* find the slope of the arrow */
713 arrowslope = (float) slope->dy / slope->dx;
714 if (bestslope == NULL || ABS(m - arrowslope) < minerror) {
715 minerror = ABS(m - arrowslope);
720 /* now we have the best slope arrow */
721 /* maybe it's exactly the right slope! */
722 if (minerror == 0.0) /* unlikely but possible */
723 fprintf(gpoutfile, "\\put(%d,%d){\\%s(%d,%d){%d}}\n",
724 sx, sy, head ? "vector" : "line",
725 bestslope->dx * sign(ex - sx), bestslope->dy * sign(ey - sy),
728 /* we draw the line the usual way, with thin lines */
731 LATEX_linetype(LATEX_THIN_LINE);
732 EMTEX_solid_line(sx, ex, sy, ey);
736 LATEX_linetype(LATEX_THIN_LINE);
737 LATEX_solid_line(sx, ex, sy, ey);
742 EEPIC_vector(ex, ey);
745 /* and then draw an arrowhead (a short vector) there */
747 fprintf(gpoutfile, "\\put(%d,%d){\\vector(%d,%d){0}}\n",
749 bestslope->dx * sign(ex - sx), bestslope->dy * sign(ey - sy));
755 LATEX_put_text(unsigned int x, unsigned int y, const char str[])
757 static const char *justify[] = { "[l]", "", "[r]" };
760 /* ignore empty strings */
764 for (flag = FALSE, i = 0; str[i] && !flag;)
765 flag = (str[i++] == '\\') && (str[i++] == '\\');
767 fprintf(gpoutfile, "\\put(%d,%d)", x, y);
768 if ((str[0] == '{') || (str[0] == '[')) {
769 fprintf(gpoutfile, "{\\makebox(0,0)%s}\n", str);
771 fprintf(gpoutfile, "{\\makebox(0,0)%s{\\shortstack{%s}}}\n",
772 justify[latex_justify], str);
774 fprintf(gpoutfile, "{\\makebox(0,0)%s{%s}}\n",
775 justify[latex_justify], str);
779 LATEX_justify_text(enum JUSTIFY mode)
781 latex_justify = mode;
786 LATEX_text_angle(int ang)
788 /* we can't really write text vertically, but this will
789 put the ylabel centred at the left of the plot, and
790 then we'll make a \shortstack */
791 latex_angle = (ang ? 1 : 0);
798 LATEX_posx = LATEX_posy = 0; /* current position */
799 LATEX_moved = TRUE; /* pen is up after move */
809 LATEX_posx = LATEX_posy = 0;
810 fprintf(gpoutfile, "\
811 %% GNUPLOT: LaTeX picture with emtex specials\n\
812 \\setlength{\\unitlength}{%fpt}\n\
813 \\ifx\\plotpoint\\undefined\\newsavebox{\\plotpoint}\\fi\n",
815 LATEX_linetype(LT_AXIS);
823 LATEX_posx = LATEX_posy = 0;
830 fputs("\\end{picture}\n", gpoutfile);
835 EMTEX_solid_line(int x1, int x2, int y1, int y2)
837 /* emtex special solid line */
839 fprintf(gpoutfile, "\\put(%d,%d){\\special{em:moveto}}\n", x1, y1);
840 if ((x1 != x2) || (y1 != y2))
841 fprintf(gpoutfile, "\\put(%d,%d){\\special{em:lineto}}\n", x2, y2);
850 #endif /* TERM_BODY */
851 #endif /* TERM_PROTO_ONLY */
855 TERM_TABLE_START(latex_driver)
856 "latex", "LaTeX picture environment",
857 LATEX_XMAX, LATEX_YMAX, LATEX_VCHAR, LATEX_HCHAR,
858 LATEX_VTIC, LATEX_HTIC, LATEX_options, LATEX_init, LATEX_reset,
859 LATEX_text, null_scale, LATEX_graphics, LATEX_move, LATEX_vector,
860 LATEX_linetype, LATEX_put_text, LATEX_text_angle,
861 LATEX_justify_text, LATEX_point, LATEX_arrow, set_font_null
862 TERM_TABLE_END(latex_driver)
865 #define LAST_TERM latex_driver
869 TERM_TABLE_START(emtex_driver)
870 "emtex", "LaTeX picture environment with emTeX specials",
871 LATEX_XMAX, LATEX_YMAX, LATEX_VCHAR, LATEX_HCHAR,
872 LATEX_VTIC, LATEX_HTIC, LATEX_options, EMTEX_init, EMTEX_reset,
873 EMTEX_text, null_scale, LATEX_graphics, LATEX_move, LATEX_vector,
874 LATEX_linetype, LATEX_put_text, LATEX_text_angle,
875 LATEX_justify_text, LATEX_point, LATEX_arrow, set_font_null
876 TERM_TABLE_END(emtex_driver)
879 #define LAST_TERM emtex_driver
882 #endif /* TERM_TABLE */
888 "?commands set terminal emtex",
889 "?set terminal emtex",
894 "?commands set terminal latex",
895 "?set terminal latex",
901 " set terminal {latex | emtex} {default | {courier|roman} {<fontsize>}}",
902 " {size <XX>{unit}, <YY>{unit}}",
904 " By default the plot will inherit font settings from the embedding document.",
905 " You have the option of forcing either Courier (cmtt) or Roman (cmr) fonts",
906 " instead. In this case you may also specify a fontsize.",
907 " Unless your driver is capable of building fonts at any size (e.g. dvips),",
908 " stick to the standard 10, 11 and 12 point sizes.",
910 " METAFONT users beware: METAFONT does not like odd sizes.",
912 " All drivers for LaTeX offer a special way of controlling text positioning:",
913 " If any text string begins with '{', you also need to include a '}' at the",
914 " end of the text, and the whole text will be centered both horizontally and",
915 " vertically. If the text string begins with '[', you need to follow this with",
916 " a position specification (up to two out of t,b,l,r), ']{', the text itself,",
917 " and finally '}'. The text itself may be anything LaTeX can typeset as an",
918 " LR-box. '\\rule{}{}'s may help for best positioning.",
920 " Points, among other things, are drawn using the LaTeX commands \"\\Diamond\" and",
921 " \"\\Box\". These commands no longer belong to the LaTeX2e core; they are included",
922 " in the latexsym package, which is part of the base distribution and thus part",
923 " of any LaTeX implementation. Please do not forget to use this package.",
925 " The default size for the plot is 5 inches by 3 inches. The `size` option",
926 " changes this to whatever the user requests. By default the X and Y sizes",
927 " are taken to be in inches, but other units are possible (currently only cm).",
930 " About label positioning:",
931 " Use gnuplot defaults (mostly sensible, but sometimes not really best):",
932 " set title '\\LaTeX\\ -- $ \\gamma $'",
933 " Force centering both horizontally and vertically:",
934 " set label '{\\LaTeX\\ -- $ \\gamma $}' at 0,0",
935 " Specify own positioning (top here):",
936 " set xlabel '[t]{\\LaTeX\\ -- $ \\gamma $}'",
937 " The other label -- account for long ticlabels:",
938 " set ylabel '[r]{\\LaTeX\\ -- $ \\gamma $\\rule{7mm}{0pt}}'"
940 #endif /* TERM_TABLE */