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 = gfig_obj_counts (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 659
GString *
gfig_save_as_string ()
Manish Singh's avatar
Manish Singh committed
660
{
661 662 663 664 665
  DAllObjs *objs;
  gint      count = 0;
  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 = gfig_obj_counts (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
  for (objs = gfig_context->current_obj->obj_list; objs; objs = objs->next)
Manish Singh's avatar
Manish Singh committed
685
    {
686
      gfig_save_obj_start (objs->obj, string);
687

688
      gfig_save_style (&objs->obj->style, string);
689

690
      if (objs->obj->points)
691
        d_save_object (objs->obj, string);
Manish Singh's avatar
Manish Singh committed
692

693
      gfig_save_obj_end (objs->obj, string);
Manish Singh's avatar
Manish Singh committed
694 695
    }

696
  return string;
Manish Singh's avatar
Manish Singh committed
697 698 699
}


700 701
gboolean
gfig_save_as_parasite ()
Manish Singh's avatar
Manish Singh committed
702
{
703 704
  GimpParasite *parasite;
  GString       *string;
Manish Singh's avatar
Manish Singh committed
705

706
  string = gfig_save_as_string ();
Michael Natterer's avatar
Michael Natterer committed
707

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

716
  parasite = gimp_parasite_new ("gfig", GIMP_PARASITE_UNDOABLE,
717
                                string->len, string->str);
Michael Natterer's avatar
Michael Natterer committed
718

719
  g_string_free (string, TRUE);
Michael Natterer's avatar
Michael Natterer committed
720

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

728 729
  gimp_parasite_free (parasite);
  return TRUE;
Manish Singh's avatar
Manish Singh committed
730 731
}

732 733
GFigObj *
gfig_load_from_parasite ()
Manish Singh's avatar
Manish Singh committed
734
{
735 736 737 738
  FILE         *fp;
  gchar        *fname;
  GimpParasite *parasite;
  GFigObj      *gfig;
Manish Singh's avatar
Manish Singh committed
739

740 741 742 743 744 745 746
  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
747

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

750 751
  if (!parasite)
    return NULL;
752

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

755 756 757 758 759 760 761
  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
762

763 764
  gfig = gfig_load (fname, "(none)");
  unlink (fname);
Manish Singh's avatar
Manish Singh committed
765

766
  return (gfig);
Manish Singh's avatar
Manish Singh committed
767 768
}

769 770
void
gfig_save_callbk (void)
Manish Singh's avatar
Manish Singh committed
771
{
772 773 774
  FILE     *fp;
  gchar    *savename;
  GString  *string;
Manish Singh's avatar
Manish Singh committed
775

776
  savename = gfig_context->current_obj->filename;
Manish Singh's avatar
Manish Singh committed
777

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

780
  if (!fp)
Manish Singh's avatar
Manish Singh committed
781
    {
William Skaggs's avatar