Annotation of OpenXM_contrib/gnuplot/term/pstricks.trm, Revision 1.1.1.3
1.1.1.3 ! ohara 1: /*
! 2: * $Id: pstricks.trm,v 1.12.2.2 2002/01/26 19:05:34 lhecking Exp $
1.1 maekawa 3: */
4:
5: /* GNUPLOT - pstricks.trm */
6:
7: /*[
8: * Copyright 1990 - 1993, 1998
9: *
10: * Permission to use, copy, and distribute this software and its
11: * documentation for any purpose with or without fee is hereby granted,
12: * provided that the above copyright notice appear in all copies and
13: * that both that copyright notice and this permission notice appear
14: * in supporting documentation.
15: *
16: * Permission to modify the software is granted, but not the right to
17: * distribute the complete modified source code. Modifications are to
18: * be distributed as patches to the released version. Permission to
19: * distribute binaries produced by compiling modified sources is granted,
20: * provided you
21: * 1. distribute the corresponding source modifications from the
22: * released version in the form of a patch file along with the binaries,
23: * 2. add special version identification to distinguish your version
24: * in addition to the base release version number,
25: * 3. provide your name and address as the primary contact for the
26: * support of your modified version, and
27: * 4. retain our contact information in regard to use of the base
28: * software.
29: * Permission to distribute the released version of the source code along
30: * with corresponding source modifications in the form of a patch file is
31: * granted with same provisions 2 through 4 for binary distributions.
32: *
33: * This software is provided "as is" without express or implied warranty
34: * to the extent permitted by applicable law.
35: ]*/
36:
37: /*
38: * This file is included by ../term.c.
39: *
40: * This terminal driver supports:
41: * The PSTricks macros for LaTeX.
42: *
43: * AUTHORS
44: * David Kotz
45: *
46: * Raymond Toy toy@soho.crd.ge.com
47: * Modified the eepic.trm file to use PSTricks macros instead.
48: *
49: * 20 Mar 93:
50: * Utilized many suggestions from Gisli Ottarsson
51: * (gisli@liapunov.eecs.umich.edu) to create a new version.
52: * Should also work with TeX as well as LaTeX.
53: *
54: * If you have PSTricks version 0.91, #define OLD_PST to
55: * get the right dots.
56: *
57: * Added a really ugly hack (enabled by default) to print
58: * "nice" numbers for axis labels. This should really be at
59: * a higher level in the code, but I'm lazy right now.
60: *
61: * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
62: *
63: */
64:
65: /*
66: * This file contains the PSTricks terminal driver, intended for use with the
67: * pstricks.sty macro package for LaTeX. This is an alternative to the
68: * eepic and latex driver. You need pstricks.sty, and, of course, a printer
69: * that understands PostScript. Ghostscript understands Postscript too.
70: *
71: * PSTricks is available via anonymous ftp from the /pub directory
72: * at Princeton.EDU. This driver definitely does not come close to
73: * using the full capability of the PSTricks package.
74: */
75: /*
76: * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
77: */
78:
79: #include "driver.h"
80:
81: #ifdef TERM_REGISTER
82: register_term(pstricks)
83: #endif
84:
85: #ifdef TERM_PROTO
86: TERM_PUBLIC void PSTRICKS_options __PROTO((void));
87: TERM_PUBLIC void PSTRICKS_init __PROTO((void));
88: TERM_PUBLIC void PSTRICKS_graphics __PROTO((void));
89: TERM_PUBLIC void PSTRICKS_text __PROTO((void));
90: TERM_PUBLIC void PSTRICKS_linetype __PROTO((int linetype));
91: TERM_PUBLIC void PSTRICKS_move __PROTO((unsigned int x, unsigned int y));
92: TERM_PUBLIC void PSTRICKS_point __PROTO((unsigned int x, unsigned int y, int number));
93: TERM_PUBLIC void PSTRICKS_vector __PROTO((unsigned int ux, unsigned int uy));
94: TERM_PUBLIC void PSTRICKS_arrow __PROTO((unsigned int sx, unsigned int sy, unsigned int ex, unsigned int ey, TBOOLEAN head));
95: TERM_PUBLIC void PSTRICKS_put_text __PROTO((unsigned int x, unsigned int y, char str[]));
96: TERM_PUBLIC int PSTRICKS_justify_text __PROTO((enum JUSTIFY mode));
97: TERM_PUBLIC int PSTRICKS_text_angle __PROTO((int ang));
98: TERM_PUBLIC void PSTRICKS_reset __PROTO((void));
99:
100: #define PSTRICKS_XMAX 10000.0
101: #define PSTRICKS_YMAX 10000.0
102:
103: #define PSTRICKS_HTIC 150
104: #define PSTRICKS_VTIC 200
105: #define PSTRICKS_HCHAR 160
106: #define PSTRICKS_VCHAR 420
107: #endif /* TERM_PROTO */
108:
109: #ifndef TERM_PROTO_ONLY
110: #ifdef TERM_BODY
111: static void PSTRICKS_endline __PROTO((void));
1.1.1.3 ! ohara 112: static char *PSTRICKS_hack_text __PROTO((char *s));
1.1 maekawa 113:
114: static float PSTRICKS_posx;
115: static float PSTRICKS_posy;
1.1.1.3 ! ohara 116: static enum JUSTIFY PSTRICKS_justify = LEFT;
1.1 maekawa 117: static int PSTRICKS_angle = 0;
118:
119: #define PSTRICKS_TINY_DOT 0.00025 /* A tiny dot */
120:
121: /* POINTS */
122: #define PSTRICKS_POINT_TYPES 12 /* we supply more point types */
1.1.1.3 ! ohara 123:
! 124: static char *PSTRICKS_points[] = {
1.1 maekawa 125: "\\PST@Diamond",
126: "\\PST@Plus",
127: "\\PST@Square",
128: "\\PST@Cross",
129: "\\PST@Circle",
130: "\\PST@Triangle",
131: "\\PST@Pentagon",
132: "\\PST@Filldiamond",
133: "\\PST@Fillsquare",
134: "\\PST@Filltriangle",
135: "\\PST@Fillcircle",
136: "\\PST@Fillpentagon"
137: };
138:
139: /* LINES */
140: #define PSTRICKS_NUMLINES 6 /* number of linetypes below */
1.1.1.3 ! ohara 141:
! 142: static char *PSTRICKS_lines[] = {
1.1 maekawa 143: "\\PST@Border",
144: "\\PST@Axes",
145: "\\PST@Solid",
146: "\\PST@Dashed",
147: "\\PST@Dotted",
148: "\\PST@LongDash"
149: };
150:
151: /* current line type */
152: static int PSTRICKS_type;
153:
154: /* are we in the middle of a line */
155: static TBOOLEAN PSTRICKS_inline = FALSE;
156:
157: /* terminate any line in progress */
158: static void PSTRICKS_endline __PROTO((void));
159:
160: /* number of points in line so far */
161: static int PSTRICKS_linecount = 0;
162:
163: /* max value for linecount */
164: #define PSTRICKS_LINEMAX 100
165:
166: /*
167: * Handle options
168: */
169:
170: static int PST_hack_text = TRUE; /* Hack text on */
171: static int PST_unit_plot = FALSE; /* Unit-sized plot off */
172:
1.1.1.3 ! ohara 173: TERM_PUBLIC void
! 174: PSTRICKS_options()
1.1 maekawa 175: {
176: if (!END_OF_COMMAND) {
177: if (almost_equals(c_token, "no$hacktext")) {
178: PST_hack_text = FALSE;
179: c_token++;
180: } else if (almost_equals(c_token, "u$nit")) {
181: PST_unit_plot = TRUE;
182: c_token++;
183: }
184: }
185: }
186:
1.1.1.3 ! ohara 187: TERM_PUBLIC void
! 188: PSTRICKS_init()
1.1 maekawa 189: {
190: PSTRICKS_posx = PSTRICKS_posy = 0;
191: PSTRICKS_linetype(-1);
192: fputs("% GNUPLOT: LaTeX picture using PSTRICKS macros\n", gpoutfile);
193: }
194:
195:
1.1.1.3 ! ohara 196: TERM_PUBLIC void
! 197: PSTRICKS_graphics()
1.1 maekawa 198: {
199: fputs("\
200: % Define new PST objects, if not already defined\n\
201: \\ifx\\PSTloaded\\undefined\n\
202: \\def\\PSTloaded{t}\n\
203: \\psset{arrowsize=.01 3.2 1.4 .3}\n\
204: \\psset{dotsize=.01}\n\
205: \\catcode`@=11\n\n", gpoutfile);
206:
207: /* Define line type objects */
208: fputs("\
209: \\newpsobject{PST@Border}{psline}{linewidth=.0015,linestyle=solid}\n\
210: \\newpsobject{PST@Axes}{psline}{linewidth=.0015,linestyle=dotted,dotsep=.004}\n\
211: \\newpsobject{PST@Solid}{psline}{linewidth=.0015,linestyle=solid}\n\
212: \\newpsobject{PST@Dashed}{psline}{linewidth=.0015,linestyle=dashed,dash=.01 .01}\n\
213: \\newpsobject{PST@Dotted}{psline}{linewidth=.0025,linestyle=dotted,dotsep=.008}\n\
214: \\newpsobject{PST@LongDash}{psline}{linewidth=.0015,linestyle=dashed,dash=.02 .01}\n", gpoutfile);
215:
216: /* Define point objects */
217:
218: #ifdef OLD_PST
219: /* PSTricks version 0.91 had x and diamond dot types */
220: fputs("\
221: \\newpsobject(PST@Diamond}{psdots}{linewidth=.001,linestyle=solid,dotstyle=diamond}\n\
222: \\newpsobject(PST@Filldiamond}{psdots}{linewidth=.001,linestyle=solid,dotstyle=diamond*}\n\
223: \\newpsobject{PST@Cross}{psdots}{linewidth=.001,linestyle=solid,dotstyle=x}\n", gpoutfile);
224: #else
225: /* Newer versions use rotated plus and square to get the x and diamond dots */
226: fputs("\
227: \\newpsobject{PST@Diamond}{psdots}{linewidth=.001,linestyle=solid,dotstyle=square,dotangle=45}\n\
228: \\newpsobject{PST@Filldiamond}{psdots}{linewidth=.001,linestyle=solid,dotstyle=square*,dotangle=45}\n\
229: \\newpsobject{PST@Cross}{psdots}{linewidth=.001,linestyle=solid,dotstyle=+,dotangle=45}\n", gpoutfile);
230: #endif
231:
232: fputs("\
233: \\newpsobject{PST@Plus}{psdots}{linewidth=.001,linestyle=solid,dotstyle=+}\n\
234: \\newpsobject{PST@Square}{psdots}{linewidth=.001,linestyle=solid,dotstyle=square}\n\
235: \\newpsobject{PST@Circle}{psdots}{linewidth=.001,linestyle=solid,dotstyle=o}\n\
236: \\newpsobject{PST@Triangle}{psdots}{linewidth=.001,linestyle=solid,dotstyle=triangle}\n\
237: \\newpsobject{PST@Pentagon}{psdots}{linewidth=.001,linestyle=solid,dotstyle=pentagon}\n\
238: \\newpsobject{PST@Fillsquare}{psdots}{linewidth=.001,linestyle=solid,dotstyle=square*}\n\
239: \\newpsobject{PST@Fillcircle}{psdots}{linewidth=.001,linestyle=solid,dotstyle=*}\n\
240: \\newpsobject{PST@Filltriangle}{psdots}{linewidth=.001,linestyle=solid,dotstyle=triangle*}\n\
241: \\newpsobject{PST@Fillpentagon}{psdots}{linewidth=.001,linestyle=solid,dotstyle=pentagon*}\n", gpoutfile);
242:
243: /* Define arrow object */
244: fputs("\
245: \\newpsobject{PST@Arrow}{psline}{linewidth=.001,linestyle=solid}\n\
246: \\catcode`@=12\n\n\
247: \\fi\n", gpoutfile);
248:
249: /* Set the scaled plot size, if it's not a unit plot */
250: if (!PST_unit_plot) {
1.1.1.3 ! ohara 251: fputs("\\psset{unit=5.0in,xunit=5.0in,yunit=3.0in}\n", gpoutfile);
1.1 maekawa 252: }
1.1.1.3 ! ohara 253: /* HBB 20001027: fix bounding box bug by letting the currently
! 254: * active 'size' and 'offset' setting influence the area used by
! 255: * the picture environment */
! 256: fprintf(gpoutfile, "\
! 257: \\pspicture(%f,%f)(%f,%f)\n\
1.1 maekawa 258: \\ifx\\nofigs\\undefined\n\
1.1.1.3 ! ohara 259: \\catcode`@=11\n\n",
! 260: xoffset,
! 261: yoffset,
! 262: (xoffset + xsize),
! 263: (yoffset + ysize)
! 264: );
1.1 maekawa 265: }
266:
267:
1.1.1.3 ! ohara 268: TERM_PUBLIC void
! 269: PSTRICKS_text()
1.1 maekawa 270: {
271: PSTRICKS_endline();
272: fputs("\
273: \\catcode`@=12\n\
274: \\fi\n\
275: \\endpspicture\n", gpoutfile);
276: }
277:
278:
1.1.1.3 ! ohara 279: TERM_PUBLIC void
! 280: PSTRICKS_linetype(linetype)
1.1 maekawa 281: int linetype;
282: {
283: PSTRICKS_endline();
284:
285: if (linetype >= PSTRICKS_NUMLINES - 2)
286: linetype %= (PSTRICKS_NUMLINES - 2);
287:
288: PSTRICKS_type = linetype;
289: }
290:
291:
292:
1.1.1.3 ! ohara 293: TERM_PUBLIC void
! 294: PSTRICKS_move(x, y)
1.1 maekawa 295: unsigned int x;
296: unsigned int y;
297: {
298: PSTRICKS_endline();
299:
300: PSTRICKS_posx = x / PSTRICKS_XMAX;
301: PSTRICKS_posy = y / PSTRICKS_YMAX;
302: }
303:
304:
1.1.1.3 ! ohara 305: TERM_PUBLIC void
! 306: PSTRICKS_point(x, y, number) /* version of line_and_point */
1.1 maekawa 307: unsigned x;
308: unsigned y;
309: int number;
310: {
311: PSTRICKS_move(x, y);
312:
313: /* Print the character defined by 'number'; number < 0 means
314: to use a dot, otherwise one of the defined points. */
315:
316: if (number < 0) {
317: fprintf(gpoutfile, "\\qdisk(%.4f,%.4f){%.4f}\n",
318: x / PSTRICKS_XMAX,
319: y / PSTRICKS_YMAX,
320: PSTRICKS_TINY_DOT);
321: } else {
322: fprintf(gpoutfile, "%s(%.4f,%.4f)\n",
323: PSTRICKS_points[number % PSTRICKS_POINT_TYPES],
324: x / PSTRICKS_XMAX,
325: y / PSTRICKS_YMAX);
326: }
327: }
328:
329:
1.1.1.3 ! ohara 330: TERM_PUBLIC void
! 331: PSTRICKS_vector(ux, uy)
1.1 maekawa 332: unsigned ux;
333: unsigned uy;
334: {
335: if (!PSTRICKS_inline) {
336: PSTRICKS_inline = TRUE;
337:
338: /* Start a new line. This depends on line type */
1.1.1.3 ! ohara 339: fprintf(gpoutfile, "%s(%.4f,%.4f)\n",
! 340: PSTRICKS_lines[PSTRICKS_type + 2],
1.1 maekawa 341: PSTRICKS_posx, PSTRICKS_posy);
342: PSTRICKS_linecount = 1;
343: } else {
344: /*
345: * Even though we are in middle of a path,
346: * we may want to start a new path command.
347: * If they are too long then latex will choke.
348: */
349: if (PSTRICKS_linecount++ >= PSTRICKS_LINEMAX) {
1.1.1.3 ! ohara 350: /* fprintf(gpoutfile, "\n"); */
! 351: fprintf(gpoutfile, "%s(%.4f,%.4f)\n",
! 352: PSTRICKS_lines[PSTRICKS_type + 2],
1.1 maekawa 353: PSTRICKS_posx, PSTRICKS_posy);
354: PSTRICKS_linecount = 1;
355: }
356: }
357: PSTRICKS_posx = ux / PSTRICKS_XMAX;
358: PSTRICKS_posy = uy / PSTRICKS_YMAX;
359: fprintf(gpoutfile, "(%.4f,%.4f)\n", PSTRICKS_posx, PSTRICKS_posy);
360: }
361:
1.1.1.3 ! ohara 362: static void
! 363: PSTRICKS_endline()
1.1 maekawa 364: {
365: if (PSTRICKS_inline) {
366: putc('\n', gpoutfile);
367: PSTRICKS_inline = FALSE;
368: }
369: }
370:
371:
1.1.1.3 ! ohara 372: TERM_PUBLIC void
! 373: PSTRICKS_arrow(sx, sy, ex, ey, head)
1.1 maekawa 374: unsigned int sx;
375: unsigned int sy;
376: unsigned int ex;
377: unsigned int ey;
378: TBOOLEAN head;
379: {
380: fprintf(gpoutfile, "\\PST@Arrow%s(%.4f,%.4f)(%.4f,%.4f)\n",
381: head ? "{->}" : "",
382: sx / PSTRICKS_XMAX,
383: sy / PSTRICKS_YMAX,
384: ex / PSTRICKS_XMAX,
385: ey / PSTRICKS_YMAX);
386:
387: PSTRICKS_posx = ex / PSTRICKS_XMAX;
388: PSTRICKS_posy = ey / PSTRICKS_YMAX;
389: }
390:
391: /*
392: * A really ugly hack!!!
393: *
394: * This function takes an input string and hacks it up. If the
395: * input string starts with a number, it converts the number into a
396: * TeX style number including exponential notation. Thus, if
397: * the input is the string "3.14159e3 is a number", then
398: * the output is "$3.14159\cdot 10^{3}$ is a number", so that TeX
399: * will produce something nice.
400: *
401: * This is basically meant for producing axis labels that look nice.
402: *
403: * What a hack!
404: */
405:
406:
1.1.1.3 ! ohara 407: static char *
! 408: PSTRICKS_hack_text(s)
! 409: char *s;
1.1 maekawa 410: {
411: double value;
412: char *ends;
413: static char hack[BUFSIZ];
414:
415: /*
416: * Does the string start with a number?
417: */
418:
419: value = strtod(s, &ends);
420:
421: if (s == ends) {
422: /*
423: * This doesn't start a number, so just copy the string over
424: */
425:
426: strcpy(hack, s);
427: } else {
428: char *ptr;
429:
430: /*
431: * We have a number! Check to see if the number
432: * is in scientific notation
433: */
434:
1.1.1.2 maekawa 435: safe_strncpy(hack, s, ends - s + 1);
1.1 maekawa 436: /* hack[ends - s] = '\0'; */
437:
438: ptr = strchr(hack, 'e');
439: if (ptr == NULL) {
440: ptr = strchr(hack, 'E');
441: }
442: if (ptr != NULL) {
443: /*
444: * Exponential notation! Let's get the mantissa and exponent separately
445: */
446:
447: double man_val;
448: int expo_val;
449:
450: *ptr = NUL;
451:
452: man_val = atof(hack);
453: expo_val = atoi(ptr + 1);
454:
455: if (man_val == 0) {
456: sprintf(hack, "0");
457: } else if (man_val == 1) {
458: sprintf(hack, "$10^{%d}$", expo_val);
459: } else if (man_val == (int) man_val) {
460: if (expo_val == 1) {
461: sprintf(hack, "$%d$", (int) man_val);
462: } else {
463: sprintf(hack, "$%d \\times 10^{%d}$", (int) man_val, expo_val);
464: }
465: } else {
466: if (expo_val == 1) {
467: sprintf(hack, "$%f$", man_val);
468: } else {
469: sprintf(hack, "$%f \\times 10^{%d}$", man_val, expo_val);
470: }
471: }
472: }
473: /*
474: * Copy anything that's left of the string
475: */
476:
477: strcat(hack, ends);
478: }
479:
480: return hack;
481: }
482:
1.1.1.3 ! ohara 483: TERM_PUBLIC void
! 484: PSTRICKS_put_text(x, y, str)
1.1 maekawa 485: unsigned int x;
486: unsigned int y;
487: char str[];
488: {
489: PSTRICKS_endline();
490:
491: /* Skip this if the string is empty */
492:
493: if (strlen(str) > 0) {
494: fputs("\\rput", gpoutfile);
495:
496: /* Set justification */
497:
498: switch (PSTRICKS_justify) {
499: case LEFT:
500: fputs("[l]", gpoutfile);
501: break;
502: case CENTRE:
503: break;
504: case RIGHT:
505: fputs("[r]", gpoutfile);
506: break;
507: }
508:
509: /* Set text angle */
510:
511: switch (PSTRICKS_angle) {
512: case 0:
513: break;
514: case 1:
515: fputs("{L}", gpoutfile);
516: break;
517: }
518:
519: /* Set reference position and text */
520:
521: fprintf(gpoutfile, "(%.4f,%.4f)",
522: x / PSTRICKS_XMAX,
523: y / PSTRICKS_YMAX);
524: if (PST_hack_text) {
525: char *hack;
526:
527: /* Hack leading numbers to something nice for TeX */
528:
529: hack = PSTRICKS_hack_text(str);
530: fprintf(gpoutfile, "{%s}\n", hack);
531: } else {
532: fprintf(gpoutfile, "{%s}\n", str);
533: }
534: }
535: }
536:
537:
538:
1.1.1.3 ! ohara 539: TERM_PUBLIC int
! 540: PSTRICKS_justify_text(mode)
1.1 maekawa 541: enum JUSTIFY mode;
542: {
543: PSTRICKS_justify = mode;
544: return (TRUE);
545: }
546:
1.1.1.3 ! ohara 547: TERM_PUBLIC int
! 548: PSTRICKS_text_angle(ang)
1.1 maekawa 549: int ang;
550: {
551: PSTRICKS_angle = ang;
552: return (TRUE);
553: }
554:
1.1.1.3 ! ohara 555: TERM_PUBLIC void
! 556: PSTRICKS_reset()
1.1 maekawa 557: {
558: PSTRICKS_endline();
559: PSTRICKS_posx = PSTRICKS_posy = 0;
560: }
561:
562: #endif /* TERM_BODY */
563:
564: #ifdef TERM_TABLE
565:
566: TERM_TABLE_START(pstricks_driver)
567: "pstricks", "LaTeX picture environment with PSTricks macros",
568: PSTRICKS_XMAX, PSTRICKS_YMAX, PSTRICKS_VCHAR, PSTRICKS_HCHAR,
569: PSTRICKS_VTIC, PSTRICKS_HTIC, PSTRICKS_options, PSTRICKS_init, PSTRICKS_reset,
570: PSTRICKS_text, null_scale, PSTRICKS_graphics, PSTRICKS_move, PSTRICKS_vector,
571: PSTRICKS_linetype, PSTRICKS_put_text, PSTRICKS_text_angle,
572: PSTRICKS_justify_text, PSTRICKS_point, PSTRICKS_arrow, set_font_null
573: TERM_TABLE_END(pstricks_driver)
574:
575: #undef LAST_TERM
576: #define LAST_TERM pstricks_driver
577:
578: #endif /* TERM_TABLE */
579: #endif /* TERM_PROTO_ONLY */
580:
581: #ifdef TERM_HELP
582: START_HELP(pstricks)
583: "1 pstricks",
584: "?commands set terminal pstricks",
585: "?set terminal pstricks",
586: "?set term pstricks",
587: "?terminal pstricks",
588: "?term pstricks",
589: "?pstricks",
590: " The `pstricks` driver is intended for use with the \"pstricks.sty\" macro",
591: " package for LaTeX. It is an alternative to the `eepic` and `latex` drivers.",
592: " You need \"pstricks.sty\", and, of course, a printer that understands",
593: " PostScript, or a converter such as Ghostscript.",
594: "",
595: " PSTricks is available via anonymous ftp from the /pub directory at",
596: " Princeton.EDU. This driver definitely does not come close to using the full",
597: " capability of the PSTricks package.",
598: "",
599: " Syntax:",
600: " set terminal pstricks {hacktext | nohacktext} {unit | nounit}",
601: "",
602: " The first option invokes an ugly hack that gives nicer numbers; the second",
603: " has to do with plot scaling. The defaults are `hacktext` and `nounit`."
604: END_HELP(pstricks)
605: #endif /* TERM_HELP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>