gfig.c 20 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 <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

Manish Singh's avatar
Manish Singh committed
35
#include <string.h>
36 37 38 39 40 41

#ifdef __GNUC__
#warning GTK_DISABLE_DEPRECATED
#endif
#undef GTK_DISABLE_DEPRECATED

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

44
#ifdef G_OS_WIN32
Tor Lillqvist's avatar
Tor Lillqvist committed
45 46 47 48
#  include <io.h>
#  ifndef W_OK
#    define W_OK 2
#  endif
49 50
#endif

51 52
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
53 54
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk-pixbuf/gdk-pixdata.h>
55 56
#include "libgimp/stdplugins-intl.h"

57
#include "gfig.h"
58 59
#include "gfig-style.h"
#include "gfig-dialog.h"
60 61 62 63 64
#include "gfig-arc.h"
#include "gfig-bezier.h"
#include "gfig-circle.h"
#include "gfig-dobject.h"
#include "gfig-ellipse.h"
65
#include "gfig-grid.h"
66 67
#include "gfig-line.h"
#include "gfig-poly.h"
68
#include "gfig-preview.h"
69 70
#include "gfig-spiral.h"
#include "gfig-star.h"
71 72
#include "gfig-stock.h"

73
#include "pix-data.h"
Manish Singh's avatar
Manish Singh committed
74

75

Manish Singh's avatar
Manish Singh committed
76 77
/***** Magic numbers *****/

78 79
#define GFIG_HEADER      "GFIG Version 0.2\n"

Manish Singh's avatar
Manish Singh committed
80 81

static void      query  (void);
82
static void      run    (const gchar      *name,
83 84 85 86
                         gint              nparams,
                         const GimpParam  *param,
                         gint             *nreturn_vals,
                         GimpParam       **return_vals);
87

88

Manish Singh's avatar
Manish Singh committed
89

90
GimpPlugInInfo PLUG_IN_INFO =
Manish Singh's avatar
Manish Singh committed
91
{
92 93 94 95
  NULL,  /* init_proc  */
  NULL,  /* quit_proc  */
  query, /* query_proc */
  run,   /* run_proc   */
Manish Singh's avatar
Manish Singh committed
96 97 98 99
};



100
gint   line_no;
Manish Singh's avatar
Manish Singh committed
101

102
gint obj_show_single   = -1; /* -1 all >= 0 object number */
Manish Singh's avatar
Manish Singh committed
103 104 105 106 107

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


108 109
Dobject *obj_creating; /* Object we are creating */
Dobject *tmp_line;     /* Needed when drawing lines */
Manish Singh's avatar
Manish Singh committed
110

111

112
GFigObj  *pic_obj;
113
gint      need_to_scale;
114

Manish Singh's avatar
Manish Singh committed
115

116
/* Don't you just like BIGGG source files? */
117

Manish Singh's avatar
Manish Singh committed
118

119 120
static gint       load_options            (GFigObj *gfig, FILE *fp);

Manish Singh's avatar
Manish Singh committed
121 122
/* globals */

123
GdkGC  *gfig_gc;
Manish Singh's avatar
Manish Singh committed
124 125

/* Stuff for the preview bit */
126 127 128 129 130
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
131

Adrian Likins's avatar
Adrian Likins committed
132
MAIN ()
Manish Singh's avatar
Manish Singh committed
133 134

static void
135
query (void)
Manish Singh's avatar
Manish Singh committed
136
{
137
  static GimpParamDef args[] =
Manish Singh's avatar
Manish Singh committed
138
  {
139 140
    { GIMP_PDB_INT32,    "run_mode", "Interactive, non-interactive" },
    { GIMP_PDB_IMAGE,    "image",    "Input image (unused)" },
141
    { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
142
    { GIMP_PDB_INT32,    "dummy",    "dummy" }
Manish Singh's avatar
Manish Singh committed
143
  };
David Monniaux's avatar
David Monniaux committed
144

Manish Singh's avatar
Manish Singh committed
145
  gimp_install_procedure ("plug_in_gfig",
146 147 148 149 150
                          "Create Geometrical shapes with the Gimp",
                          "More here later",
                          "Andy Thomas",
                          "Andy Thomas",
                          "1997",
151
                          N_("_Gfig..."),
152 153 154 155
                          "RGB*, GRAY*",
                          GIMP_PLUGIN,
                          G_N_ELEMENTS (args), 0,
                          args, NULL);
156 157 158

  gimp_plugin_menu_register ("plug_in_gfig",
                             N_("<Image>/Filters/Render"));
Manish Singh's avatar
Manish Singh committed
159 160 161
}

static void
162 163 164 165 166
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
Manish Singh's avatar
Manish Singh committed
167
{
168 169 170 171
  GimpParam         *values = g_new (GimpParam, 1);
  GimpDrawable      *drawable;
  GimpRunMode        run_mode;
  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
172
  gint               pwidth, pheight;
173 174
  INIT_I18N ();

175 176 177
  gfig_context = (GFigContext*)g_malloc (sizeof (GFigContext));
  gfig_context->show_background = TRUE;
  gfig_context->selected_obj = NULL;
Manish Singh's avatar
Manish Singh committed
178
  run_mode = param[0].data.d_int32;
179 180
  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
181 182 183 184

  *nreturn_vals = 1;
  *return_vals = values;

185
  values[0].type = GIMP_PDB_STATUS;
Manish Singh's avatar
Manish Singh committed
186 187
  values[0].data.d_status = status;

188 189
  gimp_image_undo_group_start (gfig_context->image_id);

190

191
  drawable = gimp_drawable_get (param[2].data.d_drawable);
Manish Singh's avatar
Manish Singh committed
192 193

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

197
  gimp_drawable_mask_bounds (drawable->drawable_id,
198
                             &sel_x1, &sel_y1, &sel_x2, &sel_y2);
Manish Singh's avatar
Manish Singh committed
199 200 201 202

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

203

Manish Singh's avatar
Manish Singh committed
204
  /* Calculate preview size */
205

206 207 208 209 210 211 212 213 214
  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;
215
    }
216
  
217

218
  preview_width  = MAX (pwidth, 2);  /* Min size is 2 */
219
  preview_height = MAX (pheight, 2);
Manish Singh's avatar
Manish Singh committed
220

221 222 223 224
  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;
225

226 227 228 229 230
  gimp_tile_cache_ntiles ((drawable->width + gimp_tile_width () - 1) /
                          gimp_tile_width ());

  gimp_drawable_detach (drawable);

Manish Singh's avatar
Manish Singh committed
231 232
  switch (run_mode)
    {
233
    case GIMP_RUN_INTERACTIVE:
Manish Singh's avatar
Manish Singh committed
234
      /*gimp_get_data ("plug_in_gfig", &selvals);*/
235
      if (! gfig_dialog ())
236
        {
237 238 239
          gimp_drawable_detach (gfig_drawable);
          gimp_image_undo_group_end (gfig_context->image_id);

240 241
          return;
        }
Manish Singh's avatar
Manish Singh committed
242 243
      break;

244 245
    case GIMP_RUN_NONINTERACTIVE:
      status = GIMP_PDB_CALLING_ERROR;
Manish Singh's avatar
Manish Singh committed
246 247
      break;

248
    case GIMP_RUN_WITH_LAST_VALS:
Manish Singh's avatar
Manish Singh committed
249 250 251 252 253 254 255
      /*gimp_get_data ("plug_in_gfig", &selvals);*/
      break;

    default:
      break;
    }

256 257 258 259 260
  gimp_image_undo_group_end (gfig_context->image_id);
  
  if (run_mode != GIMP_RUN_NONINTERACTIVE)
    gimp_displays_flush ();
  else  
Manish Singh's avatar
Manish Singh committed
261
#if 0
262 263
  if (run_mode == GIMP_RUN_INTERACTIVE)
    gimp_set_data ("plug_in_gfig", &selvals, sizeof (SelectItVals));
Manish Singh's avatar
Manish Singh committed
264
  else
265
#endif /* 0 */
Manish Singh's avatar
Manish Singh committed
266
    {
267
      status = GIMP_PDB_EXECUTION_ERROR;
Manish Singh's avatar
Manish Singh committed
268 269 270 271 272 273 274 275 276
    }

  values[0].data.d_status = status;

  gimp_drawable_detach (drawable);
}

/*
  Translate SPACE to "\\040", etc.
Manish Singh's avatar
Manish Singh committed
277
  Taken from gflare plugin
Manish Singh's avatar
Manish Singh committed
278
 */
279
void
280
gfig_name_encode (gchar *dest,
281
                  gchar *src)
Manish Singh's avatar
Manish Singh committed
282
{
283
  gint cnt = MAX_LOAD_LINE - 1;
Manish Singh's avatar
Manish Singh committed
284 285 286

  while (*src && cnt--)
    {
287
      if (g_ascii_iscntrl (*src) || g_ascii_isspace (*src) || *src == '\\')
288 289 290 291
        {
          sprintf (dest, "\\%03o", *src++);
          dest += 4;
        }
Manish Singh's avatar
Manish Singh committed
292
      else
293
        *dest++ = *src++;
Manish Singh's avatar
Manish Singh committed
294 295 296 297 298 299 300
    }
  *dest = '\0';
}

/*
  Translate "\\040" to SPACE, etc.
 */
301
void
302
gfig_name_decode (gchar       *dest,
303
                  const gchar *src)
Manish Singh's avatar
Manish Singh committed
304
{
305 306
  gint  cnt = MAX_LOAD_LINE - 1;
  guint tmp;
Manish Singh's avatar
Manish Singh committed
307 308 309 310

  while (*src && cnt--)
    {
      if (*src == '\\' && *(src+1) && *(src+2) && *(src+3))
311 312 313 314 315
        {
          sscanf (src+1, "%3o", &tmp);
          *dest++ = tmp;
          src += 4;
        }
Manish Singh's avatar
Manish Singh committed
316
      else
317
        *dest++ = *src++;
Manish Singh's avatar
Manish Singh committed
318 319 320 321 322 323 324 325 326 327 328
    }
  *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.
 */

329
gint
330
gfig_list_pos (GFigObj *gfig)
Manish Singh's avatar
Manish Singh committed
331
{
332 333
  GFigObj *g;
  gint n;
Manish Singh's avatar
Manish Singh committed
334 335 336
  GList *tmp;

  n = 0;
337

338
  for (tmp = gfig_list; tmp; tmp = g_list_next (tmp))
Manish Singh's avatar
Manish Singh committed
339 340
    {
      g = tmp->data;
341

Manish Singh's avatar
Manish Singh committed
342
      if (strcmp (gfig->draw_name, g->draw_name) <= 0)
343
        break;
344

Manish Singh's avatar
Manish Singh committed
345 346
      n++;
    }
347
  return n;
Manish Singh's avatar
Manish Singh committed
348 349
}

350
/*
351
 *      Insert gfigs in alphabetical order
352 353
 */

354
gint
355
gfig_list_insert (GFigObj *gfig)
Manish Singh's avatar
Manish Singh committed
356
{
357
  gint n;
Manish Singh's avatar
Manish Singh committed
358

359
  n = gfig_list_pos (gfig);
Manish Singh's avatar
Manish Singh committed
360 361 362 363 364 365

  gfig_list = g_list_insert (gfig_list, gfig, n);

  return n;
}

366
void
367
gfig_free (GFigObj *gfig)
Manish Singh's avatar
Manish Singh committed
368 369 370
{
  g_assert (gfig != NULL);

371
  free_all_objs (gfig->obj_list);
372 373 374 375 376

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

Manish Singh's avatar
Manish Singh committed
377 378 379
  g_free (gfig);
}

380
GFigObj *
381
gfig_new (void)
Manish Singh's avatar
Manish Singh committed
382
{
383
  return g_new0 (GFigObj, 1);
Manish Singh's avatar
Manish Singh committed
384 385
}

386

387 388
static void
gfig_load_objs (GFigObj *gfig,
389 390
                gint     load_count,
                FILE    *fp)
Manish Singh's avatar
Manish Singh committed
391
{
392
  Dobject *obj;
Manish Singh's avatar
Manish Singh committed
393
  gchar load_buf[MAX_LOAD_LINE];
394 395 396
  glong offset;
  glong offset2;
  Style style;
Manish Singh's avatar
Manish Singh committed
397

398
  while (load_count-- > 0)
Manish Singh's avatar
Manish Singh committed
399 400
    {
      obj = NULL;
401 402
      get_line (load_buf, MAX_LOAD_LINE, fp, 0);

403 404 405 406 407
      /* kludge */
      offset = ftell (fp);
      gfig_skip_style (&style, fp);

      if (!strcmp (load_buf, "<Object Line>"))
408 409 410
        {
          obj = d_load_line (fp);
        }
411
      else if (!strcmp (load_buf, "<Object Circle>"))
412 413 414
        {
          obj = d_load_circle (fp);
        }
415
      else if (!strcmp (load_buf, "<Object Ellipse>"))
416 417 418
        {
          obj = d_load_ellipse (fp);
        }
419
      else if (!strcmp (load_buf, "<Object Poly>"))
420 421 422
        {
          obj = d_load_poly (fp);
        }
423
      else if (!strcmp (load_buf, "<Object Star>"))
424 425 426
        {
          obj = d_load_star (fp);
        }
427
      else if (!strcmp (load_buf, "<Object Spiral>"))
428 429 430
        {
          obj = d_load_spiral (fp);
        }
431
      else if (!strcmp (load_buf, "<Object Bezier>"))
432 433 434
        {
          obj = d_load_bezier (fp);
        }
435
      else if (!strcmp (load_buf, "<Object Arc>"))
436 437 438
        {
          obj = d_load_arc (fp);
        }
Manish Singh's avatar
Manish Singh committed
439
      else
440 441 442
        {
          g_warning ("Unknown obj type file %s line %d\n", gfig->filename, line_no);
        }
443

444
      if (obj)
445 446
        {
          add_to_all_obj (gfig, obj);
447 448 449 450
          offset2 = ftell (fp);
          fseek (fp, offset, SEEK_SET);
          gfig_load_style (&obj->style, fp);
          fseek (fp, offset2, SEEK_SET);
451
        }
Manish Singh's avatar
Manish Singh committed
452 453 454
    }
}

455
GFigObj *
456 457
gfig_load (const gchar *filename,
           const gchar *name)
Manish Singh's avatar
Manish Singh committed
458
{
459 460 461 462 463 464
  GFigObj *gfig;
  FILE    *fp;
  gchar    load_buf[MAX_LOAD_LINE];
  gchar    str_buf[MAX_LOAD_LINE];
  gint     chk_count;
  gint     load_count = 0;
465 466 467
  gdouble  version;
  guchar   magic1[20];
  guchar   magic2[20];
Manish Singh's avatar
Manish Singh committed
468 469 470
  g_assert (filename != NULL);

#ifdef DEBUG
471
  printf ("Loading %s (%s)\n", filename, name);
Manish Singh's avatar
Manish Singh committed
472 473 474 475 476
#endif /* DEBUG */

  fp = fopen (filename, "r");
  if (!fp)
    {
477
      g_message (_("Could not open '%s' for reading: %s"),
478
                  gimp_filename_to_utf8 (filename), g_strerror (errno));
Manish Singh's avatar
Manish Singh committed
479 480 481
      return NULL;
    }

482
  gfig = gfig_new ();
Manish Singh's avatar
Manish Singh committed
483

484 485
  gfig->name = g_strdup (name);
  gfig->filename = g_strdup (filename);
Manish Singh's avatar
Manish Singh committed
486 487 488 489 490 491 492 493


  /* HEADER
   * draw_name
   * version
   * obj_list
   */

494
  get_line (load_buf, MAX_LOAD_LINE, fp, 1);
Manish Singh's avatar
Manish Singh committed
495

496 497 498
  sscanf (load_buf, "%10s %10s %lf", magic1, magic2, &version);

  if (strcmp (magic1, "GFIG") || strcmp (magic2, "Version"))
Manish Singh's avatar
Manish Singh committed
499
    {
500 501
      g_message ("File '%s' is not a gfig file",
                  gimp_filename_to_utf8 (gfig->filename));
502
      return NULL;
Manish Singh's avatar
Manish Singh committed
503
    }
504

505 506 507 508
  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);
509
  
510
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
511 512
  if (strncmp (load_buf, "Version: ", 9) == 0)
    gfig->version = g_ascii_strtod (load_buf + 9, NULL);
513
  
514 515
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
  sscanf (load_buf, "ObjCount: %d", &load_count);
516
  
517
  if (load_options (gfig, fp))
Manish Singh's avatar
Manish Singh committed
518
    {
519
      g_message ("File '%s' corrupt file - Line %d Option section incorrect",
520
                 gimp_filename_to_utf8 (filename), line_no);
521
      return NULL;
Manish Singh's avatar
Manish Singh committed
522 523
    }

524 525 526 527 528 529 530
  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
531

532
  
533
  gfig_load_objs (gfig, load_count, fp);
534
  
Manish Singh's avatar
Manish Singh committed
535
  /* Check count ? */
536
  
537
  chk_count = gfig_obj_counts (gfig->obj_list);
538
  
539
  if (chk_count != load_count)
Manish Singh's avatar
Manish Singh committed
540
    {
541
      g_message ("File '%s' corrupt file - Line %d Object count to small",
542
                 gimp_filename_to_utf8 (filename), line_no);
543
      return NULL;
Manish Singh's avatar
Manish Singh committed
544
    }
545
  
546
  fclose (fp);
Manish Singh's avatar
Manish Singh committed
547

548
  if (!pic_obj)
Manish Singh's avatar
Manish Singh committed
549 550 551 552
    pic_obj = gfig;

  gfig->obj_status = GFIG_OK;

553
  return gfig;
Manish Singh's avatar
Manish Singh committed
554 555
}

556 557
void
save_options (GString *string)
Manish Singh's avatar
Manish Singh committed
558 559
{
  /* Save options */
560 561
  g_string_append_printf (string, "<OPTIONS>\n");
  g_string_append_printf (string, "GridSpacing: %d\n", selvals.opts.gridspacing);
562
  if (selvals.opts.gridtype == RECT_GRID)
563 564 565
    {
      g_string_append_printf (string, "GridType: RECT_GRID\n");
    }
566
  else if (selvals.opts.gridtype == POLAR_GRID)
567 568 569
    {
      g_string_append_printf (string, "GridType: POLAR_GRID\n");
    }
570
  else if (selvals.opts.gridtype == ISO_GRID)
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625
    {
      g_string_append_printf (string, "GridType: ISO_GRID\n");
    }
  else 
    {
      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");
}

static void 
gfig_save_obj_start (Dobject *obj, 
                     GString *string)
{
  switch (obj->type)
    {
    case LINE:
      g_string_append_printf (string, "<Object Line>\n");
      break;
    case CIRCLE:
      g_string_append_printf (string, "<Object Circle>\n");
      break;
    case ELLIPSE:
      g_string_append_printf (string, "<Object Ellipse>\n");
      break;
    case ARC:
      g_string_append_printf (string, "<Object Arc>\n");
      break;
    case POLY:
      g_string_append_printf (string, "<Object Poly>\n");
      break;
    case STAR:
      g_string_append_printf (string, "<Object Star>\n");
      break;
    case SPIRAL:
      g_string_append_printf (string, "<Object Spiral>\n");
      break;
    case BEZIER:
      g_string_append_printf (string, "<Object Bezier>\n");
      break;
    default:
      g_message ("Unknown object type in gfig_save_obj_start");
    }
}

static void 
gfig_save_obj_end (Dobject *obj, 
                   GString *string)
{
  g_string_append_printf (string, "</Object>\n");
626 627 628 629
}

static gint
load_bool (gchar *opt_buf,
630
           gint  *toset)
631 632
{
  if (!strcmp (opt_buf, "TRUE"))
Manish Singh's avatar
Manish Singh committed
633
    *toset = 1;
634
  else if (!strcmp (opt_buf, "FALSE"))
Manish Singh's avatar
Manish Singh committed
635 636
    *toset = 0;
  else
637
    return (-1);
Manish Singh's avatar
Manish Singh committed
638

639
  return (0);
Manish Singh's avatar
Manish Singh committed
640 641
}

642 643
static gint
load_options (GFigObj *gfig,
644
              FILE    *fp)
Manish Singh's avatar
Manish Singh committed
645 646 647 648 649
{
  gchar load_buf[MAX_LOAD_LINE];
  gchar str_buf[MAX_LOAD_LINE];
  gchar opt_buf[MAX_LOAD_LINE];

650
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
Manish Singh's avatar
Manish Singh committed
651 652

#ifdef DEBUG
653
  printf ("load '%s'\n", load_buf);
Manish Singh's avatar
Manish Singh committed
654 655
#endif /* DEBUG */

656 657
  if (strcmp (load_buf, "<OPTIONS>"))
    return (-1);
658

659
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
Manish Singh's avatar
Manish Singh committed
660 661

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

665
  while (strcmp (load_buf, "</OPTIONS>"))
Manish Singh's avatar
Manish Singh committed
666 667 668
    {
      /* Get option name */
#ifdef DEBUG
669
      printf ("num = %d\n", sscanf (load_buf, "%s %s", str_buf, opt_buf));
Manish Singh's avatar
Manish Singh committed
670

671
      printf ("option %s val %s\n", str_buf, opt_buf);
Manish Singh's avatar
Manish Singh committed
672
#else
673
      sscanf (load_buf, "%s %s", str_buf, opt_buf);
Manish Singh's avatar
Manish Singh committed
674 675
#endif /* DEBUG */

676
      if (!strcmp (str_buf, "GridSpacing:"))
677 678 679 680 681 682 683 684
        {
          /* Value is decimal */
          int sp = 0;
          sp = atoi (opt_buf);
          if (sp <= 0)
            return (-1);
          gfig->opts.gridspacing = sp;
        }
685
      else if (!strcmp (str_buf, "DrawGrid:"))
686 687 688 689 690
        {
          /* Value is bool */
          if (load_bool (opt_buf, &gfig->opts.drawgrid))
            return (-1);
        }
691
      else if (!strcmp (str_buf, "Snap2Grid:"))
692 693 694 695 696
        {
          /* Value is bool */
          if (load_bool (opt_buf, &gfig->opts.snap2grid))
            return (-1);
        }
697
      else if (!strcmp (str_buf, "LockOnGrid:"))
698 699 700 701 702
        {
          /* Value is bool */
          if (load_bool (opt_buf, &gfig->opts.lockongrid))
            return (-1);
        }
703
      else if (!strcmp (str_buf, "ShowControl:"))
704 705 706 707 708
        {
          /* Value is bool */
          if (load_bool (opt_buf, &gfig->opts.showcontrol))
            return (-1);
        }
709
      else if (!strcmp (str_buf, "GridType:"))
710 711 712 713 714 715 716 717 718 719 720
        {
          /* 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
721

722
      get_line (load_buf, MAX_LOAD_LINE, fp, 0);
723

Manish Singh's avatar
Manish Singh committed
724
#ifdef DEBUG
725
      printf ("opt line '%s'\n", load_buf);
Manish Singh's avatar
Manish Singh committed
726
#endif /* DEBUG */
727
    }
728
  return (0);
Manish Singh's avatar
Manish Singh committed
729 730
}

731 732
GString *
gfig_save_as_string ()
Manish Singh's avatar
Manish Singh committed
733
{
734 735 736 737 738
  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
739

740 741 742 743 744 745 746 747
  string = g_string_new (GFIG_HEADER);
  
  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
748

749
  count = gfig_obj_counts (objs);
Manish Singh's avatar
Manish Singh committed
750

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

753
  save_options (string);
Manish Singh's avatar
Manish Singh committed
754

755
  gfig_save_styles (string);
756

757
  for (objs = gfig_context->current_obj->obj_list; objs; objs = objs->next)
Manish Singh's avatar
Manish Singh committed
758
    {
759
      gfig_save_obj_start (objs->obj, string);
760

761
      gfig_save_style (&objs->obj->style, string);
762

763
      if (objs->obj->points)
764
        {
765
          objs->obj->savefunc (objs->obj, string);
766
        }
Manish Singh's avatar
Manish Singh committed
767

768
      gfig_save_obj_end (objs->obj, string);
Manish Singh's avatar
Manish Singh committed
769 770
    }

771
  return string;
Manish Singh's avatar
Manish Singh committed
772 773 774
}


775 776
gboolean
gfig_save_as_parasite ()
Manish Singh's avatar
Manish Singh committed
777
{
778 779
  GimpParasite *parasite;
  GString       *string;
Manish Singh's avatar
Manish Singh committed
780

781
  string = gfig_save_as_string ();
Michael Natterer's avatar
Michael Natterer committed
782

783 784 785 786 787 788 789
  /* temporarily make the parasite non-persistent until the
   * format has stabilized.
   */
#if 0
  parasite = gimp_parasite_new ("gfig", GIMP_PARASITE_PERSISTENT | GIMP_PARASITE_UNDOABLE, 
                                datasize, data);
#endif
Michael Natterer's avatar
Michael Natterer committed
790

791 792
  parasite = gimp_parasite_new ("gfig", GIMP_PARASITE_UNDOABLE, 
                                string->len, string->str);
Michael Natterer's avatar
Michael Natterer committed
793

794
  g_string_free (string, TRUE);
Michael Natterer's avatar
Michael Natterer committed
795

796
  if (!gimp_drawable_parasite_attach (gfig_context->drawable_id, parasite))
797
    {
798 799 800
      g_message (_("Error trying to save figure as a parasite: can't attach parasite to drawable.\n"));
      gimp_parasite_free (parasite);
      return FALSE;
801
    }
Manish Singh's avatar
Manish Singh committed
802

803 804
  gimp_parasite_free (parasite);
  return TRUE;
Manish Singh's avatar
Manish Singh committed
805 806
}

807 808
GFigObj *
gfig_load_from_parasite ()
Manish Singh's avatar
Manish Singh committed
809
{
810 811 812 813
  FILE         *fp;
  gchar        *fname;
  GimpParasite *parasite;
  GFigObj      *gfig;
Manish Singh's avatar
Manish Singh committed
814

815 816 817 818 819 820 821
  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
822

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

825 826
  if (!parasite)
    return NULL;
827

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

830 831 832 833