gfig.c 19.3 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
117
118
119
static gint       load_options            (GFigObj *gfig, 
                                           FILE    *fp);
static gboolean   match_element           (gchar   *buf,
                                           gchar   *element_name);
Manish Singh's avatar
Manish Singh committed
120
121
/* globals */

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

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

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

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

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

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

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

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

  *nreturn_vals = 1;
  *return_vals = values;

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

187
188
  gimp_image_undo_group_start (gfig_context->image_id);

189

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

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

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

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

202

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

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

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

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

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

  gimp_drawable_detach (drawable);

230
231
232
  /* initialize */
  gfig_init_object_classes ();

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

242
243
          return;
        }
Manish Singh's avatar
Manish Singh committed
244
245
      break;

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

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

    default:
      break;
    }

258
259
260
261
262
  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
263
#if 0
264
265
  if (run_mode == GIMP_RUN_INTERACTIVE)
    gimp_set_data ("plug_in_gfig", &selvals, sizeof (SelectItVals));
Manish Singh's avatar
Manish Singh committed
266
  else
267
#endif /* 0 */
Manish Singh's avatar
Manish Singh committed
268
    {
269
      status = GIMP_PDB_EXECUTION_ERROR;
Manish Singh's avatar
Manish Singh committed
270
271
272
273
274
275
276
277
278
    }

  values[0].data.d_status = status;

  gimp_drawable_detach (drawable);
}

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

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

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

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

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

  n = 0;
339

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

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

Manish Singh's avatar
Manish Singh committed
347
348
      n++;
    }
349
  return n;
Manish Singh's avatar
Manish Singh committed
350
351
}

352
/*
353
 *      Insert gfigs in alphabetical order
354
355
 */

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

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

  gfig_list = g_list_insert (gfig_list, gfig, n);

  return n;
}

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

373
  free_all_objs (gfig->obj_list);
374
375
376
377
378

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

Manish Singh's avatar
Manish Singh committed
379
380
381
  g_free (gfig);
}

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

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

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

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

408
      obj = d_load_object (load_buf, fp);
409

410
      if (obj)
411
412
        {
          add_to_all_obj (gfig, obj);
413
414
415
416
          offset2 = ftell (fp);
          fseek (fp, offset, SEEK_SET);
          gfig_load_style (&obj->style, fp);
          fseek (fp, offset2, SEEK_SET);
417
        }
418
419
420
421
      else
        {
          g_message ("Failed to load object, load count = %d", load_count);
        }
Manish Singh's avatar
Manish Singh committed
422
423
424
    }
}

425
GFigObj *
426
427
gfig_load (const gchar *filename,
           const gchar *name)
Manish Singh's avatar
Manish Singh committed
428
{
429
430
431
432
433
434
  GFigObj *gfig;
  FILE    *fp;
  gchar    load_buf[MAX_LOAD_LINE];
  gchar    str_buf[MAX_LOAD_LINE];
  gint     chk_count;
  gint     load_count = 0;
435
436
437
  gdouble  version;
  guchar   magic1[20];
  guchar   magic2[20];
Manish Singh's avatar
Manish Singh committed
438
439
440
  g_assert (filename != NULL);

#ifdef DEBUG
441
  printf ("Loading %s (%s)\n", filename, name);
Manish Singh's avatar
Manish Singh committed
442
443
444
445
446
#endif /* DEBUG */

  fp = fopen (filename, "r");
  if (!fp)
    {
447
      g_message (_("Could not open '%s' for reading: %s"),
448
                  gimp_filename_to_utf8 (filename), g_strerror (errno));
Manish Singh's avatar
Manish Singh committed
449
450
451
      return NULL;
    }

452
  gfig = gfig_new ();
Manish Singh's avatar
Manish Singh committed
453

454
455
  gfig->name = g_strdup (name);
  gfig->filename = g_strdup (filename);
Manish Singh's avatar
Manish Singh committed
456
457
458
459
460
461
462
463


  /* HEADER
   * draw_name
   * version
   * obj_list
   */

464
  get_line (load_buf, MAX_LOAD_LINE, fp, 1);
Manish Singh's avatar
Manish Singh committed
465

466
467
468
  sscanf (load_buf, "%10s %10s %lf", magic1, magic2, &version);

  if (strcmp (magic1, "GFIG") || strcmp (magic2, "Version"))
Manish Singh's avatar
Manish Singh committed
469
    {
470
471
      g_message ("File '%s' is not a gfig file",
                  gimp_filename_to_utf8 (gfig->filename));
472
      return NULL;
Manish Singh's avatar
Manish Singh committed
473
    }
474

475
476
477
478
  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);
479
  
480
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
481
482
  if (strncmp (load_buf, "Version: ", 9) == 0)
    gfig->version = g_ascii_strtod (load_buf + 9, NULL);
483
  
484
485
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
  sscanf (load_buf, "ObjCount: %d", &load_count);
486
  
487
  if (load_options (gfig, fp))
Manish Singh's avatar
Manish Singh committed
488
    {
489
      g_message ("File '%s' corrupt file - Line %d Option section incorrect",
490
                 gimp_filename_to_utf8 (filename), line_no);
491
      return NULL;
Manish Singh's avatar
Manish Singh committed
492
493
    }

494
495
496
497
498
499
500
  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
501

502
  
503
  gfig_load_objs (gfig, load_count, fp);
504
  
Manish Singh's avatar
Manish Singh committed
505
  /* Check count ? */
506
  
507
  chk_count = gfig_obj_counts (gfig->obj_list);
508
  
509
  if (chk_count != load_count)
Manish Singh's avatar
Manish Singh committed
510
    {
511
      g_message ("File '%s' corrupt file - Line %d Object count to small",
512
                 gimp_filename_to_utf8 (filename), line_no);
513
      return NULL;
Manish Singh's avatar
Manish Singh committed
514
    }
515
  
516
  fclose (fp);
Manish Singh's avatar
Manish Singh committed
517

518
  if (!pic_obj)
Manish Singh's avatar
Manish Singh committed
519
520
521
522
    pic_obj = gfig;

  gfig->obj_status = GFIG_OK;

523
  return gfig;
Manish Singh's avatar
Manish Singh committed
524
525
}

526
527
void
save_options (GString *string)
Manish Singh's avatar
Manish Singh committed
528
529
{
  /* Save options */
530
531
  g_string_append_printf (string, "<OPTIONS>\n");
  g_string_append_printf (string, "GridSpacing: %d\n", selvals.opts.gridspacing);
532
  if (selvals.opts.gridtype == RECT_GRID)
533
534
535
    {
      g_string_append_printf (string, "GridType: RECT_GRID\n");
    }
536
  else if (selvals.opts.gridtype == POLAR_GRID)
537
538
539
    {
      g_string_append_printf (string, "GridType: POLAR_GRID\n");
    }
540
  else if (selvals.opts.gridtype == ISO_GRID)
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
    {
      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:
563
      g_string_append_printf (string, "<Line>\n");
564
565
      break;
    case CIRCLE:
566
      g_string_append_printf (string, "<Circle>\n");
567
568
      break;
    case ELLIPSE:
569
      g_string_append_printf (string, "<Ellipse>\n");
570
571
      break;
    case ARC:
572
      g_string_append_printf (string, "<Arc>\n");
573
574
      break;
    case POLY:
575
      g_string_append_printf (string, "<Poly>\n");
576
577
      break;
    case STAR:
578
      g_string_append_printf (string, "<Star>\n");
579
580
      break;
    case SPIRAL:
581
      g_string_append_printf (string, "<Spiral>\n");
582
583
      break;
    case BEZIER:
584
      g_string_append_printf (string, "<Bezier>\n");
585
586
587
588
589
590
591
592
593
594
595
      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");
596
597
598
599
}

static gint
load_bool (gchar *opt_buf,
600
           gint  *toset)
601
602
{
  if (!strcmp (opt_buf, "TRUE"))
Manish Singh's avatar
Manish Singh committed
603
    *toset = 1;
604
  else if (!strcmp (opt_buf, "FALSE"))
Manish Singh's avatar
Manish Singh committed
605
606
    *toset = 0;
  else
607
    return (-1);
Manish Singh's avatar
Manish Singh committed
608

609
  return (0);
Manish Singh's avatar
Manish Singh committed
610
611
}

612
613
static gint
load_options (GFigObj *gfig,
614
              FILE    *fp)
Manish Singh's avatar
Manish Singh committed
615
616
617
618
619
{
  gchar load_buf[MAX_LOAD_LINE];
  gchar str_buf[MAX_LOAD_LINE];
  gchar opt_buf[MAX_LOAD_LINE];

620
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
Manish Singh's avatar
Manish Singh committed
621
622

#ifdef DEBUG
623
  printf ("load '%s'\n", load_buf);
Manish Singh's avatar
Manish Singh committed
624
625
#endif /* DEBUG */

626
627
  if (strcmp (load_buf, "<OPTIONS>"))
    return (-1);
628

629
  get_line (load_buf, MAX_LOAD_LINE, fp, 0);
Manish Singh's avatar
Manish Singh committed
630
631

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

635
  while (strcmp (load_buf, "</OPTIONS>"))
Manish Singh's avatar
Manish Singh committed
636
637
638
    {
      /* Get option name */
#ifdef DEBUG
639
      printf ("num = %d\n", sscanf (load_buf, "%s %s", str_buf, opt_buf));
Manish Singh's avatar
Manish Singh committed
640

641
      printf ("option %s val %s\n", str_buf, opt_buf);
Manish Singh's avatar
Manish Singh committed
642
#else
643
      sscanf (load_buf, "%s %s", str_buf, opt_buf);
Manish Singh's avatar
Manish Singh committed
644
645
#endif /* DEBUG */

646
      if (!strcmp (str_buf, "GridSpacing:"))
647
648
649
650
651
652
653
654
        {
          /* Value is decimal */
          int sp = 0;
          sp = atoi (opt_buf);
          if (sp <= 0)
            return (-1);
          gfig->opts.gridspacing = sp;
        }
655
      else if (!strcmp (str_buf, "DrawGrid:"))
656
657
658
659
660
        {
          /* Value is bool */
          if (load_bool (opt_buf, &gfig->opts.drawgrid))
            return (-1);
        }
661
      else if (!strcmp (str_buf, "Snap2Grid:"))
662
663
664
665
666
        {
          /* Value is bool */
          if (load_bool (opt_buf, &gfig->opts.snap2grid))
            return (-1);
        }
667
      else if (!strcmp (str_buf, "LockOnGrid:"))
668
669
670
671
672
        {
          /* Value is bool */
          if (load_bool (opt_buf, &gfig->opts.lockongrid))
            return (-1);
        }
673
      else if (!strcmp (str_buf, "ShowControl:"))
674
675
676
677
678
        {
          /* Value is bool */
          if (load_bool (opt_buf, &gfig->opts.showcontrol))
            return (-1);
        }
679
      else if (!strcmp (str_buf, "GridType:"))
680
681
682
683
684
685
686
687
688
689
690
        {
          /* 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
691

692
      get_line (load_buf, MAX_LOAD_LINE, fp, 0);
693

Manish Singh's avatar
Manish Singh committed
694
#ifdef DEBUG
695
      printf ("opt line '%s'\n", load_buf);
Manish Singh's avatar
Manish Singh committed
696
#endif /* DEBUG */
697
    }
698
  return (0);
Manish Singh's avatar
Manish Singh committed
699
700
}

701
702
GString *
gfig_save_as_string ()
Manish Singh's avatar
Manish Singh committed
703
{
704
705
706
707
708
  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
709

710
711
712
713
714
715
716
717
  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
718

719
  count = gfig_obj_counts (objs);
Manish Singh's avatar
Manish Singh committed
720

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

723
  save_options (string);
Manish Singh's avatar
Manish Singh committed
724

725
  gfig_save_styles (string);
726

727
  for (objs = gfig_context->current_obj->obj_list; objs; objs = objs->next)
Manish Singh's avatar
Manish Singh committed
728
    {
729
      gfig_save_obj_start (objs->obj, string);
730

731
      gfig_save_style (&objs->obj->style, string);
732

733
      if (objs->obj->points)
734
        d_save_object (objs->obj, string);
Manish Singh's avatar
Manish Singh committed
735

736
      gfig_save_obj_end (objs->obj, string);
Manish Singh's avatar
Manish Singh committed
737
738
    }

739
  return string;
Manish Singh's avatar
Manish Singh committed
740
741
742
}


743
744
gboolean
gfig_save_as_parasite ()
Manish Singh's avatar
Manish Singh committed
745
{
746
747
  GimpParasite *parasite;
  GString       *string;
Manish Singh's avatar
Manish Singh committed
748

749
  string = gfig_save_as_string ();
Michael Natterer's avatar
Michael Natterer committed
750

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

759
760
  parasite = gimp_parasite_new ("gfig", GIMP_PARASITE_UNDOABLE, 
                                string->len, string->str);
Michael Natterer's avatar
Michael Natterer committed
761

762
  g_string_free (string, TRUE);
Michael Natterer's avatar
Michael Natterer committed
763

764
  if (!gimp_drawable_parasite_attach (gfig_context->drawable_id, parasite))
765
    {
766
767
768
      g_message (_("Error trying to save figure as a parasite: can't attach parasite to drawable.\n"));
      gimp_parasite_free (parasite);
      return FALSE;
769
    }
Manish Singh's avatar
Manish Singh committed
770

771
772
  gimp_parasite_free (parasite);
  return TRUE;
Manish Singh's avatar
Manish Singh committed
773
774
}

775
776
GFigObj *
gfig_load_from_parasite ()
Manish Singh's avatar
Manish Singh committed
777
{
778
779
780
781
  FILE         *fp;
  gchar        *fname;
  GimpParasite *parasite;
  GFigObj      *gfig;
Manish Singh's avatar
Manish Singh committed
782

783
784
785
786
787
788
789
  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
790

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

793
794
  if (!parasite)
    return NULL;
795

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

798
799
800
801
802
803
804
  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
805

806
807
  gfig = gfig_load (fname, "(none)");
  unlink (fname);
Manish Singh's avatar
Manish Singh committed
808

809
  return (gfig);
Manish Singh's avatar
Manish Singh committed
810
811
}

812
813
void
gfig_save_callbk (void)
Manish Singh's avatar
Manish Singh committed
814
{
815
816
817
  FILE     *fp;
  gchar    *savename;
  GString  *string;
Manish Singh's avatar
Manish Singh committed
818

819
  savename = gfig_context->current_obj->filename;
Manish Singh's avatar
Manish Singh committed
820

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

823
  if (!fp)
Manish Singh's avatar
Manish Singh committed
824
    {
825
826
827
      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
828
829
    }

830
  string = gfig_save_as_string ();
831

832
  fwrite (string->str, string->len, 1, fp);
833

834
835
836
837
838
  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
839
840
    }

841
  fclose (fp);
Manish Singh's avatar
Manish Singh committed
842

843
}