gfig.c 18.5 KB
Newer Older
Manish Singh's avatar
Manish Singh committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * This is a plug-in for the GIMP.
 *
 * Generates images containing vector type drawings.
 *
 * Copyright (C) 1997 Andy Thomas  alt@picnic.demon.co.uk
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Manish Singh's avatar
Manish Singh committed
23
24
 */

Tor Lillqvist's avatar
Tor Lillqvist committed
25
26
#include "config.h"

Manish Singh's avatar
Manish Singh committed
27
28
#include <stdio.h>
#include <stdlib.h>
29
#include <string.h>
30
#include <errno.h>
31

Tor Lillqvist's avatar
Tor Lillqvist committed
32
#ifdef HAVE_UNISTD_H
Manish Singh's avatar
Manish Singh committed
33
#include <unistd.h>
Tor Lillqvist's avatar
Tor Lillqvist committed
34
#endif
35

Manish Singh's avatar
Manish Singh committed
36
#include <gtk/gtk.h>
Tor Lillqvist's avatar
Tor Lillqvist committed
37

38
39
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
40

41
42
#include "libgimp/stdplugins-intl.h"

43
#include "gfig.h"
44
45
#include "gfig-style.h"
#include "gfig-dialog.h"
46
47
48
49
50
#include "gfig-arc.h"
#include "gfig-bezier.h"
#include "gfig-circle.h"
#include "gfig-dobject.h"
#include "gfig-ellipse.h"
51
#include "gfig-grid.h"
52
53
#include "gfig-line.h"
#include "gfig-poly.h"
54
#include "gfig-preview.h"
55
56
#include "gfig-spiral.h"
#include "gfig-star.h"
57
58
#include "gfig-stock.h"

Manish Singh's avatar
Manish Singh committed
59
60
/***** Magic numbers *****/

61
62
#define GFIG_HEADER      "GFIG Version 0.2\n"

Manish Singh's avatar
Manish Singh committed
63
static void      query  (void);
64
static void      run    (const gchar      *name,
65
66
67
68
                         gint              nparams,
                         const GimpParam  *param,
                         gint             *nreturn_vals,
                         GimpParam       **return_vals);
69

70

71
GimpPlugInInfo PLUG_IN_INFO =
Manish Singh's avatar
Manish Singh committed
72
{
73
74
75
76
  NULL,  /* init_proc  */
  NULL,  /* quit_proc  */
  query, /* query_proc */
  run,   /* run_proc   */
Manish Singh's avatar
Manish Singh committed
77
78
79
80
};



81
gint line_no;
Manish Singh's avatar
Manish Singh committed
82

83
gint obj_show_single   = -1; /* -1 all >= 0 object number */
Manish Singh's avatar
Manish Singh committed
84
85
86
87
88

/* Structures etc for the objects */
/* Points used to draw the object  */


89
90
Dobject *obj_creating; /* Object we are creating */
Dobject *tmp_line;     /* Needed when drawing lines */
Manish Singh's avatar
Manish Singh committed
91

92

93
gint need_to_scale;
94

Manish Singh's avatar
Manish Singh committed
95

96
static gint       load_options            (GFigObj *gfig,
97
                                           FILE    *fp);
Manish Singh's avatar
Manish Singh committed
98
99
/* globals */

100
GdkGC  *gfig_gc;
Manish Singh's avatar
Manish Singh committed
101
102

/* Stuff for the preview bit */
103
104
105
106
107
static gint  sel_x1, sel_y1, sel_x2, sel_y2;
static gint  sel_width, sel_height;
gint         preview_width, preview_height;
gdouble      scale_x_factor, scale_y_factor;
GdkPixbuf   *back_pixbuf = NULL;
Manish Singh's avatar
Manish Singh committed
108

Adrian Likins's avatar
Adrian Likins committed
109
MAIN ()
Manish Singh's avatar
Manish Singh committed
110
111

static void
112
query (void)
Manish Singh's avatar
Manish Singh committed
113
{
114
  static GimpParamDef args[] =
Manish Singh's avatar
Manish Singh committed
115
  {
116
117
    { GIMP_PDB_INT32,    "run_mode", "Interactive, non-interactive" },
    { GIMP_PDB_IMAGE,    "image",    "Input image (unused)" },
118
    { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
119
    { GIMP_PDB_INT32,    "dummy",    "dummy" }
Manish Singh's avatar
Manish Singh committed
120
  };
David Monniaux's avatar
David Monniaux committed
121

Manish Singh's avatar
Manish Singh committed
122
  gimp_install_procedure ("plug_in_gfig",
123
124
125
126
127
                          "Create Geometrical shapes with the Gimp",
                          "More here later",
                          "Andy Thomas",
                          "Andy Thomas",
                          "1997",
128
                          N_("_Gfig..."),
129
130
131
132
                          "RGB*, GRAY*",
                          GIMP_PLUGIN,
                          G_N_ELEMENTS (args), 0,
                          args, NULL);
133

134
  gimp_plugin_menu_register ("plug_in_gfig", "<Image>/Filters/Render");
Manish Singh's avatar
Manish Singh committed
135
136
137
}

static void
138
139
140
141
142
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
Manish Singh's avatar
Manish Singh committed
143
{
144
145
146
147
  GimpParam         *values = g_new (GimpParam, 1);
  GimpDrawable      *drawable;
  GimpRunMode        run_mode;
  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
148
  gint               pwidth, pheight;
149
150
  INIT_I18N ();

David Odin's avatar
typo    
David Odin committed
151
  gfig_context = g_new (GFigContext, 1);
152
153
  gfig_context->show_background = TRUE;
  gfig_context->selected_obj = NULL;
Manish Singh's avatar
Manish Singh committed
154
  run_mode = param[0].data.d_int32;
155
156
  gfig_context->image_id = param[1].data.d_image;
  gfig_context->drawable_id = param[2].data.d_drawable;
Manish Singh's avatar
Manish Singh committed
157
158
159
160

  *nreturn_vals = 1;
  *return_vals = values;

161
  values[0].type = GIMP_PDB_STATUS;
Manish Singh's avatar
Manish Singh committed
162
163
  values[0].data.d_status = status;

164
165
166
  gimp_image_undo_group_start (gfig_context->image_id);

  drawable = gimp_drawable_get (param[2].data.d_drawable);
Manish Singh's avatar
Manish Singh committed
167
168

  /* TMP Hack - clear any selections */
169
  if (! gimp_selection_is_empty (gfig_context->image_id))
170
    gimp_selection_none (gfig_context->image_id);
Manish Singh's avatar
Manish Singh committed
171

172
  gimp_drawable_mask_bounds (drawable->drawable_id,
173
                             &sel_x1, &sel_y1, &sel_x2, &sel_y2);
Manish Singh's avatar
Manish Singh committed
174
175
176
177

  sel_width  = sel_x2 - sel_x1;
  sel_height = sel_y2 - sel_y1;

178

Manish Singh's avatar
Manish Singh committed
179
  /* Calculate preview size */
180

181
182
183
184
185
186
187
188
189
  if (sel_width > sel_height)
    {
      pwidth  = MIN (sel_width, PREVIEW_SIZE);
      pheight = sel_height * pwidth / sel_width;
    }
  else
    {
      pheight = MIN (sel_height, PREVIEW_SIZE);
      pwidth  = sel_width * pheight / sel_height;
190
    }
191

192

193
  preview_width  = MAX (pwidth, 2);  /* Min size is 2 */
194
  preview_height = MAX (pheight, 2);
Manish Singh's avatar
Manish Singh committed
195

196
197
198
199
  org_scale_x_factor = scale_x_factor =
    (gdouble) sel_width / (gdouble) preview_width;
  org_scale_y_factor = scale_y_factor =
    (gdouble) sel_height / (gdouble) preview_height;
200

201
202
203
204
205
  gimp_tile_cache_ntiles ((drawable->width + gimp_tile_width () - 1) /
                          gimp_tile_width ());

  gimp_drawable_detach (drawable);

206
207
208
  /* initialize */
  gfig_init_object_classes ();

Manish Singh's avatar
Manish Singh committed
209
210
  switch (run_mode)
    {
211
    case GIMP_RUN_INTERACTIVE:
Manish Singh's avatar
Manish Singh committed
212
      /*gimp_get_data ("plug_in_gfig", &selvals);*/
213
      if (! gfig_dialog ())
214
        {
215
216
217
          gimp_drawable_detach (gfig_drawable);
          gimp_image_undo_group_end (gfig_context->image_id);

218
219
          return;
        }
Manish Singh's avatar
Manish Singh committed
220
221
      break;

222
223
    case GIMP_RUN_NONINTERACTIVE:
      status = GIMP_PDB_CALLING_ERROR;
Manish Singh's avatar
Manish Singh committed
224
225
      break;

226
    case GIMP_RUN_WITH_LAST_VALS:
Manish Singh's avatar
Manish Singh committed
227
228
229
230
231
232
233
      /*gimp_get_data ("plug_in_gfig", &selvals);*/
      break;

    default:
      break;
    }

234
  gimp_image_undo_group_end (gfig_context->image_id);
235

236
237
  if (run_mode != GIMP_RUN_NONINTERACTIVE)
    gimp_displays_flush ();
238
  else
Manish Singh's avatar
Manish Singh committed
239
#if 0
240
241
  if (run_mode == GIMP_RUN_INTERACTIVE)
    gimp_set_data ("plug_in_gfig", &selvals, sizeof (SelectItVals));
Manish Singh's avatar
Manish Singh committed
242
  else
243
#endif /* 0 */
Manish Singh's avatar
Manish Singh committed
244
    {
245
      status = GIMP_PDB_EXECUTION_ERROR;
Manish Singh's avatar
Manish Singh committed
246
247
248
249
    }

  values[0].data.d_status = status;

250
  /* gimp_drawable_detach (drawable) already done above, don't do it twice */
Manish Singh's avatar
Manish Singh committed
251
252
253
254
}

/*
  Translate SPACE to "\\040", etc.
Manish Singh's avatar
Manish Singh committed
255
  Taken from gflare plugin
Manish Singh's avatar
Manish Singh committed
256
 */
257
void
258
gfig_name_encode (gchar *dest,
259
                  gchar *src)
Manish Singh's avatar
Manish Singh committed
260
{
261
  gint cnt = MAX_LOAD_LINE - 1;
Manish Singh's avatar
Manish Singh committed
262
263
264

  while (*src && cnt--)
    {
265
      if (g_ascii_iscntrl (*src) || g_ascii_isspace (*src) || *src == '\\')
266
267
268
269
        {
          sprintf (dest, "\\%03o", *src++);
          dest += 4;
        }
Manish Singh's avatar
Manish Singh committed
270
      else
271
        *dest++ = *src++;
Manish Singh's avatar
Manish Singh committed
272
273
274
275
276
277
278
    }
  *dest = '\0';
}

/*
  Translate "\\040" to SPACE, etc.
 */
279
void
280
gfig_name_decode (gchar       *dest,
281
                  const gchar *src)
Manish Singh's avatar
Manish Singh committed
282
{
283
284
  gint  cnt = MAX_LOAD_LINE - 1;
  guint tmp;
Manish Singh's avatar
Manish Singh committed
285
286
287
288

  while (*src && cnt--)
    {
      if (*src == '\\' && *(src+1) && *(src+2) && *(src+3))
289
290
291
292
293
        {
          sscanf (src+1, "%3o", &tmp);
          *dest++ = tmp;
          src += 4;
        }
Manish Singh's avatar
Manish Singh committed
294
      else
295
        *dest++ = *src++;
Manish Singh's avatar
Manish Singh committed
296
297
298
299
300
301
302
303
304
305
306
    }
  *dest = '\0';
}


/*
 * Load all gfig, which are founded in gfig-path-list, into gfig_list.
 * gfig-path-list must be initialized first. (plug_in_parse_gfig_path ())
 * based on code from Gflare.
 */

307
gint
308
gfig_list_pos (GFigObj *gfig)
Manish Singh's avatar
Manish Singh committed
309
{
310
  GFigObj *g;
311
312
  gint     n;
  GList   *tmp;
Manish Singh's avatar
Manish Singh committed
313
314

  n = 0;
315

316
  for (tmp = gfig_list; tmp; tmp = g_list_next (tmp))
Manish Singh's avatar
Manish Singh committed
317
318
    {
      g = tmp->data;
319

Manish Singh's avatar
Manish Singh committed
320
      if (strcmp (gfig->draw_name, g->draw_name) <= 0)
321
        break;
322

Manish Singh's avatar
Manish Singh committed
323
324
      n++;
    }
325
  return n;
Manish Singh's avatar
Manish Singh committed
326
327
}

328
/*
329
 *      Insert gfigs in alphabetical order
330
331
 */

332
gint
333
gfig_list_insert (GFigObj *gfig)
Manish Singh's avatar
Manish Singh committed
334
{
335
  gint n;
Manish Singh's avatar
Manish Singh committed
336

337
  n = gfig_list_pos (gfig);
Manish Singh's avatar
Manish Singh committed
338
339
340
341
342
343

  gfig_list = g_list_insert (gfig_list, gfig, n);

  return n;
}

344
void
345
gfig_free (GFigObj *gfig)
Manish Singh's avatar
Manish Singh committed
346
347
348
{
  g_assert (gfig != NULL);

349
  free_all_objs (gfig->obj_list);
350
351
352
353
354

  g_free (gfig->name);
  g_free (gfig->filename);
  g_free (gfig->draw_name);

Manish Singh's avatar
Manish Singh committed
355
356
357
  g_free (gfig);
}

358
GFigObj *
359
gfig_new (void)
Manish Singh's avatar
Manish Singh committed
360
{
361
  return g_new0 (GFigObj, 1);
Manish Singh's avatar
Manish Singh committed
362
363
}

364
365
static void
gfig_load_objs (GFigObj *gfig,
366
367
                gint     load_count,
                FILE    *fp)
Manish Singh's avatar
Manish Singh committed
368
{
369
  Dobject *obj;
370
371
372
373
  gchar    load_buf[MAX_LOAD_LINE];
  glong    offset;
  glong    offset2;
  Style    style;
Manish Singh's avatar
Manish Singh committed
374

375
  while (load_count-- > 0)
Manish Singh's avatar
Manish Singh committed
376
377
    {
      obj = NULL;
378
379
      get_line (load_buf, MAX_LOAD_LINE, fp, 0);

380
381
382
383
      /* kludge */
      offset = ftell (fp);
      gfig_skip_style (&style, fp);

384
      obj = d_load_object (load_buf, fp);
385

386
      if (obj)
387
388
        {
          add_to_all_obj (gfig, obj);
389
390
391
392
          offset2 = ftell (fp);
          fseek (fp, offset, SEEK_SET);
          gfig_load_style (&obj->style, fp);
          fseek (fp, offset2, SEEK_SET);
393
        }
394
395
396
397
      else
        {
          g_message ("Failed to load object, load count = %d", load_count);
        }
Manish Singh's avatar
Manish Singh committed
398
399
400
    }
}

401
GFigObj *
402
403
gfig_load (const gchar *filename,
           const gchar *name)
Manish Singh's avatar
Manish Singh committed
404
{
405
406
407
408
409
410
  GFigObj *gfig;
  FILE    *fp;
  gchar    load_buf[MAX_LOAD_LINE];
  gchar    str_buf[MAX_LOAD_LINE];
  gint     chk_count;
  gint     load_count = 0;
411
412
413
  gdouble  version;
  guchar   magic1[20];
  guchar   magic2[20];
414

Manish Singh's avatar
Manish Singh committed
415
416
417
  g_assert (filename != NULL);

#ifdef DEBUG
418
  printf ("Loading %s (%s)\n", filename, name);
Manish Singh's avatar
Manish Singh committed
419
420
421
422
423
#endif /* DEBUG */

  fp = fopen (filename, "r");
  if (!fp)
    {
424
      g_message (_("Could not open '%s' for reading: %s"),
425
                  gimp_filename_to_utf8 (filename), g_strerror (errno));
Manish Singh's avatar
Manish Singh committed
426
427
428
      return NULL;
    }

429
  gfig = gfig_new ();
Manish Singh's avatar
Manish Singh committed
430

431
432
  gfig->name = g_strdup (name);
  gfig->filename = g_strdup (filename);
Manish Singh's avatar
Manish Singh committed
433
434
435
436
437
438
439
440


  /* HEADER
   * draw_name
   * version
   * obj_list
   */

441
  get_line (load_buf, MAX_LOAD_LINE, fp, 1);
Manish Singh's avatar
Manish Singh committed
442

443
444
445
  sscanf (load_buf, "%10s %10s %lf", magic1, magic2, &version);

  if (strcmp (magic1, "GFIG") || strcmp (magic2, "Version"))
Manish Singh's avatar
Manish Singh committed
446
    {
447
448
      g_message ("File '%s' is not a gfig file",
                  gimp_filename_to_utf8 (gfig->filename));
449
      return NULL;
Manish Singh's avatar
Manish Singh committed
450
    }
451

452
453
454
455
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
  sscanf (load_buf, "Name: %100s", str_buf);
  gfig_name_decode (load_buf, str_buf);
  gfig->draw_name = g_strdup (load_buf);
456

457
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
458
459
  if (strncmp (load_buf, "Version: ", 9) == 0)
    gfig->version = g_ascii_strtod (load_buf + 9, NULL);
460

461
462
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
  sscanf (load_buf, "ObjCount: %d", &load_count);
463

464
  if (load_options (gfig, fp))
Manish Singh's avatar
Manish Singh committed
465
    {
466
      g_message ("File '%s' corrupt file - Line %d Option section incorrect",
467
                 gimp_filename_to_utf8 (filename), line_no);
468
      return NULL;
Manish Singh's avatar
Manish Singh committed
469
470
    }

471
472
473
474
475
476
  if (gfig_load_styles (gfig, fp))
    {
      g_message ("File '%s' corrupt file - Line %d Option section incorrect",
                 gimp_filename_to_utf8 (filename), line_no);
      return NULL;
    }
Manish Singh's avatar
Manish Singh committed
477

478
479


480
  gfig_load_objs (gfig, load_count, fp);
481

Manish Singh's avatar
Manish Singh committed
482
  /* Check count ? */
483

484
  chk_count = g_list_length (gfig->obj_list);
485

486
  if (chk_count != load_count)
Manish Singh's avatar
Manish Singh committed
487
    {
488
      g_message ("File '%s' corrupt file - Line %d Object count to small",
489
                 gimp_filename_to_utf8 (filename), line_no);
490
      return NULL;
Manish Singh's avatar
Manish Singh committed
491
    }
492

493
  fclose (fp);
Manish Singh's avatar
Manish Singh committed
494

495
496
  if (!gfig_context->current_obj)
    gfig_context->current_obj = gfig;
Manish Singh's avatar
Manish Singh committed
497
498
499

  gfig->obj_status = GFIG_OK;

500
  return gfig;
Manish Singh's avatar
Manish Singh committed
501
502
}

503
504
void
save_options (GString *string)
Manish Singh's avatar
Manish Singh committed
505
506
{
  /* Save options */
507
  g_string_append_printf (string, "<OPTIONS>\n");
508
509
  g_string_append_printf (string, "GridSpacing: %d\n",
                          selvals.opts.gridspacing);
510
  if (selvals.opts.gridtype == RECT_GRID)
511
512
513
    {
      g_string_append_printf (string, "GridType: RECT_GRID\n");
    }
514
  else if (selvals.opts.gridtype == POLAR_GRID)
515
516
517
    {
      g_string_append_printf (string, "GridType: POLAR_GRID\n");
    }
518
  else if (selvals.opts.gridtype == ISO_GRID)
519
520
521
    {
      g_string_append_printf (string, "GridType: ISO_GRID\n");
    }
522
  else
523
    {
524
525
      /* default to RECT_GRID */
      g_string_append_printf (string, "GridType: RECT_GRID\n");
526
527
    }

528
529
530
531
532
533
534
535
  g_string_append_printf (string, "DrawGrid: %s\n",
                          (selvals.opts.drawgrid) ? "TRUE" : "FALSE");
  g_string_append_printf (string, "Snap2Grid: %s\n",
                          (selvals.opts.snap2grid) ? "TRUE" : "FALSE");
  g_string_append_printf (string, "LockOnGrid: %s\n",
                          (selvals.opts.lockongrid) ? "TRUE" : "FALSE");
  g_string_append_printf (string, "ShowControl: %s\n",
                          (selvals.opts.showcontrol) ? "TRUE" : "FALSE");
536
537
538
  g_string_append_printf (string, "</OPTIONS>\n");
}

539
540
static void
gfig_save_obj_start (Dobject *obj,
541
542
                     GString *string)
{
543
544
545
  g_string_append_printf (string, "<%s ", obj->class->name);
  gfig_style_save_as_attributes (&obj->style, string);
  g_string_append_printf (string, ">\n");
546
547
}

548
549
static void
gfig_save_obj_end (Dobject *obj,
550
551
                   GString *string)
{
552
  g_string_append_printf (string, "</%s>\n",obj->class->name);
553
554
}

555
static gboolean
556
load_bool (gchar *opt_buf,
557
           gint  *toset)
558
559
{
  if (!strcmp (opt_buf, "TRUE"))
Manish Singh's avatar
Manish Singh committed
560
    *toset = 1;
561
  else if (!strcmp (opt_buf, "FALSE"))
Manish Singh's avatar
Manish Singh committed
562
563
    *toset = 0;
  else
564
    return TRUE;
Manish Singh's avatar
Manish Singh committed
565

566
  return FALSE;
Manish Singh's avatar
Manish Singh committed
567
568
}

569
570
static gint
load_options (GFigObj *gfig,
571
              FILE    *fp)
Manish Singh's avatar
Manish Singh committed
572
573
574
575
576
{
  gchar load_buf[MAX_LOAD_LINE];
  gchar str_buf[MAX_LOAD_LINE];
  gchar opt_buf[MAX_LOAD_LINE];

577
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
Manish Singh's avatar
Manish Singh committed
578
579

#ifdef DEBUG
580
  printf ("load '%s'\n", load_buf);
Manish Singh's avatar
Manish Singh committed
581
582
#endif /* DEBUG */

583
584
  if (strcmp (load_buf, "<OPTIONS>"))
    return (-1);
585

586
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
Manish Singh's avatar
Manish Singh committed
587
588

#ifdef DEBUG
589
  printf ("opt line '%s'\n", load_buf);
Manish Singh's avatar
Manish Singh committed
590
591
#endif /* DEBUG */

592
  while (strcmp (load_buf, "</OPTIONS>"))
Manish Singh's avatar
Manish Singh committed
593
594
595
    {
      /* Get option name */
#ifdef DEBUG
596
      printf ("num = %d\n", sscanf (load_buf, "%s %s", str_buf, opt_buf));
Manish Singh's avatar
Manish Singh committed
597

598
      printf ("option %s val %s\n", str_buf, opt_buf);
Manish Singh's avatar
Manish Singh committed
599
#else
600
      sscanf (load_buf, "%s %s", str_buf, opt_buf);
Manish Singh's avatar
Manish Singh committed
601
602
#endif /* DEBUG */

603
      if (!strcmp (str_buf, "GridSpacing:"))
604
605
606
607
608
609
610
611
        {
          /* Value is decimal */
          int sp = 0;
          sp = atoi (opt_buf);
          if (sp <= 0)
            return (-1);
          gfig->opts.gridspacing = sp;
        }
612
      else if (!strcmp (str_buf, "DrawGrid:"))
613
614
615
616
617
        {
          /* Value is bool */
          if (load_bool (opt_buf, &gfig->opts.drawgrid))
            return (-1);
        }
618
      else if (!strcmp (str_buf, "Snap2Grid:"))
619
620
621
622
623
        {
          /* Value is bool */
          if (load_bool (opt_buf, &gfig->opts.snap2grid))
            return (-1);
        }
624
      else if (!strcmp (str_buf, "LockOnGrid:"))
625
626
627
628
629
        {
          /* Value is bool */
          if (load_bool (opt_buf, &gfig->opts.lockongrid))
            return (-1);
        }
630
      else if (!strcmp (str_buf, "ShowControl:"))
631
632
633
634
635
        {
          /* Value is bool */
          if (load_bool (opt_buf, &gfig->opts.showcontrol))
            return (-1);
        }
636
      else if (!strcmp (str_buf, "GridType:"))
637
638
639
640
641
642
643
644
645
646
647
        {
          /* Value is string */
          if (!strcmp (opt_buf, "RECT_GRID"))
            gfig->opts.gridtype = RECT_GRID;
          else if (!strcmp (opt_buf, "POLAR_GRID"))
            gfig->opts.gridtype = POLAR_GRID;
          else if (!strcmp (opt_buf, "ISO_GRID"))
            gfig->opts.gridtype = ISO_GRID;
          else
            return (-1);
        }
Manish Singh's avatar
Manish Singh committed
648

649
      get_line (load_buf, MAX_LOAD_LINE, fp, 0);
650

Manish Singh's avatar
Manish Singh committed
651
#ifdef DEBUG
652
      printf ("opt line '%s'\n", load_buf);
Manish Singh's avatar
Manish Singh committed
653
#endif /* DEBUG */
654
    }
655
  return (0);
Manish Singh's avatar
Manish Singh committed
656
657
}

658
GString *
659
gfig_save_as_string (void)
Manish Singh's avatar
Manish Singh committed
660
{
661
662
  GList    *objs;
  gint      count;
663
664
665
  gchar     buf[G_ASCII_DTOSTR_BUF_SIZE];
  gchar     conv_buf[MAX_LOAD_LINE * 3 + 1];
  GString  *string;
Manish Singh's avatar
Manish Singh committed
666

667
  string = g_string_new (GFIG_HEADER);
668

669
670
671
672
673
674
  gfig_name_encode (conv_buf, gfig_context->current_obj->draw_name);
  g_string_append_printf (string, "Name: %s\n", conv_buf);
  g_string_append_printf (string, "Version: %s\n",
                          g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f",
                                           gfig_context->current_obj->version));
  objs = gfig_context->current_obj->obj_list;
Manish Singh's avatar
Manish Singh committed
675

676
  count = g_list_length (objs);
Manish Singh's avatar
Manish Singh committed
677

678
  g_string_append_printf (string, "ObjCount: %d\n", count);
Manish Singh's avatar
Manish Singh committed
679

680
  save_options (string);
Manish Singh's avatar
Manish Singh committed
681

682
  gfig_save_styles (string);
683

684
685
686
  for (objs = gfig_context->current_obj->obj_list;
       objs;
       objs = g_list_next (objs))
Manish Singh's avatar
Manish Singh committed
687
    {
688
      Dobject *object = objs->data;
689

690
      gfig_save_obj_start (object, string);
691

692
      gfig_save_style (&object->style, string);
Manish Singh's avatar
Manish Singh committed
693

694
695
696
697
      if (object->points)
        d_save_object (object, string);

      gfig_save_obj_end (object, string);
Manish Singh's avatar
Manish Singh committed
698
699
    }

700
  return string;
Manish Singh's avatar
Manish Singh committed
701
702
703
}


704
gboolean
705
gfig_save_as_parasite (void)
Manish Singh's avatar
Manish Singh committed
706
{
707
708
  GimpParasite *parasite;
  GString       *string;
Manish Singh's avatar
Manish Singh committed
709

710
  string = gfig_save_as_string ();
Michael Natterer's avatar
Michael Natterer committed
711

712
713
714
715
  /* temporarily make the parasite non-persistent until the
   * format has stabilized.
   */
#if 0
716
  parasite = gimp_parasite_new ("gfig", GIMP_PARASITE_PERSISTENT | GIMP_PARASITE_UNDOABLE,
717
718
                                datasize, data);
#endif
Michael Natterer's avatar
Michael Natterer committed
719

720
  parasite = gimp_parasite_new ("gfig", GIMP_PARASITE_UNDOABLE,
721
                                string->len, string->str);
Michael Natterer's avatar
Michael Natterer committed
722

723
  g_string_free (string, TRUE);
Michael Natterer's avatar
Michael Natterer committed
724

725
  if (!gimp_drawable_parasite_attach (gfig_context->drawable_id, parasite))
726
    {
727
728
729
      g_message (_("Error trying to save figure as a parasite: can't attach parasite to drawable.\n"));
      gimp_parasite_free (parasite);
      return FALSE;
730
    }
Manish Singh's avatar
Manish Singh committed
731

732
733
  gimp_parasite_free (parasite);
  return TRUE;
Manish Singh's avatar
Manish Singh committed
734
735
}

736
GFigObj *
737
gfig_load_from_parasite (void)
Manish Singh's avatar
Manish Singh committed
738
{
739
740
741
742
  FILE         *fp;
  gchar        *fname;
  GimpParasite *parasite;
  GFigObj      *gfig;
Manish Singh's avatar
Manish Singh committed
743

744
745
746
747
748
749
750
  fname = gimp_temp_name ("gfigtmp");
  fp = fopen (fname, "w");
  if (!fp)
    {
      g_message (_("Error trying to open temp file '%s'for parasite loading.\n"), fname);
      return NULL;
    }
Manish Singh's avatar
Manish Singh committed
751

752
  parasite = gimp_drawable_parasite_find (gfig_context->drawable_id, "gfig");
Manish Singh's avatar
Manish Singh committed
753

754
755
  if (!parasite)
    return NULL;
756

757
  fprintf (stderr, "GFig parasite found.\n");
Manish Singh's avatar
Manish Singh committed
758

759
760
761
762
763
764
765
  fwrite (gimp_parasite_data (parasite),
          sizeof (guchar),
          gimp_parasite_data_size (parasite),
          fp);

  gimp_parasite_free (parasite);
  fclose (fp);
Manish Singh's avatar
Manish Singh committed
766

767
768
  gfig = gfig_load (fname, "(none)");
  unlink (fname);
Manish Singh's avatar
Manish Singh committed
769

770
  return (gfig);
Manish Singh's avatar
Manish Singh committed
771
772
}

773
774
void
gfig_save_callbk (void)
Manish Singh's avatar
Manish Singh committed
775
{
776
777
778
  FILE     *fp;
  gchar    *savename;
  GString  *string;
Manish Singh's avatar
Manish Singh committed
779

780
  savename = gfig_context->current_obj->filename;
Manish Singh's avatar
Manish Singh committed
781

782
  fp = fopen (savename, "w+");
Manish Singh's avatar
Manish Singh committed
783

784
  if (!fp)
Manish Singh's avatar
Manish Singh committed
785
    {
786
787
788
      g_message (_("Could not open '%s' for writing: %s"),
                 gimp_filename_to_utf8 (savename), g_strerror (errno));
      return;
Manish Singh's avatar
Manish Singh committed
789
790
    }

791
  string = gfig_save_as_string ();
792

793
  fwrite (string->str, string->len, 1, fp);
794

795
796
797
798
799
  if (ferror (fp))
    g_message ("Failed to write file\n");
  else
    {
      gfig_context->current_obj->obj_status &= ~(GFIG_MODIFIED | GFIG_READONLY);
Manish Singh's avatar
Manish Singh committed
800
801
    }

802
  fclose (fp);
Manish Singh's avatar
Manish Singh committed
803

804
}