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
417
418
  gdouble  version;
  guchar   magic1[20];
  guchar   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;
Manish Singh's avatar
Manish Singh committed
784

785
  fp = g_fopen (savename, "w+");
Manish Singh's avatar
Manish Singh committed
786

787
  if (!fp)
Manish Singh's avatar
Manish Singh committed
788
    {
789
790
791
      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
792
793
    }

794
  string = gfig_save_as_string ();
795

796
  fwrite (string->str, string->len, 1, fp);
797

798
  if (ferror (fp))
799
    g_message ("Failed to write file.");
800
  else
801
    gfig_context->current_obj->obj_status &= ~(GFIG_MODIFIED | GFIG_READONLY);
Manish Singh's avatar
Manish Singh committed
802

803
  fclose (fp);
804
}