Initial release of Maemo 5 port of gnuplot
[gnuplot] / src / save.c
1 #ifndef lint
2 static char *RCSid() { return RCSid("$Id: save.c,v 1.132.2.14 2009/07/16 15:52:26 sfeam Exp $"); }
3 #endif
4
5 /* GNUPLOT - save.c */
6
7 /*[
8  * Copyright 1986 - 1993, 1998, 2004   Thomas Williams, Colin Kelley
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 #include "save.h"
38
39 #include "command.h"
40 #include "contour.h"
41 #include "datafile.h"
42 #include "eval.h"
43 #include "fit.h"
44 #include "gp_time.h"
45 #include "graphics.h"
46 #include "hidden3d.h"
47 #include "misc.h"
48 #include "plot2d.h"
49 #include "plot3d.h"
50 #include "setshow.h"
51 #include "term_api.h"
52 #include "util.h"
53 #include "variable.h"
54 #include "pm3d.h"
55 #include "getcolor.h"
56
57 static void save_functions__sub __PROTO((FILE *));
58 static void save_variables__sub __PROTO((FILE *));
59 static void save_tics __PROTO((FILE *, AXIS_INDEX));
60 static void save_position __PROTO((FILE *, struct position *, TBOOLEAN offset));
61 static void save_zeroaxis __PROTO((FILE *,AXIS_INDEX));
62 static void save_set_all __PROTO((FILE *));
63
64 /*
65  *  functions corresponding to the arguments of the GNUPLOT `save` command
66  */
67 void
68 save_functions(FILE *fp)
69 {
70     /* I _love_ information written at the top and the end
71      * of a human readable ASCII file. */
72     show_version(fp);
73     save_functions__sub(fp);
74     fputs("#    EOF\n", fp);
75 }
76
77
78 void
79 save_variables(FILE *fp)
80 {
81         show_version(fp);
82         save_variables__sub(fp);
83         fputs("#    EOF\n", fp);
84 }
85
86
87 void
88 save_set(FILE *fp)
89 {
90         show_version(fp);
91         save_set_all(fp);
92         fputs("#    EOF\n", fp);
93 }
94
95
96 void
97 save_all(FILE *fp)
98 {
99         show_version(fp);
100         save_set_all(fp);
101         save_functions__sub(fp);
102         save_variables__sub(fp);
103         fprintf(fp, "%s\n", replot_line);
104         if (wri_to_fil_last_fit_cmd(NULL)) {
105             fputs("## ", fp);
106             wri_to_fil_last_fit_cmd(fp);
107             putc('\n', fp);
108         }
109         fputs("#    EOF\n", fp);
110 }
111
112 /*
113  *  auxiliary functions
114  */
115
116 static void
117 save_functions__sub(FILE *fp)
118 {
119     struct udft_entry *udf = first_udf;
120
121     while (udf) {
122         if (udf->definition) {
123             fprintf(fp, "%s\n", udf->definition);
124         }
125         udf = udf->next_udf;
126     }
127 }
128
129 static void
130 save_variables__sub(FILE *fp)
131 {
132     /* always skip pi */
133     struct udvt_entry *udv = first_udv->next_udv;
134
135     while (udv) {
136         if (!udv->udv_undef) {
137             if (strncmp(udv->udv_name,"GPVAL_",6) 
138              && strncmp(udv->udv_name,"MOUSE_",6)
139              && strncmp(udv->udv_name,"NaN",4)) {
140                 fprintf(fp, "%s = ", udv->udv_name);
141                 disp_value(fp, &(udv->udv_value), TRUE);
142                 (void) putc('\n', fp);
143             }
144         }
145         udv = udv->next_udv;
146     }
147 }
148
149 /* HBB 19990823: new function 'save term'. This will be mainly useful
150  * for the typical 'set term post ... plot ... set term <normal term>
151  * sequence. It's the only 'save' function that will write the
152  * current term setting to a file uncommentedly. */
153 void
154 save_term(FILE *fp)
155 {
156         show_version(fp);
157
158         /* A possible gotcha: the default initialization often doesn't set
159          * term_options, but a 'set term <type>' without options doesn't
160          * reset the options to startup defaults. This may have to be
161          * changed on a per-terminal driver basis... */
162         if (term)
163             fprintf(fp, "set terminal %s %s\n", term->name, term_options);
164         else
165             fputs("set terminal unknown\n", fp);
166
167         /* output will still be written in commented form.  Otherwise, the
168          * risk of overwriting files is just too high */
169         if (outstr)
170             fprintf(fp, "# set output '%s'\n", outstr);
171         else
172             fputs("# set output\n", fp);
173         fputs("#    EOF\n", fp);
174 }
175
176
177 static void
178 save_set_all(FILE *fp)
179 {
180     struct text_label *this_label;
181     struct arrow_def *this_arrow;
182     struct linestyle_def *this_linestyle;
183     struct arrowstyle_def *this_arrowstyle;
184     legend_key *key = &keyT;
185
186     /* opinions are split as to whether we save term and outfile
187      * as a compromise, we output them as comments !
188      */
189     if (term)
190         fprintf(fp, "# set terminal %s %s\n", term->name, term_options);
191     else
192         fputs("# set terminal unknown\n", fp);
193
194     if (outstr)
195         fprintf(fp, "# set output '%s'\n", outstr);
196     else
197         fputs("# set output\n", fp);
198
199     fprintf(fp, "\
200 %sset clip points\n\
201 %sset clip one\n\
202 %sset clip two\n\
203 set bar %f\n",
204             (clip_points) ? "" : "un",
205             (clip_lines1) ? "" : "un",
206             (clip_lines2) ? "" : "un",
207             bar_size);
208
209     if (draw_border) {
210         fprintf(fp, "set border %d %s", draw_border, border_layer == 0 ? "back" : "front");
211         save_linetype(fp, &border_lp, FALSE);
212         fprintf(fp, "\n");
213     } else
214         fputs("unset border\n", fp);
215
216     fprintf(fp, "\
217 set xdata%s\n\
218 set ydata%s\n\
219 set zdata%s\n\
220 set x2data%s\n\
221 set y2data%s\n",
222             axis_array[FIRST_X_AXIS].is_timedata ? " time" : "",
223             axis_array[FIRST_Y_AXIS].is_timedata ? " time" : "",
224             axis_array[FIRST_Z_AXIS].is_timedata ? " time" : "",
225             axis_array[SECOND_X_AXIS].is_timedata ? " time" : "",
226             axis_array[SECOND_Y_AXIS].is_timedata ? " time" : "");
227
228 #define SAVE_TIMEFMT(axis)                                              \
229     if (strlen(axis_array[axis].timefmt))                               \
230         fprintf(fp, "set timefmt %s \"%s\"\n", axis_defaults[axis].name,\
231                 conv_text(axis_array[axis].timefmt));
232     SAVE_TIMEFMT(FIRST_X_AXIS);
233     SAVE_TIMEFMT(FIRST_Y_AXIS);
234     SAVE_TIMEFMT(FIRST_Z_AXIS);
235     SAVE_TIMEFMT(SECOND_X_AXIS);
236     SAVE_TIMEFMT(SECOND_Y_AXIS);
237     SAVE_TIMEFMT(COLOR_AXIS);
238 #undef SAVE_TIMEFMT
239
240     if (boxwidth < 0.0)
241         fputs("set boxwidth\n", fp);
242     else
243         fprintf(fp, "set boxwidth %g %s\n", boxwidth,
244                 (boxwidth_is_absolute) ? "absolute" : "relative");
245
246     fprintf(fp, "set style fill ");
247     save_fillstyle(fp, &default_fillstyle);
248
249 #ifdef EAM_OBJECTS
250     /* Default rectangle style */
251     fprintf(fp, "set style rectangle %s fc ",
252             default_rectangle.layer > 0 ? "front" : 
253             default_rectangle.layer < 0 ? "behind" : "back");
254     if (default_rectangle.lp_properties.use_palette)
255         save_pm3dcolor(fp, &default_rectangle.lp_properties.pm3d_color);
256     else
257         fprintf(fp, "lt %d",default_rectangle.lp_properties.l_type+1);
258     fprintf(fp, " fillstyle ");
259     save_fillstyle(fp, &default_rectangle.fillstyle);
260 #endif
261
262     if (dgrid3d)
263         fprintf(fp, "set dgrid3d %d,%d, %d\n",
264                 dgrid3d_row_fineness,
265                 dgrid3d_col_fineness,
266                 dgrid3d_norm_value);
267
268     fprintf(fp, "set dummy %s,%s\n", set_dummy_var[0], set_dummy_var[1]);
269
270 #define SAVE_FORMAT(axis)                                               \
271     fprintf(fp, "set format %s \"%s\"\n", axis_defaults[axis].name,     \
272             conv_text(axis_array[axis].formatstring));
273     SAVE_FORMAT(FIRST_X_AXIS );
274     SAVE_FORMAT(FIRST_Y_AXIS );
275     SAVE_FORMAT(SECOND_X_AXIS);
276     SAVE_FORMAT(SECOND_Y_AXIS);
277     SAVE_FORMAT(FIRST_Z_AXIS );
278     SAVE_FORMAT(COLOR_AXIS );
279 #undef SAVE_FORMAT
280
281     fprintf(fp, "set angles %s\n",
282             (ang2rad == 1.0) ? "radians" : "degrees");
283
284     /* Grid back/front controls tics also. Make sure it is saved */
285     if (grid_layer >= 0)
286         fprintf(fp,"set tics %s\n", grid_layer == 0 ? "back" : "front");
287     
288     if (! some_grid_selected())
289         fputs("unset grid\n", fp);
290     else {
291         if (polar_grid_angle)   /* set angle already output */
292             fprintf(fp, "set grid polar %f\n", polar_grid_angle / ang2rad);
293         else
294             fputs("set grid nopolar\n", fp);
295
296 #define SAVE_GRID(axis)                                 \
297         fprintf(fp, " %s%stics %sm%stics",              \
298                 axis_array[axis].gridmajor ? "" : "no", \
299                 axis_defaults[axis].name,               \
300                 axis_array[axis].gridminor ? "" : "no", \
301                 axis_defaults[axis].name);
302         fputs("set grid", fp);
303         SAVE_GRID(FIRST_X_AXIS);
304         SAVE_GRID(FIRST_Y_AXIS);
305         SAVE_GRID(FIRST_Z_AXIS);
306         fputs(" \\\n", fp);
307         SAVE_GRID(SECOND_X_AXIS);
308         SAVE_GRID(SECOND_Y_AXIS);
309         SAVE_GRID(COLOR_AXIS);
310         fputs("\n", fp);
311 #undef SAVE_GRID
312
313         fprintf(fp, "set grid %s  ", (grid_layer==-1) ? "layerdefault" : ((grid_layer==0) ? "back" : "front"));
314         save_linetype(fp, &grid_lp, FALSE);
315         fprintf(fp, ", ");
316         save_linetype(fp, &mgrid_lp, FALSE);
317         fputc('\n', fp);
318     }
319
320     fprintf(fp, "set key title \"%s\"\n", conv_text(key->title));
321     if (!(key->visible))
322         fputs("unset key\n", fp);
323     else {
324         fputs("set key ", fp);
325         switch (key->region) {
326         case GPKEY_AUTO_INTERIOR_LRTBC:
327             fputs("inside", fp);
328             break;
329         case GPKEY_AUTO_EXTERIOR_LRTBC:
330             fputs("outside", fp);
331             break;
332         case GPKEY_AUTO_EXTERIOR_MARGIN:
333             switch (key->margin) {
334             case GPKEY_TMARGIN:
335                 fputs("tmargin", fp);
336                 break;
337             case GPKEY_BMARGIN:
338                 fputs("bmargin", fp);
339                 break;
340             case GPKEY_LMARGIN:
341                 fputs("lmargin", fp);
342                 break;
343             case GPKEY_RMARGIN:
344                 fputs("rmargin", fp);
345                 break;
346             }
347             break;
348         case GPKEY_USER_PLACEMENT:
349             save_position(fp, &key->user_pos, FALSE);
350             break;
351         }
352         if (!(key->region == GPKEY_AUTO_EXTERIOR_MARGIN
353               && (key->margin == GPKEY_LMARGIN || key->margin == GPKEY_RMARGIN))) {
354             switch (key->hpos) {
355             case RIGHT:
356                 fputs(" right", fp);
357                 break;
358             case LEFT:
359                 fputs(" left", fp);
360                 break;
361             case CENTRE:
362                 fputs(" center", fp);
363                 break;
364             }
365         }
366         if (!(key->region == GPKEY_AUTO_EXTERIOR_MARGIN
367               && (key->margin == GPKEY_TMARGIN || key->margin == GPKEY_BMARGIN))) {
368             switch (key->vpos) {
369             case JUST_TOP:
370                 fputs(" top", fp);
371                 break;
372             case JUST_BOT:
373                 fputs(" bottom", fp);
374                 break;
375             case JUST_CENTRE:
376                 fputs(" center", fp);
377                 break;
378             }
379         }
380         fprintf(fp, " %s %s %sreverse %senhanced %s ",
381                 key->stack_dir == GPKEY_VERTICAL ? "vertical" : "horizontal",
382                 key->just == GPKEY_LEFT ? "Left" : "Right",
383                 key->reverse ? "" : "no",
384                 key->enhanced ? "" : "no",
385                 key->auto_titles == COLUMNHEAD_KEYTITLES ? "autotitles columnhead"
386                 : key->auto_titles == FILENAME_KEYTITLES ? "autotitles"
387                 : "noautotitles" );
388         if (key->box.l_type > LT_NODRAW) {
389             fputs("box", fp);
390             save_linetype(fp, &(key->box), FALSE);
391         } else
392             fputs("nobox", fp);
393         /* Put less common options on a separate line*/
394         fprintf(fp, "\nset key %sinvert samplen %g spacing %g width %g height %g ",
395                 key->invert ? "" : "no",
396                 key->swidth, key->vert_factor, key->width_fix, key->height_fix);
397         fputc('\n', fp);
398     }
399
400     fputs("unset label\n", fp);
401     for (this_label = first_label; this_label != NULL;
402          this_label = this_label->next) {
403         fprintf(fp, "set label %d \"%s\" at ",
404                 this_label->tag,
405                 conv_text(this_label->text));
406         save_position(fp, &this_label->place, FALSE);
407
408         switch (this_label->pos) {
409         case LEFT:
410             fputs(" left", fp);
411             break;
412         case CENTRE:
413             fputs(" centre", fp);
414             break;
415         case RIGHT:
416             fputs(" right", fp);
417             break;
418         }
419         if (this_label->rotate)
420             fprintf(fp, " rotate by %d", this_label->rotate);
421         else
422             fprintf(fp, " norotate");
423         if (this_label->font != NULL)
424             fprintf(fp, " font \"%s\"", this_label->font);
425         fprintf(fp, " %s", (this_label->layer==0) ? "back" : "front");
426         if (this_label->noenhanced)
427             fprintf(fp, " noenhanced");
428         save_textcolor(fp, &(this_label->textcolor));
429         if (this_label->lp_properties.pointflag == 0)
430             fprintf(fp, " nopoint");
431         else {
432             fprintf(fp, " point");
433             save_linetype(fp, &(this_label->lp_properties), TRUE);
434         }
435         save_position(fp, &this_label->offset, TRUE);
436         fputc('\n', fp);
437     }
438     fputs("unset arrow\n", fp);
439     for (this_arrow = first_arrow; this_arrow != NULL;
440          this_arrow = this_arrow->next) {
441         fprintf(fp, "set arrow %d from ", this_arrow->tag);
442         save_position(fp, &this_arrow->start, FALSE);
443         fputs(this_arrow->relative ? " rto " : " to ", fp);
444         save_position(fp, &this_arrow->end, FALSE);
445         fprintf(fp, " %s %s %s",
446                 arrow_head_names[this_arrow->arrow_properties.head],
447                 (this_arrow->arrow_properties.layer==0) ? "back" : "front",
448                 ( (this_arrow->arrow_properties.head_filled==2) ? "filled" :
449                   ( (this_arrow->arrow_properties.head_filled==1) ? "empty" :
450                     "nofilled" )) );
451         save_linetype(fp, &(this_arrow->arrow_properties.lp_properties), FALSE);
452         if (this_arrow->arrow_properties.head_length > 0) {
453             static char *msg[] = {"first", "second", "graph", "screen",
454                                   "character"};
455             fprintf(fp, " size %s %.3f,%.3f,%.3f",
456                     msg[this_arrow->arrow_properties.head_lengthunit],
457                     this_arrow->arrow_properties.head_length,
458                     this_arrow->arrow_properties.head_angle,
459                     this_arrow->arrow_properties.head_backangle);
460         }
461         fprintf(fp, "\n");
462     }
463     fprintf(fp, "set style increment %s\n", prefer_line_styles ? "userstyles" : "default");
464     fputs("unset style line\n", fp);
465     for (this_linestyle = first_linestyle; this_linestyle != NULL;
466          this_linestyle = this_linestyle->next) {
467         fprintf(fp, "set style line %d ", this_linestyle->tag);
468         save_linetype(fp, &(this_linestyle->lp_properties), TRUE);
469         fprintf(fp, "\n");
470     }
471     fputs("unset style arrow\n", fp);
472     for (this_arrowstyle = first_arrowstyle; this_arrowstyle != NULL;
473          this_arrowstyle = this_arrowstyle->next) {
474         fprintf(fp, "set style arrow %d", this_arrowstyle->tag);
475         fprintf(fp, " %s %s %s",
476                 arrow_head_names[this_arrowstyle->arrow_properties.head],
477                 (this_arrowstyle->arrow_properties.layer==0)?"back":"front",
478                 ( (this_arrowstyle->arrow_properties.head_filled==2)?"filled":
479                   ( (this_arrowstyle->arrow_properties.head_filled==1)?"empty":
480                     "nofilled" )) );
481         save_linetype(fp, &(this_arrowstyle->arrow_properties.lp_properties), FALSE);
482         if (this_arrowstyle->arrow_properties.head_length > 0) {
483             static char *msg[] = {"first", "second", "graph", "screen",
484                                   "character"};
485             fprintf(fp, " size %s %.3f,%.3f,%.3f",
486                     msg[this_arrowstyle->arrow_properties.head_lengthunit],
487                     this_arrowstyle->arrow_properties.head_length,
488                     this_arrowstyle->arrow_properties.head_angle,
489                     this_arrowstyle->arrow_properties.head_backangle);
490         }
491         fprintf(fp, "\n");
492     }
493
494 #ifdef EAM_HISTOGRAMS
495     fprintf(fp, "set style histogram ");
496     switch (histogram_opts.type) {
497         default:
498         case HT_CLUSTERED:
499             fprintf(fp,"clustered gap %d ",histogram_opts.gap); break;
500         case HT_ERRORBARS:
501             fprintf(fp,"errorbars gap %d lw %g",histogram_opts.gap,histogram_opts.bar_lw); break;
502         case HT_STACKED_IN_LAYERS:
503             fprintf(fp,"rowstacked "); break;
504         case HT_STACKED_IN_TOWERS:
505             fprintf(fp,"columnstacked "); break;
506     }
507     fprintf(fp,"title ");
508     save_position(fp, &histogram_opts.title.offset, TRUE);
509     fprintf(fp, "\n");
510 #endif
511
512 #ifdef EAM_OBJECTS
513     save_rectangle(fp, 0);
514 #endif
515
516     fputs("unset logscale\n", fp);
517 #define SAVE_LOG(axis)                                                  \
518     if (axis_array[axis].log)                                           \
519         fprintf(fp, "set logscale %s %g\n", axis_defaults[axis].name,   \
520                 axis_array[axis].base);
521     SAVE_LOG(FIRST_X_AXIS );
522     SAVE_LOG(FIRST_Y_AXIS );
523     SAVE_LOG(SECOND_X_AXIS);
524     SAVE_LOG(SECOND_Y_AXIS);
525     SAVE_LOG(FIRST_Z_AXIS );
526     SAVE_LOG(COLOR_AXIS );
527 #undef SAVE_LOG
528
529     /* FIXME */
530     fprintf(fp, "\
531 set offsets %g, %g, %g, %g\n\
532 set pointsize %g\n\
533 set encoding %s\n\
534 %sset polar\n\
535 %sset parametric\n",
536             loff, roff, toff, boff,
537             pointsize,
538             encoding_names[encoding],
539             (polar) ? "" : "un",
540             (parametric) ? "" : "un");
541     if (decimalsign != NULL) {
542 #ifdef HAVE_LOCALE_H
543         fprintf(fp, "set decimalsign locale \"%s\"\n", setlocale(LC_NUMERIC,NULL));
544 #endif
545         fprintf(fp, "set decimalsign '%s'\n", decimalsign);
546     } else
547         fprintf(fp, "unset decimalsign\n");
548
549     fputs("set view ", fp);
550     if (splot_map == TRUE)
551         fputs("map", fp);
552     else {
553         fprintf(fp, "%g, %g, %g, %g",
554             surface_rot_x, surface_rot_z, surface_scale, surface_zscale);
555     }
556     fprintf(fp, "  %s", aspect_ratio_3D == 2 ? "equal xy" :
557                         aspect_ratio_3D == 3 ? "equal xyz": "");
558
559     fprintf(fp, "\n\
560 set samples %d, %d\n\
561 set isosamples %d, %d\n\
562 %sset surface\n\
563 %sset contour",
564             samples_1, samples_2,
565             iso_samples_1, iso_samples_2,
566             (draw_surface) ? "" : "un",
567             (draw_contour) ? "" : "un");
568
569     switch (draw_contour) {
570     case CONTOUR_NONE:
571         fputc('\n', fp);
572         break;
573     case CONTOUR_BASE:
574         fputs(" base\n", fp);
575         break;
576     case CONTOUR_SRF:
577         fputs(" surface\n", fp);
578         break;
579     case CONTOUR_BOTH:
580         fputs(" both\n", fp);
581         break;
582     }
583     if (label_contours)
584         fprintf(fp, "set clabel '%s'\n", contour_format);
585     else
586         fputs("unset clabel\n", fp);
587
588 #ifdef GP_MACROS
589     if (expand_macros)
590         fputs("set macros\n", fp);
591 #endif
592
593     fputs("set mapping ", fp);
594     switch (mapping3d) {
595     case MAP3D_SPHERICAL:
596         fputs("spherical\n", fp);
597         break;
598     case MAP3D_CYLINDRICAL:
599         fputs("cylindrical\n", fp);
600         break;
601     case MAP3D_CARTESIAN:
602     default:
603         fputs("cartesian\n", fp);
604         break;
605     }
606
607     if (missing_val != NULL)
608         fprintf(fp, "set datafile missing '%s'\n", missing_val);
609     if (df_separator != '\0')
610         fprintf(fp, "set datafile separator \"%c\"\n",df_separator);
611     else
612         fprintf(fp, "set datafile separator whitespace\n");
613     if (strcmp(df_commentschars, DEFAULT_COMMENTS_CHARS))
614         fprintf(fp, "set datafile commentschars '%s'\n", df_commentschars);
615     if (df_fortran_constants)
616         fprintf(fp, "set datafile fortran\n");
617
618     save_hidden3doptions(fp);
619     fprintf(fp, "set cntrparam order %d\n", contour_order);
620     fputs("set cntrparam ", fp);
621     switch (contour_kind) {
622     case CONTOUR_KIND_LINEAR:
623         fputs("linear\n", fp);
624         break;
625     case CONTOUR_KIND_CUBIC_SPL:
626         fputs("cubicspline\n", fp);
627         break;
628     case CONTOUR_KIND_BSPLINE:
629         fputs("bspline\n", fp);
630         break;
631     }
632     fputs("set cntrparam levels ", fp);
633     switch (contour_levels_kind) {
634     case LEVELS_AUTO:
635         fprintf(fp, "auto %d\n", contour_levels);
636         break;
637     case LEVELS_INCREMENTAL:
638         fprintf(fp, "incremental %g,%g,%g\n",
639                 contour_levels_list[0], contour_levels_list[1],
640                 contour_levels_list[0] + contour_levels_list[1] * contour_levels);
641         break;
642     case LEVELS_DISCRETE:
643         {
644             int i;
645             fprintf(fp, "discrete %g", contour_levels_list[0]);
646             for (i = 1; i < contour_levels; i++)
647                 fprintf(fp, ",%g ", contour_levels_list[i]);
648             fputc('\n', fp);
649         }
650     }
651     fprintf(fp, "\
652 set cntrparam points %d\n\
653 set size ratio %g %g,%g\n\
654 set origin %g,%g\n",
655             contour_pts,
656             aspect_ratio, xsize, ysize,
657             xoffset, yoffset);
658
659     fprintf(fp, "set style data ");
660     save_data_func_style(fp,"data",data_style);
661     fprintf(fp, "set style function ");
662     save_data_func_style(fp,"function",func_style);
663
664     save_zeroaxis(fp, FIRST_X_AXIS);
665     save_zeroaxis(fp, FIRST_Y_AXIS);
666     save_zeroaxis(fp, FIRST_Z_AXIS);
667     save_zeroaxis(fp, SECOND_X_AXIS);
668     save_zeroaxis(fp, SECOND_Y_AXIS);
669
670     if (xyplane.absolute)
671         fprintf(fp, "set xyplane at %g\n", xyplane.xyplane_z);
672     else
673         fprintf(fp, "set ticslevel %g\n", xyplane.ticslevel);
674
675 #define SAVE_MINI(axis)                                                 \
676     switch(axis_array[axis].minitics & TICS_MASK) {                     \
677     case 0:                                                             \
678         fprintf(fp, "set nom%stics\n", axis_defaults[axis].name);       \
679         break;                                                          \
680     case MINI_AUTO:                                                     \
681         fprintf(fp, "set m%stics\n", axis_defaults[axis].name);         \
682         break;                                                          \
683     case MINI_DEFAULT:                                                  \
684         fprintf(fp, "set m%stics default\n", axis_defaults[axis].name); \
685         break;                                                          \
686     case MINI_USER:                                                     \
687         fprintf(fp, "set m%stics %f\n", axis_defaults[axis].name,       \
688                 axis_array[axis].mtic_freq);                            \
689         break;                                                          \
690     }
691
692     SAVE_MINI(FIRST_X_AXIS);
693     SAVE_MINI(FIRST_Y_AXIS);
694     SAVE_MINI(FIRST_Z_AXIS);    /* HBB 20000506: noticed mztics were not saved! */
695     SAVE_MINI(SECOND_X_AXIS);
696     SAVE_MINI(SECOND_Y_AXIS);
697     SAVE_MINI(COLOR_AXIS);
698 #undef SAVE_MINI
699
700     save_tics(fp, FIRST_X_AXIS);
701     save_tics(fp, FIRST_Y_AXIS);
702     save_tics(fp, FIRST_Z_AXIS);
703     save_tics(fp, SECOND_X_AXIS);
704     save_tics(fp, SECOND_Y_AXIS);
705     save_tics(fp, COLOR_AXIS);
706
707 #define SAVE_AXISLABEL_OR_TITLE(name,suffix,lab)                         \
708     {                                                                    \
709         fprintf(fp, "set %s%s \"%s\" ",                                  \
710                 name, suffix, lab.text ? conv_text(lab.text) : "");      \
711         fprintf(fp, "\nset %s%s ", name, suffix);                        \
712         save_position(fp, &(lab.offset), TRUE);                          \
713         fprintf(fp, " font \"%s\"", lab.font ? conv_text(lab.font) : "");\
714         save_textcolor(fp, &(lab.textcolor));                            \
715         if (lab.rotate)                                                  \
716             fprintf(fp, " rotate by %d", lab.rotate);                    \
717         else                                                             \
718             fprintf(fp, " norotate");                                    \
719         fprintf(fp, "%s\n", (lab.noenhanced) ? " noenhanced" : "");      \
720     }
721
722     SAVE_AXISLABEL_OR_TITLE("", "title", title);
723
724     /* FIXME */
725     fprintf(fp, "set timestamp %s \n", timelabel_bottom ? "bottom" : "top");
726     SAVE_AXISLABEL_OR_TITLE("", "timestamp", timelabel);
727
728     save_range(fp, R_AXIS);
729     save_range(fp, T_AXIS);
730     save_range(fp, U_AXIS);
731     save_range(fp, V_AXIS);
732
733 #define SAVE_AXISLABEL(axis)                                    \
734     SAVE_AXISLABEL_OR_TITLE(axis_defaults[axis].name,"label",   \
735                             axis_array[axis].label)
736
737     SAVE_AXISLABEL(FIRST_X_AXIS);
738     SAVE_AXISLABEL(SECOND_X_AXIS);
739     save_range(fp, FIRST_X_AXIS);
740     save_range(fp, SECOND_X_AXIS);
741
742     SAVE_AXISLABEL(FIRST_Y_AXIS);
743     SAVE_AXISLABEL(SECOND_Y_AXIS);
744     if (splot_map == FALSE) {
745         save_range(fp, FIRST_Y_AXIS);
746         save_range(fp, SECOND_Y_AXIS);
747     } else { /* 'set view map' uses flipped y-axes */
748         splot_map_deactivate();
749         save_range(fp, FIRST_Y_AXIS);
750         save_range(fp, SECOND_Y_AXIS);
751         splot_map_activate();
752     }
753
754     SAVE_AXISLABEL(FIRST_Z_AXIS);
755     save_range(fp, FIRST_Z_AXIS);
756
757     SAVE_AXISLABEL(COLOR_AXIS);
758     save_range(fp, COLOR_AXIS);
759 #undef SAVE_AXISLABEL
760 #undef SAVE_AXISLABEL_OR_TITLE
761
762     fprintf(fp, "set zero %g\n", zero);
763
764     fprintf(fp, "set lmargin %s %g\n",
765             lmargin.scalex == screen ? "at screen" : "", lmargin.x);
766     fprintf(fp, "set bmargin %s %g\n",
767             bmargin.scalex == screen ? "at screen" : "", bmargin.x);
768     fprintf(fp, "set rmargin %s %g\n",
769             rmargin.scalex == screen ? "at screen" : "", rmargin.x);
770     fprintf(fp, "set tmargin %s %g\n",
771             tmargin.scalex == screen ? "at screen" : "", tmargin.x);
772
773     fprintf(fp, "set locale \"%s\"\n", get_locale());
774
775     fputs("set pm3d ", fp);
776     fputs((PM3D_IMPLICIT == pm3d.implicit ? "implicit" : "explicit"), fp);
777     fprintf(fp, " at %s\n", pm3d.where);
778     fputs("set pm3d ", fp);
779     switch (pm3d.direction) {
780     case PM3D_SCANS_AUTOMATIC: fputs("scansautomatic\n", fp); break;
781     case PM3D_SCANS_FORWARD: fputs("scansforward\n", fp); break;
782     case PM3D_SCANS_BACKWARD: fputs("scansbackward\n", fp); break;
783     case PM3D_DEPTH: fputs("depthorder\n", fp); break;
784     }
785     fprintf(fp, "set pm3d interpolate %d,%d", pm3d.interp_i, pm3d.interp_j);
786     fputs(" flush ", fp);
787     switch (pm3d.flush) {
788     case PM3D_FLUSH_CENTER: fputs("center", fp); break;
789     case PM3D_FLUSH_BEGIN: fputs("begin", fp); break;
790     case PM3D_FLUSH_END: fputs("end", fp); break;
791     }
792     fputs((pm3d.ftriangles ? " " : " no"), fp);
793     fputs("ftriangles", fp);
794     if (pm3d.hidden3d_tag) fprintf(fp," hidden3d %d", pm3d.hidden3d_tag);
795         else fputs(" nohidden3d", fp);
796 #if PM3D_HAVE_SOLID
797     fputs((pm3d.solid ? " solid" : " transparent"), fp);
798 #endif
799     fputs(" corners2color ", fp);
800     switch (pm3d.which_corner_color) {
801         case PM3D_WHICHCORNER_MEAN:    fputs("mean", fp); break;
802         case PM3D_WHICHCORNER_GEOMEAN: fputs("geomean", fp); break;
803         case PM3D_WHICHCORNER_MEDIAN:  fputs("median", fp); break;
804         case PM3D_WHICHCORNER_MIN:     fputs("min", fp); break;
805         case PM3D_WHICHCORNER_MAX:     fputs("max", fp); break;
806         default: /* PM3D_WHICHCORNER_C1 ... _C4 */
807              fprintf(fp, "c%i", pm3d.which_corner_color - PM3D_WHICHCORNER_C1 + 1);
808     }
809     fputs("\n", fp);
810
811     /*
812      *  Save palette information
813      */
814
815     fprintf( fp, "set palette %s %s maxcolors %d ",
816              sm_palette.positive==SMPAL_POSITIVE ? "positive" : "negative",
817              sm_palette.ps_allcF ? "ps_allcF" : "nops_allcF",
818         sm_palette.use_maxcolors);
819     fprintf( fp, "gamma %g ", sm_palette.gamma );
820     if (sm_palette.colorMode == SMPAL_COLOR_MODE_GRAY) {
821       fputs( "gray\n", fp );
822     }
823     else {
824       fputs( "color model ", fp );
825       switch( sm_palette.cmodel ) {
826         case C_MODEL_RGB: fputs( "RGB ", fp ); break;
827         case C_MODEL_HSV: fputs( "HSV ", fp ); break;
828         case C_MODEL_CMY: fputs( "CMY ", fp ); break;
829         case C_MODEL_YIQ: fputs( "YIQ ", fp ); break;
830         case C_MODEL_XYZ: fputs( "XYZ ", fp ); break;
831         default:
832           fprintf( stderr, "%s:%d ooops: Unknown color model '%c'.\n",
833                    __FILE__, __LINE__, (char)(sm_palette.cmodel) );
834       }
835       fputs( "\nset palette ", fp );
836       switch( sm_palette.colorMode ) {
837       case SMPAL_COLOR_MODE_RGB:
838         fprintf( fp, "rgbformulae %d, %d, %d\n", sm_palette.formulaR,
839                  sm_palette.formulaG, sm_palette.formulaB );
840         break;
841       case SMPAL_COLOR_MODE_GRADIENT: {
842         int i=0;
843         fprintf( fp, "defined (" );
844         for( i=0; i<sm_palette.gradient_num; ++i ) {
845           fprintf( fp, " %.4g %.4g %.4g %.4g", sm_palette.gradient[i].pos,
846                    sm_palette.gradient[i].col.r, sm_palette.gradient[i].col.g,
847                    sm_palette.gradient[i].col.b );
848           if (i<sm_palette.gradient_num-1)  {
849               fputs( ",", fp);
850               if (i==2 || i%4==2)  fputs( "\\\n    ", fp );
851           }
852         }
853         fputs( " )\n", fp );
854         break;
855       }
856       case SMPAL_COLOR_MODE_FUNCTIONS:
857         fprintf( fp, "functions %s, %s, %s\n", sm_palette.Afunc.definition,
858                  sm_palette.Bfunc.definition, sm_palette.Cfunc.definition );
859         break;
860       default:
861         fprintf( stderr, "%s:%d ooops: Unknown color mode '%c'.\n",
862                  __FILE__, __LINE__, (char)(sm_palette.colorMode) );
863       }
864     }
865
866     /*
867      *  Save colorbox info
868      */
869     if (color_box.where != SMCOLOR_BOX_NO)
870         fprintf(fp,"set colorbox %s\n", color_box.where==SMCOLOR_BOX_DEFAULT ? "default" : "user");
871     fprintf(fp, "set colorbox %sal origin ", color_box.rotation ==  'v' ? "vertic" : "horizont");
872     save_position(fp, &color_box.origin, FALSE);
873     fputs(" size ", fp);
874     save_position(fp, &color_box.size, FALSE);
875     fprintf(fp, " %s ", color_box.layer ==  LAYER_FRONT ? "front" : "back");
876     if (color_box.border == 0) fputs("noborder", fp);
877         else if (color_box.border_lt_tag < 0) fputs("bdefault", fp);
878                  else fprintf(fp, "border %d", color_box.border_lt_tag);
879     if (color_box.where == SMCOLOR_BOX_NO) fputs("\nunset colorbox\n", fp);
880         else fputs("\n", fp);
881
882     fputs("set loadpath ", fp);
883     {
884         char *s;
885         while ((s = save_loadpath()) != NULL)
886             fprintf(fp, "\"%s\" ", s);
887         fputc('\n', fp);
888     }
889
890     fputs("set fontpath ", fp);
891     {
892         char *s;
893         while ((s = save_fontpath()) != NULL)
894             fprintf(fp, "\"%s\" ", s);
895         fputc('\n', fp);
896     }
897
898     /* HBB NEW 20020927: fit logfile name option */
899 #if GP_FIT_ERRVARS
900     fprintf(fp, "set fit %serrorvariables",
901             fit_errorvariables ? "" : "no");
902     if (fitlogfile) {
903         fprintf(fp, " logfile \'%s\'", fitlogfile);
904     }
905     fputc('\n', fp);
906 #else
907     if (fitlogfile) {
908         fprintf(fp, "set fit logfile \'%s\'\n", fitlogfile);
909     }
910 #endif /* GP_FIT_ERRVARS */
911
912 }
913
914 static void
915 save_tics(FILE *fp, AXIS_INDEX axis)
916 {
917     if ((axis_array[axis].ticmode & TICS_MASK) == NO_TICS) {
918         fprintf(fp, "set no%stics\n", axis_defaults[axis].name);
919         return;
920     }
921     fprintf(fp, "set %stics %s %s scale %g,%g %smirror %s ",
922             axis_defaults[axis].name,
923             ((axis_array[axis].ticmode & TICS_MASK) == TICS_ON_AXIS)
924             ? "axis" : "border",
925             (axis_array[axis].tic_in) ? "in" : "out",
926             axis_array[axis].ticscale, axis_array[axis].miniticscale,
927             (axis_array[axis].ticmode & TICS_MIRROR) ? "" : "no",
928             axis_array[axis].tic_rotate ? "rotate" : "norotate");
929     if (axis_array[axis].tic_rotate)
930         fprintf(fp,"by %d ",axis_array[axis].tic_rotate);
931     save_position(fp, &axis_array[axis].ticdef.offset, TRUE);
932     fprintf(fp, "\nset %stics ", axis_defaults[axis].name);
933     switch (axis_array[axis].ticdef.type) {
934     case TIC_COMPUTED:{
935             fputs("autofreq ", fp);
936             break;
937         }
938     case TIC_MONTH:{
939             fprintf(fp, "\nset %smtics", axis_defaults[axis].name);
940             break;
941         }
942     case TIC_DAY:{
943             fprintf(fp, "\nset %sdtics", axis_defaults[axis].name);
944             break;
945         }
946     case TIC_SERIES:
947         if (axis_array[axis].ticdef.def.series.start != -VERYLARGE) {
948             SAVE_NUM_OR_TIME(fp,
949                              (double) axis_array[axis].ticdef.def.series.start,
950                              axis);
951             putc(',', fp);
952         }
953         fprintf(fp, "%g", axis_array[axis].ticdef.def.series.incr);
954         if (axis_array[axis].ticdef.def.series.end != VERYLARGE) {
955             putc(',', fp);
956             SAVE_NUM_OR_TIME(fp,
957                              (double) axis_array[axis].ticdef.def.series.end,
958                              axis);
959         }
960         break;
961     case TIC_USER:
962         break;
963     }
964
965     fprintf(fp, (axis_array[axis].ticdef.rangelimited)?" rangelimit":" norangelimit");
966
967     if (axis_array[axis].ticdef.font && *axis_array[axis].ticdef.font)
968         fprintf(fp, " font \"%s\"", axis_array[axis].ticdef.font);
969
970     if (axis_array[axis].ticdef.textcolor.type != TC_DEFAULT)
971         save_textcolor(fp, &axis_array[axis].ticdef.textcolor);
972
973     putc('\n', fp);
974
975     if (axis_array[axis].ticdef.def.user) { 
976         struct ticmark *t;
977         fprintf(fp, "set %stics %s ", axis_defaults[axis].name,
978                 (axis_array[axis].ticdef.type == TIC_USER) ? "" : "add");
979         fputs(" (", fp);
980         for (t = axis_array[axis].ticdef.def.user; t != NULL; t = t->next) {
981             if (t->level < 0)   /* Don't save ticlabels read from data file */
982                 continue;
983             if (t->label)
984                 fprintf(fp, "\"%s\" ", conv_text(t->label));
985             SAVE_NUM_OR_TIME(fp, (double) t->position, axis);
986             if (t->level)
987                 fprintf(fp, " %d", t->level);
988             if (t->next) {
989                 fputs(", ", fp);
990             }
991         }
992         fputs(")\n", fp);
993     }
994
995 }
996
997 static void
998 save_position(FILE *fp, struct position *pos, TBOOLEAN offset)
999 {
1000     static const char *msg[] = { "first ", "second ", "graph ", "screen ",
1001                                  "character "};
1002  
1003     assert(first_axes == 0 && second_axes == 1 && graph == 2 && screen == 3 &&
1004            character == 4);
1005
1006     if (offset)
1007         fprintf(fp, " offset ");
1008
1009     fprintf(fp, "%s%g, %s%g, %s%g",
1010             pos->scalex == first_axes ? "" : msg[pos->scalex], pos->x,
1011             pos->scaley == pos->scalex ? "" : msg[pos->scaley], pos->y,
1012             pos->scalez == pos->scaley ? "" : msg[pos->scalez], pos->z);
1013 }
1014
1015
1016 void
1017 save_range(FILE *fp, AXIS_INDEX axis)
1018 {
1019     fprintf(fp, "set %srange [ ", axis_defaults[axis].name);
1020     if (axis_array[axis].set_autoscale & AUTOSCALE_MIN) {
1021         putc('*', fp);
1022     } else {
1023         SAVE_NUM_OR_TIME(fp, axis_array[axis].set_min, axis);
1024     }
1025     fputs(" : ", fp);
1026     if (axis_array[axis].set_autoscale & AUTOSCALE_MAX) {
1027         putc('*', fp);
1028     } else {
1029         SAVE_NUM_OR_TIME(fp, axis_array[axis].set_max, axis);
1030     }
1031
1032     fprintf(fp, " ] %sreverse %swriteback",
1033             axis_array[axis].range_flags & RANGE_REVERSE ? "" : "no",
1034             axis_array[axis].range_flags & RANGE_WRITEBACK ? "" : "no");
1035
1036     if (axis_array[axis].set_autoscale) {
1037         /* add current (hidden) range as comments */
1038         fputs("  # (currently [", fp);
1039         if (axis_array[axis].set_autoscale & AUTOSCALE_MIN) {
1040             SAVE_NUM_OR_TIME(fp, axis_array[axis].set_min, axis);
1041         }
1042         putc(':', fp);
1043         if (axis_array[axis].set_autoscale & AUTOSCALE_MAX) {
1044             SAVE_NUM_OR_TIME(fp, axis_array[axis].set_max, axis);
1045         }
1046         fputs("] )\n", fp);
1047
1048         if (axis_array[axis].set_autoscale & (AUTOSCALE_FIXMIN))
1049             fprintf(fp, "set autoscale %sfixmin\n", axis_defaults[axis].name);
1050         if (axis_array[axis].set_autoscale & AUTOSCALE_FIXMAX)
1051             fprintf(fp, "set autoscale %sfixmax\n", axis_defaults[axis].name);
1052     } else
1053         putc('\n', fp);
1054 }
1055
1056 static void
1057 save_zeroaxis(FILE *fp, AXIS_INDEX axis)
1058 {
1059     fprintf(fp, "set %szeroaxis", axis_defaults[axis].name);
1060     save_linetype(fp, &(axis_array[axis].zeroaxis), FALSE);
1061     putc('\n', fp);
1062 }
1063
1064 void
1065 save_fillstyle(FILE *fp, const struct fill_style_type *fs)
1066 {
1067     switch(fs->fillstyle) {
1068     case FS_SOLID:
1069         fprintf(fp, " solid %.2f ", fs->filldensity / 100.0);
1070         break;
1071     case FS_PATTERN:
1072         fprintf(fp, " pattern %d ", fs->fillpattern);
1073         break;
1074     case FS_DEFAULT:
1075         fprintf(fp, " default\n");
1076         return;
1077     default:
1078         fprintf(fp, " empty ");
1079         break;
1080     }
1081     if (fs->border_linetype == LT_NODRAW)
1082         fprintf(fp, "noborder\n");
1083     else if (fs->border_linetype == LT_UNDEFINED)
1084         fprintf(fp, "border\n");
1085     else
1086         fprintf(fp, "border %d\n",fs->border_linetype+1);
1087 }
1088
1089 void
1090 save_textcolor(FILE *fp, const struct t_colorspec *tc)
1091 {
1092     if (tc->type) {
1093         fprintf(fp, " textcolor");
1094         save_pm3dcolor(fp, tc);
1095     }
1096 }
1097
1098
1099 void
1100 save_pm3dcolor(FILE *fp, const struct t_colorspec *tc)
1101 {
1102     if (tc->type) {
1103         switch(tc->type) {
1104         case TC_LT:   fprintf(fp," lt %d", tc->lt+1);
1105                       break;
1106         case TC_LINESTYLE:   fprintf(fp," linestyle %d", tc->lt);
1107                       break;
1108         case TC_Z:    fprintf(fp," palette z");
1109                       break;
1110         case TC_CB:   fprintf(fp," palette cb %g", tc->value);
1111                       break;
1112         case TC_FRAC: fprintf(fp," palette fraction %4.2f", tc->value);
1113                       break;
1114         case TC_RGB:  {
1115                       const char *color = reverse_table_lookup(pm3d_color_names_tbl, tc->lt);
1116                       if (color)
1117                         fprintf(fp," rgb \"%s\" ", color);
1118                       else
1119                         fprintf(fp," rgb \"#%6.6x\" ", tc->lt);
1120                       break;
1121                       }
1122         default:      break;
1123         }
1124     }
1125 }
1126
1127 void
1128 save_data_func_style(FILE *fp, const char *which, enum PLOT_STYLE style)
1129 {
1130     switch (style) {
1131     case LINES:
1132         fputs("lines\n", fp);
1133         break;
1134     case POINTSTYLE:
1135         fputs("points\n", fp);
1136         break;
1137     case IMPULSES:
1138         fputs("impulses\n", fp);
1139         break;
1140     case LINESPOINTS:
1141         fputs("linespoints\n", fp);
1142         break;
1143     case DOTS:
1144         fputs("dots\n", fp);
1145         break;
1146     case YERRORLINES:
1147         fputs("yerrorlines\n", fp);
1148         break;
1149     case XERRORLINES:
1150         fputs("xerrorlines\n", fp);
1151         break;
1152     case XYERRORLINES:
1153         fputs("xyerrorlines\n", fp);
1154         break;
1155     case YERRORBARS:
1156         fputs("yerrorbars\n", fp);
1157         break;
1158     case XERRORBARS:
1159         fputs("xerrorbars\n", fp);
1160         break;
1161     case XYERRORBARS:
1162         fputs("xyerrorbars\n", fp);
1163         break;
1164     case BOXES:
1165         fputs("boxes\n", fp);
1166         break;
1167 #ifdef EAM_HISTOGRAMS
1168     case HISTOGRAMS:
1169         fputs("histograms\n", fp);
1170         break;
1171 #endif
1172     case FILLEDCURVES:
1173         fputs("filledcurves ", fp);
1174         if (!strcmp(which, "data") || !strcmp(which, "Data"))
1175             filledcurves_options_tofile(&filledcurves_opts_data, fp);
1176         else
1177             filledcurves_options_tofile(&filledcurves_opts_func, fp);
1178         fputc('\n', fp);
1179         break;
1180     case BOXERROR:
1181         fputs("boxerrorbars\n", fp);
1182         break;
1183     case BOXXYERROR:
1184         fputs("boxxyerrorbars\n", fp);
1185         break;
1186     case STEPS:
1187         fputs("steps\n", fp);
1188         break;                  /* JG */
1189     case FSTEPS:
1190         fputs("fsteps\n", fp);
1191         break;                  /* HOE */
1192     case HISTEPS:
1193         fputs("histeps\n", fp);
1194         break;                  /* CAC */
1195     case VECTOR:
1196         fputs("vector\n", fp);
1197         break;
1198     case FINANCEBARS:
1199         fputs("financebars\n", fp);
1200         break;
1201     case CANDLESTICKS:
1202         fputs("candlesticks\n", fp);
1203         break;
1204     case PM3DSURFACE:
1205         fputs("pm3d\n", fp);
1206         break;
1207 #ifdef EAM_DATASTRINGS
1208     case LABELPOINTS:
1209         fputs("labels\n", fp);
1210         break;
1211 #endif
1212 #ifdef WITH_IMAGE
1213     case IMAGE:
1214         fputs("image\n", stderr);
1215         break;
1216     case RGBIMAGE:
1217         fputs("rgbimage\n", stderr);
1218         break;
1219 #endif
1220     default:
1221         fputs("---error!---\n", fp);
1222     }
1223 }
1224
1225 void
1226 save_linetype(FILE *fp, lp_style_type *lp, TBOOLEAN show_point)
1227 {
1228
1229     fprintf(fp, " linetype %d", lp->l_type + 1);
1230     if (lp->use_palette) {
1231         fprintf(fp, " linecolor");
1232         if (lp->pm3d_color.type == TC_LT)
1233             fprintf(fp, " %d", lp->pm3d_color.lt+1);
1234         else
1235             save_pm3dcolor(fp,&(lp->pm3d_color));
1236     }
1237     fprintf(fp, " linewidth %.3f", lp->l_width);
1238
1239     if (show_point && lp->pointflag) {
1240         fprintf(fp, " pointtype %d", lp->p_type + 1);
1241         if (lp->p_size == PTSZ_VARIABLE)
1242             fprintf(fp, " pointsize variable");
1243         else if (lp->p_size == PTSZ_DEFAULT)
1244             fprintf(fp, " pointsize default");
1245         else
1246             fprintf(fp, " pointsize %.3f", lp->p_size);
1247     }
1248         
1249 }
1250
1251 #ifdef EAM_OBJECTS
1252
1253 /* Save/show rectangle <tag> (0 means show all) */
1254 void
1255 save_rectangle(FILE *fp, int tag)
1256 {
1257     t_object *this_object;
1258     t_rectangle *this_rect;
1259     TBOOLEAN showed = FALSE;
1260
1261     for (this_object = first_object; this_object != NULL; this_object = this_object->next) {
1262         if (this_object->object_type == OBJ_RECTANGLE)
1263             this_rect = &this_object->o.rectangle;
1264         else
1265             continue;
1266         if (tag == 0 || tag == this_object->tag) {
1267             showed = TRUE;
1268             fprintf(fp, "%sobject %2d rect ", (fp==stderr) ? "\t" : "set ",this_object->tag);
1269
1270             if (this_rect->type == 1) {
1271                 fprintf(fp, "center ");
1272                 save_position(fp, &this_rect->center, FALSE);
1273                 fprintf(fp, " size ");
1274                 save_position(fp, &this_rect->extent, FALSE);
1275             } else {
1276                 fprintf(fp, "from ");
1277                 save_position(fp, &this_rect->bl, FALSE);
1278                 fprintf(fp, " to ");
1279                 save_position(fp, &this_rect->tr, FALSE);
1280             }
1281
1282             fprintf(fp, " %s ", this_object->layer > 0 ? "front" : this_object->layer < 0 ? "behind" : "back");
1283             if (this_object->lp_properties.l_width)
1284                 fprintf(fp, "lw %.1f ",this_object->lp_properties.l_width);
1285             fprintf(fp, "fc ");
1286             if (this_object->lp_properties.l_type == LT_DEFAULT)
1287                 fprintf(fp,"default");
1288             else if (this_object->lp_properties.use_palette)
1289                 save_pm3dcolor(fp, &this_object->lp_properties.pm3d_color);
1290             else
1291                 fprintf(fp, "lt %d",this_object->lp_properties.l_type+1);
1292             fprintf(fp, " fillstyle ");
1293             save_fillstyle(fp, &this_object->fillstyle);
1294         }
1295     }
1296     if (tag > 0 && !showed)
1297         int_error(c_token, "rect not found");
1298 }
1299
1300 #endif
1301