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"

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
GfigObject *obj_creating; /* Object we are creating */
GfigObject *tmp_line;     /* Needed when drawing lines */
91

92
gboolean need_to_scale;
Manish Singh's avatar
Manish Singh committed
93

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

98
GdkGC  *gfig_gc;
Manish Singh's avatar
Manish Singh committed
99
100

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

Adrian Likins's avatar
Adrian Likins committed
107
MAIN ()
Manish Singh's avatar
Manish Singh committed
108
109

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

Manish Singh's avatar
Manish Singh committed
120
  gimp_install_procedure ("plug_in_gfig",
121
                          "Create Geometrical shapes with the Gimp",
122
123
124
125
126
127
128
                          "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.  ",
129
130
131
                          "Andy Thomas",
                          "Andy Thomas",
                          "1997",
132
                          N_("_Gfig..."),
133
134
135
136
                          "RGB*, GRAY*",
                          GIMP_PLUGIN,
                          G_N_ELEMENTS (args), 0,
                          args, NULL);
137

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

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

David Odin's avatar
typo    
David Odin committed
155
  gfig_context = g_new (GFigContext, 1);
156
157
  gfig_context->show_background = TRUE;
  gfig_context->selected_obj = NULL;
Sven Neumann's avatar
Sven Neumann committed
158

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

161
162
  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
163
164
165
166

  *nreturn_vals = 1;
  *return_vals = values;

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

170
171
  gimp_image_undo_group_start (gfig_context->image_id);

Sven Neumann's avatar
Sven Neumann committed
172
173
  gimp_context_push ();

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

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

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

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

186

Manish Singh's avatar
Manish Singh committed
187
  /* Calculate preview size */
188

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

200

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

204
205
206
207
  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;
208

209
210
211
212
213
  gimp_tile_cache_ntiles ((drawable->width + gimp_tile_width () - 1) /
                          gimp_tile_width ());

  gimp_drawable_detach (drawable);

214
215
216
  /* initialize */
  gfig_init_object_classes ();

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

227
228
          return;
        }
Manish Singh's avatar
Manish Singh committed
229
230
      break;

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

    default:
      break;
    }

Sven Neumann's avatar
Sven Neumann committed
239
240
  gimp_context_pop ();

241
  gimp_image_undo_group_end (gfig_context->image_id);
242

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

  values[0].data.d_status = status;

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

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

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

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

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

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

  n = 0;
322

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

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

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

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

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

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

  gfig_list = g_list_insert (gfig_list, gfig, n);

  return n;
}

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

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

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

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

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

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

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

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

391
      obj = d_load_object (load_buf, fp);
392

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

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

Manish Singh's avatar
Manish Singh committed
422
423
424
  g_assert (filename != NULL);

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

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

436
  gfig = gfig_new ();
Manish Singh's avatar
Manish Singh committed
437

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


  /* HEADER
   * draw_name
   * version
   * obj_list
   */

448
  get_line (load_buf, MAX_LOAD_LINE, fp, 1);
Manish Singh's avatar
Manish Singh committed
449

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

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

459
460
461
462
  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);
463

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

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

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

478
479
480
481
482
483
  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
484

485
486


487
  gfig_load_objs (gfig, load_count, fp);
488

Manish Singh's avatar
Manish Singh committed
489
  /* Check count ? */
490

491
  chk_count = g_list_length (gfig->obj_list);
492

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

500
  fclose (fp);
Manish Singh's avatar
Manish Singh committed
501

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

  gfig->obj_status = GFIG_OK;

507
  return gfig;
Manish Singh's avatar
Manish Singh committed
508
509
}

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

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

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

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

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

573
  return FALSE;
Manish Singh's avatar
Manish Singh committed
574
575
}

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

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

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

590
591
  if (strcmp (load_buf, "<OPTIONS>"))
    return (-1);
592

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

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

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

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

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

656
      get_line (load_buf, MAX_LOAD_LINE, fp, 0);
657

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

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

674
  string = g_string_new (GFIG_HEADER);
675

676
677
678
679
680
681
  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
682

683
  count = g_list_length (objs);
Manish Singh's avatar
Manish Singh committed
684

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

687
  save_options (string);
Manish Singh's avatar
Manish Singh committed
688

689
  gfig_save_styles (string);
690

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

697
      gfig_save_obj_start (object, string);
698

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

701
702
703
704
      if (object->points)
        d_save_object (object, string);

      gfig_save_obj_end (object, string);
Manish Singh's avatar
Manish Singh committed
705
706
    }

707
  return string;
Manish Singh's avatar
Manish Singh committed
708
709
710
}


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

717
  string = gfig_save_as_string ();
Michael Natterer's avatar
Michael Natterer committed
718

719
720
721
722
  /* temporarily make the parasite non-persistent until the
   * format has stabilized.
   */
#if 0
723
  parasite = gimp_parasite_new ("gfig", GIMP_PARASITE_PERSISTENT | GIMP_PARASITE_UNDOABLE,
724
725
                                datasize, data);
#endif
Michael Natterer's avatar
Michael Natterer committed
726

727
  parasite = gimp_parasite_new ("gfig", GIMP_PARASITE_UNDOABLE,
728
                                string->len, string->str);
Michael Natterer's avatar
Michael Natterer committed
729

730
  g_string_free (string, TRUE);
Michael Natterer's avatar
Michael Natterer committed
731

732
  if (!gimp_drawable_parasite_attach (gfig_context->drawable_id, parasite))
733
    {
734
735
736
      g_message (_("Error trying to save figure as a parasite: can't attach parasite to drawable.\n"));
      gimp_parasite_free (parasite);
      return FALSE;
737
    }
Manish Singh's avatar
Manish Singh committed
738

739
740
  gimp_parasite_free (parasite);
  return TRUE;
Manish Singh's avatar
Manish Singh committed
741
742
}

743
GFigObj *
744
gfig_load_from_parasite (void)
Manish Singh's avatar
Manish Singh committed
745
{
746
747
748
749
  FILE         *fp;
  gchar        *fname;
  GimpParasite *parasite;
  GFigObj      *gfig;
Manish Singh's avatar
Manish Singh committed
750

751
752
753
754
755
756
757
  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
758

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

761
762
  if (!parasite)
    return NULL;
763

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

766
767
768
769
770
771
772
  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
773

774
775
  gfig = gfig_load (fname, "(none)");
  unlink (fname);
Manish Singh's avatar
Manish Singh committed
776

777
  return (gfig);
Manish Singh's avatar
Manish Singh committed
778
779
}

780
781
void
gfig_save_callbk (void)
Manish Singh's avatar
Manish Singh committed
782
{
783
784
785
  FILE     *fp;
  gchar    *savename;
  GString  *string;
Manish Singh's avatar
Manish Singh committed
786

787
  savename = gfig_context->current_obj->filename;
Manish Singh's avatar
Manish Singh committed
788

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

791
  if (!fp)
Manish Singh's avatar
Manish Singh committed
792
    {
793
794
795
      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
796
797
    }

798
  string = gfig_save_as_string ();
799

800
  fwrite (string->str, string->len, 1, fp);
801

802
803
804
805
806
  if (ferror (fp))
    g_message ("Failed to write file\n");
  else
    {
      gfig_context->current_obj->obj_status &= ~(GFIG_MODIFIED | GFIG_READONLY);
Manish Singh's avatar
Manish Singh committed
807
808
    }

809
  fclose (fp);
Manish Singh's avatar
Manish Singh committed
810

811
}