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

27
#include <string.h>
28
#include <stdlib.h>
29
#include <errno.h>
30

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

35
#include <glib/gstdio.h>
Tor Lillqvist's avatar
Tor Lillqvist committed
36

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

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

56 57 58
#include "libgimp/stdplugins-intl.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
gint line_no;
Manish Singh's avatar
Manish Singh committed
81

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

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

87 88
GfigObject *obj_creating; /* Object we are creating */
GfigObject *tmp_line;     /* Needed when drawing lines */
89

90
gboolean need_to_scale;
Manish Singh's avatar
Manish Singh committed
91

92
static gint       load_options            (GFigObj *gfig,
93
                                           FILE    *fp);
Manish Singh's avatar
Manish Singh committed
94 95
/* globals */

96
GdkGC  *gfig_gc;
Manish Singh's avatar
Manish Singh committed
97 98

/* Stuff for the preview bit */
99 100 101 102 103
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
104

Adrian Likins's avatar
Adrian Likins committed
105
MAIN ()
Manish Singh's avatar
Manish Singh committed
106 107

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

Manish Singh's avatar
Manish Singh committed
118
  gimp_install_procedure ("plug_in_gfig",
119
                          "Create Geometrical shapes with the Gimp",
120 121 122 123 124 125 126
                          "Draw Vector Graphics and paint them onto your images.  "
                          "Gfig allows you to draw many types of objects "
                          "inlcuding Lines, Circles, Ellipses, Curves, Polygons, "
                          "pointed stars, Bezier curves, and Spirals.  "
                          "Objects can be painted using Brushes or other tools"
                          "or filled using colours or patterns.  "
                          "Gfig objects can also be used to create selections.  ",
127 128 129
                          "Andy Thomas",
                          "Andy Thomas",
                          "1997",
130
                          N_("_Gfig..."),
131 132 133 134
                          "RGB*, GRAY*",
                          GIMP_PLUGIN,
                          G_N_ELEMENTS (args), 0,
                          args, NULL);
135

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

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

153
  gfig_context = g_new0 (GFigContext, 1);
154 155
  gfig_context->show_background = TRUE;
  gfig_context->selected_obj = NULL;
Sven Neumann's avatar
Sven Neumann committed
156

Manish Singh's avatar
Manish Singh committed
157
  run_mode = param[0].data.d_int32;
Sven Neumann's avatar
Sven Neumann committed
158

159 160
  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
161 162 163 164

  *nreturn_vals = 1;
  *return_vals = values;

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

168 169
  gimp_image_undo_group_start (gfig_context->image_id);

Sven Neumann's avatar
Sven Neumann committed
170 171
  gimp_context_push ();

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
  if (! gimp_selection_is_empty (gfig_context->image_id))
176
    gimp_selection_none (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:
Sven Neumann's avatar
Sven Neumann committed
218
    case GIMP_RUN_WITH_LAST_VALS:
Manish Singh's avatar
Manish Singh committed
219
      /*gimp_get_data ("plug_in_gfig", &selvals);*/
220
      if (! gfig_dialog ())
221
        {
222 223 224
          gimp_drawable_detach (gfig_drawable);
          gimp_image_undo_group_end (gfig_context->image_id);

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

229 230
    case GIMP_RUN_NONINTERACTIVE:
      status = GIMP_PDB_CALLING_ERROR;
Manish Singh's avatar
Manish Singh committed
231 232 233 234 235 236
      break;

    default:
      break;
    }

Sven Neumann's avatar
Sven Neumann committed
237 238
  gimp_context_pop ();

239
  gimp_image_undo_group_end (gfig_context->image_id);
240

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

  values[0].data.d_status = status;

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

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

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

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

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

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

  n = 0;
320

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

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

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

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

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

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

  gfig_list = g_list_insert (gfig_list, gfig, n);

  return n;
}

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

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

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

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

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

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

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

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

389
      obj = d_load_object (load_buf, fp);
390

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

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

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
#endif /* DEBUG */

426
  fp = g_fopen (filename, "r");
Manish Singh's avatar
Manish Singh committed
427 428
  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 = g_list_length (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
  g_string_append_printf (string, "<OPTIONS>\n");
513 514
  g_string_append_printf (string, "GridSpacing: %d\n",
                          selvals.opts.gridspacing);
515
  if (selvals.opts.gridtype == RECT_GRID)
516 517 518
    {
      g_string_append_printf (string, "GridType: RECT_GRID\n");
    }
519
  else if (selvals.opts.gridtype == POLAR_GRID)
520 521 522
    {
      g_string_append_printf (string, "GridType: POLAR_GRID\n");
    }
523
  else if (selvals.opts.gridtype == ISO_GRID)
524 525 526
    {
      g_string_append_printf (string, "GridType: ISO_GRID\n");
    }
527
  else
528
    {
529 530
      /* default to RECT_GRID */
      g_string_append_printf (string, "GridType: RECT_GRID\n");
531 532
    }

533 534 535 536 537 538 539 540
  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");
541 542 543
  g_string_append_printf (string, "</OPTIONS>\n");
}

544
static void
545 546
gfig_save_obj_start (GfigObject *obj,
                     GString    *string)
547
{
548 549 550
  g_string_append_printf (string, "<%s ", obj->class->name);
  gfig_style_save_as_attributes (&obj->style, string);
  g_string_append_printf (string, ">\n");
551 552
}

553
static void
554 555
gfig_save_obj_end (GfigObject *obj,
                   GString    *string)
556
{
557
  g_string_append_printf (string, "</%s>\n",obj->class->name);
558 559
}

560
static gboolean
561
load_bool (gchar *opt_buf,
562
           gint  *toset)
563 564
{
  if (!strcmp (opt_buf, "TRUE"))
Manish Singh's avatar
Manish Singh committed
565
    *toset = 1;
566
  else if (!strcmp (opt_buf, "FALSE"))
Manish Singh's avatar
Manish Singh committed
567 568
    *toset = 0;
  else
569
    return TRUE;
Manish Singh's avatar
Manish Singh committed
570

571
  return FALSE;
Manish Singh's avatar
Manish Singh committed
572 573
}

574 575
static gint
load_options (GFigObj *gfig,
576
              FILE    *fp)
Manish Singh's avatar
Manish Singh committed
577 578 579 580 581
{
  gchar load_buf[MAX_LOAD_LINE];
  gchar str_buf[MAX_LOAD_LINE];
  gchar opt_buf[MAX_LOAD_LINE];

582
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
Manish Singh's avatar
Manish Singh committed
583 584

#ifdef DEBUG
585
  printf ("load '%s'\n", load_buf);
Manish Singh's avatar
Manish Singh committed
586 587
#endif /* DEBUG */

588 589
  if (strcmp (load_buf, "<OPTIONS>"))
    return (-1);
590

591
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
Manish Singh's avatar
Manish Singh committed
592 593

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

597
  while (strcmp (load_buf, "</OPTIONS>"))
Manish Singh's avatar
Manish Singh committed
598 599 600
    {
      /* Get option name */
#ifdef DEBUG
601
      printf ("num = %d\n", sscanf (load_buf, "%s %s", str_buf, opt_buf));
Manish Singh's avatar
Manish Singh committed
602

603
      printf ("option %s val %s\n", str_buf, opt_buf);
Manish Singh's avatar
Manish Singh committed
604
#else
605
      sscanf (load_buf, "%s %s", str_buf, opt_buf);
Manish Singh's avatar
Manish Singh committed
606 607
#endif /* DEBUG */

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

654
      get_line (load_buf, MAX_LOAD_LINE, fp, 0);
655

Manish Singh's avatar
Manish Singh committed
656
#ifdef DEBUG
657
      printf ("opt line '%s'\n", load_buf);
Manish Singh's avatar
Manish Singh committed
658
#endif /* DEBUG */
659
    }
660
  return (0);
Manish Singh's avatar
Manish Singh committed
661 662
}

663
GString *
664
gfig_save_as_string (void)
Manish Singh's avatar
Manish Singh committed
665
{
666 667
  GList    *objs;
  gint      count;
668 669 670
  gchar     buf[G_ASCII_DTOSTR_BUF_SIZE];
  gchar     conv_buf[MAX_LOAD_LINE * 3 + 1];
  GString  *string;
Manish Singh's avatar
Manish Singh committed
671

672
  string = g_string_new (GFIG_HEADER);
673

674 675 676 677 678 679
  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
680

681
  count = g_list_length (objs);
Manish Singh's avatar
Manish Singh committed
682

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

685
  save_options (string);
Manish Singh's avatar
Manish Singh committed
686

687
  gfig_save_styles (string);
688

689 690 691
  for (objs = gfig_context->current_obj->obj_list;
       objs;
       objs = g_list_next (objs))
Manish Singh's avatar
Manish Singh committed
692
    {
693
      GfigObject *object = objs->data;
694

695
      gfig_save_obj_start (object, string);
696

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

699 700 701 702
      if (object->points)
        d_save_object (object, string);

      gfig_save_obj_end (object, string);
Manish Singh's avatar
Manish Singh committed
703 704
    }

705
  return string;
Manish Singh's avatar
Manish Singh committed
706 707 708
}


709
gboolean
710
gfig_save_as_parasite (void)
Manish Singh's avatar
Manish Singh committed
711
{
712 713
  GimpParasite *parasite;
  GString       *string;
Manish Singh's avatar
Manish Singh committed
714

715
  string = gfig_save_as_string ();
Michael Natterer's avatar
Michael Natterer committed
716

717 718 719
  parasite = gimp_parasite_new ("gfig",
                                GIMP_PARASITE_PERSISTENT |
                                GIMP_PARASITE_UNDOABLE,
720
                                string->len, string->str);
Michael Natterer's avatar
Michael Natterer committed
721

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

724
  if (!gimp_drawable_parasite_attach (gfig_context->drawable_id, parasite))
725
    {
726 727
      g_message (_("Error trying to save figure as a parasite: "
                   "can't attach parasite to drawable."));
728 729
      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
  parasite = gimp_drawable_parasite_find (gfig_context->drawable_id, "gfig");
  if (! parasite)
    return NULL;

748
  fname = gimp_temp_name ("gfigtmp");
749

750
  fp = g_fopen (fname, "w");
751 752
  if (!fp)
    {
753 754 755
      g_message (_("Error trying to open temporary file '%s' "
                   "for parasite loading: %s"),
                 gimp_filename_to_utf8 (fname), g_strerror (errno));
756 757
      return NULL;
    }
Manish Singh's avatar
Manish Singh committed
758

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

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

767
  gfig = gfig_load (fname, "(none)");
768

769
  g_unlink (fname);
Manish Singh's avatar
Manish Singh committed
770

771 772 773
  g_free (fname);

  return gfig;
Manish Singh's avatar
Manish Singh committed
774 775
}

776 777
void
gfig_save_callbk (void)
Manish Singh's avatar
Manish Singh committed
778
{
779 780 781
  FILE     *fp;
  gchar    *savename;
  GString  *string;
Manish Singh's avatar
Manish Singh committed
782

783
  savename = gfig_context->current_obj->filename;