~ubuntu-branches/ubuntu/maverick/gimp/maverick-updates

« back to all changes in this revision

Viewing changes to plug-ins/gfig/gfig.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2005-12-09 19:44:52 UTC
  • Revision ID: james.westby@ubuntu.com-20051209194452-yggpemjlofpjqyf4
Tags: upstream-2.2.9
ImportĀ upstreamĀ versionĀ 2.2.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 
3
 *
 
4
 * This is a plug-in for the GIMP.
 
5
 *
 
6
 * Generates images containing vector type drawings.
 
7
 *
 
8
 * Copyright (C) 1997 Andy Thomas  alt@picnic.demon.co.uk
 
9
 *
 
10
 * This program is free software; you can redistribute it and/or modify
 
11
 * it under the terms of the GNU General Public License as published by
 
12
 * the Free Software Foundation; either version 2 of the License, or
 
13
 * (at your option) any later version.
 
14
 *
 
15
 * This program is distributed in the hope that it will be useful,
 
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
 * GNU General Public License for more details.
 
19
 *
 
20
 * You should have received a copy of the GNU General Public License
 
21
 * along with this program; if not, write to the Free Software
 
22
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
23
 */
 
24
 
 
25
#include "config.h"
 
26
 
 
27
#include <stdio.h>
 
28
#include <stdlib.h>
 
29
#include <string.h>
 
30
#include <errno.h>
 
31
 
 
32
#ifdef HAVE_UNISTD_H
 
33
#include <unistd.h>
 
34
#endif
 
35
 
 
36
#include <gtk/gtk.h>
 
37
 
 
38
#include <libgimp/gimp.h>
 
39
#include <libgimp/gimpui.h>
 
40
 
 
41
#include "libgimp/stdplugins-intl.h"
 
42
 
 
43
#include "gfig.h"
 
44
#include "gfig-style.h"
 
45
#include "gfig-dialog.h"
 
46
#include "gfig-arc.h"
 
47
#include "gfig-bezier.h"
 
48
#include "gfig-circle.h"
 
49
#include "gfig-dobject.h"
 
50
#include "gfig-ellipse.h"
 
51
#include "gfig-grid.h"
 
52
#include "gfig-line.h"
 
53
#include "gfig-poly.h"
 
54
#include "gfig-preview.h"
 
55
#include "gfig-spiral.h"
 
56
#include "gfig-star.h"
 
57
#include "gfig-stock.h"
 
58
 
 
59
/***** Magic numbers *****/
 
60
 
 
61
#define GFIG_HEADER      "GFIG Version 0.2\n"
 
62
 
 
63
static void      query  (void);
 
64
static void      run    (const gchar      *name,
 
65
                         gint              nparams,
 
66
                         const GimpParam  *param,
 
67
                         gint             *nreturn_vals,
 
68
                         GimpParam       **return_vals);
 
69
 
 
70
 
 
71
GimpPlugInInfo PLUG_IN_INFO =
 
72
{
 
73
  NULL,  /* init_proc  */
 
74
  NULL,  /* quit_proc  */
 
75
  query, /* query_proc */
 
76
  run,   /* run_proc   */
 
77
};
 
78
 
 
79
 
 
80
 
 
81
gint line_no;
 
82
 
 
83
gint obj_show_single   = -1; /* -1 all >= 0 object number */
 
84
 
 
85
/* Structures etc for the objects */
 
86
/* Points used to draw the object  */
 
87
 
 
88
 
 
89
GfigObject *obj_creating; /* Object we are creating */
 
90
GfigObject *tmp_line;     /* Needed when drawing lines */
 
91
 
 
92
gboolean need_to_scale;
 
93
 
 
94
static gint       load_options            (GFigObj *gfig,
 
95
                                           FILE    *fp);
 
96
/* globals */
 
97
 
 
98
GdkGC  *gfig_gc;
 
99
 
 
100
/* Stuff for the preview bit */
 
101
static gint  sel_x1, sel_y1, sel_x2, sel_y2;
 
102
static gint  sel_width, sel_height;
 
103
gint         preview_width, preview_height;
 
104
gdouble      scale_x_factor, scale_y_factor;
 
105
GdkPixbuf   *back_pixbuf = NULL;
 
106
 
 
107
MAIN ()
 
108
 
 
109
static void
 
110
query (void)
 
111
{
 
112
  static GimpParamDef args[] =
 
113
  {
 
114
    { GIMP_PDB_INT32,    "run_mode", "Interactive, non-interactive" },
 
115
    { GIMP_PDB_IMAGE,    "image",    "Input image (unused)" },
 
116
    { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
 
117
    { GIMP_PDB_INT32,    "dummy",    "dummy" }
 
118
  };
 
119
 
 
120
  gimp_install_procedure ("plug_in_gfig",
 
121
                          "Create Geometrical shapes with the Gimp",
 
122
                          "Draw Vector Graphics and paint them onto your images.  "
 
123
                          "Gfig allows you to draw many types of objects "
 
124
                          "inlcuding Lines, Circles, Ellipses, Curves, Polygons, "
 
125
                          "pointed stars, Bezier curves, and Spirals.  "
 
126
                          "Objects can be painted using Brushes or other tools"
 
127
                          "or filled using colours or patterns.  "
 
128
                          "Gfig objects can also be used to create selections.  ",
 
129
                          "Andy Thomas",
 
130
                          "Andy Thomas",
 
131
                          "1997",
 
132
                          N_("_Gfig..."),
 
133
                          "RGB*, GRAY*",
 
134
                          GIMP_PLUGIN,
 
135
                          G_N_ELEMENTS (args), 0,
 
136
                          args, NULL);
 
137
 
 
138
  gimp_plugin_menu_register ("plug_in_gfig", "<Image>/Filters/Render");
 
139
}
 
140
 
 
141
static void
 
142
run (const gchar      *name,
 
143
     gint              nparams,
 
144
     const GimpParam  *param,
 
145
     gint             *nreturn_vals,
 
146
     GimpParam       **return_vals)
 
147
{
 
148
  GimpParam         *values = g_new (GimpParam, 1);
 
149
  GimpDrawable      *drawable;
 
150
  GimpRunMode        run_mode;
 
151
  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
 
152
  gint               pwidth, pheight;
 
153
  INIT_I18N ();
 
154
 
 
155
  gfig_context = g_new (GFigContext, 1);
 
156
  gfig_context->show_background = TRUE;
 
157
  gfig_context->selected_obj = NULL;
 
158
 
 
159
  run_mode = param[0].data.d_int32;
 
160
 
 
161
  gfig_context->image_id = param[1].data.d_image;
 
162
  gfig_context->drawable_id = param[2].data.d_drawable;
 
163
 
 
164
  *nreturn_vals = 1;
 
165
  *return_vals = values;
 
166
 
 
167
  values[0].type = GIMP_PDB_STATUS;
 
168
  values[0].data.d_status = status;
 
169
 
 
170
  gimp_image_undo_group_start (gfig_context->image_id);
 
171
 
 
172
  gimp_context_push ();
 
173
 
 
174
  drawable = gimp_drawable_get (param[2].data.d_drawable);
 
175
 
 
176
  /* TMP Hack - clear any selections */
 
177
  if (! gimp_selection_is_empty (gfig_context->image_id))
 
178
    gimp_selection_none (gfig_context->image_id);
 
179
 
 
180
  gimp_drawable_mask_bounds (drawable->drawable_id,
 
181
                             &sel_x1, &sel_y1, &sel_x2, &sel_y2);
 
182
 
 
183
  sel_width  = sel_x2 - sel_x1;
 
184
  sel_height = sel_y2 - sel_y1;
 
185
 
 
186
 
 
187
  /* Calculate preview size */
 
188
 
 
189
  if (sel_width > sel_height)
 
190
    {
 
191
      pwidth  = MIN (sel_width, PREVIEW_SIZE);
 
192
      pheight = sel_height * pwidth / sel_width;
 
193
    }
 
194
  else
 
195
    {
 
196
      pheight = MIN (sel_height, PREVIEW_SIZE);
 
197
      pwidth  = sel_width * pheight / sel_height;
 
198
    }
 
199
 
 
200
 
 
201
  preview_width  = MAX (pwidth, 2);  /* Min size is 2 */
 
202
  preview_height = MAX (pheight, 2);
 
203
 
 
204
  org_scale_x_factor = scale_x_factor =
 
205
    (gdouble) sel_width / (gdouble) preview_width;
 
206
  org_scale_y_factor = scale_y_factor =
 
207
    (gdouble) sel_height / (gdouble) preview_height;
 
208
 
 
209
  gimp_tile_cache_ntiles ((drawable->width + gimp_tile_width () - 1) /
 
210
                          gimp_tile_width ());
 
211
 
 
212
  gimp_drawable_detach (drawable);
 
213
 
 
214
  /* initialize */
 
215
  gfig_init_object_classes ();
 
216
 
 
217
  switch (run_mode)
 
218
    {
 
219
    case GIMP_RUN_INTERACTIVE:
 
220
    case GIMP_RUN_WITH_LAST_VALS:
 
221
      /*gimp_get_data ("plug_in_gfig", &selvals);*/
 
222
      if (! gfig_dialog ())
 
223
        {
 
224
          gimp_drawable_detach (gfig_drawable);
 
225
          gimp_image_undo_group_end (gfig_context->image_id);
 
226
 
 
227
          return;
 
228
        }
 
229
      break;
 
230
 
 
231
    case GIMP_RUN_NONINTERACTIVE:
 
232
      status = GIMP_PDB_CALLING_ERROR;
 
233
      break;
 
234
 
 
235
    default:
 
236
      break;
 
237
    }
 
238
 
 
239
  gimp_context_pop ();
 
240
 
 
241
  gimp_image_undo_group_end (gfig_context->image_id);
 
242
 
 
243
  if (run_mode != GIMP_RUN_NONINTERACTIVE)
 
244
    gimp_displays_flush ();
 
245
  else
 
246
#if 0
 
247
  if (run_mode == GIMP_RUN_INTERACTIVE)
 
248
    gimp_set_data ("plug_in_gfig", &selvals, sizeof (SelectItVals));
 
249
  else
 
250
#endif /* 0 */
 
251
    {
 
252
      status = GIMP_PDB_EXECUTION_ERROR;
 
253
    }
 
254
 
 
255
  values[0].data.d_status = status;
 
256
 
 
257
  /* gimp_drawable_detach (drawable) already done above, don't do it twice */
 
258
}
 
259
 
 
260
/*
 
261
  Translate SPACE to "\\040", etc.
 
262
  Taken from gflare plugin
 
263
 */
 
264
void
 
265
gfig_name_encode (gchar *dest,
 
266
                  gchar *src)
 
267
{
 
268
  gint cnt = MAX_LOAD_LINE - 1;
 
269
 
 
270
  while (*src && cnt--)
 
271
    {
 
272
      if (g_ascii_iscntrl (*src) || g_ascii_isspace (*src) || *src == '\\')
 
273
        {
 
274
          sprintf (dest, "\\%03o", *src++);
 
275
          dest += 4;
 
276
        }
 
277
      else
 
278
        *dest++ = *src++;
 
279
    }
 
280
  *dest = '\0';
 
281
}
 
282
 
 
283
/*
 
284
  Translate "\\040" to SPACE, etc.
 
285
 */
 
286
void
 
287
gfig_name_decode (gchar       *dest,
 
288
                  const gchar *src)
 
289
{
 
290
  gint  cnt = MAX_LOAD_LINE - 1;
 
291
  guint tmp;
 
292
 
 
293
  while (*src && cnt--)
 
294
    {
 
295
      if (*src == '\\' && *(src+1) && *(src+2) && *(src+3))
 
296
        {
 
297
          sscanf (src+1, "%3o", &tmp);
 
298
          *dest++ = tmp;
 
299
          src += 4;
 
300
        }
 
301
      else
 
302
        *dest++ = *src++;
 
303
    }
 
304
  *dest = '\0';
 
305
}
 
306
 
 
307
 
 
308
/*
 
309
 * Load all gfig, which are founded in gfig-path-list, into gfig_list.
 
310
 * gfig-path-list must be initialized first. (plug_in_parse_gfig_path ())
 
311
 * based on code from Gflare.
 
312
 */
 
313
 
 
314
gint
 
315
gfig_list_pos (GFigObj *gfig)
 
316
{
 
317
  GFigObj *g;
 
318
  gint     n;
 
319
  GList   *tmp;
 
320
 
 
321
  n = 0;
 
322
 
 
323
  for (tmp = gfig_list; tmp; tmp = g_list_next (tmp))
 
324
    {
 
325
      g = tmp->data;
 
326
 
 
327
      if (strcmp (gfig->draw_name, g->draw_name) <= 0)
 
328
        break;
 
329
 
 
330
      n++;
 
331
    }
 
332
  return n;
 
333
}
 
334
 
 
335
/*
 
336
 *      Insert gfigs in alphabetical order
 
337
 */
 
338
 
 
339
gint
 
340
gfig_list_insert (GFigObj *gfig)
 
341
{
 
342
  gint n;
 
343
 
 
344
  n = gfig_list_pos (gfig);
 
345
 
 
346
  gfig_list = g_list_insert (gfig_list, gfig, n);
 
347
 
 
348
  return n;
 
349
}
 
350
 
 
351
void
 
352
gfig_free (GFigObj *gfig)
 
353
{
 
354
  g_assert (gfig != NULL);
 
355
 
 
356
  free_all_objs (gfig->obj_list);
 
357
 
 
358
  g_free (gfig->name);
 
359
  g_free (gfig->filename);
 
360
  g_free (gfig->draw_name);
 
361
 
 
362
  g_free (gfig);
 
363
}
 
364
 
 
365
GFigObj *
 
366
gfig_new (void)
 
367
{
 
368
  return g_new0 (GFigObj, 1);
 
369
}
 
370
 
 
371
static void
 
372
gfig_load_objs (GFigObj *gfig,
 
373
                gint     load_count,
 
374
                FILE    *fp)
 
375
{
 
376
  GfigObject *obj;
 
377
  gchar       load_buf[MAX_LOAD_LINE];
 
378
  glong       offset;
 
379
  glong       offset2;
 
380
  Style       style;
 
381
 
 
382
  while (load_count-- > 0)
 
383
    {
 
384
      obj = NULL;
 
385
      get_line (load_buf, MAX_LOAD_LINE, fp, 0);
 
386
 
 
387
      /* kludge */
 
388
      offset = ftell (fp);
 
389
      gfig_skip_style (&style, fp);
 
390
 
 
391
      obj = d_load_object (load_buf, fp);
 
392
 
 
393
      if (obj)
 
394
        {
 
395
          add_to_all_obj (gfig, obj);
 
396
          offset2 = ftell (fp);
 
397
          fseek (fp, offset, SEEK_SET);
 
398
          gfig_load_style (&obj->style, fp);
 
399
          fseek (fp, offset2, SEEK_SET);
 
400
        }
 
401
      else
 
402
        {
 
403
          g_message ("Failed to load object, load count = %d", load_count);
 
404
        }
 
405
    }
 
406
}
 
407
 
 
408
GFigObj *
 
409
gfig_load (const gchar *filename,
 
410
           const gchar *name)
 
411
{
 
412
  GFigObj *gfig;
 
413
  FILE    *fp;
 
414
  gchar    load_buf[MAX_LOAD_LINE];
 
415
  gchar    str_buf[MAX_LOAD_LINE];
 
416
  gint     chk_count;
 
417
  gint     load_count = 0;
 
418
  gdouble  version;
 
419
  guchar   magic1[20];
 
420
  guchar   magic2[20];
 
421
 
 
422
  g_assert (filename != NULL);
 
423
 
 
424
#ifdef DEBUG
 
425
  printf ("Loading %s (%s)\n", filename, name);
 
426
#endif /* DEBUG */
 
427
 
 
428
  fp = fopen (filename, "r");
 
429
  if (!fp)
 
430
    {
 
431
      g_message (_("Could not open '%s' for reading: %s"),
 
432
                  gimp_filename_to_utf8 (filename), g_strerror (errno));
 
433
      return NULL;
 
434
    }
 
435
 
 
436
  gfig = gfig_new ();
 
437
 
 
438
  gfig->name = g_strdup (name);
 
439
  gfig->filename = g_strdup (filename);
 
440
 
 
441
 
 
442
  /* HEADER
 
443
   * draw_name
 
444
   * version
 
445
   * obj_list
 
446
   */
 
447
 
 
448
  get_line (load_buf, MAX_LOAD_LINE, fp, 1);
 
449
 
 
450
  sscanf (load_buf, "%10s %10s %lf", magic1, magic2, &version);
 
451
 
 
452
  if (strcmp (magic1, "GFIG") || strcmp (magic2, "Version"))
 
453
    {
 
454
      g_message ("File '%s' is not a gfig file",
 
455
                  gimp_filename_to_utf8 (gfig->filename));
 
456
      return NULL;
 
457
    }
 
458
 
 
459
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
 
460
  sscanf (load_buf, "Name: %100s", str_buf);
 
461
  gfig_name_decode (load_buf, str_buf);
 
462
  gfig->draw_name = g_strdup (load_buf);
 
463
 
 
464
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
 
465
  if (strncmp (load_buf, "Version: ", 9) == 0)
 
466
    gfig->version = g_ascii_strtod (load_buf + 9, NULL);
 
467
 
 
468
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
 
469
  sscanf (load_buf, "ObjCount: %d", &load_count);
 
470
 
 
471
  if (load_options (gfig, fp))
 
472
    {
 
473
      g_message ("File '%s' corrupt file - Line %d Option section incorrect",
 
474
                 gimp_filename_to_utf8 (filename), line_no);
 
475
      return NULL;
 
476
    }
 
477
 
 
478
  if (gfig_load_styles (gfig, fp))
 
479
    {
 
480
      g_message ("File '%s' corrupt file - Line %d Option section incorrect",
 
481
                 gimp_filename_to_utf8 (filename), line_no);
 
482
      return NULL;
 
483
    }
 
484
 
 
485
 
 
486
 
 
487
  gfig_load_objs (gfig, load_count, fp);
 
488
 
 
489
  /* Check count ? */
 
490
 
 
491
  chk_count = g_list_length (gfig->obj_list);
 
492
 
 
493
  if (chk_count != load_count)
 
494
    {
 
495
      g_message ("File '%s' corrupt file - Line %d Object count to small",
 
496
                 gimp_filename_to_utf8 (filename), line_no);
 
497
      return NULL;
 
498
    }
 
499
 
 
500
  fclose (fp);
 
501
 
 
502
  if (!gfig_context->current_obj)
 
503
    gfig_context->current_obj = gfig;
 
504
 
 
505
  gfig->obj_status = GFIG_OK;
 
506
 
 
507
  return gfig;
 
508
}
 
509
 
 
510
void
 
511
save_options (GString *string)
 
512
{
 
513
  /* Save options */
 
514
  g_string_append_printf (string, "<OPTIONS>\n");
 
515
  g_string_append_printf (string, "GridSpacing: %d\n",
 
516
                          selvals.opts.gridspacing);
 
517
  if (selvals.opts.gridtype == RECT_GRID)
 
518
    {
 
519
      g_string_append_printf (string, "GridType: RECT_GRID\n");
 
520
    }
 
521
  else if (selvals.opts.gridtype == POLAR_GRID)
 
522
    {
 
523
      g_string_append_printf (string, "GridType: POLAR_GRID\n");
 
524
    }
 
525
  else if (selvals.opts.gridtype == ISO_GRID)
 
526
    {
 
527
      g_string_append_printf (string, "GridType: ISO_GRID\n");
 
528
    }
 
529
  else
 
530
    {
 
531
      /* default to RECT_GRID */
 
532
      g_string_append_printf (string, "GridType: RECT_GRID\n");
 
533
    }
 
534
 
 
535
  g_string_append_printf (string, "DrawGrid: %s\n",
 
536
                          (selvals.opts.drawgrid) ? "TRUE" : "FALSE");
 
537
  g_string_append_printf (string, "Snap2Grid: %s\n",
 
538
                          (selvals.opts.snap2grid) ? "TRUE" : "FALSE");
 
539
  g_string_append_printf (string, "LockOnGrid: %s\n",
 
540
                          (selvals.opts.lockongrid) ? "TRUE" : "FALSE");
 
541
  g_string_append_printf (string, "ShowControl: %s\n",
 
542
                          (selvals.opts.showcontrol) ? "TRUE" : "FALSE");
 
543
  g_string_append_printf (string, "</OPTIONS>\n");
 
544
}
 
545
 
 
546
static void
 
547
gfig_save_obj_start (GfigObject *obj,
 
548
                     GString    *string)
 
549
{
 
550
  g_string_append_printf (string, "<%s ", obj->class->name);
 
551
  gfig_style_save_as_attributes (&obj->style, string);
 
552
  g_string_append_printf (string, ">\n");
 
553
}
 
554
 
 
555
static void
 
556
gfig_save_obj_end (GfigObject *obj,
 
557
                   GString    *string)
 
558
{
 
559
  g_string_append_printf (string, "</%s>\n",obj->class->name);
 
560
}
 
561
 
 
562
static gboolean
 
563
load_bool (gchar *opt_buf,
 
564
           gint  *toset)
 
565
{
 
566
  if (!strcmp (opt_buf, "TRUE"))
 
567
    *toset = 1;
 
568
  else if (!strcmp (opt_buf, "FALSE"))
 
569
    *toset = 0;
 
570
  else
 
571
    return TRUE;
 
572
 
 
573
  return FALSE;
 
574
}
 
575
 
 
576
static gint
 
577
load_options (GFigObj *gfig,
 
578
              FILE    *fp)
 
579
{
 
580
  gchar load_buf[MAX_LOAD_LINE];
 
581
  gchar str_buf[MAX_LOAD_LINE];
 
582
  gchar opt_buf[MAX_LOAD_LINE];
 
583
 
 
584
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
 
585
 
 
586
#ifdef DEBUG
 
587
  printf ("load '%s'\n", load_buf);
 
588
#endif /* DEBUG */
 
589
 
 
590
  if (strcmp (load_buf, "<OPTIONS>"))
 
591
    return (-1);
 
592
 
 
593
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
 
594
 
 
595
#ifdef DEBUG
 
596
  printf ("opt line '%s'\n", load_buf);
 
597
#endif /* DEBUG */
 
598
 
 
599
  while (strcmp (load_buf, "</OPTIONS>"))
 
600
    {
 
601
      /* Get option name */
 
602
#ifdef DEBUG
 
603
      printf ("num = %d\n", sscanf (load_buf, "%s %s", str_buf, opt_buf));
 
604
 
 
605
      printf ("option %s val %s\n", str_buf, opt_buf);
 
606
#else
 
607
      sscanf (load_buf, "%s %s", str_buf, opt_buf);
 
608
#endif /* DEBUG */
 
609
 
 
610
      if (!strcmp (str_buf, "GridSpacing:"))
 
611
        {
 
612
          /* Value is decimal */
 
613
          int sp = 0;
 
614
          sp = atoi (opt_buf);
 
615
          if (sp <= 0)
 
616
            return (-1);
 
617
          gfig->opts.gridspacing = sp;
 
618
        }
 
619
      else if (!strcmp (str_buf, "DrawGrid:"))
 
620
        {
 
621
          /* Value is bool */
 
622
          if (load_bool (opt_buf, &gfig->opts.drawgrid))
 
623
            return (-1);
 
624
        }
 
625
      else if (!strcmp (str_buf, "Snap2Grid:"))
 
626
        {
 
627
          /* Value is bool */
 
628
          if (load_bool (opt_buf, &gfig->opts.snap2grid))
 
629
            return (-1);
 
630
        }
 
631
      else if (!strcmp (str_buf, "LockOnGrid:"))
 
632
        {
 
633
          /* Value is bool */
 
634
          if (load_bool (opt_buf, &gfig->opts.lockongrid))
 
635
            return (-1);
 
636
        }
 
637
      else if (!strcmp (str_buf, "ShowControl:"))
 
638
        {
 
639
          /* Value is bool */
 
640
          if (load_bool (opt_buf, &gfig->opts.showcontrol))
 
641
            return (-1);
 
642
        }
 
643
      else if (!strcmp (str_buf, "GridType:"))
 
644
        {
 
645
          /* Value is string */
 
646
          if (!strcmp (opt_buf, "RECT_GRID"))
 
647
            gfig->opts.gridtype = RECT_GRID;
 
648
          else if (!strcmp (opt_buf, "POLAR_GRID"))
 
649
            gfig->opts.gridtype = POLAR_GRID;
 
650
          else if (!strcmp (opt_buf, "ISO_GRID"))
 
651
            gfig->opts.gridtype = ISO_GRID;
 
652
          else
 
653
            return (-1);
 
654
        }
 
655
 
 
656
      get_line (load_buf, MAX_LOAD_LINE, fp, 0);
 
657
 
 
658
#ifdef DEBUG
 
659
      printf ("opt line '%s'\n", load_buf);
 
660
#endif /* DEBUG */
 
661
    }
 
662
  return (0);
 
663
}
 
664
 
 
665
GString *
 
666
gfig_save_as_string (void)
 
667
{
 
668
  GList    *objs;
 
669
  gint      count;
 
670
  gchar     buf[G_ASCII_DTOSTR_BUF_SIZE];
 
671
  gchar     conv_buf[MAX_LOAD_LINE * 3 + 1];
 
672
  GString  *string;
 
673
 
 
674
  string = g_string_new (GFIG_HEADER);
 
675
 
 
676
  gfig_name_encode (conv_buf, gfig_context->current_obj->draw_name);
 
677
  g_string_append_printf (string, "Name: %s\n", conv_buf);
 
678
  g_string_append_printf (string, "Version: %s\n",
 
679
                          g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f",
 
680
                                           gfig_context->current_obj->version));
 
681
  objs = gfig_context->current_obj->obj_list;
 
682
 
 
683
  count = g_list_length (objs);
 
684
 
 
685
  g_string_append_printf (string, "ObjCount: %d\n", count);
 
686
 
 
687
  save_options (string);
 
688
 
 
689
  gfig_save_styles (string);
 
690
 
 
691
  for (objs = gfig_context->current_obj->obj_list;
 
692
       objs;
 
693
       objs = g_list_next (objs))
 
694
    {
 
695
      GfigObject *object = objs->data;
 
696
 
 
697
      gfig_save_obj_start (object, string);
 
698
 
 
699
      gfig_save_style (&object->style, string);
 
700
 
 
701
      if (object->points)
 
702
        d_save_object (object, string);
 
703
 
 
704
      gfig_save_obj_end (object, string);
 
705
    }
 
706
 
 
707
  return string;
 
708
}
 
709
 
 
710
 
 
711
gboolean
 
712
gfig_save_as_parasite (void)
 
713
{
 
714
  GimpParasite *parasite;
 
715
  GString       *string;
 
716
 
 
717
  string = gfig_save_as_string ();
 
718
 
 
719
  parasite = gimp_parasite_new ("gfig", GIMP_PARASITE_PERSISTENT | GIMP_PARASITE_UNDOABLE,
 
720
                                string->len, string->str);
 
721
 
 
722
  g_string_free (string, TRUE);
 
723
 
 
724
  if (!gimp_drawable_parasite_attach (gfig_context->drawable_id, parasite))
 
725
    {
 
726
      g_message (_("Error trying to save figure as a parasite: can't attach parasite to drawable.\n"));
 
727
      gimp_parasite_free (parasite);
 
728
      return FALSE;
 
729
    }
 
730
 
 
731
  gimp_parasite_free (parasite);
 
732
  return TRUE;
 
733
}
 
734
 
 
735
GFigObj *
 
736
gfig_load_from_parasite (void)
 
737
{
 
738
  FILE         *fp;
 
739
  gchar        *fname;
 
740
  GimpParasite *parasite;
 
741
  GFigObj      *gfig;
 
742
 
 
743
  parasite = gimp_drawable_parasite_find (gfig_context->drawable_id, "gfig");
 
744
  if (! parasite)
 
745
    return NULL;
 
746
 
 
747
  fname = gimp_temp_name ("gfigtmp");
 
748
 
 
749
  fp = fopen (fname, "w");
 
750
  if (!fp)
 
751
    {
 
752
      g_message (_("Error trying to open temporary file '%s' "
 
753
                   "for parasite loading: %s"),
 
754
                 gimp_filename_to_utf8 (fname), g_strerror (errno));
 
755
      return NULL;
 
756
    }
 
757
 
 
758
  fwrite (gimp_parasite_data (parasite),
 
759
          sizeof (guchar),
 
760
          gimp_parasite_data_size (parasite),
 
761
          fp);
 
762
  fclose (fp);
 
763
 
 
764
  gimp_parasite_free (parasite);
 
765
 
 
766
  gfig = gfig_load (fname, "(none)");
 
767
 
 
768
  unlink (fname);
 
769
 
 
770
  g_free (fname);
 
771
 
 
772
  return gfig;
 
773
}
 
774
 
 
775
void
 
776
gfig_save_callbk (void)
 
777
{
 
778
  FILE     *fp;
 
779
  gchar    *savename;
 
780
  GString  *string;
 
781
 
 
782
  savename = gfig_context->current_obj->filename;
 
783
 
 
784
  fp = fopen (savename, "w+");
 
785
 
 
786
  if (!fp)
 
787
    {
 
788
      g_message (_("Could not open '%s' for writing: %s"),
 
789
                 gimp_filename_to_utf8 (savename), g_strerror (errno));
 
790
      return;
 
791
    }
 
792
 
 
793
  string = gfig_save_as_string ();
 
794
 
 
795
  fwrite (string->str, string->len, 1, fp);
 
796
 
 
797
  if (ferror (fp))
 
798
    g_message ("Failed to write file\n");
 
799
  else
 
800
    {
 
801
      gfig_context->current_obj->obj_status &= ~(GFIG_MODIFIED | GFIG_READONLY);
 
802
    }
 
803
 
 
804
  fclose (fp);
 
805
 
 
806
}