Initial release of Maemo 5 port of gnuplot
[gnuplot] / term / texdraw.trm
1 /* Hello, Emacs, this is -*-C-*-
2  * $Id: texdraw.trm,v 1.19 2006/07/21 02:35:48 sfeam Exp $
3  */
4
5 /* GNUPLOT - texdraw.trm */
6
7 /*[
8  * Copyright 1990 - 1993, 1998, 2004
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 TEXDRAW macros for LaTeX.
42  *
43  * AUTHORS
44  *   Khun Yee Fung. Modified from eepic.trm.
45  *   clipper@csd.uwo.ca
46  *   January 20, 1992
47  *
48  * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
49  *
50  */
51
52 /*
53  *  This file contains the texdraw terminal driver, intended for use with the
54  *  texdraw macro package for LaTeX. This is an alternative to the
55  *  latex driver. You need texdraw.sty, and texdraw.tex in the texdraw package.
56  *
57  */
58 #include "driver.h"
59
60 #ifdef TERM_REGISTER
61 register_term(texdraw)
62 #endif
63
64 #ifdef TERM_PROTO
65 TERM_PUBLIC void TEXDRAW_init __PROTO((void));
66 TERM_PUBLIC void TEXDRAW_graphics __PROTO((void));
67 TERM_PUBLIC void TEXDRAW_text __PROTO((void));
68 TERM_PUBLIC void TEXDRAW_linetype __PROTO((int linetype));
69 TERM_PUBLIC void TEXDRAW_move __PROTO((unsigned int x, unsigned int y));
70 TERM_PUBLIC void TEXDRAW_point __PROTO((unsigned int x, unsigned int y,
71                                         int number));
72 TERM_PUBLIC void TEXDRAW_vector __PROTO((unsigned int ux, unsigned int uy));
73 TERM_PUBLIC void TEXDRAW_arrow __PROTO((unsigned int sx, unsigned int sy,
74                                         unsigned int ex, unsigned int ey,
75                                         int head));
76 TERM_PUBLIC void TEXDRAW_put_text __PROTO((unsigned int x, unsigned int y,
77                                            const char str[]));
78 TERM_PUBLIC int TEXDRAW_justify_text __PROTO((enum JUSTIFY mode));
79 TERM_PUBLIC int TEXDRAW_text_angle __PROTO((int ang));
80 TERM_PUBLIC void TEXDRAW_reset __PROTO((void));
81
82 #define TEXDRAW_PTS_PER_INCH (72.27)
83 /* resolution of printer we expect to use */
84 #define DOTS_PER_INCH (300)
85 /* dot size in pt */
86 #define TEXDRAW_UNIT (TEXDRAW_PTS_PER_INCH/DOTS_PER_INCH)
87
88 /* 5 inches wide by 3 inches high (default) */
89 #define TEXDRAW_XMAX (5*DOTS_PER_INCH)
90 #define TEXDRAW_YMAX (3*DOTS_PER_INCH)
91
92 #define TEXDRAW_HTIC (5*DOTS_PER_INCH/72)       /* (5./TEXDRAW_UNIT) */
93 #define TEXDRAW_VTIC (5*DOTS_PER_INCH/72)       /* (5./TEXDRAW_UNIT) */
94 #define TEXDRAW_HCHAR (DOTS_PER_INCH*53/10/72)  /* (5.3/TEXDRAW_UNIT) */
95 #define TEXDRAW_VCHAR (DOTS_PER_INCH*11/72)     /* (11./TEXDRAW_UNIT) */
96
97 #define GOT_TEXDRAW_PROTO
98 #endif
99
100 #ifndef TERM_PROTO_ONLY
101 #ifdef TERM_BODY
102 static void TEXDRAW_endline __PROTO((void));
103 static unsigned int TEXDRAW_posx;
104 static unsigned int TEXDRAW_posy;
105 static enum JUSTIFY TEXDRAW_justify = LEFT;
106 static enum JUSTIFY TEXDRAW_last_justify = LEFT;
107 static int TEXDRAW_angle = 0;
108 static float TEXDRAW_scalefactor = 0.2409;
109 static double TEXDRAW_xscale = 1.0, TEXDRAW_yscale = 1.0;
110
111 /* for DOTS point style */
112 #define TEXDRAW_TINY_DOT "\\htext{$\\cdot$}"
113
114 /* POINTS */
115 #define TEXDRAW_POINT_TYPES 12  /* we supply more point types */
116
117 static const char GPFAR *GPFAR TEXDRAW_points[] = {
118     "\\rmove(0 4)\\htext{$\\Diamond$}",
119     "\\htext{$+$}",
120     "\\rmove(0 4)\\htext{$\\Box$}",
121     "\\htext{$\\times$}",
122     "\\htext{$\\triangle$}",
123     "\\htext{$\\star$}",
124     "\\lcir r:9",
125     "\\lcir r:12",
126     "\\lcir r:16",
127     "\\fcir f:0.9 r:9",
128     "\\fcir f:0.9 r:12",
129     "\\fcir f:0.9 r:16"
130 };
131
132 /* LINES */
133 #define TEXDRAW_NUMLINES 5      /* number of linetypes below */
134
135 static const int TEXDRAW_lines[] = {
136     4,                          /* -2 border */
137     3,                          /* -1 axes */
138     3,                          /*  0 solid thin  */
139     4,                          /*  1 solid thick */
140     6,                          /*  2 solid Thick */
141 };
142
143 /* The line type selected most recently */
144 static int TEXDRAW_last_type = 0;
145 /* current line type */
146 static int TEXDRAW_type;
147 /* are we in the middle of a line */
148 static TBOOLEAN TEXDRAW_inline = FALSE;
149 /* terminate any line in progress */
150 static void TEXDRAW_endline __PROTO((void));
151 /* number of points in line so far */
152 static int TEXDRAW_linecount = 0;
153 /* max value for linecount */
154 #define TEXDRAW_LINEMAX 5
155
156 TERM_PUBLIC void
157 TEXDRAW_init()
158 {
159     TEXDRAW_posx = TEXDRAW_posy = 0;
160     TEXDRAW_linetype(-1);
161     fputs("%% GNUPLOT: LaTeX using TEXDRAW macros\n", gpoutfile);
162 }
163
164 TERM_PUBLIC void
165 TEXDRAW_graphics()
166 {
167     static char GPFAR tdg1[] = "\
168 \\begin{texdraw}\n\
169 \\normalsize\n\
170 \\ifx\\pathDEFINED\\relax\\else\\let\\pathDEFINED\\relax\n\
171  \\def\\QtGfr{\\ifx (\\TGre \\let\\YhetT\\cpath\\else\\let\\YhetT\\relax\\fi\\YhetT}\n\
172  \\def\\path (#1 #2){\\move (#1 #2)\\futurelet\\TGre\\QtGfr}\n\
173  \\def\\cpath (#1 #2){\\lvec (#1 #2)\\futurelet\\TGre\\QtGfr}\n\
174 \\fi\n\
175 \\drawdim pt\n\
176 \\setunitscale %2.2f\n\
177 \\linewd %d\n\
178 \\textref h:L v:C\n";
179     fprintf(gpoutfile, tdg1,
180             TEXDRAW_scalefactor,
181             TEXDRAW_lines[2]);
182     TEXDRAW_last_type = 0;
183     TEXDRAW_type = 0;
184 }
185
186 TERM_PUBLIC void
187 TEXDRAW_text()
188 {
189     TEXDRAW_endline();
190     fputs("\\end{texdraw}\n", gpoutfile);
191 }
192
193 TERM_PUBLIC void
194 TEXDRAW_linetype(int linetype)
195 {
196     TEXDRAW_endline();
197
198     if (linetype >= TEXDRAW_NUMLINES - 2)
199         linetype %= (TEXDRAW_NUMLINES - 2);
200
201     TEXDRAW_type = linetype > -2 ? linetype : LT_BLACK;
202 }
203
204 TERM_PUBLIC void
205 TEXDRAW_move(unsigned int x, unsigned int y)
206 {
207     TEXDRAW_endline();
208
209     TEXDRAW_posx = x;
210     TEXDRAW_posy = y;
211 }
212
213 TERM_PUBLIC void
214 TEXDRAW_point(unsigned int x, unsigned int y, int number)
215 {
216     TEXDRAW_move(x, y);
217
218     /* Print the character defined by 'number'; number < 0 means
219      * to use a dot, otherwise one of the defined points. */
220     fprintf(gpoutfile, "\\move (%d %d)\n",
221             (int) ((double) x * TEXDRAW_xscale),
222             (int) ((double) y * TEXDRAW_yscale));
223     if (TEXDRAW_last_justify != CENTRE) {
224         fprintf(gpoutfile, "\\textref h:C v:C ");
225         TEXDRAW_last_justify = CENTRE;
226     }
227     fprintf(gpoutfile, "%s\n",
228             (number < 0 ?
229              TEXDRAW_TINY_DOT :
230              TEXDRAW_points[number % TEXDRAW_POINT_TYPES]));
231 }
232
233 TERM_PUBLIC void
234 TEXDRAW_vector(unsigned int ux, unsigned int uy)
235 {
236     if (!TEXDRAW_inline) {
237         TEXDRAW_inline = TRUE;
238
239         /* Start a new line. This depends on line type */
240         if (TEXDRAW_type != TEXDRAW_last_type) {
241             if (TEXDRAW_lines[TEXDRAW_type + 2] != TEXDRAW_lines[TEXDRAW_last_type + 2])
242                 fprintf(gpoutfile, "\\linewd %d\n",
243                         TEXDRAW_lines[TEXDRAW_type + 2]);
244             TEXDRAW_last_type = TEXDRAW_type;
245         }
246         fprintf(gpoutfile, "\\path (%d %d)",
247                 (int) ((double) TEXDRAW_posx * TEXDRAW_xscale),
248                 (int) ((double) TEXDRAW_posy * TEXDRAW_yscale));
249         TEXDRAW_linecount = 1;
250     } else {
251         /* Even though we are in middle of a path,
252          * we may want to start a new path command.
253          * If they are too long then latex will choke.
254          */
255         if (TEXDRAW_linecount++ >= TEXDRAW_LINEMAX) {
256             fputs("\n\\cpath ", gpoutfile);
257             TEXDRAW_linecount = 1;
258         }
259     }
260     fprintf(gpoutfile, "(%d %d)",
261             (int) ((double) ux * TEXDRAW_xscale),
262             (int) ((double) uy * TEXDRAW_yscale));
263     TEXDRAW_posx = ux;
264     TEXDRAW_posy = uy;
265 }
266
267 static void
268 TEXDRAW_endline()
269 {
270     if (TEXDRAW_inline) {
271         putc('\n', gpoutfile);
272         TEXDRAW_inline = FALSE;
273     }
274 }
275
276 TERM_PUBLIC void
277 TEXDRAW_arrow(
278     unsigned int sx, unsigned int sy,
279     unsigned int ex, unsigned int ey,
280     int head)
281 {
282     char text;
283
284     if (head)
285         text = 'a';
286     else
287         text = 'l';
288     fprintf(gpoutfile, "\\move (%d %d)\\%cvec (%d %d)",
289             (int) ((double) sx * TEXDRAW_xscale),
290             (int) ((double) sy * TEXDRAW_yscale),
291             text,
292             (int) ((double) ex * TEXDRAW_xscale),
293             (int) ((double) ey * TEXDRAW_yscale));
294     TEXDRAW_posx = ex;
295     TEXDRAW_posy = ey;
296 }
297
298 TERM_PUBLIC void
299 TEXDRAW_put_text(unsigned int x, unsigned int y, const char str[])
300 {
301     char text;
302
303     TEXDRAW_endline();
304
305     fprintf(gpoutfile, "\\move (%d %d)",
306             (int) ((double) x * TEXDRAW_xscale),
307             (int) ((double) y * TEXDRAW_yscale));
308
309     if (!TEXDRAW_angle)
310         text = 'h';
311     else
312         text = 'v';
313
314     if (TEXDRAW_last_justify != TEXDRAW_justify) {
315         TEXDRAW_last_justify = TEXDRAW_justify;
316         if (TEXDRAW_justify == LEFT)
317             fputs("\\textref h:L v:C ", gpoutfile);
318         else if (TEXDRAW_justify == CENTRE)
319             fputs("\\textref h:C v:C ", gpoutfile);
320         else if (TEXDRAW_justify == RIGHT)
321             fputs("\\textref h:R v:C ", gpoutfile);
322     }
323     fprintf(gpoutfile, "\\%ctext{%s}\n", text, str);
324 }
325
326
327 TERM_PUBLIC int
328 TEXDRAW_justify_text(enum JUSTIFY mode)
329 {
330     TEXDRAW_justify = mode;
331     return (TRUE);
332 }
333
334 TERM_PUBLIC int
335 TEXDRAW_text_angle(int ang)
336 {
337     TEXDRAW_angle = ang;
338     return (TRUE);
339 }
340
341 TERM_PUBLIC void
342 TEXDRAW_reset()
343 {
344     TEXDRAW_endline();
345     TEXDRAW_posx = TEXDRAW_posy = 0;
346 }
347
348 #endif /* TERM_BODY */
349
350 #ifdef TERM_TABLE
351
352 TERM_TABLE_START(texdraw_driver)
353     "texdraw",
354     "LaTeX texdraw environment",
355     TEXDRAW_XMAX, TEXDRAW_YMAX, TEXDRAW_VCHAR, TEXDRAW_HCHAR,
356     TEXDRAW_VTIC, TEXDRAW_HTIC, options_null, TEXDRAW_init, TEXDRAW_reset,
357     TEXDRAW_text, null_scale, TEXDRAW_graphics, TEXDRAW_move, TEXDRAW_vector,
358     TEXDRAW_linetype, TEXDRAW_put_text, TEXDRAW_text_angle,
359     TEXDRAW_justify_text, TEXDRAW_point, TEXDRAW_arrow, set_font_null
360 TERM_TABLE_END(texdraw_driver)
361
362 #undef LAST_TERM
363 #define LAST_TERM texdraw_driver
364
365 #endif /* TERM_TABLE */
366
367 #endif /* TERM_PROTO_ONLY */
368
369 #ifdef TERM_HELP
370 START_HELP(texdraw)
371 "1 texdraw",
372 "?commands set terminal texdraw",
373 "?set terminal texdraw",
374 "?set term texdraw",
375 "?terminal texdraw",
376 "?term texdraw",
377 "?texdraw",
378 " The `texdraw` terminal driver supports the LaTeX texdraw environment.  It is",
379 " intended for use with \"texdraw.sty\" and \"texdraw.tex\" in the texdraw package.",
380 "",
381 " Points, among other things, are drawn using the LaTeX commands \"\\Diamond\" and",
382 " \"\\Box\".  These commands no longer belong to the LaTeX2e core; they are included",
383 " in the latexsym package, which is part of the base distribution and thus part",
384 " of any LaTeX implementation.  Please do not forget to use this package.",
385 "",
386 " It has no options."
387 END_HELP(texdraw)
388 #endif /* TERM_HELP */