- Optification is done by auto builder now
[gnuplot] / term / pstricks.trm
1 /* Hey Emacs this is -*- C -*-
2  *
3  * $Id: pstricks.trm,v 1.32.2.1 2006/11/18 17:27:02 sfeam Exp $
4  */
5
6 /* GNUPLOT - pstricks.trm */
7
8 /*[
9  * Copyright 1990 - 1993, 1998, 2004
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  *   The PSTricks macros for LaTeX.
43  *
44  * AUTHORS
45  *   David Kotz
46  *
47  *   Raymond Toy        toy@soho.crd.ge.com
48  *      Modified the eepic.trm file to use PSTricks macros instead.
49  *
50  *      20 Mar 93:
51  *              Utilized many suggestions from Gisli Ottarsson
52  *              (gisli@liapunov.eecs.umich.edu) to create a new version.
53  *              Should also work with TeX as well as LaTeX.
54  *
55  *              If you have PSTricks version 0.91, #define OLD_PST to
56  *              get the right dots.
57  *
58  *              Added a really ugly hack (enabled by default) to print
59  *              "nice" numbers for axis labels.  This should really be at
60  *              a higher level in the code, but I'm lazy right now.
61  *
62  * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
63  *
64  */
65
66 /*
67  *  This file contains the PSTricks terminal driver, intended for use with the
68  *  pstricks.sty macro package for LaTeX. This is an alternative to the
69  *  eepic and latex driver. You need pstricks.sty, and, of course, a printer
70  *  that understands PostScript.  Ghostscript understands Postscript too.
71  *
72  *  PSTricks is available via anonymous ftp from the /pub directory
73  *  at Princeton.EDU.  This driver definitely does not come close to
74  *  using the full capability of the PSTricks package.
75  */
76 /*
77  * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
78  *
79  * adapted to support pm3d by Tim Piessens and Petr Mikulik (Jan. 2003)
80  */
81
82 #include "driver.h"
83
84 #ifdef TERM_REGISTER
85 register_term(pstricks)
86 #endif
87
88 #ifdef TERM_PROTO
89 TERM_PUBLIC void PSTRICKS_options __PROTO((void));
90 TERM_PUBLIC void PSTRICKS_init __PROTO((void));
91 TERM_PUBLIC void PSTRICKS_graphics __PROTO((void));
92 TERM_PUBLIC void PSTRICKS_text __PROTO((void));
93 TERM_PUBLIC void PSTRICKS_linetype __PROTO((int linetype));
94 TERM_PUBLIC void PSTRICKS_move __PROTO((unsigned int x, unsigned int y));
95 TERM_PUBLIC void PSTRICKS_point __PROTO((unsigned int x, unsigned int y, int number));
96 TERM_PUBLIC void PSTRICKS_vector __PROTO((unsigned int ux, unsigned int uy));
97 TERM_PUBLIC void PSTRICKS_arrow __PROTO((unsigned int sx, unsigned int sy, unsigned int ex, unsigned int ey, int head));
98 TERM_PUBLIC void PSTRICKS_put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
99 TERM_PUBLIC int PSTRICKS_justify_text __PROTO((enum JUSTIFY mode));
100 TERM_PUBLIC int PSTRICKS_text_angle __PROTO((int ang));
101 TERM_PUBLIC void PSTRICKS_reset __PROTO((void));
102 TERM_PUBLIC int PSTRICKS_make_palette __PROTO((t_sm_palette *));
103 TERM_PUBLIC void PSTRICKS_set_color __PROTO((t_colorspec *));
104 TERM_PUBLIC void PSTRICKS_filled_polygon __PROTO((int, gpiPoint *));
105
106 #define PSTRICKS_XMAX 10000.0
107 #define PSTRICKS_YMAX 10000.0
108
109 #define PSTRICKS_HTIC   150
110 #define PSTRICKS_VTIC   200
111 #define PSTRICKS_HCHAR  160
112 #define PSTRICKS_VCHAR  420
113 #endif /* TERM_PROTO */
114
115 #ifndef TERM_PROTO_ONLY
116 #ifdef TERM_BODY
117 static void PSTRICKS_endline __PROTO((void));
118 static char *PSTRICKS_hack_text __PROTO((const char *s));
119
120 static float PSTRICKS_posx;
121 static float PSTRICKS_posy;
122 static enum JUSTIFY PSTRICKS_justify = LEFT;
123 static int PSTRICKS_angle = 0;
124
125 /* if 1 below, then the file size is shorter thanks to a macro for polygon */
126 #define PSTRICKS_SHORTER_FILE 1
127
128 #ifdef PSTRICKS_SHORTER_FILE
129 static int PSTRICKS_color = 0;
130 #else
131 static char PSTRICKS_color_str[16] = "";
132 #endif
133 static int PSTRICKS_palette_set = FALSE;
134 static int PSTRICKS_palette_size = 128;
135
136 #define PSTRICKS_TINY_DOT       0.00025         /* A tiny dot */
137
138 /* POINTS */
139 #define PSTRICKS_POINT_TYPES 12 /* we supply more point types */
140
141 static const char *PSTRICKS_points[] = {
142     "\\PST@Diamond",
143     "\\PST@Plus",
144     "\\PST@Square",
145     "\\PST@Cross",
146     "\\PST@Circle",
147     "\\PST@Triangle",
148     "\\PST@Pentagon",
149     "\\PST@Filldiamond",
150     "\\PST@Fillsquare",
151     "\\PST@Filltriangle",
152     "\\PST@Fillcircle",
153     "\\PST@Fillpentagon"
154 };
155
156 /* LINES */
157 #define PSTRICKS_NUMLINES 6     /* number of linetypes below */
158
159 static const char *PSTRICKS_lines[] = {
160     "\\PST@Border",
161     "\\PST@Axes",
162     "\\PST@Solid",
163     "\\PST@Dashed",
164     "\\PST@Dotted",
165     "\\PST@LongDash"
166 };
167
168 /* current line type */
169 static int PSTRICKS_type;
170
171 /* are we in the middle of a line */
172 static TBOOLEAN PSTRICKS_inline = FALSE;
173
174 /* terminate any line in progress */
175 static void PSTRICKS_endline __PROTO((void));
176
177 /* number of points in line so far */
178 static int PSTRICKS_linecount = 0;
179
180 /* max value for linecount */
181 #define PSTRICKS_LINEMAX 100
182
183 /*
184  * Handle options
185  */
186
187 static int PST_hack_text = TRUE;        /* Hack text on */
188 static int PST_unit_plot = FALSE;       /* Unit-sized plot off */
189
190 TERM_PUBLIC void
191 PSTRICKS_options()
192 {
193     if (!END_OF_COMMAND) {
194         if (almost_equals(c_token, "no$hacktext")) {
195             PST_hack_text = FALSE;
196             c_token++;
197         } else if (almost_equals(c_token, "u$nit")) {
198             PST_unit_plot = TRUE;
199             c_token++;
200         }
201     }
202 }
203
204 TERM_PUBLIC void
205 PSTRICKS_init()
206 {
207     PSTRICKS_posx = PSTRICKS_posy = 0;
208     PSTRICKS_linetype(-1);
209     fseek(gpoutfile,0,SEEK_SET);
210     fputs("% GNUPLOT: LaTeX picture using PSTRICKS macros\n", gpoutfile);
211     PSTRICKS_palette_set = FALSE;    /* PM3D palette set? */
212 }
213
214
215 TERM_PUBLIC void
216 PSTRICKS_graphics()
217 {
218     fputs("\
219 % Define new PST objects, if not already defined\n\
220 \\ifx\\PSTloaded\\undefined\n\
221 \\def\\PSTloaded{t}\n\
222 \\psset{arrowsize=.01 3.2 1.4 .3}\n\
223 \\psset{dotsize=.01}\n\
224 \\catcode`@=11\n\n", gpoutfile);
225
226     /* Define line type objects */
227     fputs("\
228 \\newpsobject{PST@Border}{psline}{linewidth=.0015,linestyle=solid}\n\
229 \\newpsobject{PST@Axes}{psline}{linewidth=.0015,linestyle=dotted,dotsep=.004}\n\
230 \\newpsobject{PST@Solid}{psline}{linewidth=.0015,linestyle=solid}\n\
231 \\newpsobject{PST@Dashed}{psline}{linewidth=.0015,linestyle=dashed,dash=.01 .01}\n\
232 \\newpsobject{PST@Dotted}{psline}{linewidth=.0025,linestyle=dotted,dotsep=.008}\n\
233 \\newpsobject{PST@LongDash}{psline}{linewidth=.0015,linestyle=dashed,dash=.02 .01}\n", gpoutfile);
234
235     /* Define point objects */
236
237 #ifdef  OLD_PST
238     /* PSTricks version 0.91 had x and diamond dot types */
239     fputs("\
240 \\newpsobject(PST@Diamond}{psdots}{linewidth=.001,linestyle=solid,dotstyle=diamond}\n\
241 \\newpsobject(PST@Filldiamond}{psdots}{linewidth=.001,linestyle=solid,dotstyle=diamond*}\n\
242 \\newpsobject{PST@Cross}{psdots}{linewidth=.001,linestyle=solid,dotstyle=x}\n", gpoutfile);
243 #else
244     /* Newer versions use rotated plus and square to get the x and diamond dots */
245     fputs("\
246 \\newpsobject{PST@Diamond}{psdots}{linewidth=.001,linestyle=solid,dotstyle=square,dotangle=45}\n\
247 \\newpsobject{PST@Filldiamond}{psdots}{linewidth=.001,linestyle=solid,dotstyle=square*,dotangle=45}\n\
248 \\newpsobject{PST@Cross}{psdots}{linewidth=.001,linestyle=solid,dotstyle=+,dotangle=45}\n", gpoutfile);
249 #endif
250
251     fputs("\
252 \\newpsobject{PST@Plus}{psdots}{linewidth=.001,linestyle=solid,dotstyle=+}\n\
253 \\newpsobject{PST@Square}{psdots}{linewidth=.001,linestyle=solid,dotstyle=square}\n\
254 \\newpsobject{PST@Circle}{psdots}{linewidth=.001,linestyle=solid,dotstyle=o}\n\
255 \\newpsobject{PST@Triangle}{psdots}{linewidth=.001,linestyle=solid,dotstyle=triangle}\n\
256 \\newpsobject{PST@Pentagon}{psdots}{linewidth=.001,linestyle=solid,dotstyle=pentagon}\n\
257 \\newpsobject{PST@Fillsquare}{psdots}{linewidth=.001,linestyle=solid,dotstyle=square*}\n\
258 \\newpsobject{PST@Fillcircle}{psdots}{linewidth=.001,linestyle=solid,dotstyle=*}\n\
259 \\newpsobject{PST@Filltriangle}{psdots}{linewidth=.001,linestyle=solid,dotstyle=triangle*}\n\
260 \\newpsobject{PST@Fillpentagon}{psdots}{linewidth=.001,linestyle=solid,dotstyle=pentagon*}\n", gpoutfile);
261
262     /* Define arrow object */
263     fputs("\
264 \\newpsobject{PST@Arrow}{psline}{linewidth=.001,linestyle=solid}\n\
265 \\catcode`@=12\n\n\
266 \\fi\n", gpoutfile);
267
268     /* Set the scaled plot size, if it's not a unit plot */
269     if (!PST_unit_plot) {
270         fputs("\\psset{unit=5.0in,xunit=5.0in,yunit=3.0in}\n", gpoutfile);
271     }
272     /* HBB 20001027: fix bounding box bug by letting the currently
273      * active 'size' and 'offset' setting influence the area used by
274      * the picture environment */
275     fprintf(gpoutfile, "\
276 \\pspicture(%f,%f)(%f,%f)\n\
277 \\ifx\\nofigs\\undefined\n\
278 \\catcode`@=11\n\n",
279             xoffset,
280             yoffset,
281             (xoffset + xsize),
282             (yoffset + ysize)
283     );
284 }
285
286
287 TERM_PUBLIC void
288 PSTRICKS_text()
289 {
290     PSTRICKS_endline();
291     fputs("\
292 \\catcode`@=12\n\
293 \\fi\n\
294 \\endpspicture\n", gpoutfile);
295 }
296
297
298 TERM_PUBLIC void
299 PSTRICKS_linetype(int linetype)
300 {
301     PSTRICKS_endline();
302
303     if (linetype >= PSTRICKS_NUMLINES - 2)
304         linetype %= (PSTRICKS_NUMLINES - 2);
305
306     if (linetype < -2)
307         linetype = LT_BLACK;
308
309     PSTRICKS_type = linetype;
310 }
311
312
313
314 TERM_PUBLIC void
315 PSTRICKS_move(unsigned int x, unsigned int y)
316 {
317     PSTRICKS_endline();
318
319     PSTRICKS_posx = x / PSTRICKS_XMAX;
320     PSTRICKS_posy = y / PSTRICKS_YMAX;
321 }
322
323
324 TERM_PUBLIC void
325 PSTRICKS_point(unsigned int x, unsigned int y, int number)
326 {
327     PSTRICKS_move(x, y);
328
329     /* Print the character defined by 'number'; number < 0 means
330        to use a dot, otherwise one of the defined points. */
331
332     if (number < 0) {
333         fprintf(gpoutfile, "\\qdisk(%.4f,%.4f){%.4f}\n",
334                 x / PSTRICKS_XMAX,
335                 y / PSTRICKS_YMAX,
336                 PSTRICKS_TINY_DOT);
337     } else {
338         fprintf(gpoutfile, "%s(%.4f,%.4f)\n",
339                 PSTRICKS_points[number % PSTRICKS_POINT_TYPES],
340                 x / PSTRICKS_XMAX,
341                 y / PSTRICKS_YMAX);
342     }
343 }
344
345
346 TERM_PUBLIC void
347 PSTRICKS_vector(unsigned ux, unsigned uy)
348 {
349     if (!PSTRICKS_inline) {
350         PSTRICKS_inline = TRUE;
351
352         /* Start a new line. This depends on line type */
353         fprintf(gpoutfile, "%s(%.4f,%.4f)\n",
354                 PSTRICKS_lines[PSTRICKS_type + 2],
355                 PSTRICKS_posx, PSTRICKS_posy);
356         PSTRICKS_linecount = 1;
357     } else {
358         /*
359          * Even though we are in middle of a path,
360          * we may want to start a new path command.
361          * If they are too long then latex will choke.
362          */
363         if (PSTRICKS_linecount++ >= PSTRICKS_LINEMAX) {
364             /* fprintf(gpoutfile, "\n"); */
365             fprintf(gpoutfile, "%s(%.4f,%.4f)\n",
366                     PSTRICKS_lines[PSTRICKS_type + 2],
367                     PSTRICKS_posx, PSTRICKS_posy);
368             PSTRICKS_linecount = 1;
369         }
370     }
371     PSTRICKS_posx = ux / PSTRICKS_XMAX;
372     PSTRICKS_posy = uy / PSTRICKS_YMAX;
373     fprintf(gpoutfile, "(%.4f,%.4f)\n", PSTRICKS_posx, PSTRICKS_posy);
374 }
375
376 static void
377 PSTRICKS_endline()
378 {
379     if (PSTRICKS_inline) {
380         putc('\n', gpoutfile);
381         PSTRICKS_inline = FALSE;
382     }
383 }
384
385
386 TERM_PUBLIC void
387 PSTRICKS_arrow(
388     unsigned int sx, unsigned int sy,
389     unsigned int ex, unsigned int ey,
390     int head)
391 {
392     fprintf(gpoutfile, "\\PST@Arrow%s(%.4f,%.4f)(%.4f,%.4f)\n",
393             head ? "{->}" : "",
394             sx / PSTRICKS_XMAX,
395             sy / PSTRICKS_YMAX,
396             ex / PSTRICKS_XMAX,
397             ey / PSTRICKS_YMAX);
398
399     PSTRICKS_posx = ex / PSTRICKS_XMAX;
400     PSTRICKS_posy = ey / PSTRICKS_YMAX;
401 }
402
403 /*
404  * A really ugly hack!!!
405  *
406  * This function takes an input string and hacks it up.  If the
407  * input string starts with a number, it converts the number into a
408  * TeX style number including exponential notation.  Thus, if
409  * the input is the string "3.14159e3 is a number", then
410  * the output is "$3.14159\cdot 10^{3}$ is a number", so that TeX
411  * will produce something nice.
412  *
413  * This is basically meant for producing axis labels that look nice.
414  *
415  * What a hack!
416  */
417
418
419 static char *
420 PSTRICKS_hack_text(const char *s)
421 {
422     double value;
423     char *ends;
424     static char hack[BUFSIZ];
425
426     /*
427      * Does the string start with a number?
428      */
429
430     value = strtod(s, &ends);
431
432     if (s == ends) {
433         /*
434          * This doesn't start a number, so just copy the string over
435          */
436
437         strcpy(hack, s);
438     } else {
439         char *ptr;
440
441         /*
442          * We have a number!  Check to see if the number
443          * is in scientific notation
444          */
445
446         safe_strncpy(hack, s, ends - s + 1);
447         /* hack[ends - s] = '\0'; */
448
449         ptr = strchr(hack, 'e');
450         if (ptr == NULL) {
451             ptr = strchr(hack, 'E');
452         }
453         if (ptr != NULL) {
454             /*
455              * Exponential notation!  Let's get the mantissa and exponent separately
456              */
457
458             double man_val;
459             int expo_val;
460
461             *ptr = NUL;
462
463             man_val = atof(hack);
464             expo_val = atoi(ptr + 1);
465
466             if (man_val == 0) {
467                 sprintf(hack, "0");
468             } else if (man_val == 1) {
469                 sprintf(hack, "$10^{%d}$", expo_val);
470             } else if (man_val == (int) man_val) {
471                 if (expo_val == 1) {
472                     sprintf(hack, "$%d$", (int) man_val);
473                 } else {
474                     sprintf(hack, "$%d \\times 10^{%d}$", (int) man_val, expo_val);
475                 }
476             } else {
477                 if (expo_val == 1) {
478                     sprintf(hack, "$%f$", man_val);
479                 } else {
480                     sprintf(hack, "$%f \\times 10^{%d}$", man_val, expo_val);
481                 }
482             }
483         }
484         /*
485          * Copy anything that's left of the string
486          */
487
488         strcat(hack, ends);
489     }
490
491     return hack;
492 }
493
494 TERM_PUBLIC void
495 PSTRICKS_put_text(unsigned int x, unsigned int y, const char str[])
496 {
497     PSTRICKS_endline();
498
499     /* Skip this if the string is empty */
500
501     if (strlen(str) > 0) {
502         fputs("\\rput", gpoutfile);
503
504         /* Set justification */
505
506         switch (PSTRICKS_justify) {
507         case LEFT:
508             fputs("[l]", gpoutfile);
509             break;
510         case CENTRE:
511             break;
512         case RIGHT:
513             fputs("[r]", gpoutfile);
514             break;
515         }
516
517         /* Set text angle */
518
519         switch (PSTRICKS_angle) {
520         case 0:
521             break;
522         case 1:
523             fputs("{L}", gpoutfile);
524             break;
525         }
526
527         /* Set reference position and text */
528
529         fprintf(gpoutfile, "(%.4f,%.4f)",
530                 x / PSTRICKS_XMAX,
531                 y / PSTRICKS_YMAX);
532         if (PST_hack_text) {
533             char *hack;
534
535             /* Hack leading numbers to something nice for TeX */
536
537             hack = PSTRICKS_hack_text(str);
538             fprintf(gpoutfile, "{%s}\n", hack);
539         } else {
540             fprintf(gpoutfile, "{%s}\n", str);
541         }
542     }
543 }
544
545
546
547 TERM_PUBLIC int
548 PSTRICKS_justify_text(enum JUSTIFY mode)
549 {
550     PSTRICKS_justify = mode;
551     return (TRUE);
552 }
553
554 TERM_PUBLIC int
555 PSTRICKS_text_angle(int ang)
556 {
557     PSTRICKS_angle = (ang ? 1 : 0);
558     return (TRUE);
559 }
560
561 TERM_PUBLIC void
562 PSTRICKS_reset()
563 {
564     PSTRICKS_endline();
565     PSTRICKS_posx = PSTRICKS_posy = 0;
566 }
567
568
569 TERM_PUBLIC int
570 PSTRICKS_make_palette (t_sm_palette *palette)
571 {
572     /* Query to determine palette size */
573     if (palette==NULL) {
574         return PSTRICKS_palette_size;
575     }
576
577     if (PSTRICKS_palette_set == FALSE) {
578         int i;
579         /* Create new palette */
580         PSTRICKS_palette_set = TRUE;
581         if (sm_palette.colorMode == SMPAL_COLOR_MODE_GRAY) {
582             /* Grey palette */
583             for (i=0; i < sm_palette.colors; i++) {
584                 double g = i * 1.0 / (sm_palette.colors - 1);
585                 g = 1e-3 * (int)(g * 1000); /* round to 3 digits to use %g below */
586                 fprintf(gpoutfile, "\\newgray{PST@COLOR%d}{%g}\n", i, g);
587             }
588         } else
589             if (sm_palette.colorMode == SMPAL_COLOR_MODE_RGB) {
590                 /* Color palette */
591                 double r, g, b;
592                 for (i=0; i < sm_palette.colors; i++) {
593                     /* round to 3 digits to avoid sth like 1e-7 in %g below */
594                     r = 1e-3 * (int)(palette->color[i].r * 1000);
595                     g = 1e-3 * (int)(palette->color[i].g * 1000);
596                     b = 1e-3 * (int)(palette->color[i].b * 1000);
597                     fprintf(gpoutfile, "\\newrgbcolor{PST@COLOR%d}{%g %g %g}\n", i, r, g, b);
598                 }
599             }
600     }
601     /* use the following macro to shorten the file size */
602     fprintf(gpoutfile, "\\def\\polypmIIId#1{\\pspolygon[linestyle=none,fillstyle=solid,fillcolor=PST@COLOR#1]}\n\n");
603     return 0;
604 }
605
606
607 TERM_PUBLIC void
608 PSTRICKS_set_color (t_colorspec *colorspec)
609 {
610     int new_color;
611     double gray = colorspec->value;
612
613     if (colorspec->type != TC_FRAC)
614         return;
615
616     new_color = (gray <=0) ? 0 : (int)(gray*sm_palette.colors);
617     if (new_color >= PSTRICKS_palette_size)
618         new_color = PSTRICKS_palette_size - 1;
619     if (PSTRICKS_palette_set == FALSE) {
620         fprintf(stderr, "pstricks: Palette used before set!\n");
621     }
622 #ifdef PSTRICKS_SHORTER_FILE
623     PSTRICKS_color = new_color;
624 #else
625     sprintf(PSTRICKS_color_str, "PST@COLOR%d", new_color);
626 #endif
627 }
628
629
630 TERM_PUBLIC void
631 PSTRICKS_filled_polygon (int points, gpiPoint *corners)
632 {
633     int i;
634
635 #ifdef PSTRICKS_SHORTER_FILE
636     /* using a macro for an abbreviation */
637     fprintf(gpoutfile, "\\polypmIIId{%d}", PSTRICKS_color);
638 #else
639     fprintf(gpoutfile, "\\pspolygon[linestyle=none,fillstyle=solid,fillcolor=%s]", PSTRICKS_color_str);
640 #endif
641     for (i=0; i < points; i++) {
642         if (i % 8 == 7) /* up to 8 corners per line */
643             fprintf(gpoutfile, "\n");
644         fprintf(gpoutfile,"(%.4g,%.4g)", corners[i].x/PSTRICKS_XMAX, corners[i].y/PSTRICKS_YMAX);
645     }
646     fprintf(gpoutfile, "\n");
647 }
648
649 #endif /* TERM_BODY */
650
651
652 #ifdef TERM_TABLE
653
654 TERM_TABLE_START(pstricks_driver)
655     "pstricks", "LaTeX picture environment with PSTricks macros",
656     PSTRICKS_XMAX, PSTRICKS_YMAX, PSTRICKS_VCHAR, PSTRICKS_HCHAR,
657     PSTRICKS_VTIC, PSTRICKS_HTIC, PSTRICKS_options, PSTRICKS_init, PSTRICKS_reset,
658     PSTRICKS_text, null_scale, PSTRICKS_graphics, PSTRICKS_move, PSTRICKS_vector,
659     PSTRICKS_linetype, PSTRICKS_put_text, PSTRICKS_text_angle,
660     PSTRICKS_justify_text, PSTRICKS_point, PSTRICKS_arrow, set_font_null, 0,
661     TERM_BINARY /*flags*/, 0 /*suspend*/, 0 /*resume*/, 0 , 0
662 #ifdef USE_MOUSE
663     , 0, 0, 0, 0, 0
664 #endif
665      , PSTRICKS_make_palette, 0,  PSTRICKS_set_color, PSTRICKS_filled_polygon
666 TERM_TABLE_END(pstricks_driver)
667
668 #undef LAST_TERM
669 #define LAST_TERM pstricks_driver
670
671 #endif /* TERM_TABLE */
672 #endif /* TERM_PROTO_ONLY */
673
674 #ifdef TERM_HELP
675 START_HELP(pstricks)
676 "1 pstricks",
677 "?commands set terminal pstricks",
678 "?set terminal pstricks",
679 "?set term pstricks",
680 "?terminal pstricks",
681 "?term pstricks",
682 "?pstricks",
683 " The `pstricks` driver is intended for use with the \"pstricks.sty\" macro",
684 " package for LaTeX.  It is an alternative to the `eepic` and `latex` drivers.",
685 " You need \"pstricks.sty\", and, of course, a printer that understands",
686 " PostScript, or a converter such as Ghostscript.",
687 "",
688 " PSTricks is available via anonymous ftp from the /pub directory at",
689 " Princeton.edu.  This driver definitely does not come close to using the full",
690 " capability of the PSTricks package.",
691 "",
692 " Syntax:",
693 "       set terminal pstricks {hacktext | nohacktext} {unit | nounit}",
694 "",
695 " The first option invokes an ugly hack that gives nicer numbers; the second",
696 " has to do with plot scaling.  The defaults are `hacktext` and `nounit`."
697 END_HELP(pstricks)
698 #endif /* TERM_HELP */