1 /* GNUPLOT - save.c */
2
3 /*[
4 * Copyright 1986 - 1993, 1998, 2004 Thomas Williams, Colin Kelley
5 *
6 * Permission to use, copy, and distribute this software and its
7 * documentation for any purpose with or without fee is hereby granted,
8 * provided that the above copyright notice appear in all copies and
9 * that both that copyright notice and this permission notice appear
10 * in supporting documentation.
11 *
12 * Permission to modify the software is granted, but not the right to
13 * distribute the complete modified source code. Modifications are to
14 * be distributed as patches to the released version. Permission to
15 * distribute binaries produced by compiling modified sources is granted,
16 * provided you
17 * 1. distribute the corresponding source modifications from the
18 * released version in the form of a patch file along with the binaries,
19 * 2. add special version identification to distinguish your version
20 * in addition to the base release version number,
21 * 3. provide your name and address as the primary contact for the
22 * support of your modified version, and
23 * 4. retain our contact information in regard to use of the base
24 * software.
25 * Permission to distribute the released version of the source code along
26 * with corresponding source modifications in the form of a patch file is
27 * granted with same provisions 2 through 4 for binary distributions.
28 *
29 * This software is provided "as is" without express or implied warranty
30 * to the extent permitted by applicable law.
31 ]*/
32
33 #include "save.h"
34
35 #include "command.h"
36 #include "contour.h"
37 #include "datafile.h"
38 #include "eval.h"
39 #include "fit.h"
40 #include "gp_time.h"
41 #include "graphics.h"
42 #include "hidden3d.h"
43 #include "jitter.h"
44 #include "misc.h"
45 #include "plot2d.h"
46 #include "plot3d.h"
47 #include "setshow.h"
48 #include "term_api.h"
49 #include "util.h"
50 #include "variable.h"
51 #include "pm3d.h"
52 #include "getcolor.h"
53
54 static void save_functions__sub(FILE *);
55 static void save_variables__sub(FILE *);
56 static void save_tics(FILE *, struct axis *);
57 static void save_mtics(FILE *, struct axis *);
58 static void save_zeroaxis(FILE *,AXIS_INDEX);
59 static void save_set_all(FILE *);
60 static void save_justification(int just, FILE *fp);
61
62 const char *coord_msg[] = {"first ", "second ", "graph ", "screen ", "character ", "polar "};
63 /*
64 * functions corresponding to the arguments of the GNUPLOT `save` command
65 */
66 void
save_functions(FILE * fp)67 save_functions(FILE *fp)
68 {
69 /* I _love_ information written at the top and the end
70 * of a human readable ASCII file. */
71 show_version(fp);
72 save_functions__sub(fp);
73 fputs("# EOF\n", fp);
74 }
75
76
77 void
save_variables(FILE * fp)78 save_variables(FILE *fp)
79 {
80 show_version(fp);
81 save_variables__sub(fp);
82 fputs("# EOF\n", fp);
83 }
84
85
86 void
save_set(FILE * fp)87 save_set(FILE *fp)
88 {
89 show_version(fp);
90 save_set_all(fp);
91 fputs("# EOF\n", fp);
92 }
93
94
95 void
save_all(FILE * fp)96 save_all(FILE *fp)
97 {
98 show_version(fp);
99 save_set_all(fp);
100 save_functions__sub(fp);
101 save_variables__sub(fp);
102 if (df_filename)
103 fprintf(fp, "## Last datafile plotted: \"%s\"\n", df_filename);
104 fprintf(fp, "%s\n", replot_line);
105 if (wri_to_fil_last_fit_cmd(NULL)) {
106 fputs("## ", fp);
107 wri_to_fil_last_fit_cmd(fp);
108 putc('\n', fp);
109 }
110 fputs("# EOF\n", fp);
111 }
112
113 /*
114 * auxiliary functions
115 */
116
117 static void
save_functions__sub(FILE * fp)118 save_functions__sub(FILE *fp)
119 {
120 struct udft_entry *udf = first_udf;
121
122 while (udf) {
123 if (udf->definition) {
124 fprintf(fp, "%s\n", udf->definition);
125 }
126 udf = udf->next_udf;
127 }
128 }
129
130 static void
save_variables__sub(FILE * fp)131 save_variables__sub(FILE *fp)
132 {
133 /* always skip pi */
134 struct udvt_entry *udv = first_udv->next_udv;
135
136 while (udv) {
137 if (udv->udv_value.type != NOTDEFINED) {
138 if ((udv->udv_value.type == ARRAY)
139 && strncmp(udv->udv_name,"ARGV",4)) {
140 fprintf(fp,"array %s[%d] = ", udv->udv_name,
141 (int)(udv->udv_value.v.value_array[0].v.int_val));
142 save_array_content(fp, udv->udv_value.v.value_array);
143 } else if (strncmp(udv->udv_name,"GPVAL_",6)
144 && strncmp(udv->udv_name,"GPFUN_",6)
145 && strncmp(udv->udv_name,"MOUSE_",6)
146 && strncmp(udv->udv_name,"$",1)
147 && (strncmp(udv->udv_name,"ARG",3) || (strlen(udv->udv_name) != 4))
148 && strncmp(udv->udv_name,"NaN",4)) {
149 fprintf(fp, "%s = ", udv->udv_name);
150 disp_value(fp, &(udv->udv_value), TRUE);
151 (void) putc('\n', fp);
152 }
153 }
154 udv = udv->next_udv;
155 }
156 }
157
158 void
save_array_content(FILE * fp,struct value * array)159 save_array_content(FILE *fp, struct value *array)
160 {
161 int i;
162 int size = array[0].v.int_val;
163 fprintf(fp, "[");
164 for (i=1; i<=size; i++) {
165 if (array[i].type != NOTDEFINED)
166 disp_value(fp, &(array[i]), TRUE);
167 if (i < size)
168 fprintf(fp, ",");
169 }
170 fprintf(fp, "]\n");
171 }
172
173 /* HBB 19990823: new function 'save term'. This will be mainly useful
174 * for the typical 'set term post ... plot ... set term <normal term>
175 * sequence. It's the only 'save' function that will write the
176 * current term setting to a file uncommentedly. */
177 void
save_term(FILE * fp)178 save_term(FILE *fp)
179 {
180 show_version(fp);
181
182 /* A possible gotcha: the default initialization often doesn't set
183 * term_options, but a 'set term <type>' without options doesn't
184 * reset the options to startup defaults. This may have to be
185 * changed on a per-terminal driver basis... */
186 if (term)
187 fprintf(fp, "set terminal %s %s\n", term->name, term_options);
188 else
189 fputs("set terminal unknown\n", fp);
190
191 /* output will still be written in commented form. Otherwise, the
192 * risk of overwriting files is just too high */
193 if (outstr)
194 fprintf(fp, "# set output '%s'\n", outstr);
195 else
196 fputs("# set output\n", fp);
197 fputs("# EOF\n", fp);
198 }
199
200 /* helper function */
201 void
save_axis_label_or_title(FILE * fp,char * name,char * suffix,struct text_label * label,TBOOLEAN savejust)202 save_axis_label_or_title(FILE *fp, char *name, char *suffix,
203 struct text_label *label, TBOOLEAN savejust)
204 {
205 fprintf(fp, "set %s%s \"%s\" ",
206 name, suffix, label->text ? conv_text(label->text) : "");
207 fprintf(fp, "\nset %s%s ", name, suffix);
208 save_position(fp, &(label->offset), 3, TRUE);
209 fprintf(fp, " font \"%s\"", label->font ? conv_text(label->font) : "");
210 save_textcolor(fp, &(label->textcolor));
211 if (savejust && (label->pos != CENTRE)) save_justification(label->pos,fp);
212 if (label->tag == ROTATE_IN_3D_LABEL_TAG)
213 fprintf(fp, " rotate parallel");
214 else if (label->rotate == TEXT_VERTICAL)
215 fprintf(fp, " rotate");
216 else if (label->rotate)
217 fprintf(fp, " rotate by %d", label->rotate);
218 else
219 fprintf(fp, " norotate");
220
221 if (label == &title && label->boxed) {
222 fprintf(fp," boxed ");
223 if (label->boxed > 0)
224 fprintf(fp,"bs %d ",label->boxed);
225 }
226 fprintf(fp, "%s\n", (label->noenhanced) ? " noenhanced" : "");
227 }
228
229 static void
save_justification(int just,FILE * fp)230 save_justification(int just, FILE *fp)
231 {
232 switch (just) {
233 case RIGHT:
234 fputs(" right", fp);
235 break;
236 case LEFT:
237 fputs(" left", fp);
238 break;
239 case CENTRE:
240 fputs(" center", fp);
241 break;
242 }
243 }
244
245 static void
save_set_all(FILE * fp)246 save_set_all(FILE *fp)
247 {
248 struct text_label *this_label;
249 struct arrow_def *this_arrow;
250 struct linestyle_def *this_linestyle;
251 struct arrowstyle_def *this_arrowstyle;
252 legend_key *key = &keyT;
253 int axis;
254
255 /* opinions are split as to whether we save term and outfile
256 * as a compromise, we output them as comments !
257 */
258 if (term)
259 fprintf(fp, "# set terminal %s %s\n", term->name, term_options);
260 else
261 fputs("# set terminal unknown\n", fp);
262
263 if (outstr)
264 fprintf(fp, "# set output '%s'\n", outstr);
265 else
266 fputs("# set output\n", fp);
267
268 fprintf(fp, "\
269 %sset clip points\n\
270 %sset clip one\n\
271 %sset clip two\n\
272 %sset clip radial\n",
273 (clip_points) ? "" : "un",
274 (clip_lines1) ? "" : "un",
275 (clip_lines2) ? "" : "un",
276 (clip_radial) ? "" : "un"
277 );
278
279 save_bars(fp);
280
281 if (draw_border) {
282 fprintf(fp, "set border %d %s", draw_border,
283 border_layer == LAYER_BEHIND ? "behind" : border_layer == LAYER_BACK ? "back" : "front");
284 save_linetype(fp, &border_lp, FALSE);
285 fprintf(fp, "\n");
286 } else
287 fputs("unset border\n", fp);
288
289 for (axis = 0; axis < NUMBER_OF_MAIN_VISIBLE_AXES; axis++) {
290 if (axis == SAMPLE_AXIS) continue;
291 if (axis == COLOR_AXIS) continue;
292 if (axis == POLAR_AXIS) continue;
293 fprintf(fp, "set %sdata %s\n", axis_name(axis),
294 axis_array[axis].datatype == DT_TIMEDATE ? "time" :
295 axis_array[axis].datatype == DT_DMS ? "geographic" :
296 "");
297 }
298
299 if (boxwidth < 0.0)
300 fputs("set boxwidth\n", fp);
301 else
302 fprintf(fp, "set boxwidth %g %s\n", boxwidth,
303 (boxwidth_is_absolute) ? "absolute" : "relative");
304 fprintf(fp, "set boxdepth %g\n", boxdepth > 0 ? boxdepth : 0.0);
305
306 fprintf(fp, "set style fill ");
307 save_fillstyle(fp, &default_fillstyle);
308
309 /* Default rectangle style */
310 fprintf(fp, "set style rectangle %s fc ",
311 default_rectangle.layer > 0 ? "front" :
312 default_rectangle.layer < 0 ? "behind" : "back");
313 save_pm3dcolor(fp, &default_rectangle.lp_properties.pm3d_color);
314 fprintf(fp, " fillstyle ");
315 save_fillstyle(fp, &default_rectangle.fillstyle);
316
317 /* Default circle properties */
318 fprintf(fp, "set style circle radius ");
319 save_position(fp, &default_circle.o.circle.extent, 1, FALSE);
320 fputs(" \n", fp);
321
322 /* Default ellipse properties */
323 fprintf(fp, "set style ellipse size ");
324 save_position(fp, &default_ellipse.o.ellipse.extent, 2, FALSE);
325 fprintf(fp, " angle %g ", default_ellipse.o.ellipse.orientation);
326 fputs("units ", fp);
327 switch (default_ellipse.o.ellipse.type) {
328 case ELLIPSEAXES_XY:
329 fputs("xy\n", fp);
330 break;
331 case ELLIPSEAXES_XX:
332 fputs("xx\n", fp);
333 break;
334 case ELLIPSEAXES_YY:
335 fputs("yy\n", fp);
336 break;
337 }
338
339 if (dgrid3d) {
340 if (dgrid3d_mode == DGRID3D_QNORM) {
341 fprintf(fp, "set dgrid3d %d,%d, %d\n",
342 dgrid3d_row_fineness,
343 dgrid3d_col_fineness,
344 dgrid3d_norm_value);
345 } else if (dgrid3d_mode == DGRID3D_SPLINES) {
346 fprintf(fp, "set dgrid3d %d,%d splines\n",
347 dgrid3d_row_fineness, dgrid3d_col_fineness );
348 } else {
349 fprintf(fp, "set dgrid3d %d,%d %s%s %f,%f\n",
350 dgrid3d_row_fineness,
351 dgrid3d_col_fineness,
352 reverse_table_lookup(dgrid3d_mode_tbl, dgrid3d_mode),
353 dgrid3d_kdensity ? " kdensity2d" : "",
354 dgrid3d_x_scale,
355 dgrid3d_y_scale );
356 }
357 }
358
359 /* Dummy variable names */
360 fprintf(fp, "set dummy %s", set_dummy_var[0]);
361 for (axis=1; axis<MAX_NUM_VAR; axis++) {
362 if (*set_dummy_var[axis] == '\0')
363 break;
364 fprintf(fp, ", %s", set_dummy_var[axis]);
365 }
366 fprintf(fp, "\n");
367
368 save_axis_format(fp, FIRST_X_AXIS );
369 save_axis_format(fp, FIRST_Y_AXIS );
370 save_axis_format(fp, SECOND_X_AXIS);
371 save_axis_format(fp, SECOND_Y_AXIS);
372 save_axis_format(fp, FIRST_Z_AXIS );
373 save_axis_format(fp, COLOR_AXIS);
374 save_axis_format(fp, POLAR_AXIS);
375 fprintf(fp, "set ttics format \"%s\"\n", THETA_AXIS.formatstring);
376
377 fprintf(fp, "set timefmt \"%s\"\n", timefmt);
378
379 fprintf(fp, "set angles %s\n",
380 (ang2rad == 1.0) ? "radians" : "degrees");
381
382 fprintf(fp,"set tics %s\n", grid_tics_in_front ? "front" : "back");
383
384 if (! some_grid_selected())
385 fputs("unset grid\n", fp);
386 else {
387 if (polar_grid_angle) /* set angle already output */
388 fprintf(fp, "set grid polar %f\n", polar_grid_angle / ang2rad);
389 else
390 fputs("set grid nopolar\n", fp);
391
392 #define SAVE_GRID(axis) \
393 fprintf(fp, " %s%stics %sm%stics", \
394 axis_array[axis].gridmajor ? "" : "no", \
395 axis_name(axis), \
396 axis_array[axis].gridminor ? "" : "no", \
397 axis_name(axis));
398 fputs("set grid", fp);
399 SAVE_GRID(FIRST_X_AXIS);
400 SAVE_GRID(FIRST_Y_AXIS);
401 SAVE_GRID(FIRST_Z_AXIS);
402 SAVE_GRID(POLAR_AXIS);
403 fputs(" \\\n", fp);
404 SAVE_GRID(SECOND_X_AXIS);
405 SAVE_GRID(SECOND_Y_AXIS);
406 SAVE_GRID(COLOR_AXIS);
407 fputs("\n", fp);
408 #undef SAVE_GRID
409
410 fprintf(fp, "set grid %s%s ",
411 (grid_vertical_lines) ? "vertical " : "",
412 (grid_layer==-1) ? "layerdefault" : ((grid_layer==0) ? "back" : "front"));
413 save_linetype(fp, &grid_lp, FALSE);
414 fprintf(fp, ", ");
415 save_linetype(fp, &mgrid_lp, FALSE);
416 fputc('\n', fp);
417 }
418 fprintf(fp, "%sset raxis\n", raxis ? "" : "un");
419
420 /* Theta axis origin and direction */
421 fprintf(fp, "set theta %s %s\n",
422 theta_direction > 0 ? "counterclockwise" : "clockwise",
423 theta_origin == 180 ? "left" : theta_origin == 90 ? "top" :
424 theta_origin == -90 ? "bottom" : "right");
425
426 /* Save parallel axis state */
427 save_style_parallel(fp);
428
429 if (key->title.text == NULL)
430 fprintf(fp, "set key notitle\n");
431 else {
432 fprintf(fp, "set key title \"%s\"", conv_text(key->title.text));
433 if (key->title.font)
434 fprintf(fp, " font \"%s\" ", key->title.font);
435 save_justification(key->title.pos, fp);
436 fputs("\n", fp);
437 }
438
439 fputs("set key ", fp);
440 switch (key->region) {
441 case GPKEY_AUTO_INTERIOR_LRTBC:
442 fputs(key->fixed ? "fixed" : "inside", fp);
443 break;
444 case GPKEY_AUTO_EXTERIOR_LRTBC:
445 fputs("outside", fp);
446 break;
447 case GPKEY_AUTO_EXTERIOR_MARGIN:
448 switch (key->margin) {
449 case GPKEY_TMARGIN:
450 fputs("tmargin", fp);
451 break;
452 case GPKEY_BMARGIN:
453 fputs("bmargin", fp);
454 break;
455 case GPKEY_LMARGIN:
456 fputs("lmargin", fp);
457 break;
458 case GPKEY_RMARGIN:
459 fputs("rmargin", fp);
460 break;
461 }
462 break;
463 case GPKEY_USER_PLACEMENT:
464 fputs("at ", fp);
465 save_position(fp, &key->user_pos, 2, FALSE);
466 break;
467 }
468 if (!(key->region == GPKEY_AUTO_EXTERIOR_MARGIN
469 && (key->margin == GPKEY_LMARGIN || key->margin == GPKEY_RMARGIN))) {
470 save_justification(key->hpos, fp);
471 }
472 if (!(key->region == GPKEY_AUTO_EXTERIOR_MARGIN
473 && (key->margin == GPKEY_TMARGIN || key->margin == GPKEY_BMARGIN))) {
474 switch (key->vpos) {
475 case JUST_TOP:
476 fputs(" top", fp);
477 break;
478 case JUST_BOT:
479 fputs(" bottom", fp);
480 break;
481 case JUST_CENTRE:
482 fputs(" center", fp);
483 break;
484 }
485 }
486 fprintf(fp, " %s %s %sreverse %senhanced %s ",
487 key->stack_dir == GPKEY_VERTICAL ? "vertical" : "horizontal",
488 key->just == GPKEY_LEFT ? "Left" : "Right",
489 key->reverse ? "" : "no",
490 key->enhanced ? "" : "no",
491 key->auto_titles == COLUMNHEAD_KEYTITLES ? "autotitle columnhead"
492 : key->auto_titles == FILENAME_KEYTITLES ? "autotitle"
493 : "noautotitle" );
494 if (key->box.l_type > LT_NODRAW) {
495 fputs("box", fp);
496 save_linetype(fp, &(key->box), FALSE);
497 } else
498 fputs("nobox", fp);
499
500 /* These are for the key entries, not the key title */
501 if (key->font)
502 fprintf(fp, " font \"%s\"", key->font);
503 if (key->textcolor.type != TC_LT || key->textcolor.lt != LT_BLACK)
504 save_textcolor(fp, &key->textcolor);
505
506 /* Put less common options on separate lines */
507 fprintf(fp, "\nset key %sinvert samplen %g spacing %g width %g height %g ",
508 key->invert ? "" : "no",
509 key->swidth, key->vert_factor, key->width_fix, key->height_fix);
510 fprintf(fp, "\nset key maxcolumns %d maxrows %d",key->maxcols,key->maxrows);
511 fputc('\n', fp);
512 fprintf(fp, "set key %sopaque\n", key->front ? "" : "no");
513
514 if (!(key->visible))
515 fputs("unset key\n", fp);
516
517 fputs("unset label\n", fp);
518 for (this_label = first_label; this_label != NULL;
519 this_label = this_label->next) {
520 fprintf(fp, "set label %d \"%s\" at ",
521 this_label->tag,
522 conv_text(this_label->text));
523 save_position(fp, &this_label->place, 3, FALSE);
524 if (this_label->hypertext)
525 fprintf(fp, " hypertext");
526
527 save_justification(this_label->pos, fp);
528 if (this_label->rotate)
529 fprintf(fp, " rotate by %d", this_label->rotate);
530 else
531 fprintf(fp, " norotate");
532 if (this_label->font != NULL)
533 fprintf(fp, " font \"%s\"", this_label->font);
534 fprintf(fp, " %s", (this_label->layer==0) ? "back" : "front");
535 if (this_label->noenhanced)
536 fprintf(fp, " noenhanced");
537 save_textcolor(fp, &(this_label->textcolor));
538 if ((this_label->lp_properties.flags & LP_SHOW_POINTS) == 0)
539 fprintf(fp, " nopoint");
540 else {
541 fprintf(fp, " point");
542 save_linetype(fp, &(this_label->lp_properties), TRUE);
543 }
544 save_position(fp, &this_label->offset, 3, TRUE);
545 if (this_label->boxed) {
546 fprintf(fp," boxed ");
547 if (this_label->boxed > 0)
548 fprintf(fp,"bs %d ",this_label->boxed);
549 }
550 fputc('\n', fp);
551 }
552 fputs("unset arrow\n", fp);
553 for (this_arrow = first_arrow; this_arrow != NULL;
554 this_arrow = this_arrow->next) {
555 fprintf(fp, "set arrow %d from ", this_arrow->tag);
556 save_position(fp, &this_arrow->start, 3, FALSE);
557 if (this_arrow->type == arrow_end_absolute) {
558 fputs(" to ", fp);
559 save_position(fp, &this_arrow->end, 3, FALSE);
560 } else if (this_arrow->type == arrow_end_absolute) {
561 fputs(" rto ", fp);
562 save_position(fp, &this_arrow->end, 3, FALSE);
563 } else { /* type arrow_end_oriented */
564 struct position *e = &this_arrow->end;
565 fputs(" length ", fp);
566 fprintf(fp, "%s%g", e->scalex == first_axes ? "" : coord_msg[e->scalex], e->x);
567 fprintf(fp, " angle %g", this_arrow->angle);
568 }
569 fprintf(fp, " %s %s %s",
570 arrow_head_names[this_arrow->arrow_properties.head],
571 (this_arrow->arrow_properties.layer==0) ? "back" : "front",
572 (this_arrow->arrow_properties.headfill==AS_FILLED) ? "filled" :
573 (this_arrow->arrow_properties.headfill==AS_EMPTY) ? "empty" :
574 (this_arrow->arrow_properties.headfill==AS_NOBORDER) ? "noborder" :
575 "nofilled");
576 save_linetype(fp, &(this_arrow->arrow_properties.lp_properties), FALSE);
577 if (this_arrow->arrow_properties.head_length > 0) {
578 fprintf(fp, " size %s %.3f,%.3f,%.3f",
579 coord_msg[this_arrow->arrow_properties.head_lengthunit],
580 this_arrow->arrow_properties.head_length,
581 this_arrow->arrow_properties.head_angle,
582 this_arrow->arrow_properties.head_backangle);
583 }
584 fprintf(fp, "\n");
585 }
586
587 /* Mostly for backwards compatibility */
588 if (prefer_line_styles)
589 fprintf(fp, "set style increment userstyles\n");
590 fputs("unset style line\n", fp);
591 for (this_linestyle = first_linestyle; this_linestyle != NULL;
592 this_linestyle = this_linestyle->next) {
593 fprintf(fp, "set style line %d ", this_linestyle->tag);
594 save_linetype(fp, &(this_linestyle->lp_properties), TRUE);
595 fprintf(fp, "\n");
596 }
597
598 fputs("unset style arrow\n", fp);
599 for (this_arrowstyle = first_arrowstyle; this_arrowstyle != NULL;
600 this_arrowstyle = this_arrowstyle->next) {
601 fprintf(fp, "set style arrow %d", this_arrowstyle->tag);
602 fprintf(fp, " %s %s %s",
603 arrow_head_names[this_arrowstyle->arrow_properties.head],
604 (this_arrowstyle->arrow_properties.layer==0)?"back":"front",
605 (this_arrowstyle->arrow_properties.headfill==AS_FILLED)?"filled":
606 (this_arrowstyle->arrow_properties.headfill==AS_EMPTY)?"empty":
607 (this_arrowstyle->arrow_properties.headfill==AS_NOBORDER)?"noborder":
608 "nofilled");
609 save_linetype(fp, &(this_arrowstyle->arrow_properties.lp_properties), FALSE);
610 if (this_arrowstyle->arrow_properties.head_length > 0) {
611 fprintf(fp, " size %s %.3f,%.3f,%.3f",
612 coord_msg[this_arrowstyle->arrow_properties.head_lengthunit],
613 this_arrowstyle->arrow_properties.head_length,
614 this_arrowstyle->arrow_properties.head_angle,
615 this_arrowstyle->arrow_properties.head_backangle);
616 if (this_arrowstyle->arrow_properties.head_fixedsize) {
617 fputs(" ", fp);
618 fputs(" fixed", fp);
619 }
620 }
621 fprintf(fp, "\n");
622 }
623
624 fprintf(fp, "set style histogram ");
625 save_histogram_opts(fp);
626
627 save_pixmaps(fp);
628
629 fprintf(fp, "unset object\n");
630 save_object(fp, 0);
631 fprintf(fp, "unset walls\n");
632 save_walls(fp);
633
634 save_style_textbox(fp);
635
636 save_offsets(fp, "set offsets");
637
638 fprintf(fp, "\
639 set pointsize %g\n\
640 set pointintervalbox %g\n\
641 set encoding %s\n\
642 %sset polar\n\
643 %sset parametric\n",
644 pointsize, pointintervalbox,
645 encoding_names[encoding],
646 (polar) ? "" : "un",
647 (parametric) ? "" : "un");
648
649 if (spiderplot) {
650 fprintf(fp, "set spiderplot\n");
651 save_style_spider(fp);
652 } else
653 fprintf(fp, "unset spiderplot\n");
654
655 if (numeric_locale)
656 fprintf(fp, "set decimalsign locale \"%s\"\n", numeric_locale);
657 if (decimalsign != NULL)
658 fprintf(fp, "set decimalsign '%s'\n", decimalsign);
659 if (!numeric_locale && !decimalsign)
660 fprintf(fp, "unset decimalsign\n");
661
662 fprintf(fp, "%sset micro\n", use_micro ? "" : "un");
663 fprintf(fp, "%sset minussign\n", use_minus_sign ? "" : "un");
664
665 fputs("set view ", fp);
666 if (splot_map == TRUE)
667 fprintf(fp, "map scale %g", mapview_scale);
668 else if (xz_projection)
669 fprintf(fp, "projection xz");
670 else if (yz_projection)
671 fprintf(fp, "projection yz");
672 else {
673 fprintf(fp, "%g, %g, %g, %g",
674 surface_rot_x, surface_rot_z, surface_scale, surface_zscale);
675 fprintf(fp, "\nset view azimuth %g", azimuth);
676 }
677 if (aspect_ratio_3D)
678 fprintf(fp, "\nset view %s", aspect_ratio_3D == 2 ? "equal xy" :
679 aspect_ratio_3D == 3 ? "equal xyz": "");
680
681 fprintf(fp, "\nset rgbmax %g", rgbmax);
682
683 fprintf(fp, "\n\
684 set samples %d, %d\n\
685 set isosamples %d, %d\n\
686 %sset surface %s",
687 samples_1, samples_2,
688 iso_samples_1, iso_samples_2,
689 (draw_surface) ? "" : "un",
690 (implicit_surface) ? "" : "explicit");
691
692 fprintf(fp, "\n\
693 %sset contour", (draw_contour) ? "" : "un");
694 switch (draw_contour) {
695 case CONTOUR_NONE:
696 fputc('\n', fp);
697 break;
698 case CONTOUR_BASE:
699 fputs(" base\n", fp);
700 break;
701 case CONTOUR_SRF:
702 fputs(" surface\n", fp);
703 break;
704 case CONTOUR_BOTH:
705 fputs(" both\n", fp);
706 break;
707 }
708
709 /* Contour label options */
710 fprintf(fp, "set cntrlabel %s format '%s' font '%s' start %d interval %d\n",
711 clabel_onecolor ? "onecolor" : "", contour_format,
712 clabel_font ? clabel_font : "",
713 clabel_start, clabel_interval);
714
715 fputs("set mapping ", fp);
716 switch (mapping3d) {
717 case MAP3D_SPHERICAL:
718 fputs("spherical\n", fp);
719 break;
720 case MAP3D_CYLINDRICAL:
721 fputs("cylindrical\n", fp);
722 break;
723 case MAP3D_CARTESIAN:
724 default:
725 fputs("cartesian\n", fp);
726 break;
727 }
728
729 if (missing_val != NULL)
730 fprintf(fp, "set datafile missing '%s'\n", missing_val);
731 if (df_separators)
732 fprintf(fp, "set datafile separator \"%s\"\n",df_separators);
733 else
734 fprintf(fp, "set datafile separator whitespace\n");
735 if (strcmp(df_commentschars, DEFAULT_COMMENTS_CHARS))
736 fprintf(fp, "set datafile commentschars '%s'\n", df_commentschars);
737 if (df_fortran_constants)
738 fprintf(fp, "set datafile fortran\n");
739 if (df_nofpe_trap)
740 fprintf(fp, "set datafile nofpe_trap\n");
741 fprintf(fp, "set datafile %scolumnheaders\n", df_columnheaders ? "" : "no");
742
743 save_hidden3doptions(fp);
744 fprintf(fp, "set cntrparam order %d\n", contour_order);
745 fputs("set cntrparam ", fp);
746 switch (contour_kind) {
747 case CONTOUR_KIND_LINEAR:
748 fputs("linear\n", fp);
749 break;
750 case CONTOUR_KIND_CUBIC_SPL:
751 fputs("cubicspline\n", fp);
752 break;
753 case CONTOUR_KIND_BSPLINE:
754 fputs("bspline\n", fp);
755 break;
756 }
757 fprintf(fp, "set cntrparam levels %d\nset cntrparam levels ", contour_levels);
758 switch (contour_levels_kind) {
759 case LEVELS_AUTO:
760 fprintf(fp, "auto");
761 break;
762 case LEVELS_INCREMENTAL:
763 fprintf(fp, "incremental %g,%g",
764 contour_levels_list[0], contour_levels_list[1]);
765 break;
766 case LEVELS_DISCRETE:
767 {
768 int i;
769 fprintf(fp, "discrete %g", contour_levels_list[0]);
770 for (i = 1; i < contour_levels; i++)
771 fprintf(fp, ",%g ", contour_levels_list[i]);
772 }
773 }
774 fprintf(fp, "\nset cntrparam firstlinetype %d", contour_firstlinetype);
775 fprintf(fp, " %ssorted\n", contour_sortlevels ? "" : "un");
776 fprintf(fp, "\
777 set cntrparam points %d\n\
778 set size ratio %g %g,%g\n\
779 set origin %g,%g\n",
780 contour_pts,
781 aspect_ratio, xsize, ysize,
782 xoffset, yoffset);
783
784 fprintf(fp, "set style data ");
785 save_data_func_style(fp,"data",data_style);
786 fprintf(fp, "set style function ");
787 save_data_func_style(fp,"function",func_style);
788
789 save_zeroaxis(fp, FIRST_X_AXIS);
790 save_zeroaxis(fp, FIRST_Y_AXIS);
791 save_zeroaxis(fp, FIRST_Z_AXIS);
792 save_zeroaxis(fp, SECOND_X_AXIS);
793 save_zeroaxis(fp, SECOND_Y_AXIS);
794
795 if (xyplane.absolute)
796 fprintf(fp, "set xyplane at %g\n", xyplane.z);
797 else
798 fprintf(fp, "set xyplane relative %g\n", xyplane.z);
799
800 {
801 int i;
802 fprintf(fp, "set tics scale ");
803 for (i=0; i<MAX_TICLEVEL; i++)
804 fprintf(fp, " %g%c", ticscale[i], i<MAX_TICLEVEL-1 ? ',' : '\n');
805 }
806
807 save_mtics(fp, &axis_array[FIRST_X_AXIS]);
808 save_mtics(fp, &axis_array[FIRST_Y_AXIS]);
809 save_mtics(fp, &axis_array[FIRST_Z_AXIS]);
810 save_mtics(fp, &axis_array[SECOND_X_AXIS]);
811 save_mtics(fp, &axis_array[SECOND_Y_AXIS]);
812 save_mtics(fp, &axis_array[COLOR_AXIS]);
813 save_mtics(fp, &R_AXIS);
814 save_mtics(fp, &THETA_AXIS);
815
816 save_tics(fp, &axis_array[FIRST_X_AXIS]);
817 save_tics(fp, &axis_array[FIRST_Y_AXIS]);
818 save_tics(fp, &axis_array[FIRST_Z_AXIS]);
819 save_tics(fp, &axis_array[SECOND_X_AXIS]);
820 save_tics(fp, &axis_array[SECOND_Y_AXIS]);
821 save_tics(fp, &axis_array[COLOR_AXIS]);
822 save_tics(fp, &R_AXIS);
823 save_tics(fp, &THETA_AXIS);
824 for (axis=0; axis<num_parallel_axes; axis++)
825 save_tics(fp, ¶llel_axis_array[axis]);
826
827 save_axis_label_or_title(fp, "", "title", &title, TRUE);
828
829 fprintf(fp, "set timestamp %s \n", timelabel_bottom ? "bottom" : "top");
830 save_axis_label_or_title(fp, "", "timestamp", &timelabel, FALSE);
831
832 save_prange(fp, axis_array + T_AXIS);
833 save_prange(fp, axis_array + U_AXIS);
834 save_prange(fp, axis_array + V_AXIS);
835
836 #define SAVE_AXISLABEL(axis) \
837 save_axis_label_or_title(fp, axis_name(axis), "label", &axis_array[axis].label, TRUE)
838
839 SAVE_AXISLABEL(FIRST_X_AXIS);
840 SAVE_AXISLABEL(SECOND_X_AXIS);
841 save_prange(fp, axis_array + FIRST_X_AXIS);
842 save_prange(fp, axis_array + SECOND_X_AXIS);
843
844 SAVE_AXISLABEL(FIRST_Y_AXIS);
845 SAVE_AXISLABEL(SECOND_Y_AXIS);
846 save_prange(fp, axis_array + FIRST_Y_AXIS);
847 save_prange(fp, axis_array + SECOND_Y_AXIS);
848
849 SAVE_AXISLABEL(FIRST_Z_AXIS);
850 save_prange(fp, axis_array + FIRST_Z_AXIS);
851
852 SAVE_AXISLABEL(COLOR_AXIS);
853 save_prange(fp, axis_array + COLOR_AXIS);
854
855 SAVE_AXISLABEL(POLAR_AXIS);
856 save_prange(fp, axis_array + POLAR_AXIS);
857
858 for (axis=0; axis<num_parallel_axes; axis++) {
859 struct axis *paxis = ¶llel_axis_array[axis];
860 save_prange(fp, paxis);
861 if (paxis->label.text)
862 save_axis_label_or_title(fp,
863 axis_name(paxis->index),"label",
864 &paxis->label, TRUE);
865 if (paxis->zeroaxis) {
866 fprintf(fp, "set paxis %d", axis+1);
867 save_linetype(fp, paxis->zeroaxis, FALSE);
868 fprintf(fp, "\n");
869 }
870 }
871
872 #undef SAVE_AXISLABEL
873
874 fputs("unset logscale\n", fp);
875 for (axis = 0; axis < NUMBER_OF_MAIN_VISIBLE_AXES; axis++) {
876 if (axis_array[axis].log)
877 fprintf(fp, "set logscale %s %g\n", axis_name(axis),
878 axis_array[axis].base);
879 else
880 save_nonlinear(fp, &axis_array[axis]);
881 }
882
883 /* These will only print something if the axis is, in fact, linked */
884 save_link(fp, axis_array + SECOND_X_AXIS);
885 save_link(fp, axis_array + SECOND_Y_AXIS);
886
887 save_jitter(fp);
888
889 fprintf(fp, "set zero %g\n", zero);
890
891 fprintf(fp, "set lmargin %s %g\n",
892 lmargin.scalex == screen ? "at screen" : "", lmargin.x);
893 fprintf(fp, "set bmargin %s %g\n",
894 bmargin.scalex == screen ? "at screen" : "", bmargin.x);
895 fprintf(fp, "set rmargin %s %g\n",
896 rmargin.scalex == screen ? "at screen" : "", rmargin.x);
897 fprintf(fp, "set tmargin %s %g\n",
898 tmargin.scalex == screen ? "at screen" : "", tmargin.x);
899
900 fprintf(fp, "set locale \"%s\"\n", get_time_locale());
901
902 /* pm3d options */
903 fputs("set pm3d ", fp);
904 fputs((PM3D_IMPLICIT == pm3d.implicit ? "implicit" : "explicit"), fp);
905 fprintf(fp, " at %s\n", pm3d.where);
906 fputs("set pm3d ", fp);
907 switch (pm3d.direction) {
908 case PM3D_SCANS_AUTOMATIC: fputs("scansautomatic\n", fp); break;
909 case PM3D_SCANS_FORWARD: fputs("scansforward\n", fp); break;
910 case PM3D_SCANS_BACKWARD: fputs("scansbackward\n", fp); break;
911 case PM3D_DEPTH: fprintf(fp, "depthorder %s\n", pm3d.base_sort ? "base" : ""); break;
912 }
913 fprintf(fp, "set pm3d interpolate %d,%d", pm3d.interp_i, pm3d.interp_j);
914 fputs(" flush ", fp);
915 switch (pm3d.flush) {
916 case PM3D_FLUSH_CENTER: fputs("center", fp); break;
917 case PM3D_FLUSH_BEGIN: fputs("begin", fp); break;
918 case PM3D_FLUSH_END: fputs("end", fp); break;
919 }
920 fputs((pm3d.ftriangles ? " " : " no"), fp);
921 fputs("ftriangles", fp);
922 if (pm3d.border.l_type == LT_NODRAW) {
923 fprintf(fp," noborder");
924 } else {
925 fprintf(fp," border");
926 save_linetype(fp, &(pm3d.border), FALSE);
927 }
928 fputs(" corners2color ", fp);
929 switch (pm3d.which_corner_color) {
930 case PM3D_WHICHCORNER_MEAN: fputs("mean", fp); break;
931 case PM3D_WHICHCORNER_GEOMEAN: fputs("geomean", fp); break;
932 case PM3D_WHICHCORNER_HARMEAN: fputs("harmean", fp); break;
933 case PM3D_WHICHCORNER_MEDIAN: fputs("median", fp); break;
934 case PM3D_WHICHCORNER_MIN: fputs("min", fp); break;
935 case PM3D_WHICHCORNER_MAX: fputs("max", fp); break;
936 case PM3D_WHICHCORNER_RMS: fputs("rms", fp); break;
937
938 default: /* PM3D_WHICHCORNER_C1 ... _C4 */
939 fprintf(fp, "c%i", pm3d.which_corner_color - PM3D_WHICHCORNER_C1 + 1);
940 }
941 fputs("\n", fp);
942
943 fprintf(fp, "set pm3d %s %s\n",
944 pm3d.clip == PM3D_CLIP_1IN ? "clip1in" :
945 pm3d.clip == PM3D_CLIP_4IN ? "clip4in" : "clip z",
946 pm3d.no_clipcb ? "noclipcb" : "");
947
948 if (pm3d_shade.strength <= 0)
949 fputs("set pm3d nolighting\n",fp);
950 else
951 fprintf(fp, "set pm3d lighting primary %g specular %g spec2 %g\n",
952 pm3d_shade.strength, pm3d_shade.spec, pm3d_shade.spec2);
953
954 /*
955 * Save palette information
956 */
957
958 fprintf( fp, "set palette %s %s maxcolors %d ",
959 sm_palette.positive==SMPAL_POSITIVE ? "positive" : "negative",
960 sm_palette.ps_allcF ? "ps_allcF" : "nops_allcF",
961 sm_palette.use_maxcolors);
962 fprintf( fp, "gamma %g ", sm_palette.gamma );
963 if (sm_palette.colorMode == SMPAL_COLOR_MODE_GRAY) {
964 fputs( "gray\n", fp );
965 }
966 else {
967 fputs( "color model ", fp );
968 switch( sm_palette.cmodel ) {
969 default:
970 case C_MODEL_RGB: fputs( "RGB ", fp ); break;
971 case C_MODEL_HSV: fputs( "HSV ", fp ); break;
972 case C_MODEL_CMY: fputs( "CMY ", fp ); break;
973 }
974 fputs( "\nset palette ", fp );
975 switch( sm_palette.colorMode ) {
976 default:
977 case SMPAL_COLOR_MODE_RGB:
978 fprintf( fp, "rgbformulae %d, %d, %d\n", sm_palette.formulaR,
979 sm_palette.formulaG, sm_palette.formulaB );
980 break;
981 case SMPAL_COLOR_MODE_GRADIENT: {
982 int i=0;
983 fprintf( fp, "defined (" );
984 for (i=0; i<sm_palette.gradient_num; i++) {
985 fprintf( fp, " %.4g %.4g %.4g %.4g", sm_palette.gradient[i].pos,
986 sm_palette.gradient[i].col.r, sm_palette.gradient[i].col.g,
987 sm_palette.gradient[i].col.b );
988 if (i<sm_palette.gradient_num-1) {
989 fputs( ",", fp);
990 if (i==2 || i%4==2) fputs( "\\\n ", fp );
991 }
992 }
993 fputs( " )\n", fp );
994 break;
995 }
996 case SMPAL_COLOR_MODE_FUNCTIONS:
997 fprintf( fp, "functions %s, %s, %s\n", sm_palette.Afunc.definition,
998 sm_palette.Bfunc.definition, sm_palette.Cfunc.definition );
999 break;
1000 case SMPAL_COLOR_MODE_CUBEHELIX:
1001 fprintf( fp, "cubehelix start %.2g cycles %.2g saturation %.2g\n",
1002 sm_palette.cubehelix_start, sm_palette.cubehelix_cycles,
1003 sm_palette.cubehelix_saturation);
1004 break;
1005 }
1006 }
1007
1008 /*
1009 * Save colorbox info
1010 */
1011 if (color_box.where != SMCOLOR_BOX_NO)
1012 fprintf(fp,"set colorbox %s\n", color_box.where==SMCOLOR_BOX_DEFAULT ? "default" : "user");
1013 fprintf(fp, "set colorbox %sal origin ", color_box.rotation == 'v' ? "vertic" : "horizont");
1014 save_position(fp, &color_box.origin, 2, FALSE);
1015 fputs(" size ", fp);
1016 save_position(fp, &color_box.size, 2, FALSE);
1017 fprintf(fp, " %s ", color_box.layer == LAYER_FRONT ? "front" : "back");
1018 fprintf(fp, " %sinvert ", color_box.invert ? "" : "no");
1019 if (color_box.border == 0) fputs("noborder", fp);
1020 else if (color_box.border_lt_tag < 0) fputs("bdefault", fp);
1021 else fprintf(fp, "border %d", color_box.border_lt_tag);
1022 if (color_box.where == SMCOLOR_BOX_NO) fputs("\nunset colorbox\n", fp);
1023 else fputs("\n", fp);
1024
1025 fprintf(fp, "set style boxplot %s %s %5.2f %soutliers pt %d separation %g labels %s %ssorted\n",
1026 boxplot_opts.plotstyle == FINANCEBARS ? "financebars" : "candles",
1027 boxplot_opts.limit_type == 1 ? "fraction" : "range",
1028 boxplot_opts.limit_value,
1029 boxplot_opts.outliers ? "" : "no",
1030 boxplot_opts.pointtype+1,
1031 boxplot_opts.separation,
1032 (boxplot_opts.labels == BOXPLOT_FACTOR_LABELS_X) ? "x" :
1033 (boxplot_opts.labels == BOXPLOT_FACTOR_LABELS_X2) ? "x2" :
1034 (boxplot_opts.labels == BOXPLOT_FACTOR_LABELS_AUTO) ? "auto" :"off",
1035 boxplot_opts.sort_factors ? "" : "un");
1036
1037 fputs("set loadpath ", fp);
1038 {
1039 char *s;
1040 while ((s = save_loadpath()) != NULL)
1041 fprintf(fp, "\"%s\" ", s);
1042 fputc('\n', fp);
1043 }
1044
1045 if (PS_fontpath)
1046 fprintf(fp, "set fontpath \"%s\"\n", PS_fontpath);
1047 else
1048 fprintf(fp, "set fontpath\n");
1049
1050 if (PS_psdir)
1051 fprintf(fp, "set psdir \"%s\"\n", PS_psdir);
1052 else
1053 fprintf(fp, "set psdir\n");
1054
1055 fprintf(fp, "set fit");
1056 if (fit_suppress_log)
1057 fprintf(fp, " nologfile");
1058 else if (fitlogfile)
1059 fprintf(fp, " logfile \'%s\'", fitlogfile);
1060 fprintf(fp, " %s", reverse_table_lookup(fit_verbosity_level, fit_verbosity));
1061 fprintf(fp, " %serrorvariables",
1062 fit_errorvariables ? "" : "no");
1063 fprintf(fp, " %scovariancevariables",
1064 fit_covarvariables ? "" : "no");
1065 fprintf(fp, " %serrorscaling",
1066 fit_errorscaling ? "" : "no");
1067 fprintf(fp, " %sprescale", fit_prescale ? "" : "no");
1068 {
1069 struct udvt_entry *v;
1070 double d;
1071 int i;
1072
1073 v = get_udv_by_name((char *)FITLIMIT);
1074 d = ((v != NULL) && (v->udv_value.type != NOTDEFINED)) ? real(&(v->udv_value)) : -1.0;
1075 if ((d > 0.) && (d < 1.))
1076 fprintf(fp, " limit %g", d);
1077
1078 if (epsilon_abs > 0.)
1079 fprintf(fp, " limit_abs %g", epsilon_abs);
1080
1081 v = get_udv_by_name((char *)FITMAXITER);
1082 i = ((v != NULL) && (v->udv_value.type != NOTDEFINED)) ? real(&(v->udv_value)) : -1;
1083 if (i > 0)
1084 fprintf(fp, " maxiter %i", i);
1085
1086 v = get_udv_by_name((char *)FITSTARTLAMBDA);
1087 d = ((v != NULL) && (v->udv_value.type != NOTDEFINED)) ? real(&(v->udv_value)) : -1.0;
1088 if (d > 0.)
1089 fprintf(fp, " start_lambda %g", d);
1090
1091 v = get_udv_by_name((char *)FITLAMBDAFACTOR);
1092 d = ((v != NULL) && (v->udv_value.type != NOTDEFINED)) ? real(&(v->udv_value)) : -1.0;
1093 if (d > 0.)
1094 fprintf(fp, " lambda_factor %g", d);
1095 }
1096 if (fit_script != NULL)
1097 fprintf(fp, " script \'%s\'", fit_script);
1098 if (fit_wrap != 0)
1099 fprintf(fp, " wrap %i", fit_wrap);
1100 else
1101 fprintf(fp, " nowrap");
1102 fprintf(fp, " v%i", fit_v4compatible ? 4 : 5);
1103 fputc('\n', fp);
1104 }
1105
1106
1107 static void
save_tics(FILE * fp,struct axis * this_axis)1108 save_tics(FILE *fp, struct axis *this_axis)
1109 {
1110 if ((this_axis->ticmode & TICS_MASK) == NO_TICS) {
1111 fprintf(fp, "unset %stics\n", axis_name(this_axis->index));
1112 return;
1113 }
1114 fprintf(fp, "set %stics %s %s scale %g,%g %smirror %s ",
1115 axis_name(this_axis->index),
1116 ((this_axis->ticmode & TICS_MASK) == TICS_ON_AXIS)
1117 ? "axis" : "border",
1118 (this_axis->tic_in) ? "in" : "out",
1119 this_axis->ticscale, this_axis->miniticscale,
1120 (this_axis->ticmode & TICS_MIRROR) ? "" : "no",
1121 this_axis->tic_rotate ? "rotate" : "norotate");
1122 if (this_axis->tic_rotate)
1123 fprintf(fp,"by %d ",this_axis->tic_rotate);
1124 save_position(fp, &this_axis->ticdef.offset, 3, TRUE);
1125 if (this_axis->manual_justify)
1126 save_justification(this_axis->tic_pos, fp);
1127 else
1128 fputs(" autojustify", fp);
1129 fprintf(fp, "\nset %stics ", axis_name(this_axis->index));
1130
1131 fprintf(fp, (this_axis->ticdef.rangelimited)?" rangelimit ":" norangelimit ");
1132
1133 if (this_axis->ticdef.logscaling)
1134 fputs("logscale ", fp);
1135
1136 switch (this_axis->ticdef.type) {
1137 case TIC_COMPUTED:{
1138 fputs("autofreq ", fp);
1139 break;
1140 }
1141 case TIC_MONTH:{
1142 fprintf(fp, "\nset %smtics", axis_name(this_axis->index));
1143 break;
1144 }
1145 case TIC_DAY:{
1146 fprintf(fp, "\nset %sdtics", axis_name(this_axis->index));
1147 break;
1148 }
1149 case TIC_SERIES:
1150 if (this_axis->ticdef.def.series.start != -VERYLARGE) {
1151 save_num_or_time_input(fp,
1152 (double) this_axis->ticdef.def.series.start,
1153 this_axis);
1154 putc(',', fp);
1155 }
1156 fprintf(fp, "%g", this_axis->ticdef.def.series.incr);
1157 if (this_axis->ticdef.def.series.end != VERYLARGE) {
1158 putc(',', fp);
1159 save_num_or_time_input(fp,
1160 (double) this_axis->ticdef.def.series.end,
1161 this_axis);
1162 }
1163 break;
1164 case TIC_USER:
1165 break;
1166 }
1167
1168 if (this_axis->ticdef.font && *this_axis->ticdef.font)
1169 fprintf(fp, " font \"%s\"", this_axis->ticdef.font);
1170
1171 if (this_axis->ticdef.enhanced == FALSE)
1172 fprintf(fp, " noenhanced");
1173
1174 if (this_axis->ticdef.textcolor.type != TC_DEFAULT)
1175 save_textcolor(fp, &this_axis->ticdef.textcolor);
1176
1177 putc('\n', fp);
1178
1179 if (this_axis->ticdef.def.user) {
1180 struct ticmark *t;
1181 fprintf(fp, "set %stics %s ", axis_name(this_axis->index),
1182 (this_axis->ticdef.type == TIC_USER) ? "" : "add");
1183 fputs(" (", fp);
1184 for (t = this_axis->ticdef.def.user; t != NULL; t = t->next) {
1185 if (t->level < 0) /* Don't save ticlabels read from data file */
1186 continue;
1187 if (t->label)
1188 fprintf(fp, "\"%s\" ", conv_text(t->label));
1189 save_num_or_time_input(fp, (double) t->position, this_axis);
1190 if (t->level)
1191 fprintf(fp, " %d", t->level);
1192 if (t->next) {
1193 fputs(", ", fp);
1194 }
1195 }
1196 fputs(")\n", fp);
1197 }
1198
1199 }
1200
1201 static void
save_mtics(FILE * fp,struct axis * axis)1202 save_mtics(FILE *fp, struct axis *axis)
1203 {
1204 char *name = axis_name(axis->index);
1205
1206 switch(axis->minitics & TICS_MASK) {
1207 case 0:
1208 fprintf(fp, "set nom%stics\n", name);
1209 break;
1210 case MINI_AUTO:
1211 fprintf(fp, "set m%stics\n", name);
1212 break;
1213 case MINI_DEFAULT:
1214 fprintf(fp, "set m%stics default\n", name);
1215 break;
1216 case MINI_USER:
1217 fprintf(fp, "set m%stics %f\n", name, axis->mtic_freq);
1218 break;
1219 }
1220 }
1221
1222 void
save_num_or_time_input(FILE * fp,double x,struct axis * this_axis)1223 save_num_or_time_input(FILE *fp, double x, struct axis *this_axis)
1224 {
1225 if (this_axis->datatype == DT_TIMEDATE) {
1226 char s[80];
1227
1228 putc('"', fp);
1229 gstrftime(s,80,timefmt,(double)(x));
1230 fputs(conv_text(s), fp);
1231 putc('"', fp);
1232 } else {
1233 fprintf(fp,"%#g",x);
1234 }
1235 }
1236
1237 void
save_axis_format(FILE * fp,AXIS_INDEX axis)1238 save_axis_format(FILE *fp, AXIS_INDEX axis)
1239 {
1240 fprintf(fp,
1241 (fp == stderr) ? "\t %s-axis: \"%s\"%s\n" : "set format %s \"%s\" %s\n",
1242 axis_name(axis), conv_text(axis_array[axis].formatstring),
1243 axis_array[axis].tictype == DT_DMS ? "geographic" :
1244 axis_array[axis].tictype == DT_TIMEDATE ? "timedate" :
1245 "");
1246 }
1247
1248 void
save_style_parallel(FILE * fp)1249 save_style_parallel(FILE *fp)
1250 {
1251 if (fp == stderr)
1252 fputs("\t",fp);
1253 fprintf(fp, "set style parallel %s ",
1254 parallel_axis_style.layer == LAYER_BACK ? "back" : "front");
1255 save_linetype(fp, &(parallel_axis_style.lp_properties), FALSE);
1256 fprintf(fp, "\n");
1257 }
1258
1259 void
save_style_spider(FILE * fp)1260 save_style_spider(FILE *fp)
1261 {
1262 fprintf(fp, "set style spiderplot ");
1263 save_linetype(fp, &(spiderplot_style.lp_properties), TRUE);
1264 fprintf(fp, "\nset style spiderplot fillstyle ");
1265 save_fillstyle(fp, &spiderplot_style.fillstyle);
1266 }
1267
1268 void
save_style_textbox(FILE * fp)1269 save_style_textbox(FILE *fp)
1270 {
1271 int bs;
1272 for (bs = 0; bs < NUM_TEXTBOX_STYLES; bs++) {
1273 textbox_style *textbox = &textbox_opts[bs];
1274 if (textbox->linewidth <= 0)
1275 continue;
1276 fprintf(fp, "set style textbox ");
1277 if (bs > 0)
1278 fprintf(fp,"%d ", bs);
1279 fprintf(fp, " %s margins %4.1f, %4.1f",
1280 textbox->opaque ? "opaque": "transparent",
1281 textbox->xmargin, textbox->ymargin);
1282 if (textbox->opaque) {
1283 fprintf(fp, " fc ");
1284 save_pm3dcolor(fp, &(textbox->fillcolor));
1285 }
1286 if (textbox->noborder) {
1287 fprintf(fp, " noborder");
1288 } else {
1289 fprintf(fp, " border ");
1290 save_pm3dcolor(fp, &(textbox->border_color));
1291 }
1292 fprintf(fp, " linewidth %4.1f", textbox->linewidth);
1293 fputs("\n",fp);
1294 }
1295 }
1296
1297 void
save_position(FILE * fp,struct position * pos,int ndim,TBOOLEAN offset)1298 save_position(FILE *fp, struct position *pos, int ndim, TBOOLEAN offset)
1299 {
1300 if (offset) {
1301 if (pos->x == 0 && pos->y == 0 && pos->z == 0)
1302 return;
1303 fprintf(fp, " offset ");
1304 }
1305
1306 /* Save in time coordinates if appropriate */
1307 if (pos->scalex == first_axes) {
1308 save_num_or_time_input(fp, pos->x, &axis_array[FIRST_X_AXIS]);
1309 } else {
1310 fprintf(fp, "%s%g", coord_msg[pos->scalex], pos->x);
1311 }
1312
1313 if (ndim == 1)
1314 return;
1315 else
1316 fprintf(fp, ", ");
1317
1318 if (pos->scaley == first_axes || pos->scalex == polar_axes) {
1319 if (pos->scaley != pos->scalex) fprintf(fp, "first ");
1320 save_num_or_time_input(fp, pos->y, &axis_array[FIRST_Y_AXIS]);
1321 } else {
1322 fprintf(fp, "%s%g",
1323 pos->scaley == pos->scalex ? "" : coord_msg[pos->scaley], pos->y);
1324 }
1325
1326 if (ndim == 2)
1327 return;
1328 else
1329 fprintf(fp, ", ");
1330
1331 if (pos->scalez == first_axes) {
1332 if (pos->scalez != pos->scaley) fprintf(fp, "first ");
1333 save_num_or_time_input(fp, pos->z, &axis_array[FIRST_Z_AXIS]);
1334 } else {
1335 fprintf(fp, "%s%g",
1336 pos->scalez == pos->scaley ? "" : coord_msg[pos->scalez], pos->z);
1337 }
1338 }
1339
1340
1341 void
save_prange(FILE * fp,struct axis * this_axis)1342 save_prange(FILE *fp, struct axis *this_axis)
1343 {
1344 TBOOLEAN noextend = FALSE;
1345
1346 fprintf(fp, "set %srange [ ", axis_name(this_axis->index));
1347 if (this_axis->set_autoscale & AUTOSCALE_MIN) {
1348 if (this_axis->min_constraint & CONSTRAINT_LOWER ) {
1349 save_num_or_time_input(fp, this_axis->min_lb, this_axis);
1350 fputs(" < ", fp);
1351 }
1352 putc('*', fp);
1353 if (this_axis->min_constraint & CONSTRAINT_UPPER ) {
1354 fputs(" < ", fp);
1355 save_num_or_time_input(fp, this_axis->min_ub, this_axis);
1356 }
1357 } else {
1358 save_num_or_time_input(fp, this_axis->set_min, this_axis);
1359 }
1360 fputs(" : ", fp);
1361 if (this_axis->set_autoscale & AUTOSCALE_MAX) {
1362 if (this_axis->max_constraint & CONSTRAINT_LOWER ) {
1363 save_num_or_time_input(fp, this_axis->max_lb, this_axis);
1364 fputs(" < ", fp);
1365 }
1366 putc('*', fp);
1367 if (this_axis->max_constraint & CONSTRAINT_UPPER ) {
1368 fputs(" < ", fp);
1369 save_num_or_time_input(fp, this_axis->max_ub, this_axis);
1370 }
1371 } else {
1372 save_num_or_time_input(fp, this_axis->set_max, this_axis);
1373 }
1374
1375 if (this_axis->index < PARALLEL_AXES)
1376 fprintf(fp, " ] %sreverse %swriteback",
1377 ((this_axis->range_flags & RANGE_IS_REVERSED)) ? "" : "no",
1378 this_axis->range_flags & RANGE_WRITEBACK ? "" : "no");
1379 else
1380 fprintf(fp, " ] ");
1381
1382 if ((this_axis->set_autoscale & AUTOSCALE_FIXMIN)
1383 && (this_axis->set_autoscale & AUTOSCALE_FIXMAX)) {
1384 fprintf(fp, " noextend");
1385 noextend = TRUE;
1386 }
1387
1388 if (this_axis->set_autoscale && fp == stderr) {
1389 /* add current (hidden) range as comments */
1390 fputs(" # (currently [", fp);
1391 save_num_or_time_input(fp, this_axis->min, this_axis);
1392 putc(':', fp);
1393 save_num_or_time_input(fp, this_axis->max, this_axis);
1394 fputs("] )\n", fp);
1395 } else
1396 putc('\n', fp);
1397
1398 if (!noextend && (fp != stderr)) {
1399 if (this_axis->set_autoscale & (AUTOSCALE_FIXMIN))
1400 fprintf(fp, "set autoscale %sfixmin\n", axis_name(this_axis->index));
1401 if (this_axis->set_autoscale & AUTOSCALE_FIXMAX)
1402 fprintf(fp, "set autoscale %sfixmax\n", axis_name(this_axis->index));
1403 }
1404 }
1405
1406 void
save_link(FILE * fp,AXIS * this_axis)1407 save_link(FILE *fp, AXIS *this_axis)
1408 {
1409 if (this_axis->linked_to_primary
1410 && this_axis->index != -this_axis->linked_to_primary->index) {
1411 fprintf(fp, "set link %s ", axis_name(this_axis->index));
1412 if (this_axis->link_udf->at)
1413 fprintf(fp, "via %s ", this_axis->link_udf->definition);
1414 if (this_axis->linked_to_primary->link_udf->at)
1415 fprintf(fp, "inverse %s ", this_axis->linked_to_primary->link_udf->definition);
1416 fputs("\n", fp);
1417 }
1418 }
1419
1420 void
save_nonlinear(FILE * fp,AXIS * this_axis)1421 save_nonlinear(FILE *fp, AXIS *this_axis)
1422 {
1423 AXIS *primary = this_axis->linked_to_primary;
1424
1425 if (primary && this_axis->index == -primary->index) {
1426 fprintf(fp, "set nonlinear %s ", axis_name(this_axis->index));
1427 if (primary->link_udf->at)
1428 fprintf(fp, "via %s ", primary->link_udf->definition);
1429 else
1430 fprintf(stderr, "[corrupt linkage] ");
1431 if (this_axis->link_udf->at)
1432 fprintf(fp, "inverse %s ", this_axis->link_udf->definition);
1433 else
1434 fprintf(stderr, "[corrupt linkage] ");
1435 fputs("\n", fp);
1436 }
1437 }
1438
1439 static void
save_zeroaxis(FILE * fp,AXIS_INDEX axis)1440 save_zeroaxis(FILE *fp, AXIS_INDEX axis)
1441 {
1442 if (axis_array[axis].zeroaxis == NULL) {
1443 fprintf(fp, "unset %szeroaxis", axis_name(axis));
1444 } else {
1445 fprintf(fp, "set %szeroaxis", axis_name(axis));
1446 if (axis_array[axis].zeroaxis != &default_axis_zeroaxis)
1447 save_linetype(fp, axis_array[axis].zeroaxis, FALSE);
1448 }
1449 putc('\n', fp);
1450 }
1451
1452 void
save_fillstyle(FILE * fp,const struct fill_style_type * fs)1453 save_fillstyle(FILE *fp, const struct fill_style_type *fs)
1454 {
1455 switch(fs->fillstyle) {
1456 case FS_SOLID:
1457 case FS_TRANSPARENT_SOLID:
1458 fprintf(fp, " %s solid %.2f ",
1459 fs->fillstyle == FS_SOLID ? "" : "transparent",
1460 fs->filldensity / 100.0);
1461 break;
1462 case FS_PATTERN:
1463 case FS_TRANSPARENT_PATTERN:
1464 fprintf(fp, " %s pattern %d ",
1465 fs->fillstyle == FS_PATTERN ? "" : "transparent",
1466 fs->fillpattern);
1467 break;
1468 case FS_DEFAULT:
1469 fprintf(fp, " default\n");
1470 return;
1471 default:
1472 fprintf(fp, " empty ");
1473 break;
1474 }
1475 if (fs->border_color.type == TC_LT && fs->border_color.lt == LT_NODRAW) {
1476 fprintf(fp, "noborder\n");
1477 } else {
1478 fprintf(fp, "border");
1479 save_pm3dcolor(fp, &fs->border_color);
1480 fprintf(fp, "\n");
1481 }
1482 }
1483
1484 void
save_textcolor(FILE * fp,const struct t_colorspec * tc)1485 save_textcolor(FILE *fp, const struct t_colorspec *tc)
1486 {
1487 if (tc->type) {
1488 fprintf(fp, " textcolor");
1489 if (tc->type == TC_VARIABLE)
1490 fprintf(fp, " variable");
1491 else
1492 save_pm3dcolor(fp, tc);
1493 }
1494 }
1495
1496
1497 void
save_pm3dcolor(FILE * fp,const struct t_colorspec * tc)1498 save_pm3dcolor(FILE *fp, const struct t_colorspec *tc)
1499 {
1500 if (tc->type) {
1501 switch(tc->type) {
1502 case TC_LT: if (tc->lt == LT_NODRAW)
1503 fprintf(fp," nodraw");
1504 else if (tc->lt == LT_BACKGROUND)
1505 fprintf(fp," bgnd");
1506 else
1507 fprintf(fp," lt %d", tc->lt+1);
1508 break;
1509 case TC_LINESTYLE: fprintf(fp," linestyle %d", tc->lt);
1510 break;
1511 case TC_Z: fprintf(fp," palette z");
1512 break;
1513 case TC_CB: fprintf(fp," palette cb %g", tc->value);
1514 break;
1515 case TC_FRAC: fprintf(fp," palette fraction %4.2f", tc->value);
1516 break;
1517 case TC_RGB: {
1518 const char *color = reverse_table_lookup(pm3d_color_names_tbl, tc->lt);
1519 if (tc->value < 0)
1520 fprintf(fp," rgb variable ");
1521 else if (color)
1522 fprintf(fp," rgb \"%s\" ", color);
1523 else
1524 fprintf(fp," rgb \"#%6.6x\" ", tc->lt);
1525 break;
1526 }
1527 default: break;
1528 }
1529 }
1530 }
1531
1532 void
save_data_func_style(FILE * fp,const char * which,enum PLOT_STYLE style)1533 save_data_func_style(FILE *fp, const char *which, enum PLOT_STYLE style)
1534 {
1535 char *answer = strdup(reverse_table_lookup(plotstyle_tbl, style));
1536 char *idollar = strchr(answer, '$');
1537 if (idollar) {
1538 do {
1539 *idollar = *(idollar+1);
1540 idollar++;
1541 } while (*idollar);
1542
1543 }
1544 fputs(answer, fp);
1545 free(answer);
1546
1547 if (style == FILLEDCURVES) {
1548 fputs(" ", fp);
1549 if (!strcmp(which, "data") || !strcmp(which, "Data"))
1550 filledcurves_options_tofile(&filledcurves_opts_data, fp);
1551 else
1552 filledcurves_options_tofile(&filledcurves_opts_func, fp);
1553 }
1554 fputc('\n', fp);
1555 }
1556
1557 void
save_dashtype(FILE * fp,int d_type,const t_dashtype * dt)1558 save_dashtype(FILE *fp, int d_type, const t_dashtype *dt)
1559 {
1560 /* this is indicated by LT_AXIS (lt 0) instead */
1561 if (d_type == DASHTYPE_AXIS)
1562 return;
1563
1564 fprintf(fp, " dashtype");
1565 if (d_type == DASHTYPE_CUSTOM) {
1566 if (dt->dstring[0] != '\0')
1567 fprintf(fp, " \"%s\"", dt->dstring);
1568 if (fp == stderr || dt->dstring[0] == '\0') {
1569 int i;
1570 fputs(" (", fp);
1571 for (i = 0; i < DASHPATTERN_LENGTH && dt->pattern[i] > 0; i++)
1572 fprintf(fp, i ? ", %.2f" : "%.2f", dt->pattern[i]);
1573 fputs(")", fp);
1574 }
1575 } else if (d_type == DASHTYPE_SOLID) {
1576 fprintf(fp, " solid");
1577 } else {
1578 fprintf(fp, " %d", d_type + 1);
1579 }
1580 }
1581
1582 void
save_linetype(FILE * fp,lp_style_type * lp,TBOOLEAN show_point)1583 save_linetype(FILE *fp, lp_style_type *lp, TBOOLEAN show_point)
1584 {
1585 if (lp->l_type == LT_NODRAW)
1586 fprintf(fp, " lt nodraw");
1587 else if (lp->l_type == LT_BACKGROUND)
1588 fprintf(fp, " lt bgnd");
1589 else if (lp->l_type == LT_DEFAULT)
1590 ; /* Dont' print anything */
1591 else if (lp->l_type == LT_AXIS)
1592 fprintf(fp, " lt 0");
1593
1594 if (lp->l_type == LT_BLACK && lp->pm3d_color.type == TC_LT)
1595 fprintf(fp, " lt black");
1596 else if (lp->pm3d_color.type != TC_DEFAULT) {
1597 fprintf(fp, " linecolor");
1598 if (lp->pm3d_color.type == TC_LT)
1599 fprintf(fp, " %d", lp->pm3d_color.lt+1);
1600 else if (lp->pm3d_color.type == TC_LINESTYLE && lp->l_type == LT_COLORFROMCOLUMN)
1601 fprintf(fp, " variable");
1602 else
1603 save_pm3dcolor(fp,&(lp->pm3d_color));
1604 }
1605 fprintf(fp, " linewidth %.3f", lp->l_width);
1606
1607 save_dashtype(fp, lp->d_type, &lp->custom_dash_pattern);
1608
1609 if (show_point) {
1610 if (lp->p_type == PT_CHARACTER)
1611 fprintf(fp, " pointtype \"%s\"", lp->p_char);
1612 else if (lp->p_type == PT_VARIABLE)
1613 fprintf(fp, " pointtype variable");
1614 else
1615 fprintf(fp, " pointtype %d", lp->p_type + 1);
1616 if (lp->p_size == PTSZ_VARIABLE)
1617 fprintf(fp, " pointsize variable");
1618 else if (lp->p_size == PTSZ_DEFAULT)
1619 fprintf(fp, " pointsize default");
1620 else
1621 fprintf(fp, " pointsize %.3f", lp->p_size);
1622 if (lp->p_interval != 0)
1623 fprintf(fp, " pointinterval %d", lp->p_interval);
1624 if (lp->p_number != 0)
1625 fprintf(fp, " pointnumber %d", lp->p_number);
1626 }
1627
1628 }
1629
1630
1631 void
save_offsets(FILE * fp,char * lead)1632 save_offsets(FILE *fp, char *lead)
1633 {
1634 fprintf(fp, "%s %s%g, %s%g, %s%g, %s%g\n", lead,
1635 loff.scalex == graph ? "graph " : "", loff.x,
1636 roff.scalex == graph ? "graph " : "", roff.x,
1637 toff.scaley == graph ? "graph " : "", toff.y,
1638 boff.scaley == graph ? "graph " : "", boff.y);
1639 }
1640
1641 void
save_bars(FILE * fp)1642 save_bars(FILE *fp)
1643 {
1644 if (bar_size == 0.0) {
1645 fprintf(fp, "unset errorbars\n");
1646 return;
1647 }
1648 fprintf(fp, "set errorbars %s", (bar_layer == LAYER_BACK) ? "back" : "front");
1649 if (bar_size > 0.0)
1650 fprintf(fp, " %f ", bar_size);
1651 else
1652 fprintf(fp," fullwidth ");
1653 if ((bar_lp.flags & LP_ERRORBAR_SET) != 0)
1654 save_linetype(fp, &bar_lp, FALSE);
1655 fputs("\n",fp);
1656 }
1657
1658 void
save_histogram_opts(FILE * fp)1659 save_histogram_opts (FILE *fp)
1660 {
1661 switch (histogram_opts.type) {
1662 default:
1663 case HT_CLUSTERED:
1664 fprintf(fp,"clustered gap %d ",histogram_opts.gap); break;
1665 case HT_ERRORBARS:
1666 fprintf(fp,"errorbars gap %d lw %g",histogram_opts.gap,histogram_opts.bar_lw); break;
1667 case HT_STACKED_IN_LAYERS:
1668 fprintf(fp,"rowstacked "); break;
1669 case HT_STACKED_IN_TOWERS:
1670 fprintf(fp,"columnstacked "); break;
1671 }
1672 if (fp == stderr)
1673 fprintf(fp,"\n\t\t");
1674 fprintf(fp,"title");
1675 save_textcolor(fp, &histogram_opts.title.textcolor);
1676 if (histogram_opts.title.font)
1677 fprintf(fp, " font \"%s\" ", histogram_opts.title.font);
1678 save_position(fp, &histogram_opts.title.offset, 2, TRUE);
1679 fprintf(fp, "\n");
1680 }
1681
1682 void
save_pixmaps(FILE * fp)1683 save_pixmaps(FILE *fp)
1684 {
1685 t_pixmap *pixmap;
1686 for (pixmap = pixmap_listhead; pixmap; pixmap = pixmap->next) {
1687 fprintf(fp, "set pixmap %d '%s' # (%d x %d pixmap)\n",
1688 pixmap->tag, pixmap->filename, pixmap->ncols, pixmap->nrows);
1689 fprintf(fp, "set pixmap %d at ", pixmap->tag);
1690 save_position(fp,&pixmap->pin, 3, FALSE);
1691 fprintf(fp, " size ");
1692 save_position(fp,&pixmap->extent, 2, FALSE);
1693 fprintf(fp, " %s %s\n",
1694 pixmap->layer == LAYER_FRONT ? "front" : "behind",
1695 pixmap->center ? "center" : "");
1696 }
1697 }
1698
1699 /* Save/show rectangle <tag> (0 means show all) */
1700 void
save_object(FILE * fp,int tag)1701 save_object(FILE *fp, int tag)
1702 {
1703 t_object *this_object;
1704 t_rectangle *this_rect;
1705 t_circle *this_circle;
1706 t_ellipse *this_ellipse;
1707 TBOOLEAN showed = FALSE;
1708
1709 for (this_object = first_object; this_object != NULL; this_object = this_object->next) {
1710 if ((this_object->object_type == OBJ_RECTANGLE)
1711 && (tag == 0 || tag == this_object->tag)) {
1712 this_rect = &this_object->o.rectangle;
1713 showed = TRUE;
1714 fprintf(fp, "%sobject %2d rect ", (fp==stderr) ? "\t" : "set ",this_object->tag);
1715
1716 if (this_rect->type == 1) {
1717 fprintf(fp, "center ");
1718 save_position(fp, &this_rect->center, 2, FALSE);
1719 fprintf(fp, " size ");
1720 save_position(fp, &this_rect->extent, 2, FALSE);
1721 } else {
1722 fprintf(fp, "from ");
1723 save_position(fp, &this_rect->bl, 2, FALSE);
1724 fprintf(fp, " to ");
1725 save_position(fp, &this_rect->tr, 2, FALSE);
1726 }
1727 }
1728
1729 else if ((this_object->object_type == OBJ_CIRCLE)
1730 && (tag == 0 || tag == this_object->tag)) {
1731 struct position *e = &this_object->o.circle.extent;
1732 this_circle = &this_object->o.circle;
1733 showed = TRUE;
1734 fprintf(fp, "%sobject %2d circle ", (fp==stderr) ? "\t" : "set ",this_object->tag);
1735
1736 fprintf(fp, "center ");
1737 save_position(fp, &this_circle->center, 3, FALSE);
1738 fprintf(fp, " size ");
1739 fprintf(fp, "%s%g", e->scalex == first_axes ? "" : coord_msg[e->scalex], e->x);
1740 fprintf(fp, " arc [%g:%g] ", this_circle->arc_begin, this_circle->arc_end);
1741 fprintf(fp, this_circle->wedge ? "wedge " : "nowedge");
1742 }
1743
1744 else if ((this_object->object_type == OBJ_ELLIPSE)
1745 && (tag == 0 || tag == this_object->tag)) {
1746 struct position *e = &this_object->o.ellipse.extent;
1747 this_ellipse = &this_object->o.ellipse;
1748 showed = TRUE;
1749 fprintf(fp, "%sobject %2d ellipse ", (fp==stderr) ? "\t" : "set ",this_object->tag);
1750 fprintf(fp, "center ");
1751 save_position(fp, &this_ellipse->center, 3, FALSE);
1752 fprintf(fp, " size ");
1753 fprintf(fp, "%s%g", e->scalex == first_axes ? "" : coord_msg[e->scalex], e->x);
1754 fprintf(fp, ", %s%g", e->scaley == e->scalex ? "" : coord_msg[e->scaley], e->y);
1755 fprintf(fp, " angle %g", this_ellipse->orientation);
1756 fputs(" units ", fp);
1757 switch (this_ellipse->type) {
1758 case ELLIPSEAXES_XY:
1759 fputs("xy", fp);
1760 break;
1761 case ELLIPSEAXES_XX:
1762 fputs("xx", fp);
1763 break;
1764 case ELLIPSEAXES_YY:
1765 fputs("yy", fp);
1766 break;
1767 }
1768 }
1769
1770 else if ((this_object->object_type == OBJ_POLYGON)
1771 && (tag == 0 || tag == this_object->tag)) {
1772 t_polygon *this_polygon = &this_object->o.polygon;
1773 int nv;
1774 showed = TRUE;
1775 fprintf(fp, "%sobject %2d polygon ", (fp==stderr) ? "\t" : "set ",this_object->tag);
1776 if (this_polygon->vertex) {
1777 fprintf(fp, "from ");
1778 save_position(fp, &this_polygon->vertex[0], 3, FALSE);
1779 }
1780 for (nv=1; nv < this_polygon->type; nv++) {
1781 fprintf(fp, (fp==stderr) ? "\n\t\t\t to " : " to ");
1782 save_position(fp, &this_polygon->vertex[nv], 3, FALSE);
1783 }
1784 }
1785
1786 /* Properties common to all objects */
1787 if (tag == 0 || tag == this_object->tag) {
1788 fprintf(fp, "\n%sobject %2d ", (fp==stderr) ? "\t" : "set ",this_object->tag);
1789 fprintf(fp, "%s ", this_object->layer == LAYER_FRONT ? "front" :
1790 this_object->layer == LAYER_DEPTHORDER ? "depthorder" :
1791 this_object->layer == LAYER_BEHIND ? "behind" :
1792 "back");
1793 if (this_object->clip == OBJ_NOCLIP)
1794 fputs("noclip ", fp);
1795 else
1796 fputs("clip ", fp);
1797
1798 if (this_object->lp_properties.l_width)
1799 fprintf(fp, "lw %.1f ",this_object->lp_properties.l_width);
1800 if (this_object->lp_properties.d_type)
1801 save_dashtype(fp, this_object->lp_properties.d_type,
1802 &this_object->lp_properties.custom_dash_pattern);
1803 fprintf(fp, " fc ");
1804 if (this_object->lp_properties.l_type == LT_DEFAULT)
1805 fprintf(fp,"default");
1806 else
1807 save_pm3dcolor(fp, &this_object->lp_properties.pm3d_color);
1808 fprintf(fp, " fillstyle ");
1809 save_fillstyle(fp, &this_object->fillstyle);
1810 }
1811
1812 }
1813 if (tag > 0 && !showed)
1814 int_error(c_token, "object not found");
1815 }
1816
1817 /* Save/show special polygon objects created by "set wall" */
1818 void
save_walls(FILE * fp)1819 save_walls(FILE *fp)
1820 {
1821 static const char* wall_name[5] = {"y0", "x0", "y1", "x1", "z0"};
1822 t_object *this_object;
1823 int i;
1824
1825 for (i = 0; i < 5; i++) {
1826 this_object = &grid_wall[i];
1827 if (this_object->layer == LAYER_FRONTBACK) {
1828 fprintf(fp, "set wall %s ", wall_name[i]);
1829 fprintf(fp, " fc ");
1830 save_pm3dcolor(fp, &this_object->lp_properties.pm3d_color);
1831 fprintf(fp, " fillstyle ");
1832 save_fillstyle(fp, &this_object->fillstyle);
1833 }
1834
1835 }
1836 }
1837
1838