gfig.c 18.4 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"

59
#include "pix-data.h"
Manish Singh's avatar
Manish Singh committed
60

61

Manish Singh's avatar
Manish Singh committed
62 63
/***** Magic numbers *****/

64 65
#define GFIG_HEADER      "GFIG Version 0.2\n"

Manish Singh's avatar
Manish Singh committed
66 67

static void      query  (void);
68
static void      run    (const gchar      *name,
69 70 71 72
                         gint              nparams,
                         const GimpParam  *param,
                         gint             *nreturn_vals,
                         GimpParam       **return_vals);
73

74

Manish Singh's avatar
Manish Singh committed
75

76
GimpPlugInInfo PLUG_IN_INFO =
Manish Singh's avatar
Manish Singh committed
77
{
78 79 80 81
  NULL,  /* init_proc  */
  NULL,  /* quit_proc  */
  query, /* query_proc */
  run,   /* run_proc   */
Manish Singh's avatar
Manish Singh committed
82 83 84 85
};



86
gint   line_no;
Manish Singh's avatar
Manish Singh committed
87

88
gint obj_show_single   = -1; /* -1 all >= 0 object number */
Manish Singh's avatar
Manish Singh committed
89 90 91 92 93

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


94 95
Dobject *obj_creating; /* Object we are creating */
Dobject *tmp_line;     /* Needed when drawing lines */
Manish Singh's avatar
Manish Singh committed
96

97

98
gint      need_to_scale;
99

Manish Singh's avatar
Manish Singh committed
100

101
static gint       load_options            (GFigObj *gfig,
102
                                           FILE    *fp);
Manish Singh's avatar
Manish Singh committed
103 104
/* globals */

105
GdkGC  *gfig_gc;
Manish Singh's avatar
Manish Singh committed
106 107

/* Stuff for the preview bit */
108 109 110 111 112
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
113

Adrian Likins's avatar
Adrian Likins committed
114
MAIN ()
Manish Singh's avatar
Manish Singh committed
115 116

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

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

139
  gimp_plugin_menu_register ("plug_in_gfig", "<Image>/Filters/Render");
Manish Singh's avatar
Manish Singh committed
140 141 142
}

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

156 157 158
  gfig_context = (GFigContext*)g_malloc (sizeof (GFigContext));
  gfig_context->show_background = TRUE;
  gfig_context->selected_obj = NULL;
Manish Singh's avatar
Manish Singh committed
159
  run_mode = param[0].data.d_int32;
160 161
  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
162 163 164 165

  *nreturn_vals = 1;
  *return_vals = values;

166
  values[0].type = GIMP_PDB_STATUS;
Manish Singh's avatar
Manish Singh committed
167 168
  values[0].data.d_status = status;

169 170
  gimp_image_undo_group_start (gfig_context->image_id);

171

172
  drawable = gimp_drawable_get (param[2].data.d_drawable);
Manish Singh's avatar
Manish Singh committed
173 174

  /* TMP Hack - clear any selections */
175 176
  if (! gimp_selection_is_empty (gfig_context->image_id))
    gimp_selection_clear (gfig_context->image_id);
Manish Singh's avatar
Manish Singh committed
177

178
  gimp_drawable_mask_bounds (drawable->drawable_id,
179
                             &sel_x1, &sel_y1, &sel_x2, &sel_y2);
Manish Singh's avatar
Manish Singh committed
180 181 182 183

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

184

Manish Singh's avatar
Manish Singh committed
185
  /* Calculate preview size */
186

187 188 189 190 191 192 193 194 195
  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;
196
    }
197

198

199
  preview_width  = MAX (pwidth, 2);  /* Min size is 2 */
200
  preview_height = MAX (pheight, 2);
Manish Singh's avatar
Manish Singh committed
201

202 203 204 205
  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;
206

207 208 209 210 211
  gimp_tile_cache_ntiles ((drawable->width + gimp_tile_width () - 1) /
                          gimp_tile_width ());

  gimp_drawable_detach (drawable);

212 213 214
  /* initialize */
  gfig_init_object_classes ();

Manish Singh's avatar
Manish Singh committed
215 216
  switch (run_mode)
    {
217
    case GIMP_RUN_INTERACTIVE:
Manish Singh's avatar
Manish Singh committed
218
      /*gimp_get_data ("plug_in_gfig", &selvals);*/
219
      if (! gfig_dialog ())
220
        {
221 222 223
          gimp_drawable_detach (gfig_drawable);
          gimp_image_undo_group_end (gfig_context->image_id);

224 225
          return;
        }
Manish Singh's avatar
Manish Singh committed
226 227
      break;

228 229
    case GIMP_RUN_NONINTERACTIVE:
      status = GIMP_PDB_CALLING_ERROR;
Manish Singh's avatar
Manish Singh committed
230 231
      break;

232
    case GIMP_RUN_WITH_LAST_VALS:
Manish Singh's avatar
Manish Singh committed
233 234 235 236 237 238 239
      /*gimp_get_data ("plug_in_gfig", &selvals);*/
      break;

    default:
      break;
    }

240
  gimp_image_undo_group_end (gfig_context->image_id);
241

242 243
  if (run_mode != GIMP_RUN_NONINTERACTIVE)
    gimp_displays_flush ();
244
  else
Manish Singh's avatar
Manish Singh committed
245
#if 0
246 247
  if (run_mode == GIMP_RUN_INTERACTIVE)
    gimp_set_data ("plug_in_gfig", &selvals, sizeof (SelectItVals));
Manish Singh's avatar
Manish Singh committed
248
  else
249
#endif /* 0 */
Manish Singh's avatar
Manish Singh committed
250
    {
251
      status = GIMP_PDB_EXECUTION_ERROR;
Manish Singh's avatar
Manish Singh committed
252 253 254 255
    }

  values[0].data.d_status = status;

256
  /* gimp_drawable_detach (drawable) already done above, don't do it twice */
Manish Singh's avatar
Manish Singh committed
257 258 259 260
}

/*
  Translate SPACE to "\\040", etc.
Manish Singh's avatar
Manish Singh committed
261
  Taken from gflare plugin
Manish Singh's avatar
Manish Singh committed
262
 */
263
void
264
gfig_name_encode (gchar *dest,
265
                  gchar *src)
Manish Singh's avatar
Manish Singh committed
266
{
267
  gint cnt = MAX_LOAD_LINE - 1;
Manish Singh's avatar
Manish Singh committed
268 269 270

  while (*src && cnt--)
    {
271
      if (g_ascii_iscntrl (*src) || g_ascii_isspace (*src) || *src == '\\')
272 273 274 275
        {
          sprintf (dest, "\\%03o", *src++);
          dest += 4;
        }
Manish Singh's avatar
Manish Singh committed
276
      else
277
        *dest++ = *src++;
Manish Singh's avatar
Manish Singh committed
278 279 280 281 282 283 284
    }
  *dest = '\0';
}

/*
  Translate "\\040" to SPACE, etc.
 */
285
void
286
gfig_name_decode (gchar       *dest,
287
                  const gchar *src)
Manish Singh's avatar
Manish Singh committed
288
{
289 290
  gint  cnt = MAX_LOAD_LINE - 1;
  guint tmp;
Manish Singh's avatar
Manish Singh committed
291 292 293 294

  while (*src && cnt--)
    {
      if (*src == '\\' && *(src+1) && *(src+2) && *(src+3))
295 296 297 298 299
        {
          sscanf (src+1, "%3o", &tmp);
          *dest++ = tmp;
          src += 4;
        }
Manish Singh's avatar
Manish Singh committed
300
      else
301
        *dest++ = *src++;
Manish Singh's avatar
Manish Singh committed
302 303 304 305 306 307 308 309 310 311 312
    }
  *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.
 */

313
gint
314
gfig_list_pos (GFigObj *gfig)
Manish Singh's avatar
Manish Singh committed
315
{
316 317
  GFigObj *g;
  gint n;
Manish Singh's avatar
Manish Singh committed
318 319 320
  GList *tmp;

  n = 0;
321

322
  for (tmp = gfig_list; tmp; tmp = g_list_next (tmp))
Manish Singh's avatar
Manish Singh committed
323 324
    {
      g = tmp->data;
325

Manish Singh's avatar
Manish Singh committed
326
      if (strcmp (gfig->draw_name, g->draw_name) <= 0)
327
        break;
328

Manish Singh's avatar
Manish Singh committed
329 330
      n++;
    }
331
  return n;
Manish Singh's avatar
Manish Singh committed
332 333
}

334
/*
335
 *      Insert gfigs in alphabetical order
336 337
 */

338
gint
339
gfig_list_insert (GFigObj *gfig)
Manish Singh's avatar
Manish Singh committed
340
{
341
  gint n;
Manish Singh's avatar
Manish Singh committed
342

343
  n = gfig_list_pos (gfig);
Manish Singh's avatar
Manish Singh committed
344 345 346 347 348 349

  gfig_list = g_list_insert (gfig_list, gfig, n);

  return n;
}

350
void
351
gfig_free (GFigObj *gfig)
Manish Singh's avatar
Manish Singh committed
352 353 354
{
  g_assert (gfig != NULL);

355
  free_all_objs (gfig->obj_list);
356 357 358 359 360

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

Manish Singh's avatar
Manish Singh committed
361 362 363
  g_free (gfig);
}

364
GFigObj *
365
gfig_new (void)
Manish Singh's avatar
Manish Singh committed
366
{
367
  return g_new0 (GFigObj, 1);
Manish Singh's avatar
Manish Singh committed
368 369
}

370 371
static void
gfig_load_objs (GFigObj *gfig,
372 373
                gint     load_count,
                FILE    *fp)
Manish Singh's avatar
Manish Singh committed
374
{
375
  Dobject *obj;
Manish Singh's avatar
Manish Singh committed
376
  gchar load_buf[MAX_LOAD_LINE];
377 378 379
  glong offset;
  glong offset2;
  Style style;
Manish Singh's avatar
Manish Singh committed
380

381
  while (load_count-- > 0)
Manish Singh's avatar
Manish Singh committed
382 383
    {
      obj = NULL;
384 385
      get_line (load_buf, MAX_LOAD_LINE, fp, 0);

386 387 388 389
      /* kludge */
      offset = ftell (fp);
      gfig_skip_style (&style, fp);

390
      obj = d_load_object (load_buf, fp);
391

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

407
GFigObj *
408 409
gfig_load (const gchar *filename,
           const gchar *name)
Manish Singh's avatar
Manish Singh committed
410
{
411 412 413 414 415 416
  GFigObj *gfig;
  FILE    *fp;
  gchar    load_buf[MAX_LOAD_LINE];
  gchar    str_buf[MAX_LOAD_LINE];
  gint     chk_count;
  gint     load_count = 0;
417 418 419
  gdouble  version;
  guchar   magic1[20];
  guchar   magic2[20];
Manish Singh's avatar
Manish Singh committed
420 421 422
  g_assert (filename != NULL);

#ifdef DEBUG
423
  printf ("Loading %s (%s)\n", filename, name);
Manish Singh's avatar
Manish Singh committed
424 425 426 427 428
#endif /* DEBUG */

  fp = fopen (filename, "r");
  if (!fp)
    {
429
      g_message (_("Could not open '%s' for reading: %s"),
430
                  gimp_filename_to_utf8 (filename), g_strerror (errno));
Manish Singh's avatar
Manish Singh committed
431 432 433
      return NULL;
    }

434
  gfig = gfig_new ();
Manish Singh's avatar
Manish Singh committed
435

436 437
  gfig->name = g_strdup (name);
  gfig->filename = g_strdup (filename);
Manish Singh's avatar
Manish Singh committed
438 439 440 441 442 443 444 445


  /* HEADER
   * draw_name
   * version
   * obj_list
   */

446
  get_line (load_buf, MAX_LOAD_LINE, fp, 1);
Manish Singh's avatar
Manish Singh committed
447

448 449 450
  sscanf (load_buf, "%10s %10s %lf", magic1, magic2, &version);

  if (strcmp (magic1, "GFIG") || strcmp (magic2, "Version"))
Manish Singh's avatar
Manish Singh committed
451
    {
452 453
      g_message ("File '%s' is not a gfig file",
                  gimp_filename_to_utf8 (gfig->filename));
454
      return NULL;
Manish Singh's avatar
Manish Singh committed
455
    }
456

457 458 459 460
  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);
461

462
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
463 464
  if (strncmp (load_buf, "Version: ", 9) == 0)
    gfig->version = g_ascii_strtod (load_buf + 9, NULL);
465

466 467
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
  sscanf (load_buf, "ObjCount: %d", &load_count);
468

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

476 477 478 479 480 481
  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
482

483 484


485
  gfig_load_objs (gfig, load_count, fp);
486

Manish Singh's avatar
Manish Singh committed
487
  /* Check count ? */
488

489
  chk_count = gfig_obj_counts (gfig->obj_list);
490

491
  if (chk_count != load_count)
Manish Singh's avatar
Manish Singh committed
492
    {
493
      g_message ("File '%s' corrupt file - Line %d Object count to small",
494
                 gimp_filename_to_utf8 (filename), line_no);
495
      return NULL;
Manish Singh's avatar
Manish Singh committed
496
    }
497

498
  fclose (fp);
Manish Singh's avatar
Manish Singh committed
499

500 501
  if (!gfig_context->current_obj)
    gfig_context->current_obj = gfig;
Manish Singh's avatar
Manish Singh committed
502 503 504

  gfig->obj_status = GFIG_OK;

505
  return gfig;
Manish Singh's avatar
Manish Singh committed
506 507
}

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

  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");
  g_string_append_printf (string, "</OPTIONS>\n");
}

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

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

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

565
  return (0);
Manish Singh's avatar
Manish Singh committed
566 567
}

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

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

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

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

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

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

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

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

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

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

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

657 658
GString *
gfig_save_as_string ()
Manish Singh's avatar
Manish Singh committed
659
{
660 661 662 663 664
  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
665

666
  string = g_string_new (GFIG_HEADER);
667

668 669 670 671 672 673
  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
674

675
  count = gfig_obj_counts (objs);
Manish Singh's avatar
Manish Singh committed
676

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

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

681
  gfig_save_styles (string);
682

683
  for (objs = gfig_context->current_obj->obj_list; objs; objs = objs->next)
Manish Singh's avatar
Manish Singh committed
684
    {
685
      gfig_save_obj_start (objs->obj, string);
686

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

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

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

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


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

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

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

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

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

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

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

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

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

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

749 750
  if (!parasite)
    return NULL;
751

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

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

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

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

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

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

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

779
  if (!fp)
Manish Singh's avatar
Manish Singh committed
780
    {
781 782 783
      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
784 785
    }