Initial release of Maemo 5 port of gnuplot
[gnuplot] / term / dxf.trm
1 /* Hello, Emacs, this is -*-C-*-
2  * $Id: dxf.trm,v 1.16 2006/07/21 02:35:45 sfeam Exp $
3  *
4  */
5
6 /* GNUPLOT - dxf.trm */
7
8 /*[
9  * Copyright 1991 - 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  *   AutoCad (Release 10.x) dxf file format (import with AutoCad dxfin command)
43  *
44  *
45  * AUTHOR
46  *   Florian Hiss  (fhis1231@w204zrz.zrz.tu-berlin.de)
47  *
48  * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
49 */
50
51 /*
52  * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
53  */
54
55 #include "driver.h"
56
57 #ifdef TERM_REGISTER
58 register_term(dxf)
59 #endif
60
61 #ifdef TERM_PROTO
62 TERM_PUBLIC void DXF_init __PROTO((void));
63 TERM_PUBLIC void DXF_graphics __PROTO((void));
64 TERM_PUBLIC void DXF_text __PROTO((void));
65 TERM_PUBLIC void DXF_linetype __PROTO((int linetype));
66 TERM_PUBLIC void DXF_move __PROTO((unsigned int x, unsigned int y));
67 TERM_PUBLIC void DXF_vector __PROTO((unsigned int ux, unsigned int uy));
68 TERM_PUBLIC void DXF_put_text __PROTO((unsigned int x, unsigned int y,
69                                        const char str[]));
70 TERM_PUBLIC int DXF_text_angle __PROTO((int ang));
71 TERM_PUBLIC int DXF_justify_text __PROTO((enum JUSTIFY mode));
72 TERM_PUBLIC void DXF_reset __PROTO((void));
73
74 #define DXF_XMAX (120.0 * DXF_UNIT)
75 #define DXF_YMAX (80.0 * DXF_UNIT)
76 #if 0 /* HBB 20030626: old version */
77 #define DXF_HTIC (0.01 * DXF_XMAX)      /* 1.0 percent */
78 #define DXF_VTIC (0.01 * DXF_YMAX)      /* 1.0 percent */
79 #else
80 /* HBB 20030626: make them have the same length in DXF_UNITs ! */
81 # define DXF_HTIC (2.0 * DXF_UNIT)
82 # define DXF_VTIC (2.0 * DXF_UNIT)
83 #endif
84 #define DXF_HCHAR (0.014 * DXF_XMAX)    /* 1.4 percent */
85 #define DXF_VCHAR (0.026 * DXF_YMAX)    /* 2.6 percent */
86 #endif /* TERM_PROTO */
87
88 #ifndef TERM_PROTO_ONLY
89 #ifdef TERM_BODY
90
91 #define DXF_UNIT 60.0
92 #define LINEWIDTH 0.0351        /* default line width is 1 pt */
93
94 /* 120 (autocad units) wide by 80 (autocad units) high (default)
95  * use the GNUPLOT 'set size' command to change the defaults */
96 /* actual text height */
97 #define DXF_TEXTHEIGHT (0.7 * DXF_VCHAR)
98
99 /* actual text width, only a guess, we don't know the width of
100  * a character of given height of the AutoCad STANDARD text font,
101  * so change it if you like */
102 #define DXF_TEXTWIDTH (0.7 * DXF_HCHAR)
103
104 /* number of line types we support. see below  */
105 #define DXF_LINE_TYPES 7
106
107 /* number of layers used for the drawing. see below */
108 #define MAX_LAYER 7
109
110 /* line type scaling */
111 #define LT_SCALE 1
112
113 static unsigned int DXF_posx;
114 static unsigned int DXF_posy;
115 /* linetype is mapped to a layer. see below. */
116 static unsigned int dxf_linetype;
117 static enum JUSTIFY dxf_justify = LEFT;
118 static float dxf_angle = 0.0;   /* 0 is horizontal, 90.0 is vertical */
119
120 /* text style used in the entire drawing */
121 static const char *text_style = "STANDARD";
122
123 /* text always resides on layer 0 */
124 #define TEXT_LAYER 0
125
126 /* each linetype resides on its own layer. each layer has its own color.
127  * this avoids difficulties that AutoCad has with proper scaling of
128  * the linetypes.
129  * change the colors according to your needs */
130 static const char *layer_name[] ={ "0", "1", "2", "3", "4", "5", "6" };
131
132 /* the colours are white, red, yellow, green, cyan, blue, magenta.
133  * change them according to your needs.
134  * when using a black and white plotting device the colours map to different
135  * line thicknesses. see description of AutoCad print / plot command */
136 static const char *layer_colour[] = { "7", "1", "2", "3", "4", "5", "6" };
137
138 /* support line types AutoCad has to offer by default. */
139 static const char *layer_lines[] = {
140     "CONTINUOUS", "DASHED", "HIDDEN", "CENTER", "PHANTOM", "DOT", "DASHDOT"
141 };
142
143 static TBOOLEAN vector_was_last = FALSE;
144
145 TERM_PUBLIC void
146 DXF_init()
147 {
148     DXF_posx = DXF_posy = 0;
149     dxf_linetype = 0;
150     dxf_angle = 0.0;
151     vector_was_last = FALSE;
152 }
153
154 TERM_PUBLIC void
155 DXF_graphics()
156 {
157     register struct termentry *t = term;
158     int i;
159     static char GPFAR dxfi1[] = "\
160 999\n\
161 %% GNUPLOT: dxf file for AutoCad\n\
162   0\nSECTION\n  2\nHEADER\n\
163   9\n$EXTMIN\n\
164  10\n0.000\n 20\n0.000\n\
165   9\n$EXTMAX\n\
166  10\n%-6.3f\n 20\n%-6.3f\n\
167   9\n$LIMMIN\n\
168  10\n0.000\n 20\n0.000\n\
169   9\n$LIMMAX\n\
170  10\n%-6.3f\n 20\n%-6.3f\n\
171   9\n$TEXTSTYLE\n  7\n%s\n\
172   9\n$TEXTSIZE\n 40\n%-6.3f\n\
173   9\n$PLINEWID\n 40\n%-6.4f\n\
174   9\n$LTSCALE\n  40\n%-6.3f\n\
175   9\n$COORDS\n 70\n  1\n\
176   9\n$CELTYPE\n 6\nBYLAYER\n\
177   9\n$CLAYER\n  8\n0\n\
178   9\n$CECOLOR\n 62\n   %s\n\
179   9\n$MENU\n  1\nacad\n\
180   0\nENDSEC\n\
181   0\nSECTION\n  2\nTABLES\n";
182     static char GPFAR dxfi2[] = "\
183 0\nTABLE\n  2\nLTYPE\n 70\n    %d\n\
184 0\nLTYPE\n  2\nCONTINUOUS\n 70\n    64\n\
185   3\nSolid line\n 72\n    65\n 73\n      0\n 40\n0.0\n\
186   0\nLTYPE\n  2\nDASHED\n 70\n    64\n\
187   3\n__ __ __ __ __ __ __ __ __ __ __ __ __ __ __\n\
188  72\n    65\n 73\n     2\n 40\n0.75\n 49\n0.5\n 49\n-0.25\n\
189   0\nLTYPE\n  2\nHIDDEN\n 70\n    64\n\
190   3\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _\n\
191  72\n    65\n 73\n     2\n 40\n0.375\n 49\n0.25\n 49\n-0.125\n\
192   0\nLTYPE\n  2\nCENTER\n 70\n    64\n\
193   3\n____ _ ____ _ ____ _ ____ _ ____ _ ____ _ ____\n\
194  72\n    65\n 73\n     4\n 40\n2.0\n 49\n1.25\n 49\n-0.25\n\
195  49\n0.25\n 49\n-0.25\n\
196   0\nLTYPE\n  2\nPHANTOM\n 70\n    64\n\
197   3\n_____ _ _ _____ _ _ _____ _ _ _____ _ _ ____\n\
198  72\n    65\n 73\n     6\n 40\n2.5\n 49\n1.25\n\
199  49\n-0.25\n 49\n0.25\n 49\n-0.25\n 49\n0.25\n 49\n-0.25\n\
200   0\nLTYPE\n  2\nDOT\n 70\n    64\n\
201   3\n...............................................\n\
202  72\n    65\n 73\n     2\n 40\n0.25\n 49\n0.0\n 49\n-0.25\n\
203   0\nLTYPE\n  2\nDASHDOT\n 70\n    64\n\
204   3\n__ . __ . __ . __ . __ . __ . __ . __ . __ . __\n\
205  72\n    65\n 73\n     4\n 40\n1.0\n 49\n0.5\n 49\n-0.25\n\
206  49\n0.0\n 49\n-0.25\n\
207   0\nENDTAB\n";
208
209     fprintf(gpoutfile, dxfi1,
210             t->xmax / DXF_UNIT, t->ymax / DXF_UNIT,
211             t->xmax / DXF_UNIT, t->ymax / DXF_UNIT,
212             text_style,
213             DXF_TEXTHEIGHT / DXF_UNIT,
214             LINEWIDTH,
215             (double) LT_SCALE,
216             layer_colour[0]);
217     /* the linetype table */
218     fprintf(gpoutfile, dxfi2, DXF_LINE_TYPES);
219     /* the layer table */
220     fprintf(gpoutfile, "  0\nTABLE\n  2\nLAYER\n 70\n   %-d\n", MAX_LAYER);
221     for (i = 1; i <= MAX_LAYER; i++)
222         fprintf(gpoutfile, "  0\nLAYER\n  2\n%s\n 70\n   64\n62\n   %s\n  6\n%s\n", layer_name[i - 1], layer_colour[i - 1], layer_lines[i - 1]);
223
224     /* no blocks for insertion */
225     /* start the entity section */
226     fputs("  0\nENDTAB\n0\nENDSEC\n\
227   0\nSECTION\n  2\nBLOCKS\n  0\nENDSEC\n\
228   0\nSECTION\n\
229   2\nENTITIES\n",
230           gpoutfile);
231 }
232
233 TERM_PUBLIC void
234 DXF_text()
235 {
236     if (vector_was_last)
237         fputs("  0\nSEQEND\n", gpoutfile);
238     fputs("  0\nENDSEC\n  0\nEOF\n", gpoutfile);
239 }
240
241 TERM_PUBLIC void
242 DXF_linetype(int linetype)
243 {
244     linetype = ABS(linetype);
245     linetype = linetype % DXF_LINE_TYPES;
246     dxf_linetype = linetype;
247 }
248
249 TERM_PUBLIC void
250 DXF_move(unsigned int x, unsigned int y)
251 {
252     DXF_posx = x;
253     DXF_posy = y;
254     if (vector_was_last)
255         fputs("  0\nSEQEND\n", gpoutfile);
256     vector_was_last = FALSE;
257     fprintf(gpoutfile, "\
258   0\nPOLYLINE\n  8\n%s\n 66\n   1\n\
259   6\n%s\n\
260   0\nVERTEX\n  8\n%s\n\
261   6\n%s\n\
262  10\n%-6.3f\n 20\n%-6.3f\n 30\n0.000\n",
263             layer_name[dxf_linetype],
264             layer_lines[dxf_linetype],
265             layer_name[dxf_linetype],
266             layer_lines[dxf_linetype],
267             DXF_posx / DXF_UNIT, DXF_posy / DXF_UNIT);
268
269 }
270
271 TERM_PUBLIC void
272 DXF_vector(unsigned int ux, unsigned int uy)
273 {
274     DXF_posx = ux;
275     DXF_posy = uy;
276     vector_was_last = TRUE;
277
278     fprintf(gpoutfile, "\
279   0\nVERTEX\n  8\n%s\n\
280   6\n%s\n\
281   10\n%-6.3f\n  20\n%-6.3f\n  30\n0.000\n",
282             layer_name[dxf_linetype],
283             layer_lines[dxf_linetype],
284             DXF_posx / DXF_UNIT, DXF_posy / DXF_UNIT);
285 }
286
287 TERM_PUBLIC void
288 DXF_put_text(unsigned int x, unsigned int y, const char str[])
289 {
290     int stl;
291     float xleftpos, yleftpos, xrightpos, yrightpos;
292
293     /* shut up gcc warnings  - SB */
294     xleftpos = yleftpos = xrightpos = yrightpos = 1.0;  /* dummy */
295     /* ignore empty strings */
296     if (str[0] == NUL)
297         return;
298
299     stl = 0;
300     while (str[stl] != NUL)
301         ++stl;                  /* get string length */
302
303     if (vector_was_last)
304         fputs("  0\nSEQEND\n", gpoutfile);
305     vector_was_last = FALSE;
306     fprintf(gpoutfile, "  0\nTEXT\n  8\n%s\n", layer_name[TEXT_LAYER]);
307     if (dxf_angle != 90.0) {
308         switch (dxf_justify) {
309         case LEFT:
310             xleftpos = (float) x;
311             yleftpos = (float) (y - DXF_VCHAR / 4.0);
312             xrightpos = (float) (x + stl * DXF_TEXTWIDTH);
313             yrightpos = yleftpos;
314             break;
315         case RIGHT:
316             xleftpos = (float) (x - stl * DXF_TEXTWIDTH);
317             yleftpos = (float) (y - DXF_VCHAR / 4.0);
318             xrightpos = (float) x;
319             yrightpos = yleftpos;
320             break;
321         case CENTRE:
322             xleftpos = (float) (x - stl * DXF_TEXTWIDTH / 2.0);
323             yleftpos = (float) (y - DXF_VCHAR / 4.0);
324             xrightpos = (float) x;      /* center point */
325             yrightpos = yleftpos;
326             break;
327         }
328     } else {
329         switch (dxf_justify) {
330         case LEFT:
331             xleftpos = (float) (x + DXF_VCHAR / 4.0);
332             yleftpos = (float) y;
333             xrightpos = xleftpos;
334             yrightpos = (float) (y + stl * DXF_TEXTWIDTH);
335             break;
336         case RIGHT:
337             xleftpos = (float) (x + DXF_VCHAR / 4.0);
338             yleftpos = (float) (y - stl * DXF_HCHAR);
339             xrightpos = xleftpos;
340             yrightpos = (float) y;
341             break;
342         case CENTRE:
343             xleftpos = (float) (x + DXF_VCHAR / 4.0);
344             yleftpos = (float) (y - stl * DXF_TEXTWIDTH / 2.0);
345             xrightpos = xleftpos;
346             yrightpos = (float) y;      /* center point */
347             break;
348         }
349     }
350
351     fprintf(gpoutfile, "\
352  10\n%-6.3f\n 20\n%-6.3f\n 30\n0.000\n\
353  40\n%-6.3f\n  1\n%s\n 50\n%-6.3f\n\
354   7\n%s\n",
355             xleftpos / DXF_UNIT, yleftpos / DXF_UNIT,
356             DXF_TEXTHEIGHT / DXF_UNIT, str, dxf_angle,
357             text_style);
358
359     if (dxf_justify != LEFT) {
360         fprintf(gpoutfile, " 72\n%d\n\
361  11\n%-6.3f\n 21\n%-6.3f\n 31\n0.000\n",
362                 dxf_justify,
363                 xrightpos / DXF_UNIT, yrightpos / DXF_UNIT);
364     }
365 }
366
367 TERM_PUBLIC int
368 DXF_text_angle(int ang)
369 {
370     dxf_angle = (ang ? 90.0 : 0.0);
371     return (TRUE);
372 }
373
374 TERM_PUBLIC int
375 DXF_justify_text(enum JUSTIFY mode)
376 {
377     dxf_justify = mode;
378     return (TRUE);
379 }
380
381 TERM_PUBLIC void
382 DXF_reset()
383 {
384     DXF_posx = DXF_posy = 0;
385 }
386
387 #endif /* TERM_BODY */
388
389 #ifdef TERM_TABLE
390 TERM_TABLE_START(dxf_driver)
391   "dxf", "dxf-file for AutoCad (default size 120x80)",
392     DXF_XMAX, DXF_YMAX, DXF_VCHAR, DXF_HCHAR,
393     DXF_VTIC, DXF_HTIC, options_null, DXF_init, DXF_reset,
394     DXF_text, null_scale, DXF_graphics, DXF_move, DXF_vector,
395     DXF_linetype, DXF_put_text, DXF_text_angle,
396     DXF_justify_text, do_point, do_arrow, set_font_null
397 TERM_TABLE_END(dxf_driver)
398
399 #undef LAST_TERM
400 #define LAST_TERM dxf_driver
401
402 #endif /* TERM_TABLE */
403 #endif /* TERM_PROTO_ONLY */
404
405 #ifdef TERM_HELP
406 START_HELP(dxf)
407 "1 dxf",
408 "?commands set terminal dxf",
409 "?set terminal dxf",
410 "?set term dxf",
411 "?terminal dxf",
412 "?term dxf",
413 "?dxf",
414 " The `dxf` terminal driver creates pictures that can be imported into AutoCad",
415 " (Release 10.x).  It has no options of its own, but some features of its plots",
416 " may be modified by other means.  The default size is 120x80 AutoCad units,",
417 " which can be changed by `set size`.  `dxf` uses seven colors (white, red,",
418 " yellow, green, cyan, blue and magenta), which can be changed only by",
419 " modifying the source file.  If a black-and-white plotting device is used, the",
420 " colors are mapped to differing line thicknesses.  See the description of the",
421 " AutoCad print/plot command."
422 END_HELP(dxf)
423 #endif /* TERM_HELP */