Initial release of Maemo 5 port of gnuplot
[gnuplot] / term / fig.trm
1 /* Hello, Emacs, this is -*-C-*-
2  * $Id: fig.trm,v 1.56.2.4 2008/05/04 04:26:07 sfeam Exp $
3  */
4
5 /* GNUPLOT - fig.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  *  Fig graphics language
42  *
43  * AUTHORS
44  *  Micah Beck, David Kotz
45  *
46  * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
47  *
48  */
49
50 /*
51  * Original for Fig code output by Micah Beck, 1989
52  * Department of Computer Science, Cornell University
53  * Updated by David Kotz for gnuplot 2.0
54  * More efficient output by Ian Dall
55  * Updated to FIG 2.1 (with color) format by Vivek Khera
56  * Updated to FIG 3.1 (higher resolution) format by Ian MacPhedran, Jan 1995
57  * Updated to conform to newterm format Ian MacPhedran, Apr 1995
58  * Point-count option joachim.selinger@ins.uni-stuttgart.de (JFS) Feb  9 1996
59  * More options (portrait/landscape, metric/inches, size, fontsize, thickness)
60  * plus symbols and depth/thickness by bernlohr@eu1.mpi-hd.mpg.de (KB) Aug 15 1996
61  * Added PM3D functionality Ian MacPhedran, April 15 1999
62  * Take into account 'set palette maxcolors' Petr Mikulik, June 11 2002
63  * Don't reset options when 'set term fig <new options>', Petr Mikulik, Aug 24 2002
64  * Ethan A Merritt - May 2008:
65  *   Bring into line with other terminals for point types, size syntax, font spec
66  */
67
68 #include "driver.h"
69
70 #ifdef TERM_REGISTER
71 register_term(fig)
72 #endif /* TERM_REGISTER */
73
74 #ifdef TERM_PROTO
75 TERM_PUBLIC void FIG_options __PROTO((void));
76 TERM_PUBLIC void FIG_init __PROTO((void));
77 TERM_PUBLIC void FIG_graphics __PROTO((void));
78 TERM_PUBLIC void FIG_text __PROTO((void));
79 TERM_PUBLIC void FIG_linetype __PROTO((int linetype));
80 TERM_PUBLIC void FIG_move __PROTO((unsigned int x, unsigned int y));
81 TERM_PUBLIC void FIG_vector __PROTO((unsigned int ux, unsigned int uy));
82 TERM_PUBLIC void FIG_arrow __PROTO((unsigned int sx, unsigned int sy, unsigned int ex, unsigned int ey, int head));
83 TERM_PUBLIC void FIG_put_text __PROTO((unsigned int x, unsigned int y, const char *str));
84 TERM_PUBLIC int FIG_justify_text __PROTO((enum JUSTIFY mode));
85 TERM_PUBLIC int FIG_text_angle __PROTO((int ang));
86 TERM_PUBLIC void FIG_pointsize __PROTO((double arg_pointsize));
87 TERM_PUBLIC void FIG_linewidth __PROTO((double linewidth));
88 TERM_PUBLIC void FIG_reset __PROTO((void));
89 TERM_PUBLIC void FIG_lpoint __PROTO((unsigned int x, unsigned int y, int number));
90 TERM_PUBLIC void FIG_boxfill __PROTO((int style, unsigned int x, unsigned int y, unsigned int w, unsigned int h));
91 TERM_PUBLIC int FIG_make_palette (t_sm_palette *);
92 /* TERM_PUBLIC void FIG_previous_palette (void); */
93 TERM_PUBLIC void FIG_set_color (t_colorspec *);
94 TERM_PUBLIC void FIG_filled_polygon (int, gpiPoint *);
95
96 #define GOT_FIG_PROTO
97 #endif /* TERM_PROTO */
98
99 #ifndef TERM_PROTO_ONLY
100 #ifdef TERM_BODY
101
102 #include "object.h"             /* modified from the XFig distribution */
103 #define FIG_DEFAULT DEFAULT
104 #define FIG_ROMAN_FONT (0)      /* actually, the default font */
105
106 #if METRIC
107 # define INCH FALSE
108 #else
109 # define INCH TRUE
110 #endif
111
112 /* These should not be defined elsewhere - ACZ */
113 /* This is now 1200 per inch */
114 #define FIG_IRES        (1200)
115 /* This is now 450 per cm */
116 #define FIG_MRES        (450)
117
118 #define FIG_COORD_SYS   2
119 #define FIG_ORIENT (FIG_portrait?"Portrait":"Landscape")
120 /* Could be "Portrait" */
121 #define FIG_JUST        "Center"
122 /* Could be "Flush Left" */
123 #define FIG_UNIT (FIG_inches?"Inches":"Metric")
124 /* Could be "Inches" */
125 #define FIG_PAPER       (FIG_inches ? "Letter" : "A4")
126 #define FIG_MAGNIFICATION  100.0
127 #define FIG_MULTIPAGE   "Single"
128 /* Could be "Multiple" */
129 #define FIG_TRANSCOLOR  -2
130 /* none: -2; background: -1; 0..31: foreground colors */
131 /* This could probably be dropped with the support of GIFs. */
132 #define FIG_TRUERES (FIG_inches ? FIG_IRES : FIG_MRES) /* ACZ */
133 #define FIG_DEFAULTVERSION "3.2"
134
135 #define FIG_HTIC(inch)  ((inch) ? (5*FIG_IRES)/80 : (15*FIG_MRES)/100)
136 #define FIG_VTIC(inch)  ((inch) ? (5*FIG_IRES)/80 : (15*FIG_MRES)/100)
137 #define FIG_FONT_S      (10)    /* size in points */
138 #define FIG_MAX_POINTS  99999L  /* almost infinite ;-) */
139
140 /* height of font in pixels: */
141 #define FIG_to_pixel_v(inch,s) (((inch) ? (s)*FIG_IRES : (s)*FIG_MRES*2.54) / 72 * 3/4)
142 /* This is fudged to enlarge the drawing area, but gives fairly good results */
143 /* this is a guess at the width: */
144 #define FIG_to_pixel_h(inch,s) (FIG_to_pixel_v(inch,s)*6/10)
145
146 #define FIG_VCHAR       FIG_to_pixel_v(INCH,FIG_FONT_S) /* just for default, */
147 #define FIG_HCHAR       FIG_to_pixel_h(INCH,FIG_FONT_S) /* not really used   */
148
149 /* Text flags (ULIG) */
150 enum FIG_TEXT_STYLEBITS {
151     FIG_TEXT_RIGID      = 1<<0,
152     FIG_TEXT_SPECIAL    = 1<<1,
153     FIG_TEXT_POSTSCRIPT = 1<<2,
154     FIG_TEXT_HIDDEN     = 1<<3
155 };
156 #define FIG_TEXT_NORMAL      FIG_TEXT_POSTSCRIPT
157
158 enum FIG_poly_stat {
159     FIG_poly_new, FIG_poly_part
160 };
161
162 static int FIG_posx;
163 static int FIG_posy;
164 static long FIG_poly_vec_cnt;
165 static int FIG_depth = 10;
166 static int FIG_linedepth = 10;
167 static int FIG_thickness = 1;
168 static int FIG_default_thickness = 1;
169 static double FIG_current_pointsize = 1.;
170 static double FIG_current_linewidth = 1.;
171
172 /* Maximum number of points per POLYLINE.
173    Default 1000 (hardcoded in help section as well) */
174 static int FIG_poly_vec_max = 999;      /* JFS */
175
176 static enum FIG_poly_stat FIG_polyvec_stat;
177
178 /* 5 inches wide by 3 inches high */
179 #define FIG_XMAX(inch) ((inch) ? 5*FIG_IRES : 12*FIG_MRES)
180 #define FIG_YMAX(inch) ((inch) ? 3*FIG_IRES :  8*FIG_MRES)
181
182 #define FIG_XOFF(inch) ((inch) ? FIG_IRES : 2*FIG_MRES)
183 #define FIG_YOFF(inch) ((inch) ? FIG_IRES : 2*FIG_MRES)
184
185
186 #define BFIG_HTIC(inch) ((inch) ? (7*FIG_IRES)/80 : (20*FIG_MRES)/100)
187 #define BFIG_VTIC(inch) ((inch) ? (7*FIG_IRES)/80 : (20*FIG_MRES)/100)
188 #define BFIG_FONT_S     (16)    /* size in points */
189 #define BFIG_VCHAR      FIG_to_pixel_v(INCH,BFIG_FONT_S)  /* height in pixels of font */
190 #define BFIG_HCHAR      FIG_to_pixel_h(INCH,BFIG_FONT_S)  /* this is a guess at the width */
191
192 static F_point *FIG_points = NULL;      /* Array for the collection of points for
193                                            POLYLINE, allocated on demand. */
194 static F_line FIG_line;
195
196 /* 8 inches wide by 5 inches high */
197 #define BFIG_XMAX(inch) ((inch) ? 8*FIG_IRES : 20*FIG_MRES)
198 #define BFIG_YMAX(inch) ((inch) ? 5*FIG_IRES : 15*FIG_MRES)
199
200 #define BFIG_XOFF(inch) ((inch) ? FIG_IRES : 2*FIG_MRES)
201 #define BFIG_YOFF(inch) ((inch) ? FIG_IRES : 2*FIG_MRES)
202
203
204 static int FIG_type;            /* negative types use real lines */
205 static float FIG_spacing;       /* length of dash or dot spacing */
206 static int FIG_justify;         /* Fig justification T_*_JUSTIFIED */
207 static float FIG_angle;         /* Fig text angle (in radians) */
208 static int FIG_use_color = FALSE;       /* do we use color or not? */
209 static int FIG_is_big = FALSE;  /* big plot ? */
210 static int FIG_color = DEFAULT; /* which color to use */
211 static int FIG_xoff = FIG_XOFF(INCH);
212 static int FIG_yoff = FIG_YOFF(INCH);
213 static int FIG_font_id = FIG_ROMAN_FONT;
214 static int FIG_font_s = FIG_FONT_S;
215 static int FIG_portrait = FALSE;
216 static int FIG_inches = INCH;
217 static int FIG_text_flags = FIG_TEXT_NORMAL;    /* whether text is special or hidden etc. */
218 static char FIG_version[MAX_ID_LEN+1] = FIG_DEFAULTVERSION;  /* file format version */
219 static int FIG_solid = FALSE;                   /* dashed lines or not */
220 static int FIG_palette_set = FALSE;     /* PM3D Palette Set ? */
221 static int FIG_palette_size = 128;      /* Number of colours in palette */
222 static int FIG_palette_offst = 32;      /* Offset from zero for user colours */
223 static int FIG_fill_style = 20;         /* Full saturation */
224
225 static void FIG_poly_clean __PROTO((enum FIG_poly_stat fig_stat));
226
227 enum FIG_id {
228     FIG_MONOCHROME, FIG_COLOR,
229     FIG_SMALL, FIG_BIG,
230     FIG_INCHES, FIG_METRIC,
231     FIG_PORTRAIT, FIG_LANDSCAPE,
232     FIG_SIZE, FIG_FONT, FIG_FONTSIZE,
233     FIG_THICKNESS, FIG_DEPTH, FIG_POINTSMAX,
234     FIG_SOLID, FIG_DASHED,
235     FIG_NORMALTEXT, FIG_SPECIALTEXT, FIG_HIDDENTEXT, FIG_RIGIDTEXT,
236     FIG_VERSION, FIG_OTHER
237 };
238
239 static struct gen_table FIG_opts[] =
240 {
241     { "b$ig", FIG_BIG },
242     { "c$olor", FIG_COLOR },
243     { "c$olour", FIG_COLOR },
244     { "da$shed", FIG_DASHED },
245     { "de$pth", FIG_DEPTH },
246     { "font", FIG_FONT },
247     { "f$ontsize", FIG_FONTSIZE },
248     { "in$ches", FIG_INCHES },
249     { "l$andscape", FIG_LANDSCAPE },
250     { "me$tric", FIG_METRIC },
251     { "mo$nochrome", FIG_MONOCHROME },
252     { "poi$ntsmax", FIG_POINTSMAX },
253     { "por$trait", FIG_PORTRAIT },
254     { "si$ze", FIG_SIZE },
255     { "sm$all", FIG_SMALL },
256     { "so$lid", FIG_SOLID },
257     { "linew$idth", FIG_THICKNESS },
258     { "t$hickness", FIG_THICKNESS },
259     { "texth$idden", FIG_HIDDENTEXT },
260     { "textn$ormal", FIG_NORMALTEXT },
261     { "textr$igid", FIG_RIGIDTEXT },
262     { "texts$pecial", FIG_SPECIALTEXT },
263     { "v$ersion", FIG_VERSION },
264     { NULL, FIG_OTHER }
265 };
266
267 const struct gen_table FIG_fonts[] =
268 {
269     { "Times Roman",  0 },
270     { "Times Italic",  1 },
271     { "Times Bold",  2 },
272     { "Times Bold Italic",  3 },
273     { "AvantGarde Book",  4 },
274     { "AvantGarde Book Oblique",  5 },
275     { "AvantGarde Demi",  6 },
276     { "AvantGarde Demi Oblique",  7 },
277     { "Bookman Light",  8 },
278     { "Bookman Light Italic",  9 },
279     { "Bookman Demi", 10 },
280     { "Bookman Demi Italic", 11 },
281     { "Courier", 12 },
282     { "Courier Oblique", 13 },
283     { "Courier Bold", 14 },
284     { "Courier Bold Oblique", 15 },
285     { "Helvetica", 16 },
286     { "Helvetica Oblique", 17 },
287     { "Helvetica Bold", 18 },
288     { "Helvetica Bold Oblique", 19 },
289     { "Helvetica Narrow", 20 },
290     { "Helvetica Narrow Oblique", 21 },
291     { "Helvetica Narrow Bold", 22 },
292     { "Helvetica Narrow Bold Oblique", 23 },
293     { "New Century Schoolbook Roman", 24 },
294     { "New Century Schoolbook Italic", 25 },
295     { "New Century Schoolbook Bold", 26 },
296     { "New Century Schoolbook Bold Italic", 27 },
297     { "Palatino Roman", 28 },
298     { "Palatino Italic", 29 },
299     { "Palatino Bold", 30 },
300     { "Palatino Bold Italic", 31 },
301     { "Symbol", 32 },
302     { "Zapf Chancery Medium Italic", 33 },
303     { "Zapf Dingbats", 34 },
304     { NULL, -1}
305 };
306
307 TERM_PUBLIC void
308 FIG_options()
309 {
310     int parse_error = FALSE;
311     long temp_max;
312     struct value a;
313     unsigned int tmax_t;
314     double xsize_t = 0, ysize_t = 0;
315     char text_flags[256]; /* for description only */
316
317 #if 0
318     /* Terminals should not reset options to defaults. */
319     FIG_use_color = FALSE;      /* default */
320     FIG_is_big = FALSE;         /* default */
321     FIG_portrait = FALSE;
322     FIG_font_id = FIG_ROMAN_FONT;
323     FIG_font_s = 0;
324     FIG_default_thickness = 1;
325     xsize_t = ysize_t = 0.;
326     FIG_inches = INCH;
327     FIG_text_flags = FIG_TEXT_NORMAL;
328     FIG_solid = FALSE;
329     strcpy( FIG_version, FIG_DEFAULTVERSION );
330 #endif
331
332     while (!END_OF_COMMAND) {
333         switch(lookup_table(&FIG_opts[0],c_token)) {
334         case FIG_MONOCHROME:
335             FIG_use_color = FALSE;
336             c_token++;
337             break;
338         case FIG_COLOR:
339             FIG_use_color = TRUE;
340             c_token++;
341             break;
342         case FIG_SMALL:
343             FIG_is_big = FALSE;
344             c_token++;
345             break;
346         case FIG_BIG:
347             FIG_is_big = TRUE;
348             c_token++;
349             break;
350         case FIG_INCHES:
351             FIG_inches = TRUE;
352             c_token++;
353             break;
354         case FIG_METRIC:
355             FIG_inches = FALSE;
356             c_token++;
357             break;
358         case FIG_SOLID:
359             FIG_solid = TRUE;
360             c_token++;
361             break;
362         case FIG_DASHED:
363             FIG_solid = FALSE;
364             c_token++;
365             break;
366         case FIG_NORMALTEXT:
367             FIG_text_flags = FIG_TEXT_NORMAL;
368             c_token++;
369             break;
370         case FIG_SPECIALTEXT:
371             FIG_text_flags |= FIG_TEXT_SPECIAL;
372             FIG_text_flags &= ~FIG_TEXT_POSTSCRIPT;
373             FIG_font_id = 0;
374             c_token++;
375             break;
376         case FIG_HIDDENTEXT:
377             FIG_text_flags |= FIG_TEXT_HIDDEN;
378             c_token++;
379             break;
380         case FIG_RIGIDTEXT:
381             FIG_text_flags |= FIG_TEXT_RIGID;
382             c_token++;
383             break;
384         case FIG_PORTRAIT:
385             FIG_portrait = TRUE;
386             c_token++;
387             break;
388         case FIG_LANDSCAPE:
389             FIG_portrait = FALSE;
390             c_token++;
391             break;
392         case FIG_SIZE:
393             c_token++;
394             if (END_OF_COMMAND) {
395                 int_error(c_token, "size: 2 numbers expected");
396             } else {
397                 xsize_t = real(const_express(&a));
398                 if (equals(c_token,","))
399                     c_token++;
400                 if (END_OF_COMMAND) {
401                     int_error(c_token, "size: 2 numbers expected");
402                     xsize_t = 0.;
403                 } else {
404                     ysize_t = real(const_express(&a));
405                 }
406                 if (xsize_t < 2. || ysize_t < 2. || xsize_t > 99. || ysize_t > 99.) {
407                     if (xsize_t != 0. || ysize_t != 0.)
408                         int_error(c_token, "size: out of range");
409                     xsize_t = ysize_t = 0.;
410                 }
411             }
412             break;
413         case FIG_FONT:
414             {
415             char *fontname = NULL;
416             int sep;
417             c_token++;
418             if (END_OF_COMMAND || !((fontname = try_to_get_string())))
419                 int_error(c_token, "expecting font name");
420             sep = strcspn(fontname,",");
421             sscanf (&(fontname[sep+1]),"%d",&FIG_font_s);
422             fontname[sep] = '\0';
423             FIG_font_id = lookup_table_entry(FIG_fonts, fontname);
424             if (FIG_font_id < 0)
425                 FIG_font_id = FIG_ROMAN_FONT;
426             free(fontname);
427             break;
428             }
429         case FIG_FONTSIZE:
430             c_token++;
431             FIG_font_s = (int) real(const_express(&a));
432             break;
433         case FIG_THICKNESS:
434             c_token++;
435             if (END_OF_COMMAND) {
436                 int_error(c_token, "thickness: number expected");
437             } else {
438                 FIG_default_thickness = (int) real(const_express(&a));
439                 if (FIG_default_thickness < 1 || FIG_default_thickness > 10) {
440                     int_error(c_token - 1, "thickness out of range");
441                     FIG_default_thickness = 1;
442                 }
443             }
444             break;
445         case FIG_DEPTH:
446             c_token++;
447             if (END_OF_COMMAND) {
448                 int_error(c_token, "depth: number expected");
449             } else {
450                 FIG_depth = (int) real(const_express(&a));
451                 if (FIG_depth < 0 || FIG_depth > 99) {
452                     int_error(c_token - 1, "depth out of range");
453                     FIG_depth = 10;
454                 }
455                 FIG_linedepth = FIG_depth;
456             }
457             break;
458         case FIG_POINTSMAX:
459             /* Skip the word and then expect the number ! */
460             c_token++;
461             if (END_OF_COMMAND) {
462                 int_error(c_token,
463                           "max. points per polyline: number expected");
464             } else {
465                 temp_max = (long) real(const_express(&a));
466                 /* Now check the range for the number */
467                 if ((temp_max > 1) && (temp_max < (FIG_MAX_POINTS + 2))) {
468                     /* OK. subtract one to the right number! See other numbers... */
469                     FIG_poly_vec_max = temp_max - 1;
470                 } else {
471                     int_error(c_token,
472                               "pointsmax: number out of range (2,%ld)",
473                               (FIG_MAX_POINTS + 1));
474                 }
475             }
476             break;
477         case FIG_VERSION:
478             c_token++;
479             if (END_OF_COMMAND) {
480                 int_error(c_token, "version: 3.1 or 3.2 expected");
481             } else {
482                 copy_str( FIG_version, c_token, MAX_ID_LEN );
483                 c_token++;
484                 if( strcmp( FIG_version, "3.1" ) != 0 &&
485                     strcmp( FIG_version, "3.2" ) != 0 ) {
486                     int_error(c_token, "wrong version number, must be 3.1 or 3.2");
487                 }
488             }
489             break;
490         case FIG_OTHER:
491         default:
492             parse_error = TRUE;
493             int_error(c_token, "unrecognized option");
494             break;
495         }
496     }
497
498     if( FIG_text_flags == FIG_TEXT_NORMAL ) {
499         strcpy( text_flags, " textnormal" );
500     } else {
501         sprintf( text_flags, "%s%s%s",
502                  (FIG_text_flags & FIG_TEXT_SPECIAL) ? " textspecial" : "",
503                  (FIG_text_flags & FIG_TEXT_HIDDEN) ? " texthidden" : "",
504                  (FIG_text_flags & FIG_TEXT_RIGID) ? " textrigid" : ""
505                );
506     }
507
508     sprintf(term_options, "%s %s %s %d %s %s %s%s %s \"%s\" %s %d %s %d %s %d %s %s",
509             FIG_use_color ? "color" : "monochrome",
510             FIG_is_big ? "big" : "small",
511             "pointsmax",
512             FIG_poly_vec_max + 1,
513             FIG_portrait ? "portrait" : "landscape",
514             FIG_inches ? "inches" : "metric",
515             FIG_solid ? "solid" : "dashed",
516             text_flags,
517             "font", FIG_fonts[FIG_font_id].key,
518             "fontsize", (FIG_font_s > 0 ? FIG_font_s :
519                          (FIG_is_big ? BFIG_FONT_S : FIG_FONT_S)),
520             "linewidth", FIG_default_thickness, "depth", FIG_depth,
521             "version", FIG_version );   /* JFS, KB, ULIG */
522     if (xsize_t > 0. && ysize_t > 0.) {
523         if (xsize_t - (int) xsize_t == 0. && ysize_t - (int) ysize_t == 0.)
524             sprintf(term_options + strlen(term_options),
525                     " size %d %d", (int) xsize_t, (int) ysize_t);
526         else
527             sprintf(term_options + strlen(term_options),
528                     " size %f %f", xsize_t, ysize_t);
529     }
530     if (!FIG_is_big) {
531         if (FIG_font_s <= 0)    /* KB */
532             FIG_font_s = FIG_FONT_S;
533         term->xmax = FIG_XMAX(FIG_inches);
534         term->ymax = FIG_YMAX(FIG_inches);
535         term->v_tic = FIG_VTIC(FIG_inches);
536         term->h_tic = FIG_HTIC(FIG_inches);
537         FIG_xoff = FIG_XOFF(FIG_inches);
538         FIG_yoff = FIG_YOFF(FIG_inches);
539     } else {
540         if (FIG_font_s <= 0)    /* KB */
541             FIG_font_s = BFIG_FONT_S;
542         term->xmax = BFIG_XMAX(FIG_inches);
543         term->ymax = BFIG_YMAX(FIG_inches);
544         term->v_tic = BFIG_VTIC(FIG_inches);
545         term->h_tic = BFIG_HTIC(FIG_inches);
546         FIG_xoff = BFIG_XOFF(FIG_inches);
547         FIG_yoff = BFIG_YOFF(FIG_inches);
548     }
549     if (FIG_portrait) {         /* KB */
550         tmax_t = term->xmax;
551         term->xmax = term->ymax;
552         term->ymax = tmax_t;
553     }
554     if (xsize_t > 0. && ysize_t > 0.) {
555         term->xmax = (unsigned int) (xsize_t * FIG_TRUERES);
556         term->ymax = (unsigned int) (ysize_t * FIG_TRUERES);
557     }
558     term->v_char = FIG_to_pixel_v(FIG_inches, FIG_font_s);
559     term->h_char = FIG_to_pixel_h(FIG_inches, FIG_font_s);
560     FIG_thickness = FIG_default_thickness;
561     if (parse_error) {          /* JFS, KB */
562         int_error(c_token, "unrecognized option");
563     }
564 }
565
566
567 static void
568 FIG_poly_clean(enum FIG_poly_stat fig_stat)
569 {
570     int i, j;
571     int cap_style;
572
573     if (fig_stat == FIG_poly_part) {
574         cap_style = (FIG_line.style==DOTTED_LINE)
575             ? CAP_ROUND : FIG_line.cap_style;
576         fprintf(gpoutfile,
577                 "%d %d %d %d %d %d %d %d %d %9.3f %d %d %d %d %d %ld\n\t",
578                 O_POLYLINE, FIG_line.type, FIG_line.style, FIG_line.thickness,
579                 FIG_line.pen_color, FIG_line.fill_color, FIG_line.depth,
580                 FIG_line.pen_style, FIG_line.fill_style, FIG_line.style_val,
581                 FIG_line.join_style, cap_style, FIG_line.radius,
582                 0, 0, FIG_poly_vec_cnt);
583
584         j = 0;
585         for (i = 0; i < FIG_poly_vec_cnt; i++) {
586             fprintf(gpoutfile, " %d %d", FIG_points[i].x, FIG_points[i].y);
587             if (j++ > 4 && i != FIG_poly_vec_cnt - 1) {
588                 fputs("\n\t", gpoutfile);
589                 j = 0;          /* JFS */
590             }
591         }
592         if (j != 0) {
593             putc('\n', gpoutfile);
594         }
595         /* Give the memory back to the system because we are done with this
596          * polyline. Make sure FIG_points contains NULL afterwards!
597          */
598         free(FIG_points);
599         FIG_points = NULL;
600     }
601     FIG_polyvec_stat = FIG_poly_new;
602 }
603
604
605 TERM_PUBLIC void
606 FIG_init()
607 {
608     FIG_posx = FIG_posy = 0;
609     FIG_polyvec_stat = FIG_poly_new;
610     FIG_linetype(-1);
611     FIG_justify_text(LEFT);
612     FIG_text_angle(0);
613
614     FIG_palette_set = FALSE;    /* PM3D Palette Set ? */
615     FIG_line.tagged = FIG_DEFAULT;
616     FIG_line.distrib = FIG_DEFAULT;
617     FIG_line.type = T_POLYLINE;
618     FIG_line.style = 0;
619     FIG_line.thickness = FIG_thickness;
620     FIG_line.fill_style = -1;
621     FIG_line.depth = FIG_linedepth;
622     FIG_line.pen_style = 0;
623     FIG_line.for_arrow = NULL;
624     FIG_line.back_arrow = NULL;
625     FIG_line.cap_style = 0;
626     FIG_line.join_style = 0;
627     FIG_line.style_val = 0.0;
628     FIG_line.radius = 0;
629     FIG_line.pic = NULL;
630     FIG_line.next = NULL;
631
632     /* Add further versions headers below (ULIG). There is probably more work to be done */
633     /* than only changing the header in future xfig versions */
634
635     if( strcmp(FIG_version, "3.1") == 0 ) {
636         fprintf( gpoutfile,
637                  "#FIG 3.1\n%s\n%s\n%s\n%d %d\n",
638                  FIG_ORIENT,
639                  FIG_JUST,
640                  FIG_UNIT,
641                  FIG_IRES, FIG_COORD_SYS
642                );
643     } else if( strcmp(FIG_version, "3.2") == 0 ) {
644         fprintf( gpoutfile,
645                  "#FIG 3.2\n%s\n%s\n%s\n%s\n%6.2f\n%s\n%d\n%d %d\n",
646                  FIG_ORIENT,
647                  FIG_JUST,
648                  FIG_UNIT,
649                  FIG_PAPER,
650                  FIG_MAGNIFICATION,
651                  FIG_MULTIPAGE,
652                  FIG_TRANSCOLOR,
653                  FIG_IRES, FIG_COORD_SYS
654                );
655     }
656 }
657
658
659 TERM_PUBLIC void
660 FIG_graphics()
661 {
662     FIG_posx = FIG_posy = 0;
663     FIG_polyvec_stat = FIG_poly_new;
664     /* there is no way to have separate pictures in a FIG file */
665 }
666
667
668 TERM_PUBLIC void
669 FIG_text()
670 {
671     /* there is no way to have separate pictures in a FIG file */
672     FIG_poly_clean(FIG_polyvec_stat);
673     FIG_posx = FIG_posy = 0;
674     fflush(gpoutfile);
675 }
676
677
678 /* Line types for FIG work like this:
679  *  for monochrome:
680  *  -2 : solid (border)
681  *  -1 : dotted 4 (axes)
682  *   0 : solid (first curve)
683  *   1 : dotted 3
684  *   2 : dashed 3
685  *   3 : dotted 6
686  *   4 : dashed 6
687  *   ... ...
688  *  for color, cycle through colors. once colors are used up, repeat colors
689  *   but start using dashed lines of different dash length. don't use white
690  *   as a color.
691  */
692
693 TERM_PUBLIC void
694 FIG_linetype(int linetype)              /* expect linetype >= -2 */
695 {
696     int last_FIG_type = FIG_type;
697     int last_FIG_spacing = FIG_spacing;
698     int last_FIG_color = FIG_color;
699     int last_FIG_depth = FIG_linedepth;
700     int last_FIG_thickness = FIG_thickness;
701
702     /* mapping of fig color codes to color sequence as in the postscript terminal */
703 #define npscolors 9
704     int fig2pscolors[npscolors] = {
705         4 /*red*/, 2 /*green*/, 1 /*blue*/,
706         5 /*magenta*/, 3 /*cyan*/, 6 /*yellow*/,
707         0 /*black*/, 26 /*brown*/,
708         11 /*use LtBlue instead of light gray*/
709         /* note: black=1, white=8 */
710     };
711
712     FIG_linedepth = FIG_depth;
713     FIG_thickness = FIG_current_linewidth * FIG_default_thickness;
714     if (FIG_thickness < 1)
715         FIG_thickness = 1;
716     FIG_color = DEFAULT;
717
718     if (linetype <= LT_NODRAW)
719         linetype = LT_BLACK;
720
721     switch (linetype) {
722     case 0:
723     case LT_BLACK:{
724             FIG_type = SOLID_LINE;
725             FIG_spacing = 0.0;
726             if (FIG_use_color)
727 #if 0 /* fig's old color sequence */
728                 FIG_color = BLACK;
729 #else /* color sequence compatible to the postscript terminal */
730                 if (linetype==0) FIG_color = fig2pscolors[0]; /* red */
731 #endif
732             break;
733         }
734     case LT_AXIS:{
735             FIG_type = DOTTED_LINE;
736             if( FIG_solid )
737                 FIG_type = SOLID_LINE;
738             FIG_spacing = 4.0;  /* gap */
739             if (FIG_use_color)
740                 FIG_color = BLACK;
741             break;
742         }
743     default:{
744             /* now linetype >= 1 --- shouldn't be negative anyway */
745             FIG_linedepth = FIG_depth + linetype / 1000;
746             linetype %= 1000;
747             /* Thickness of lines is either included in the linetype */
748             /* (in Fig units) or the default is scaled with the */
749             /* current 'linewidth'. */
750             if ((FIG_thickness = linetype / 100) == 0)
751                 FIG_thickness = FIG_current_linewidth * FIG_default_thickness;
752             if (FIG_thickness < 1)      /* Less than 1 would be invisible */
753                 FIG_thickness = 1;
754             linetype %= 100;
755             if (FIG_use_color) {
756 #if 0 /* fig's old color sequence */
757                 FIG_type = (linetype >= WHITE);         /* dashed line */
758                 FIG_color = linetype % WHITE;
759                 FIG_spacing = (linetype / WHITE) * 3;
760 #else /* color sequence compatible to the postscript terminal */
761                 FIG_type = (linetype >= npscolors);             /* dashed line */
762                 FIG_color = fig2pscolors[linetype % npscolors];
763                 FIG_spacing = (linetype / npscolors) * 3;
764 #endif
765             } else {            /* monochrome */
766                 FIG_type = (linetype)? linetype%2 + 1 : SOLID_LINE; /* dotted, dashed, ... */
767                 FIG_spacing = (linetype + 1) / 2 * 3;
768             }
769             if( FIG_solid )
770                 FIG_type = SOLID_LINE;
771             break;
772         }
773     }
774     if (FIG_type != last_FIG_type || FIG_spacing != last_FIG_spacing ||
775         FIG_color != last_FIG_color || FIG_linedepth != last_FIG_depth ||
776         FIG_thickness != last_FIG_thickness)
777         FIG_poly_clean(FIG_polyvec_stat);
778 }
779
780 TERM_PUBLIC void
781 FIG_move(unsigned int x, unsigned int y)
782 {
783     int last_FIG_posx = FIG_posx;
784     int last_FIG_posy = FIG_posy;
785
786     FIG_posx = x;
787     FIG_posy = y;
788     if (FIG_posx != last_FIG_posx || FIG_posy != last_FIG_posy)
789         FIG_poly_clean(FIG_polyvec_stat);
790 }
791
792
793 TERM_PUBLIC void
794 FIG_vector(unsigned int ux, unsigned int uy)
795 {
796     int x = ux, y = uy;
797
798     if (FIG_polyvec_stat != FIG_poly_part) {
799         FIG_line.pen_color = FIG_color;
800         FIG_line.fill_color = FIG_color;
801         FIG_line.style = FIG_type;
802         FIG_line.style_val = FIG_spacing;
803         FIG_line.depth = FIG_linedepth;
804         FIG_line.thickness = FIG_thickness;
805         FIG_poly_vec_cnt = 0;
806         /* allocate memory for the first point */
807         FIG_points = (F_point *) gp_realloc(FIG_points, sizeof(F_point), "FIG_points");         /* JFS */
808         FIG_points[FIG_poly_vec_cnt].x = FIG_xoff + FIG_posx;
809         FIG_points[FIG_poly_vec_cnt].y = term->ymax
810             + FIG_yoff - FIG_posy;
811
812         FIG_poly_vec_cnt = 1;
813         FIG_polyvec_stat = FIG_poly_part;
814     }
815     /* allocate memory for the next point */
816     FIG_points = (F_point *) gp_realloc(FIG_points, (FIG_poly_vec_cnt + 1) *
817                                         sizeof(F_point), "FIG_points");         /* JFS */
818     FIG_points[FIG_poly_vec_cnt].x = FIG_xoff + x;
819     FIG_points[FIG_poly_vec_cnt].y = term->ymax + FIG_yoff - y;
820
821     FIG_poly_vec_cnt++;
822     if (FIG_poly_vec_cnt > FIG_poly_vec_max)
823         FIG_poly_clean(FIG_polyvec_stat);
824
825     FIG_posx = x;
826     FIG_posy = y;
827 }
828
829
830 TERM_PUBLIC void
831 FIG_arrow(
832     unsigned int sx, unsigned int sy, /* start coord */
833     unsigned int ex, unsigned int ey, /* end coord */
834     int head)
835 {
836     int cap_style;
837     double awidth, aheight;     /* arrow head sizes */
838
839     FIG_poly_clean(FIG_polyvec_stat);
840     cap_style = (FIG_line.style==DOTTED_LINE)? CAP_ROUND : FIG_line.cap_style;
841     fprintf(gpoutfile, "%d %d %d %d %d %d %d %d %d %9.3f %d %d %d %d %d %d\n",
842             O_POLYLINE, FIG_line.type, FIG_type, FIG_thickness,
843             FIG_color, FIG_color, FIG_linedepth,
844             FIG_line.pen_style, FIG_line.fill_style, FIG_spacing,
845             FIG_line.join_style, cap_style, FIG_line.radius,
846             head ? 1 : 0, head==2 ? 1 : 0, 2);
847
848     /* arrow head(s) */
849     if (head) {
850         unsigned int headbackangleparameter = 0;
851         unsigned int headfillparameter = 0;
852
853         /* arrow head size */
854         if (curr_arrow_headlength==0) {
855             awidth  = (double) (term->h_tic / 2 + 1);
856             aheight = (double) term->h_tic;
857         } else {
858             awidth  = (double) curr_arrow_headlength * 2*sin(curr_arrow_headangle*M_PI/180);
859             aheight = (double) curr_arrow_headlength * cos(curr_arrow_headangle*M_PI/180);
860         }
861
862         /* arrow head geometry */
863         if ( curr_arrow_headbackangle < 70 )
864             headbackangleparameter = 2;
865         else if ( curr_arrow_headbackangle > 110 )
866             headbackangleparameter = 3;
867         else
868             headbackangleparameter = 1;
869
870         if (curr_arrow_headfilled==2)
871             headfillparameter = 1;
872         else
873             headfillparameter = 0;
874
875         /* forward head */
876         fprintf(gpoutfile, "%d %d %.3f %.3f %.3f\n",
877                 headbackangleparameter, headfillparameter,
878                 1.0, awidth, aheight);
879         /* backward head */
880         if (head==2)
881             fprintf(gpoutfile, "%d %d %.3f %.3f %.3f\n",
882                     headbackangleparameter,  headfillparameter,
883                     1.0, awidth, aheight);
884     }
885
886     /* arrow line */
887     fprintf(gpoutfile, "%d %d %d %d\n",
888             FIG_xoff + sx, FIG_yoff + term->ymax - sy,
889             FIG_yoff + ex, FIG_yoff + term->ymax - ey);
890
891     FIG_posx = ex;
892     FIG_posy = ey;
893 }
894
895
896 TERM_PUBLIC void
897 FIG_put_text(unsigned int x, unsigned int y, const char *str)
898 {
899     char *s1, *s2, *output_string;
900
901     if (strlen(str) == 0)
902         return;
903
904     output_string = (char *) gp_alloc(2*strlen(str)+1, "FIG text");
905     s1 = (char *)str;
906     s2 = output_string;
907     do {
908         if (*s1 == '\\') *(s2++) = *s1;
909         *(s2++) = *s1;
910     } while ( *(s1++) );
911     FIG_poly_clean(FIG_polyvec_stat);
912     if (FIG_angle == 0.)
913         y -= term->v_char / 2;  /* assuming vertical center justified */
914     else {
915         x += (int)(term->v_char*sin(FIG_angle)/4.);
916         y -= (int)(term->v_char*cos(FIG_angle)/4.);
917     }
918
919     fprintf(gpoutfile, "%d %d %d %d %d %d %6.3f %6.3f %d %6.3f %6.3f %d %d %s\\001\n",
920             OBJ_TEXT, FIG_justify, FIG_color, 0, FIG_DEFAULT,
921             FIG_font_id, (float) FIG_font_s,
922             FIG_angle, FIG_text_flags, (float) term->v_char,
923             (float) term->h_char * strlen(str),
924             FIG_xoff + x, term->ymax + FIG_yoff - y, output_string);
925
926     free(output_string);
927 }
928
929 TERM_PUBLIC int
930 FIG_justify_text(enum JUSTIFY mode)
931 {
932     switch (mode) {
933     case LEFT:
934         FIG_justify = T_LEFT_JUSTIFIED;
935         break;
936     case CENTRE:
937         FIG_justify = T_CENTER_JUSTIFIED;
938         break;
939     case RIGHT:
940         FIG_justify = T_RIGHT_JUSTIFIED;
941         break;
942         /* shouldn't happen */
943     default:
944         FIG_justify = T_LEFT_JUSTIFIED;
945         return (FALSE);
946         break;
947     }
948     return (TRUE);
949 }
950
951 TERM_PUBLIC int
952 FIG_text_angle(int ang)
953 {
954     FIG_angle = ang * M_PI_2 / 90. ;
955     return (TRUE);
956 }
957
958 TERM_PUBLIC void
959 FIG_lpoint(unsigned int x, unsigned int y, int number)
960 {
961     FIG_type = 0;               /* Solid lines for marker outline */
962     if (number % 100 >= 49 && number % 100 < 99) {      /* circles, squares, triangles */
963         int r, d, h, xpc, ypc;
964         int line_color, fill_color, fill_style;
965         int cnum, tnum, color, depth;
966
967         FIG_poly_clean(FIG_polyvec_stat);
968         depth = FIG_linedepth - 1;      /* Above error bars */
969         if (number > 1000)
970             depth = FIG_depth + number / 1000 - 1;
971         number %= 1000;
972         if (depth < 0)
973             depth = 0;
974         if (number < 100)
975             color = FIG_color;
976         else if (FIG_use_color)
977             color = number / 100 - 1;
978         else if (number / 100 >= WHITE)
979             color = WHITE;
980         else
981             color = DEFAULT;
982         number %= 100;
983         cnum = (number + 1) % 10;
984         tnum = (number - 49) / 10;
985         if (cnum < 5)
986             line_color = (FIG_use_color ? BLACK : DEFAULT);
987         else
988             line_color = FIG_color;
989         fill_color = color;
990         if (cnum == 0 || cnum == 5)
991             fill_style = -1;
992         else
993             fill_style = (cnum % 5) * 5;
994
995         xpc = FIG_xoff + x;
996         ypc = term->ymax + FIG_yoff - y;
997
998         if (tnum == 0) {        /* circle */
999             r = FIG_current_pointsize * term->v_char / 4 + 1;
1000             fprintf(gpoutfile,
1001                     "1 3 %d %d %d %d %d %d %d %6.3f 1 0.000 %d %d %d %d %d %d %d %d\n",
1002                     FIG_type, FIG_thickness, line_color,
1003                     fill_color, depth, 0, fill_style, FIG_spacing,
1004                     xpc, ypc, r, r, xpc, ypc, xpc, ypc - r);
1005         } else {
1006             fprintf(gpoutfile, "2 3 %d %d %d %d %d %d %d %6.3f 0 0 0 0 0 ",
1007                     FIG_type, FIG_thickness, line_color,
1008                     fill_color, depth, 0, fill_style, FIG_spacing);
1009
1010             if (tnum == 1) {    /* square */
1011                 d = FIG_current_pointsize * term->v_char / 4 + 1;
1012                 fprintf(gpoutfile, "5\n\t%d %d %d %d %d %d %d %d %d %d\n",
1013                         xpc - d, ypc - d, xpc - d, ypc + d, xpc + d, ypc + d, xpc + d, ypc - d,
1014                         xpc - d, ypc - d);
1015             } else if (tnum == 2) {     /* diamond */
1016                 d = FIG_current_pointsize * term->v_char / 3 + 1;
1017                 fprintf(gpoutfile, "5\n\t%d %d %d %d %d %d %d %d %d %d\n",
1018                         xpc - d, ypc, xpc, ypc + d, xpc + d, ypc, xpc, ypc - d, xpc - d, ypc);
1019             } else if (tnum == 3) {     /* triangle up */
1020                 d = FIG_current_pointsize * term->v_char / 3 + 1;
1021                 h = d * 4 / 7;  /* About d times one 3rd of sqrt(3) */
1022                 fprintf(gpoutfile, "4\n\t%d %d %d %d %d %d %d %d\n",
1023                         xpc - d, ypc + h, xpc, ypc - 2 * h, xpc + d, ypc + h, xpc - d, ypc + h);
1024             } else if (tnum == 4) {     /* triangle down */
1025                 d = FIG_current_pointsize * term->v_char / 3 + 1;
1026                 h = d * 4 / 7;
1027                 fprintf(gpoutfile, "4\n\t%d %d %d %d %d %d %d %d\n",
1028                         xpc - d, ypc - h, xpc, ypc + 2 * h, xpc + d, ypc - h, xpc - d, ypc - h);
1029             }
1030         }
1031     } else {
1032         int pt = number % 13;
1033         switch (pt) {
1034         default:        do_point(x, y, pt); break;
1035         case 3:         FIG_lpoint(x, y, 64); break;
1036         case 4:         FIG_lpoint(x, y, 68); break;
1037         case 5:         FIG_lpoint(x, y, 54); break;
1038         case 6:         FIG_lpoint(x, y, 58); break;
1039         case 7:         FIG_lpoint(x, y, 84); break;
1040         case 8:         FIG_lpoint(x, y, 88); break;
1041         case 9:         FIG_lpoint(x, y, 94); break;
1042         case 10:        FIG_lpoint(x, y, 98); break;
1043         case 11:        FIG_lpoint(x, y, 74); break;
1044         case 12:        FIG_lpoint(x, y, 78); break;
1045         }
1046     }
1047 }
1048
1049 TERM_PUBLIC void
1050 FIG_pointsize(double arg_pointsize)
1051 {
1052     FIG_current_pointsize = arg_pointsize < 0. ? 1. : arg_pointsize;
1053     /* Bug-fix by hkeller@gwdg.de and K.B.: set pointsize for do_point() */
1054     do_pointsize(arg_pointsize * FIG_font_s / (double) FIG_FONT_S);
1055 }
1056
1057 TERM_PUBLIC void
1058 FIG_linewidth(double linewidth)
1059 {
1060     FIG_current_linewidth = linewidth;
1061 }
1062
1063 TERM_PUBLIC void
1064 FIG_reset()
1065 {
1066     FIG_poly_clean(FIG_polyvec_stat);
1067     FIG_posx = FIG_posy = 0;
1068     fflush(gpoutfile);
1069 }
1070
1071 TERM_PUBLIC void
1072 FIG_boxfill(
1073     int style,
1074     unsigned int x, unsigned int y,
1075     unsigned int w, unsigned int h)
1076 {
1077     int pen_color, fill_color, fill_style, fill_dens;
1078
1079     FIG_poly_clean(FIG_polyvec_stat);
1080
1081     FIG_line.pen_color = FIG_color;
1082
1083     switch( style & 0xf ) {
1084     case FS_SOLID:
1085         /* style == 1 --> filled with intensity according to filldensity */
1086         pen_color = FIG_line.pen_color;
1087         fill_color = FIG_line.pen_color;
1088         fill_dens = style >> 4;
1089         if( fill_dens < 0 ) fill_dens = 0;
1090         if( fill_dens > 100 ) fill_dens = 100;
1091         if( FIG_color == -1 || FIG_color == 0 )
1092             /* default color or black: solid 0%...100% -> 0...20 */
1093             fill_style = fill_dens / 5;
1094         else
1095             /* all other colors: solid 0%...100% -> 40...20 */
1096             fill_style = 40 - fill_dens / 5;
1097         break;
1098     case FS_PATTERN:
1099         /* style == 2 --> filled with pattern according to fillpattern */
1100         pen_color = FIG_line.pen_color;
1101         fill_color = WHITE;
1102         fill_style = 41 + ( ( (style>>4) < 0 ) ? 0 : style>>4 );
1103         break;
1104     case FS_EMPTY:
1105     default:
1106         /* style == 0 or unknown --> filled with background color */
1107         pen_color = FIG_line.pen_color;
1108         fill_color = WHITE;
1109         fill_style = 20;
1110     }
1111
1112     x = FIG_xoff + x;
1113     y = term->ymax + FIG_yoff - y;
1114
1115     fprintf(gpoutfile, "%d %d %d %d %d %d %d %d %d %6.3f %d %d %d %d %d %d\n"
1116             "  %d %d %d %d %d %d %d %d %d %d\n",
1117             O_POLYLINE, FIG_line.type, FIG_line.style, FIG_line.thickness,
1118             pen_color, fill_color, FIG_line.depth, FIG_line.pen_style,
1119             fill_style, FIG_line.style_val, FIG_line.join_style,
1120             FIG_line.cap_style, FIG_line.radius, 0, 0, 5,
1121             x, y, x+w, y, x+w, y-h, x, y-h, x, y );
1122 }
1123
1124 TERM_PUBLIC int FIG_make_palette(t_sm_palette *palette)
1125 {
1126     int i;
1127
1128     /* Query to determine palette size */
1129     if (palette==NULL) {
1130         return FIG_palette_size; /* How big is palette ? */
1131     }
1132
1133     FIG_poly_clean(FIG_polyvec_stat); /* Clean up current data */
1134
1135     if (FIG_palette_set == FALSE) {
1136         /* Create new palette */
1137         FIG_palette_set = TRUE;
1138         if (FIG_use_color == FALSE || sm_palette.colorMode == SMPAL_COLOR_MODE_GRAY) {
1139             /* Gray palette */
1140             if (FIG_use_color == FALSE && sm_palette.colorMode == SMPAL_COLOR_MODE_RGB)
1141                 fprintf(stderr, "Monochrome fig file: using gray palette instead of color\n");
1142             for (i = 0; i < sm_palette.colors; i++) {
1143                 int j = (int)(i * 255.0 / (sm_palette.colors-1) + 0.5);
1144                 fprintf(gpoutfile, "%d %d #%2.2x%2.2x%2.2x\n",
1145                 O_COLOR_DEF, (i + FIG_palette_offst), j, j, j);
1146             }
1147         } else {
1148             /* Create colour/normal palette */
1149             for (i = 0; i < sm_palette.colors; i++) {
1150                 fprintf(gpoutfile, "%d %d #%2.2x%2.2x%2.2x\n",
1151                 O_COLOR_DEF, (i + FIG_palette_offst),
1152                 (int)( palette->color[i].r * 255 + 0.5 ),
1153                 (int)( palette->color[i].g * 255 + 0.5 ),
1154                 (int)( palette->color[i].b * 255 + 0.5 ) );
1155             }
1156         }
1157     } else {
1158         fprintf(stderr, "fig: Attempt to set palette twice\n");
1159     }
1160     return 0;
1161 }
1162
1163 /* This doesn't apply for FIG format files
1164 TERM_PUBLIC void FIG_previous_palette()
1165 {
1166 }
1167 */
1168
1169 TERM_PUBLIC void FIG_set_color(t_colorspec *colorspec)
1170 {
1171     double gray = colorspec->value;
1172     int new_color;
1173
1174     if (colorspec->type == TC_LT) {
1175         FIG_linetype(colorspec->lt);
1176         return;
1177     }
1178
1179     if (colorspec->type != TC_FRAC)
1180         return;
1181
1182     new_color = (gray <= 0) ? 0 : (int)(gray * sm_palette.colors);
1183     if (new_color >= FIG_palette_size)
1184         new_color = FIG_palette_size - 1;
1185     if (FIG_palette_set == FALSE) {
1186         fprintf(stderr,"fig: Palette used before set\n"); /* Error condition */
1187     }
1188     new_color += FIG_palette_offst;
1189     if (FIG_color != new_color) {
1190         FIG_poly_clean(FIG_polyvec_stat);
1191         FIG_color = new_color;
1192     }
1193 }
1194
1195 TERM_PUBLIC void FIG_filled_polygon(int points, gpiPoint *corners)
1196 {
1197     int i,j;
1198
1199     FIG_poly_clean(FIG_polyvec_stat); /* Clean up current data */
1200
1201     fprintf(gpoutfile, "%d %d %d %d %d %d %d %d %d %9.3f %d %d %d %d %d %ld\n\t",
1202         O_POLYLINE, T_POLYGON, FIG_line.style, 0,
1203         FIG_color, FIG_color, FIG_line.depth,
1204         FIG_line.pen_style, FIG_fill_style, FIG_line.style_val,
1205         FIG_line.join_style, FIG_line.cap_style, FIG_line.radius,
1206         0, 0, (long)(points+1));
1207 /* set thickness (arg 4) to 0 */
1208
1209     j = 0;
1210     for (i = 0; i < points; i++) {
1211         fprintf(gpoutfile, " %d %d", FIG_xoff + corners[i].x,
1212             term->ymax + FIG_yoff - corners[i].y);
1213         if (j++ > 4 && i != points - 1) {
1214                 fputs("\n\t", gpoutfile);
1215                 j = 0;          /* JFS */
1216         }
1217     }
1218     fprintf(gpoutfile, " %d %d", FIG_xoff + corners[0].x,
1219         term->ymax + FIG_yoff - corners[0].y);
1220     j++;
1221     if (j != 0) {
1222         putc('\n', gpoutfile);
1223     }
1224 }
1225
1226 #endif /* TERM_BODY */
1227
1228 #ifdef TERM_TABLE
1229
1230 TERM_TABLE_START(fig_driver)
1231     "fig", "FIG graphics language for XFIG graphics editor",
1232     FIG_XMAX(INCH), FIG_YMAX(INCH), FIG_VCHAR, FIG_HCHAR,
1233     FIG_VTIC(INCH), FIG_HTIC(INCH), FIG_options, FIG_init, FIG_reset,
1234     FIG_text, null_scale, FIG_graphics, FIG_move, FIG_vector,
1235     FIG_linetype, FIG_put_text, FIG_text_angle, FIG_justify_text,
1236     FIG_lpoint, FIG_arrow, set_font_null, FIG_pointsize,
1237     TERM_BINARY /*flags */ , 0 /*suspend */ , 0 /*resume */ ,
1238     FIG_boxfill, FIG_linewidth
1239 #ifdef USE_MOUSE
1240     ,0, 0, 0, 0, 0 /* no mouse support for the fig terminal */
1241 #endif
1242     , FIG_make_palette, 0 /*previous_palette*/, FIG_set_color, FIG_filled_polygon
1243 TERM_TABLE_END(fig_driver)
1244
1245 #undef LAST_TERM
1246 #define LAST_TERM fig_driver
1247 #endif /* TERM_TABLE */
1248 #endif /* TERM_PROTO_ONLY */
1249
1250 #ifdef TERM_HELP
1251 START_HELP(fig)
1252 "1 fig",
1253 "?commands set terminal fig",
1254 "?set terminal fig",
1255 "?set term fig",
1256 "?terminal fig",
1257 "?term fig",
1258 "?fig",
1259 "?xfig",
1260 " The `fig` terminal device generates output in the Fig graphics language.",
1261 "",
1262 " Syntax:",
1263 "       set terminal fig {monochrome | color}",
1264 "                        {landscape | portrait}",
1265 "                        {small | big | size <xsize> <ysize>}",
1266 "                        {metric | inches}",
1267 "                        {pointsmax <max_points>}",
1268 "                        {solid | dashed}",
1269 "                        {font <fontname>} {fontsize <fsize>}",
1270 "                        {textnormal | {textspecial texthidden textrigid}}",
1271 "                        {{thickness|linewidth} <units>}",
1272 "                        {depth <layer>}",
1273 "                        {version <number>}",
1274 "",
1275 " `monochrome` and `color` determine whether the picture is black-and-white or",
1276 " `color`.  `small` and `big` produce a 5x3 or 8x5 inch graph in the default",
1277 " `landscape` mode and 3x5 or 5x8 inches in `portrait` mode.",
1278 " `size` sets (overrides) the size of the drawing",
1279 " area to <xsize>*<ysize> in units of inches or centimeters depending on the",
1280 " `inches` or `metric` setting in effect.",
1281 " The latter settings is also used as default units for editing with \"xfig\".",
1282 "",
1283 " `pointsmax <max_points>` sets the maximum number of points per polyline.",
1284 "",
1285 " `solid` inhibits automatic usage of `dash`ed lines when solid linestyles are",
1286 " used up, which otherwise occurs.",
1287 "",
1288 " `fontsize` sets the size of the text font to <fsize> points.  `textnormal`",
1289 " resets the text flags and selects postscript fonts, `textspecial` sets the",
1290 " text flags for LaTeX specials, `texthidden` sets the hidden flag and",
1291 " `textrigid` the rigid flag. ",
1292 "",
1293 " `depth` sets the default depth layer for all lines and text.  The default",
1294 " depth is 10 to leave room for adding material with \"xfig\" on top of the",
1295 " plot.",
1296 "",
1297 " `version` sets the format version of the generated fig output. Currently",
1298 " only versions 3.1 and 3.2 are supported.",
1299 "",
1300 " `thickness` sets the default line thickness, which is 1 if not specified.",
1301 " Overriding the thickness can be achieved by adding a multiple of 100 to the",
1302 " `linetype` value for a `plot` command.  In a similar way the `depth`",
1303 " of plot elements (with respect to the default depth) can be controlled by",
1304 " adding a multiple of 1000 to <linetype>.  The depth is then <layer> +",
1305 " <linetype>/1000 and the thickness is (<linetype>%1000)/100 or, if that is",
1306 " zero, the default line thickness. `linewidth` is a synonym for `thickness`.",
1307 "",
1308 " Additional point-plot symbols are also available with the `fig` driver. The",
1309 " symbols can be used through `pointtype` values % 100 above 50, with different",
1310 " fill intensities controlled by <pointtype> % 5 and outlines in black (for",
1311 " <pointtype> % 10 < 5) or in the current color.  Available symbols are",
1312 "         50 - 59:  circles",
1313 "         60 - 69:  squares",
1314 "         70 - 79:  diamonds",
1315 "         80 - 89:  upwards triangles",
1316 "         90 - 99:  downwards triangles",
1317 " The size of these symbols is linked to the font size.  The depth of symbols",
1318 " is by default one less than the depth for lines to achieve nice error bars.",
1319 " If <pointtype> is above 1000, the depth is <layer> + <pointtype>/1000-1.  If",
1320 " <pointtype>%1000 is above 100, the fill color is (<pointtype>%1000)/100-1.",
1321 "",
1322 " Available fill colors are (from 1 to 9): black, blue, green, cyan, red,",
1323 " magenta, yellow, white and dark blue (in monochrome mode: black for 1 to 6",
1324 " and white for 7 to 9).",
1325 "",
1326 " See `plot with` for details of <linetype> and <pointtype>.",
1327 "",
1328 " The `big` option is a substitute for the `bfig` terminal in earlier versions,",
1329 " which is no longer supported.",
1330 "",
1331 " Examples:",
1332 "       set terminal fig monochrome small pointsmax 1000  # defaults",
1333 "",
1334 "       plot 'file.dat' with points linetype 102 pointtype 759",
1335 " would produce circles with a blue outline of width 1 and yellow fill color.",
1336 "",
1337 "       plot 'file.dat' using 1:2:3 with err linetype 1 pointtype 554",
1338 " would produce errorbars with black lines and circles filled red.  These",
1339 " circles are one layer above the lines (at depth 9 by default).",
1340 "",
1341 " To plot the error bars on top of the circles use",
1342 "       plot 'file.dat' using 1:2:3 with err linetype 1 pointtype 2554"
1343 END_HELP(fig)
1344 #endif /* TERM_HELP */
1345
1346
1347
1348
1349 #if 0
1350
1351 /* I hope this is enough to stop compilers looking in here
1352  * (I think that anything inside #if 0 is still strictly
1353  *  required to be valid C, rather than just any old junk
1354  *  like this.)
1355  */
1356
1357 /*
1358  * FIG : Facility for Interactive Generation of figures
1359  * Copyright (c) 1985 by Supoj Sutanthavibul
1360  * Parts Copyright (c) 1994 by Brian V. Smith
1361  * Parts Copyright (c) 1991 by Paul King
1362  *
1363  * The X Consortium, and any party obtaining a copy of these files from
1364  * the X Consortium, directly or indirectly, is granted, free of charge, a
1365  * full and unrestricted irrevocable, world-wide, paid up, royalty-free,
1366  * nonexclusive right and license to deal in this software and
1367  * documentation files (the "Software"), including without limitation the
1368  * rights to use, copy, modify, merge, publish, distribute, sublicense,
1369  * and/or sell copies of the Software, and to permit persons who receive
1370  * copies from any such party to do so, with the only requirement being
1371  * that this copyright notice remain intact.  This license includes without
1372  * limitation a license to do the foregoing actions under any patents of
1373  * the party supplying this software to the X Consortium.
1374  */
1375
1376 /*
1377 The only difference from version 3.0 to version 3.1 is that the position
1378 of the "magnet" has been shifted by 14 Fig units.
1379 In the 2.1 and older versions of xfig the grid was in multiples of 5 Fig
1380 units, but they were on intervals 4, 9, 14, 19, etc.
1381 When version 3.0 was created, coordinates were simply multiplied by the
1382 ratio of the resolutions (1200/80 = 15) so values like 4 became 60 instead
1383 of 74 ((4+1)*15 - 1).
1384
1385 This means that figures converted from 2.1 and older files are offset by
1386 14 Fig units but new objects entered with version 3.0 are correct.
1387
1388 In version 3.1 the magnet grid is at intervals 0, 75, 150, etc instead of
1389 -1, 74, 149, etc.
1390 Figures from 2.1 and older are correctly converted now and a warning is popped
1391 up when you read in a version 3.0 file that says you may have to offset the
1392 figure when you load it, using the x and y offsets in the file panel.
1393
1394 --------------------------------------------------------------------------------
1395 Description of the Fig Format Follows
1396 --------------------------------------------------------------------------------
1397
1398  (1) The very first line is a comment line containing the name and version:
1399         #FIG 3.1
1400
1401     The character # at the first column of a line indicates that the line
1402     is a comment line which will be ignored.
1403
1404  (2) The first non-comment line consists of two numbers and two strings:
1405
1406         int     fig_resolution          (Fig units/inch)
1407         string  orientation             ("Landscape" or "Portrait")
1408         string  justification           ("Center" or "Flush Left")
1409         string  units                   ("Metric" or "Inches")
1410         int     coordinate_system       (1: origin is the lower left corner (NOT USED)
1411                                          2: upper left)
1412
1413     Fig_resolution is the resolution of the figure in the file.
1414     Xfig will always write the file with a resolution of 1200ppi so it
1415     will scale the figure upon reading it in if its resolution is different
1416     from 1200ppi.  Pixels are assumed to be square.
1417
1418     Xfig will read the orientation string and change the canvas to match
1419     either the Landscape or Portrait mode of the figure file.
1420
1421     The units specification is self-explanatory.
1422
1423     The coordinate_system variable is ignored - the origin is ALWAYS the
1424     upper-left corner.
1425
1426     ** Coordinates are given in "fig_resolution" units.
1427     ** Line thicknesses are given in 1/80 of an inch ("display units").  The
1428        minimum line thickness is 0 (no line is drawn) and the maximum is 500.
1429     ** dash-lengths/dot-gaps are given in 1/80 of an inch.
1430
1431
1432  (3) The rest of the file contains various objects.  An object can be one
1433     of six classes (or types).
1434
1435         0)      Color pseudo-object.
1436         1)      Arc.
1437         2)      Ellipse which is a generalization of circle.
1438         3)      Polyline which includes polygon and box.
1439         4)      Spline which includes closed/open control/interpolated spline.
1440         5)      Text.
1441         6)      Compound object which is composed of one or more objects.
1442
1443     In the following elaboration on object formats, every value of Fig
1444     output are separated by blank characters or new line ('\n').  The
1445     value of the unused parameters will be -1.
1446
1447     Some fields are described as "enumeration type" or "bit vector"; the
1448     values which these fields can take are defined in the header file object.h.
1449     The pen_style field is unused.
1450     These values may be defined in some future version of Fig.
1451
1452     The two color fields (pen and fill; pen only, for texts) are
1453     defined as follows:
1454
1455             -1 = Default
1456              0 = Black
1457              1 = Blue
1458              2 = Green
1459              3 = Cyan
1460              4 = Red
1461              5 = Magenta
1462              6 = Yellow
1463              7 = White
1464           8-11 = four shades of blue (dark to lighter)
1465          12-14 = three shades of green (dark to lighter)
1466          15-17 = three shades of cyan (dark to lighter)
1467          18-20 = three shades of red (dark to lighter)
1468          21-23 = three shades of magenta (dark to lighter)
1469          24-26 = three shades of brown (dark to lighter)
1470          27-30 = four shades of pink (dark to lighter)
1471             31 = Gold
1472
1473          values from 32 to 543 (512 total) are user colors and
1474          are defined in color pseudo-objects (type 0)
1475
1476     For WHITE color, the area fill field is defined as follows:
1477
1478         -1 = not filled
1479          0 = black
1480         ...  values from 1 to 19 are shades of grey, from darker to lighter
1481         20 = white
1482         21-40 not used
1483         41-56 see patterns for colors, below
1484
1485     For BLACK or DEFAULT color, the area fill field is defined as follows:
1486
1487         -1 = not filled
1488          0 = white
1489         ...  values from 1 to 19 are shades of grey, from lighter to darker
1490         20 = black
1491         21-40 not used
1492         41-56 see patterns for colors, below
1493
1494     For all other colors, the area fill field is defined as follows:
1495
1496         -1 = not filled
1497          0 = black
1498         ...  values from 1 to 19 are "shades" of the color, from darker to lighter.
1499                 A shade is defined as the color mixed with black
1500         20 = full saturation of the color
1501         ...  values from 21 to 39 are "tints" of the color from the color to white.
1502                 A tint is defined as the color mixed with white
1503         40 = white
1504         41 = 30 degree left diagonal pattern
1505         42 = 30 degree right diagonal pattern
1506         43 = 30 degree crosshatch
1507         44 = 45 degree left diagonal pattern
1508         45 = 45 degree right diagonal pattern
1509         46 = 45 degree crosshatch
1510         47 = bricks
1511         48 = circles
1512         49 = horizontal lines
1513         50 = vertical lines
1514         51 = crosshatch
1515         52 = fish scales
1516         53 = small fish scales
1517         54 = octagons
1518         55 = horizontal "tire treads"
1519         56 = vertical "tire treads"
1520
1521     The depth field is defined as follows:
1522
1523          0 ... 999 where larger value means object is deeper than (under)
1524                    objects with smaller depth
1525
1526     The line_style field is defined as follows:
1527
1528         -1 = Default
1529          0 = Solid
1530          1 = Dashed
1531          2 = Dotted
1532
1533     The style_val field is defined as the length, in 1/80 inches, of the on/off
1534     dashes for dashed lines, and the distance between the dots, in 1/80 inches,
1535     for dotted lines.
1536
1537     The join_style field is defined FOR LINES only as follows:
1538
1539          0 = Miter (the default in xfig 2.1 and earlier)
1540          1 = Bevel
1541          2 = Round
1542
1543     The cap_style field is defined FOR LINES, OPEN SPLINES and ARCS only as follows:
1544
1545          0 = Butt (the default in xfig 2.1 and earlier)
1546          1 = Round
1547          2 = Projecting
1548
1549     The arrow_type field is defined for LINES, ARCS and OPEN SPLINES
1550     only as follows:
1551
1552          0 = Stick-type (the default in xfig 2.1 and earlier)
1553          1 = Closed triangle:
1554                 |\
1555                 |  \
1556                 |    \
1557                 |    /
1558                 |  /
1559                 |/
1560          2 = Closed with "indented" butt:
1561                 |\
1562                 \  \
1563                  \   \
1564                   \    \
1565                   /    /
1566                  /   /
1567                 /  /
1568                 |/
1569          3 = Closed with "pointed" butt:
1570                    |\
1571                   /   \
1572                  /      \
1573                 /         \
1574                 \         /
1575                  \      /
1576                   \   /
1577                    |/
1578
1579     The arrow_style field is defined for LINES, ARCS and OPEN SPLINES
1580     only as follows:
1581
1582          0 = Hollow (actually filled with white)
1583          1 = Filled with pen_color
1584
1585  (3.0) OBJECT DEFINITION:
1586
1587     (3.1) Color Pseudo-objects (user-defined colors)
1588           This is used to define arbitrary colors beyond the 32 standard colors.
1589           The color objects must be defined before any other Fig objects.
1590
1591     First line:
1592         type    name                    (brief description)
1593         ----    ----                    -------------------
1594         int     object_code             (always 0)
1595         int     color_number            (color number, from 32-543 (512 total))
1596      hex string rgb values              (hexadecimal string describing red,
1597                                          green and blue values (e.g. #330099) )
1598
1599     (3.2) ARC
1600
1601     First line:
1602         type    name                    (brief description)
1603         ----    ----                    -------------------
1604         int     object_code             (always 5)
1605         int     sub_type                (0: pie-wedge (closed)
1606                                          1: open ended arc)
1607         int     line_style              (enumeration type)
1608         int     line_thickness          (1/80 inch)
1609         int     pen_color               (enumeration type, pen color)
1610         int     fill_color              (enumeration type, fill color)
1611         int     depth                   (enumeration type)
1612         int     pen_style               (pen style, not used)
1613         int     area_fill               (enumeration type, -1 = no fill)
1614         float   style_val               (1/80 inch)
1615         int     cap_style               (enumeration type)
1616         int     direction               (0: clockwise, 1: counterclockwise)
1617         int     forward_arrow           (0: no forward arrow, 1: on)
1618         int     backward_arrow          (0: no forward arrow, 1: on)
1619         float   center_x, center_y      (center of the arc)
1620         int     x1, y1                  (Fig units, the 1st point the user entered)
1621         int     x2, y2                  (Fig units, the 2nd point)
1622         int     x3, y3                  (Fig units, the last point)
1623
1624     Forward arrow line (Optional; absent if forward_arrow is 0):
1625         type    name                    (brief description)
1626         ----    ----                    -------------------
1627         int     arrow_type              (enumeration type)
1628         int     arrow_style             (enumeration type)
1629         float   arrow_thickness         (1/80 inch)
1630         float   arrow_width             (Fig units)
1631         float   arrow_height            (Fig units)
1632
1633     Backward arrow line (Optional; absent if backward_arrow is 0):
1634         type    name                    (brief description)
1635         ----    ----                    -------------------
1636         int     arrow_type              (enumeration type)
1637         int     arrow_style             (enumeration type)
1638         float   arrow_thickness         (1/80 inch)
1639         float   arrow_width             (Fig units)
1640         float   arrow_height            (Fig units)
1641
1642     (3.3) COMPOUND
1643
1644     A line with object code 6 signifies the start of a compound.
1645     There are four more numbers on this line which indicate the
1646     upper right corner and the lower left corner of the bounding
1647     box of this compound.  A line with object code -6 signifies
1648     the end of the compound.  Compound may be nested.
1649
1650     First line:
1651         type    name                    (brief description)
1652         ----    ----                    -------------------
1653         int     object_code             (always 6)
1654         int     upperright_corner_x     (Fig units)
1655         int     upperright_corner_y     (Fig units)
1656         int     lowerleft_corner_x      (Fig units)
1657         int     lowerleft_corner_y      (Fig units)
1658
1659     Subsequent lines:
1660         objects
1661         .
1662         .
1663
1664     Last line:
1665         -6
1666
1667     (3.4) ELLIPSE
1668
1669     First line:
1670         type    name                    (brief description)
1671         ----    ----                    -------------------
1672         int     object_code             (always 1)
1673         int     sub_type                (1: ellipse defined by radiuses
1674                                          2: ellipse defined by diameters
1675                                          3: circle defined by radius
1676                                          4: circle defined by diameter)
1677         int     line_style              (enumeration type)
1678         int     thickness               (1/80 inch)
1679         int     pen_color               (enumeration type, pen color)
1680         int     fill_color              (enumeration type, fill color)
1681         int     depth                   (enumeration type)
1682         int     pen_style               (pen style, not used)
1683         int     area_fill               (enumeration type, -1 = no fill)
1684         float   style_val               (1/80 inch)
1685         int     direction               (always 1)
1686         float   angle                   (radians, the angle of the x-axis)
1687         int     center_x, center_y      (Fig units)
1688         int     radius_x, radius_y      (Fig units)
1689         int     start_x, start_y        (Fig units; the 1st point entered)
1690         int     end_x, end_y            (Fig units; the last point entered)
1691
1692     (3.5) POLYLINE
1693
1694     First line:
1695         type    name                    (brief description)
1696         ----    ----                    -------------------
1697         int     object_code             (always 2)
1698         int     sub_type                (1: polyline
1699                                          2: box
1700                                          3: polygon
1701                                          4: arc-box)
1702                                          5: imported-picture bounding-box)
1703         int     line_style              (enumeration type)
1704         int     thickness               (1/80 inch)
1705         int     pen_color               (enumeration type, pen color)
1706         int     fill_color              (enumeration type, fill color)
1707         int     depth                   (enumeration type)
1708         int     pen_style               (pen style, not used)
1709         int     area_fill               (enumeration type, -1 = no fill)
1710         float   style_val               (1/80 inch)
1711         int     join_style              (enumeration type)
1712         int     cap_style               (enumeration type, only used for POLYLINE)
1713         int     radius                  (1/80 inch, radius of arc-boxes)
1714         int     forward_arrow           (0: off, 1: on)
1715         int     backward_arrow          (0: off, 1: on)
1716         int     npoints                 (number of points in line)
1717
1718     Forward arrow line: same as ARC object
1719
1720     Backward arrow line: same as ARC object
1721
1722     Points line:
1723         type    name                    (brief description)
1724         ----    ----                    -------------------
1725         int     x1, y1                  (Fig units)
1726         int     x2, y2                  (Fig units)
1727           .
1728           .
1729         int     xnpoints ynpoints       (this will be the same as the 1st
1730                                         point for polygon and box)
1731
1732     PIC line:
1733         type    name                    (brief description)
1734         ----    ----                    -------------------
1735         boolean flipped                 orientation = normal (0) or flipped (1)
1736         char    file[]                  name of picture file to import
1737
1738     (3.6) SPLINE
1739
1740     First line:
1741         type    name                    (brief description)
1742         ----    ----                    -------------------
1743         int     object_code             (always 3)
1744         int     sub_type                (0: open spline
1745                                          1: closed spline
1746                                          2: open interpolated spline
1747                                          3: closed interpolated spline)
1748         int     line_style              (See the end of this section)
1749         int     thickness               (1/80 inch)
1750         int     pen_color               (enumeration type, pen color)
1751         int     fill_color              (enumeration type, fill color)
1752         int     depth                   (enumeration type)
1753         int     pen_style               (pen style, not used)
1754         int     area_fill               (enumeration type, -1 = no fill)
1755         float   style_val               (1/80 inch)
1756         int     cap_style               (enumeration type, only used for open splines)
1757         int     forward_arrow           (0: off, 1: on)
1758         int     backward_arrow          (0: off, 1: on)
1759         int     npoints                 (number of control points in spline)
1760
1761     Forward arrow line: same as ARC object
1762
1763     Backward arrow line: same as ARC object
1764
1765     Points line: same as POLYLINE object
1766
1767     Control points line (absent if sub_type is 0 or 1):
1768         Control points of interpolated spline.  There are two control
1769         points for each knots.  A section i, of the spline is drawn
1770         using Bezier cubic with the following four points:
1771                 (x ,y ), (rx ,ry ), (lx   , ly   ), (x   , y   ).
1772                   i  i      i   i      i+1    i+1     i+1   i+1
1773         For closed interpolated spline the last pair of control points,
1774         (lxnpoints,lynpoints) and (rxnpoints,rynpoints) (which can be ignored),
1775         are the same as (lx1,ly1) and (rx1,ry1) respectively.
1776
1777         type    name                    (brief description)
1778         ----    ----                    -------------------
1779         float   lx1, ly1                (Fig units)
1780         float   rx1, ry1                (Fig units)
1781         float   lx2, ly2                (Fig units)
1782         float   rx2, ry2                (Fig units)
1783           .
1784           .
1785         float   lxnpoints, lynpoints    (Fig units)
1786         float   rxnpoints, rynpoints    (Fig units)
1787
1788     (3.7) TEXT
1789         type    name                    (brief description)
1790         ----    ----                    -------------------
1791         int     object                  (always 4)
1792         int     sub_type                (0: Left justified
1793                                          1: Center justified
1794                                          2: Right justified)
1795         int     color                   (enumeration type)
1796         int     depth                   (enumeration type)
1797         int     pen_style               (enumeration , not used)
1798         int     font                    (enumeration type)
1799         float   font_size               (font size in points)
1800         float   angle                   (radians, the angle of the text)
1801         int     font_flags              (bit vector)
1802         float   height                  (Fig units)
1803         float   length                  (Fig units)
1804         int     x, y                    (Fig units, coordinate of the origin
1805                                          of the string.  If sub_type = 0, it is
1806                                          the lower left corner of the string.
1807                                          If sub_type = 1, it is the lower
1808                                          center.  Otherwise it is the lower
1809                                          right corner of the string.)
1810         char    string[]                (ASCII characters; starts after a blank
1811                                          character following the last number and
1812                                          ends before the sequence '\001'.  This
1813                                          sequence is not part of the string.
1814                                          Characters above octal 177 are
1815                                          represented by \xxx where xxx is the
1816                                          octal value.  This permits Fig files to
1817                                          be edited with 7-bit editors and sent
1818                                          by e-mail without data loss.
1819                                          Note that the string may contain '\n'.)
1820
1821     The font_flags field is defined as follows:
1822
1823          Bit    Description
1824
1825           0     Rigid text (text doesn't scale when scaling compound objects)
1826           1     Special text (for LaTeX)
1827           2     PostScript font (otherwise LaTeX font is used)
1828           3     Hidden text
1829
1830     The font field is defined as follows:
1831
1832         For font_flags bit 2 = 0 (LaTeX fonts):
1833
1834          0      Default font
1835          1      Roman
1836          2      Bold
1837          3      Italic
1838          4      Sans Serif
1839          5      Typewriter
1840
1841         For font_flags bit 3 = 1 (PostScript fonts):
1842
1843         -1      Default font
1844          0      Times Roman
1845          1      Times Italic
1846          2      Times Bold
1847          3      Times Bold Italic
1848          4      AvantGarde Book
1849          5      AvantGarde Book Oblique
1850          6      AvantGarde Demi
1851          7      AvantGarde Demi Oblique
1852          8      Bookman Light
1853          9      Bookman Light Italic
1854         10      Bookman Demi
1855         11      Bookman Demi Italic
1856         12      Courier
1857         13      Courier Oblique
1858         14      Courier Bold
1859         15      Courier Bold Oblique
1860         16      Helvetica
1861         17      Helvetica Oblique
1862         18      Helvetica Bold
1863         19      Helvetica Bold Oblique
1864         20      Helvetica Narrow
1865         21      Helvetica Narrow Oblique
1866         22      Helvetica Narrow Bold
1867         23      Helvetica Narrow Bold Oblique
1868         24      New Century Schoolbook Roman
1869         25      New Century Schoolbook Italic
1870         26      New Century Schoolbook Bold
1871         27      New Century Schoolbook Bold Italic
1872         28      Palatino Roman
1873         29      Palatino Italic
1874         30      Palatino Bold
1875         31      Palatino Bold Italic
1876         32      Symbol
1877         33      Zapf Chancery Medium Italic
1878         34      Zapf Dingbats
1879 */
1880
1881 #endif