~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

Viewing changes to plug-ins/ifscompose/ifscompose.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2007-05-02 16:33:03 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070502163303-bvzhjzbpw8qglc4y
Tags: 2.3.16-1ubuntu1
* Resynchronized with Debian, remaining Ubuntu changes:
  - debian/rules: i18n magic.
* debian/control.in:
  - Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
* debian/patches/02_help-message.patch,
  debian/patches/03_gimp.desktop.in.in.patch,
  debian/patches/10_dont_show_wizard.patch: updated.
* debian/patches/04_composite-signedness.patch,
  debian/patches/05_add-letter-spacing.patch: dropped, used upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* The GIMP -- an image manipulation program
 
1
/* GIMP - The GNU Image Manipulation Program
2
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3
3
 *
4
4
 * IfsCompose is a interface for creating IFS fractals by
22
22
/* TODO
23
23
 * ----
24
24
 *
25
 
 * 1. Run in non-interactive mode (need to figure out useful
26
 
 *    way for a script to give the 19N paramters for an image).
27
 
 *    Perhaps just support saving parameters to a file, script
28
 
 *    passes file name.  (The save-to-file part is already done [Yeti])
29
 
 * 2. Save settings on a per-layer basis (long term, needs GIMP
30
 
 *    support to do properly). Load/save from affine parameters?
31
 
 * 3. Figure out if we need multiple phases for supersampled
32
 
 *    brushes.
33
 
 * 4. (minor) Make undo work correctly when focus is in entry widget.
34
 
 *    (This seems fixed now (by mere change to spinbuttons) [Yeti])
 
25
 * 1. Run in non-interactive mode (need to figure out useful way for a
 
26
 *    script to give the 19N paramters for an image).  Perhaps just
 
27
 *    support saving parameters to a file, script passes file name.
 
28
 * 2. Figure out if we need multiple phases for supersampled brushes.
35
29
 */
36
30
 
37
31
#include "config.h"
38
32
 
39
 
#include <stdlib.h>
40
 
#include <stdio.h>
41
33
#include <string.h>
42
34
#include <errno.h>
43
35
 
44
 
#include <gtk/gtk.h>
 
36
#include <glib/gstdio.h>
45
37
 
46
38
#include <libgimp/gimp.h>
47
39
#include <libgimp/gimpui.h>
55
47
#define RESPONSE_OPEN            2
56
48
#define RESPONSE_SAVE            3
57
49
 
58
 
#define SCALE_WIDTH            150
59
 
#define ENTRY_WIDTH             60
60
50
#define DESIGN_AREA_MAX_SIZE   300
61
51
 
62
52
#define PREVIEW_RENDER_CHUNK 10000
64
54
#define UNDO_LEVELS             24
65
55
 
66
56
#define IFSCOMPOSE_PARASITE "ifscompose-parasite"
67
 
#define IFSCOMPOSE_DATA     "plug_in_ifscompose"
68
 
#define HELP_ID             "plug-in-ifs-compose"
 
57
#define IFSCOMPOSE_PROC     "plug-in-ifscompose"
69
58
 
70
59
typedef enum
71
60
{
255
244
                                           gboolean   create_scale,
256
245
                                           ValuePairType type);
257
246
static void value_pair_update             (ValuePair *value_pair);
258
 
static void value_pair_destroy_callback   (GtkWidget *widget,
259
 
                                           ValuePair *value_pair);
260
247
static void value_pair_scale_callback     (GtkAdjustment *adjustment,
261
248
                                           ValuePair *value_pair);
262
249
 
284
271
 *  Some static variables
285
272
 */
286
273
 
287
 
static IfsDialog        *ifsD      = NULL;
288
 
static IfsOptionsDialog *ifsOptD   = NULL;
289
 
static IfsDesignArea    *ifsDesign = NULL;
 
274
static IfsDialog        *ifsD       = NULL;
 
275
static IfsOptionsDialog *ifsOptD    = NULL;
 
276
static IfsDesignArea    *ifsDesign  = NULL;
 
277
 
290
278
 
291
279
static AffElement **elements = NULL;
292
280
static gint        *element_selected = NULL;
302
290
/* num_elements = 0, signals not inited */
303
291
static IfsComposeVals ifsvals =
304
292
{
305
 
  0,           /* num_elements */
 
293
  0,       /* num_elements */
306
294
  50000,   /* iterations   */
307
 
  4096,           /* max_memory   */
308
 
  4,           /* subdivide    */
309
 
  0.75,           /* radius       */
310
 
  1.0,           /* aspect ratio */
311
 
  0.5,           /* center_x     */
312
 
  0.5,           /* center_y     */
 
295
  4096,    /* max_memory   */
 
296
  4,       /* subdivide    */
 
297
  0.75,    /* radius       */
 
298
  1.0,     /* aspect ratio */
 
299
  0.5,     /* center_x     */
 
300
  0.5,     /* center_y     */
313
301
};
314
302
 
315
303
static IfsComposeInterface ifscint =
316
304
{
317
 
  FALSE,        /* run */
 
305
  FALSE,   /* run          */
318
306
};
319
307
 
320
 
GimpPlugInInfo PLUG_IN_INFO =
 
308
const GimpPlugInInfo PLUG_IN_INFO =
321
309
{
322
310
  NULL,    /* init_proc */
323
311
  NULL,    /* quit_proc */
331
319
static void
332
320
query (void)
333
321
{
334
 
  static GimpParamDef args[] =
 
322
  static const GimpParamDef args[] =
335
323
  {
336
 
    { GIMP_PDB_INT32,    "run_mode", "Interactive, non-interactive" },
 
324
    { GIMP_PDB_INT32,    "run-mode", "Interactive, non-interactive" },
337
325
    { GIMP_PDB_IMAGE,    "image",    "Input image" },
338
326
    { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
339
327
  };
340
328
 
341
 
  static GimpParamDef *return_vals = NULL;
 
329
  static const GimpParamDef *return_vals = NULL;
342
330
  static int nreturn_vals = 0;
343
331
 
344
 
  gimp_install_procedure ("plug_in_ifs_compose",
345
 
                          "Create an Iterated Function System (IFS) Fractal",
 
332
  gimp_install_procedure (IFSCOMPOSE_PROC,
 
333
                          N_("Create an Iterated Function System (IFS) fractal"),
346
334
                          "Interactively create an Iterated Function System "
347
335
                          "fractal. Use the window on the upper left to adjust "
348
336
                          "the component transformations of the fractal. The "
360
348
                          G_N_ELEMENTS (args), nreturn_vals,
361
349
                          args, return_vals);
362
350
 
363
 
  gimp_plugin_menu_register ("plug_in_ifs_compose",
 
351
  gimp_plugin_menu_register (IFSCOMPOSE_PROC,
364
352
                             "<Image>/Filters/Render/Nature");
365
353
}
366
354
 
372
360
     GimpParam       **return_vals)
373
361
{
374
362
  static GimpParam   values[1];
375
 
  GimpDrawable      *active_drawable;
 
363
  GimpDrawable      *drawable;
376
364
  GimpRunMode        run_mode;
377
365
  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
378
366
  GimpParasite      *parasite = NULL;
379
367
  guint32            image_id;
380
 
  gboolean           found_parasite;
 
368
  gboolean           found_parasite = FALSE;
381
369
 
382
370
  run_mode = param[0].data.d_int32;
383
371
 
389
377
 
390
378
  INIT_I18N ();
391
379
 
392
 
  image_id        = param[1].data.d_image;
393
 
  active_drawable = gimp_drawable_get (param[2].data.d_drawable);
 
380
  image_id = param[1].data.d_image;
 
381
  drawable = gimp_drawable_get (param[2].data.d_drawable);
394
382
 
395
383
  switch (run_mode)
396
384
    {
398
386
      /*  Possibly retrieve data; first look for a parasite -
399
387
       *  if not found, fall back to global values
400
388
       */
401
 
      parasite = gimp_drawable_parasite_find (active_drawable->drawable_id,
 
389
      parasite = gimp_drawable_parasite_find (drawable->drawable_id,
402
390
                                              IFSCOMPOSE_PARASITE);
403
 
      found_parasite = FALSE;
404
391
      if (parasite)
405
392
        {
406
393
          found_parasite = ifsvals_parse_string (gimp_parasite_data (parasite),
410
397
 
411
398
      if (!found_parasite)
412
399
        {
413
 
          gint length;
 
400
          gint length = gimp_get_data_size (IFSCOMPOSE_PROC);
414
401
 
415
 
          length = gimp_get_data_size (IFSCOMPOSE_DATA);
416
 
          if (length)
 
402
          if (length > 0)
417
403
            {
418
404
              gchar *data = g_new (gchar, length);
419
405
 
420
 
              gimp_get_data (IFSCOMPOSE_DATA, data);
 
406
              gimp_get_data (IFSCOMPOSE_PROC, data);
421
407
              ifsvals_parse_string (data, &ifsvals, &elements);
422
408
              g_free (data);
423
409
            }
427
413
      count_for_naming = ifsvals.num_elements;
428
414
 
429
415
      /*  First acquire information with a dialog  */
430
 
      if (! ifs_compose_dialog (active_drawable))
 
416
      if (! ifs_compose_dialog (drawable))
431
417
        return;
432
418
      break;
433
419
 
434
420
    case GIMP_RUN_NONINTERACTIVE:
435
 
      /*  Make sure all the arguments are there!  */
436
421
      status = GIMP_PDB_CALLING_ERROR;
437
422
      break;
438
423
 
439
424
    case GIMP_RUN_WITH_LAST_VALS:
440
 
      /*  Possibly retrieve data  */
441
 
        {
442
 
          gint length;
443
 
 
444
 
          length = gimp_get_data_size (IFSCOMPOSE_DATA);
445
 
          if (length)
446
 
            {
447
 
              gchar *data = g_new (gchar, length);
448
 
 
449
 
              gimp_get_data (IFSCOMPOSE_DATA, data);
450
 
              ifsvals_parse_string (data, &ifsvals, &elements);
451
 
              g_free (data);
452
 
            }
453
 
          else
454
 
            {
455
 
              ifs_compose_set_defaults ();
456
 
            }
457
 
        }
 
425
      {
 
426
        gint length = gimp_get_data_size (IFSCOMPOSE_PROC);
 
427
 
 
428
        if (length > 0)
 
429
          {
 
430
            gchar *data = g_new (gchar, length);
 
431
 
 
432
            gimp_get_data (IFSCOMPOSE_PROC, data);
 
433
            ifsvals_parse_string (data, &ifsvals, &elements);
 
434
            g_free (data);
 
435
          }
 
436
        else
 
437
          {
 
438
            ifs_compose_set_defaults ();
 
439
          }
 
440
      }
458
441
      break;
459
442
 
460
443
    default:
463
446
 
464
447
  /*  Render the fractal  */
465
448
  if ((status == GIMP_PDB_SUCCESS) &&
466
 
      (gimp_drawable_is_rgb (active_drawable->drawable_id) ||
467
 
       gimp_drawable_is_gray (active_drawable->drawable_id)))
 
449
      (gimp_drawable_is_rgb (drawable->drawable_id) ||
 
450
       gimp_drawable_is_gray (drawable->drawable_id)))
468
451
    {
469
452
      /*  set the tile cache size so that the operation works well  */
470
 
      gimp_tile_cache_ntiles (2 * (MAX (active_drawable->width,
471
 
                                        active_drawable->height) /
 
453
      gimp_tile_cache_ntiles (2 * (MAX (drawable->width, drawable->height) /
472
454
                                   gimp_tile_width () + 1));
473
455
 
474
456
      if (run_mode == GIMP_RUN_INTERACTIVE)
479
461
          gimp_image_undo_group_start (image_id);
480
462
 
481
463
          /*  run the effect  */
482
 
          ifs_compose (active_drawable);
 
464
          ifs_compose (drawable);
483
465
 
484
466
          /*  Store data for next invocation - both globally and
485
467
           *  as a parasite on this layer
486
468
           */
487
469
          str = ifsvals_stringify (&ifsvals, elements);
488
470
 
489
 
          gimp_set_data (IFSCOMPOSE_DATA, str, strlen (str) + 1);
 
471
          gimp_set_data (IFSCOMPOSE_PROC, str, strlen (str) + 1);
490
472
 
491
473
          parasite = gimp_parasite_new (IFSCOMPOSE_PARASITE,
492
474
                                        GIMP_PARASITE_PERSISTENT |
493
475
                                        GIMP_PARASITE_UNDOABLE,
494
476
                                        strlen (str) + 1, str);
495
 
          gimp_drawable_parasite_attach (active_drawable->drawable_id,
496
 
                                         parasite);
 
477
          gimp_drawable_parasite_attach (drawable->drawable_id, parasite);
497
478
          gimp_parasite_free (parasite);
498
479
 
499
480
          g_free (str);
503
484
      else
504
485
        {
505
486
          /*  run the effect  */
506
 
          ifs_compose (active_drawable);
 
487
          ifs_compose (drawable);
507
488
        }
508
489
 
509
490
      /*  If the run mode is interactive, flush the displays  */
517
498
 
518
499
  values[0].data.d_status = status;
519
500
 
520
 
  gimp_drawable_detach (active_drawable);
 
501
  gimp_drawable_detach (drawable);
521
502
}
522
503
 
523
504
static GtkWidget *
671
652
                    GTK_FILL, 0, 0, 0);
672
653
  gtk_widget_show (ifsD->target_cmap->hbox);
673
654
 
674
 
  label = gtk_label_new (_("Scale Hue by:"));
 
655
  label = gtk_label_new (_("Scale hue by:"));
675
656
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
676
657
  gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
677
658
                    GTK_FILL, GTK_FILL, 0, 0);
686
667
                    GTK_FILL, GTK_FILL, 0, 0);
687
668
  gtk_widget_show (ifsD->hue_scale_pair->spin);
688
669
 
689
 
  label = gtk_label_new (_("Scale Value by:"));
 
670
  label = gtk_label_new (_("Scale value by:"));
690
671
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
691
672
  gtk_table_attach (GTK_TABLE (table), label, 2, 3, 1, 2,
692
673
                    GTK_FILL, GTK_FILL, 0, 0);
709
690
  group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (ifsD->full_button));
710
691
  gtk_widget_show (ifsD->full_button);
711
692
 
712
 
  gimp_rgb_set (&color, 1.0, 0.0, 0.0);
 
693
  gimp_rgb_parse_name (&color, "red", -1);
 
694
  gimp_rgb_set_alpha (&color, 1.0);
713
695
  ifsD->red_cmap = color_map_create (_("IFS Fractal: Red"), &color,
714
696
                                     &ifsD->current_vals.red_color, FALSE);
715
697
  gtk_table_attach (GTK_TABLE (table), ifsD->red_cmap->hbox, 1, 2, 2, 3,
716
698
                    GTK_FILL, GTK_FILL, 0, 0);
717
699
  gtk_widget_show (ifsD->red_cmap->hbox);
718
700
 
719
 
  gimp_rgb_set (&color, 0.0, 1.0, 0.0);
 
701
  gimp_rgb_parse_name (&color, "green", -1);
 
702
  gimp_rgb_set_alpha (&color, 1.0);
720
703
  ifsD->green_cmap = color_map_create (_("IFS Fractal: Green"), &color,
721
704
                                       &ifsD->current_vals.green_color, FALSE);
722
705
  gtk_table_attach (GTK_TABLE (table), ifsD->green_cmap->hbox, 2, 3, 2, 3,
723
706
                    GTK_FILL, GTK_FILL, 0, 0);
724
707
  gtk_widget_show (ifsD->green_cmap->hbox);
725
708
 
726
 
  gimp_rgb_set (&color, 0.0, 0.0, 1.0);
 
709
  gimp_rgb_parse_name (&color, "blue", -1);
 
710
  gimp_rgb_set_alpha (&color, 1.0);
727
711
  ifsD->blue_cmap = color_map_create (_("IFS Fractal: Blue"), &color,
728
712
                                      &ifsD->current_vals.blue_color, FALSE);
729
713
  gtk_table_attach (GTK_TABLE (table), ifsD->blue_cmap->hbox, 3, 4, 2, 3,
730
714
                    GTK_FILL, GTK_FILL, 0, 0);
731
715
  gtk_widget_show (ifsD->blue_cmap->hbox);
732
716
 
733
 
  gimp_rgb_set (&color, 0.0, 0.0, 0.0);
 
717
  gimp_rgb_parse_name (&color, "black", -1);
 
718
  gimp_rgb_set_alpha (&color, 1.0);
734
719
  ifsD->black_cmap = color_map_create (_("IFS Fractal: Black"), &color,
735
720
                                       &ifsD->current_vals.black_color, FALSE);
736
721
  gtk_table_attach (GTK_TABLE (table), ifsD->black_cmap->hbox, 4, 5, 2, 3,
783
768
 
784
769
  dialog = gimp_dialog_new (_("IFS Fractal"), "ifscompose",
785
770
                            NULL, 0,
786
 
                            gimp_standard_help_func, HELP_ID,
 
771
                            gimp_standard_help_func, IFSCOMPOSE_PROC,
787
772
 
788
773
                            GTK_STOCK_OPEN,   RESPONSE_OPEN,
789
774
                            GTK_STOCK_SAVE,   RESPONSE_SAVE,
793
778
 
794
779
                            NULL);
795
780
 
 
781
  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
 
782
                                           RESPONSE_OPEN,
 
783
                                           RESPONSE_SAVE,
 
784
                                           RESPONSE_RESET,
 
785
                                           GTK_RESPONSE_OK,
 
786
                                           GTK_RESPONSE_CANCEL,
 
787
                                           -1);
 
788
 
 
789
  gimp_window_set_transient (GTK_WINDOW (dialog));
 
790
 
796
791
  g_object_add_weak_pointer (G_OBJECT (dialog), (gpointer) &dialog);
797
792
 
798
793
  g_signal_connect (dialog, "response",
1010
1005
  g_signal_connect (ifsDesign->area, "realize",
1011
1006
                    G_CALLBACK (design_area_realize),
1012
1007
                    NULL);
1013
 
  g_signal_connect (ifsDesign->area, "expose_event",
 
1008
  g_signal_connect (ifsDesign->area, "expose-event",
1014
1009
                    G_CALLBACK (design_area_expose),
1015
1010
                    NULL);
1016
 
  g_signal_connect (ifsDesign->area, "button_press_event",
 
1011
  g_signal_connect (ifsDesign->area, "button-press-event",
1017
1012
                    G_CALLBACK (design_area_button_press),
1018
1013
                    NULL);
1019
 
  g_signal_connect (ifsDesign->area, "button_release_event",
 
1014
  g_signal_connect (ifsDesign->area, "button-release-event",
1020
1015
                    G_CALLBACK (design_area_button_release),
1021
1016
                    NULL);
1022
 
  g_signal_connect (ifsDesign->area, "motion_notify_event",
 
1017
  g_signal_connect (ifsDesign->area, "motion-notify-event",
1023
1018
                    G_CALLBACK (design_area_motion),
1024
1019
                    NULL);
1025
 
  g_signal_connect (ifsDesign->area, "configure_event",
 
1020
  g_signal_connect (ifsDesign->area, "configure-event",
1026
1021
                    G_CALLBACK (design_area_configure),
1027
1022
                    NULL);
1028
1023
  gtk_widget_set_events (ifsDesign->area,
1068
1063
      G_CALLBACK (recompute_center_cb) },
1069
1064
 
1070
1065
    { "options", GTK_STOCK_PREFERENCES,
1071
 
      N_("Render options"), NULL, NULL,
 
1066
      N_("Render Options"), NULL, NULL,
1072
1067
      G_CALLBACK (ifs_compose_options_callback) }
1073
1068
  };
1074
1069
  static GtkRadioActionEntry radio_actions[] =
1152
1147
static void
1153
1148
design_op_actions_update (void)
1154
1149
{
1155
 
  g_object_set (gtk_ui_manager_get_action (ifsDesign->ui_manager,
1156
 
                                           "/ui/dummy-menubar/ifs-compose-menu/undo"),
1157
 
                "sensitive", undo_cur >= 0,
1158
 
                NULL);
1159
 
  g_object_set (gtk_ui_manager_get_action (ifsDesign->ui_manager,
1160
 
                                           "/ui/dummy-menubar/ifs-compose-menu/redo"),
1161
 
                "sensitive", undo_cur != undo_num - 1,
1162
 
                NULL);
1163
 
  g_object_set (gtk_ui_manager_get_action (ifsDesign->ui_manager,
1164
 
                                           "/ui/dummy-menubar/ifs-compose-menu/delete"),
1165
 
                "sensitive", ifsvals.num_elements > 2,
1166
 
                NULL);
 
1150
  GtkAction *act;
 
1151
 
 
1152
  act = gtk_ui_manager_get_action (ifsDesign->ui_manager,
 
1153
                                   "/ui/dummy-menubar/ifs-compose-menu/undo");
 
1154
  gtk_action_set_sensitive (act, undo_cur >= 0);
 
1155
 
 
1156
  act = gtk_ui_manager_get_action (ifsDesign->ui_manager,
 
1157
                                   "/ui/dummy-menubar/ifs-compose-menu/redo");
 
1158
  gtk_action_set_sensitive (act, undo_cur != undo_num - 1);
 
1159
 
 
1160
  act = gtk_ui_manager_get_action (ifsDesign->ui_manager,
 
1161
                                   "/ui/dummy-menubar/ifs-compose-menu/delete");
 
1162
  gtk_action_set_sensitive (act, ifsvals.num_elements > 2);
1167
1163
}
1168
1164
 
1169
1165
static void
1198
1194
                          FALSE, FALSE, 0);
1199
1195
      gtk_widget_show (table);
1200
1196
 
1201
 
      label = gtk_label_new (_("Max. Memory:"));
 
1197
      label = gtk_label_new (_("Max. memory:"));
1202
1198
      gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1203
1199
      gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
1204
1200
                        GTK_FILL, GTK_FILL, 0, 0);
1238
1234
                        1, 2, 2, 3, GTK_FILL, GTK_FILL, 0, 0);
1239
1235
      gtk_widget_show (ifsOptD->subdivide_pair->spin);
1240
1236
 
1241
 
      label = gtk_label_new (_("Spot Radius:"));
 
1237
      label = gtk_label_new (_("Spot radius:"));
1242
1238
      gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1243
1239
      gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4,
1244
1240
                        GTK_FILL, GTK_FILL, 0, 0);
1273
1269
  GimpImageType  type   = gimp_drawable_type (drawable->drawable_id);
1274
1270
  gint           width  = drawable->width;
1275
1271
  gint           height = drawable->height;
1276
 
  gint           num_bands, band_height, band_y, band_no;
 
1272
  gint           num_bands;
 
1273
  gint           band_height;
 
1274
  gint           band_y;
 
1275
  gint           band_no;
1277
1276
  gint           i, j;
1278
 
  gchar         *buffer;
1279
1277
  guchar        *data;
1280
1278
  guchar        *mask = NULL;
1281
1279
  guchar        *nhits;
1282
1280
  guchar         rc, gc, bc;
1283
1281
  GimpRGB        color;
1284
1282
 
1285
 
  num_bands = ceil((gdouble)(width*height*SQR(ifsvals.subdivide)*5)
 
1283
  num_bands = ceil ((gdouble) (width * height * SQR (ifsvals.subdivide) * 5)
1286
1284
                   / (1024 * ifsvals.max_memory));
1287
1285
  band_height = (height + num_bands - 1) / num_bands;
1288
1286
 
1296
1294
  gimp_context_get_background (&color);
1297
1295
  gimp_rgb_get_uchar (&color, &rc, &gc, &bc);
1298
1296
 
1299
 
  band_y = 0;
1300
 
  for (band_no = 0; band_no < num_bands; band_no++)
 
1297
 
 
1298
  for (band_no = 0, band_y = 0; band_no < num_bands; band_no++)
1301
1299
    {
1302
 
      guchar *ptr;
1303
 
      guchar *maskptr;
1304
 
      guchar *dest;
1305
 
      guchar *destrow;
1306
 
      guchar maskval;
1307
 
      GimpPixelRgn dest_rgn;
1308
 
      gint progress;
1309
 
      gint max_progress;
1310
 
 
1311
 
      gpointer pr;
1312
 
 
1313
 
      buffer = g_strdup_printf (_("Rendering IFS (%d/%d)..."),
1314
 
                                band_no+1, num_bands);
1315
 
      gimp_progress_init (buffer);
1316
 
      g_free (buffer);
 
1300
      GimpPixelRgn  dest_rgn; 
 
1301
      gpointer      pr;
 
1302
 
 
1303
      gimp_progress_init_printf (_("Rendering IFS (%d/%d)"),
 
1304
                                 band_no + 1, num_bands);
1317
1305
 
1318
1306
      /* render the band to a buffer */
1319
1307
      if (band_y + band_height > height)
1320
1308
        band_height = height - band_y;
1321
1309
 
1322
1310
      /* we don't need to clear data since we store nhits */
1323
 
      memset(mask, 0, width*band_height*SQR(ifsvals.subdivide));
1324
 
      memset(nhits, 0, width*band_height*SQR(ifsvals.subdivide));
 
1311
      memset (mask, 0, width * band_height * SQR (ifsvals.subdivide));
 
1312
      memset (nhits, 0, width * band_height * SQR (ifsvals.subdivide));
1325
1313
 
1326
1314
      ifs_render (elements,
1327
1315
                  ifsvals.num_elements, width, height, ifsvals.iterations,
1330
1318
      /* transfer the image to the drawable */
1331
1319
 
1332
1320
 
1333
 
      buffer = g_strdup_printf (_("Copying IFS to image (%d/%d)..."),
1334
 
                                band_no+1, num_bands);
1335
 
      gimp_progress_init (buffer);
1336
 
      g_free (buffer);
1337
 
 
1338
 
      progress = 0;
1339
 
      max_progress = band_height * width;
1340
 
 
1341
1321
      gimp_pixel_rgn_init (&dest_rgn, drawable, 0, band_y,
1342
1322
                           width, band_height, TRUE, TRUE);
1343
1323
 
 
1324
 
1344
1325
      for (pr = gimp_pixel_rgns_register (1, &dest_rgn);
1345
1326
           pr != NULL;
1346
1327
           pr = gimp_pixel_rgns_process (pr))
1347
1328
        {
1348
 
          destrow = dest_rgn.data;
 
1329
          guchar *destrow = dest_rgn.data;
1349
1330
 
1350
1331
          for (j = dest_rgn.y; j < (dest_rgn.y + dest_rgn.h); j++)
1351
1332
            {
1352
 
              dest = destrow;
 
1333
              guchar *dest = destrow;
1353
1334
 
1354
1335
              for (i = dest_rgn.x; i < (dest_rgn.x + dest_rgn.w); i++)
1355
1336
                {
1356
1337
                  /* Accumulate a reduced pixel */
1357
1338
 
 
1339
                  gint rtot = 0;
 
1340
                  gint btot = 0;
 
1341
                  gint gtot = 0;
 
1342
                  gint mtot = 0;
1358
1343
                  gint ii, jj;
1359
 
                  gint rtot=0;
1360
 
                  gint btot=0;
1361
 
                  gint gtot=0;
1362
 
                  gint mtot=0;
 
1344
 
1363
1345
                  for (jj = 0; jj < ifsvals.subdivide; jj++)
1364
1346
                    {
1365
 
                      ptr = data + 3 *
1366
 
                        (((j-band_y)*ifsvals.subdivide+jj) *
1367
 
                         ifsvals.subdivide*width +
1368
 
                         i*ifsvals.subdivide);
 
1347
                      guchar *ptr;
 
1348
                      guchar *maskptr;
 
1349
 
 
1350
                      ptr = data +
 
1351
                        3 * (((j - band_y) * ifsvals.subdivide + jj) *
 
1352
                             ifsvals.subdivide * width +
 
1353
                             i * ifsvals.subdivide);
1369
1354
 
1370
1355
                      maskptr = mask +
1371
 
                        ((j-band_y)*ifsvals.subdivide+jj) *
1372
 
                        ifsvals.subdivide*width +
1373
 
                        i*ifsvals.subdivide;
 
1356
                        ((j - band_y) * ifsvals.subdivide + jj) *
 
1357
                        ifsvals.subdivide * width +
 
1358
                        i * ifsvals.subdivide;
 
1359
 
1374
1360
                      for (ii = 0; ii < ifsvals.subdivide; ii++)
1375
1361
                        {
1376
 
                          maskval = *maskptr++;
 
1362
                          guchar  maskval = *maskptr++;
 
1363
 
1377
1364
                          mtot += maskval;
1378
1365
                          rtot += maskval* *ptr++;
1379
1366
                          gtot += maskval* *ptr++;
1380
1367
                          btot += maskval* *ptr++;
1381
1368
                        }
1382
1369
                    }
 
1370
 
1383
1371
                  if (mtot)
1384
1372
                    {
1385
1373
                      rtot /= mtot;
1386
1374
                      gtot /= mtot;
1387
1375
                      btot /= mtot;
1388
 
                      mtot /= SQR(ifsvals.subdivide);
 
1376
                      mtot /= SQR (ifsvals.subdivide);
1389
1377
                    }
 
1378
 
1390
1379
                  /* and store it */
1391
1380
                  switch (type)
1392
1381
                    {
1393
1382
                     case GIMP_GRAY_IMAGE:
1394
 
                      *dest++ = (mtot*(rtot+btot+gtot)+
1395
 
                                 (255-mtot)*(rc+gc+bc))/(3*255);
 
1383
                      *dest++ = (mtot * (rtot + btot + gtot) +
 
1384
                                 (255 - mtot) * (rc + gc + bc)) / (3 * 255);
1396
1385
                      break;
 
1386
 
1397
1387
                    case GIMP_GRAYA_IMAGE:
1398
 
                      *dest++ = (rtot+btot+gtot)/3;
 
1388
                      *dest++ = (rtot + btot + gtot) / 3;
1399
1389
                      *dest++ = mtot;
1400
1390
                      break;
 
1391
 
1401
1392
                    case GIMP_RGB_IMAGE:
1402
 
                      *dest++ = (mtot*rtot + (255-mtot)*rc)/255;
1403
 
                      *dest++ = (mtot*gtot + (255-mtot)*gc)/255;
1404
 
                      *dest++ = (mtot*btot + (255-mtot)*bc)/255;
 
1393
                      *dest++ = (mtot * rtot + (255 - mtot) * rc) / 255;
 
1394
                      *dest++ = (mtot * gtot + (255 - mtot) * gc) / 255;
 
1395
                      *dest++ = (mtot * btot + (255 - mtot) * bc) / 255;
1405
1396
                      break;
 
1397
 
1406
1398
                    case GIMP_RGBA_IMAGE:
1407
1399
                      *dest++ = rtot;
1408
1400
                      *dest++ = gtot;
1409
1401
                      *dest++ = btot;
1410
1402
                      *dest++ = mtot;
1411
1403
                      break;
 
1404
 
1412
1405
                    case GIMP_INDEXED_IMAGE:
1413
1406
                    case GIMP_INDEXEDA_IMAGE:
1414
1407
                      g_error ("Indexed images not supported by IFS Fractal");
1415
1408
                      break;
1416
1409
                    }
1417
1410
                }
 
1411
 
1418
1412
              destrow += dest_rgn.rowstride;
1419
1413
            }
1420
 
          progress += dest_rgn.w * dest_rgn.h;
1421
 
          gimp_progress_update ((gdouble) progress / (gdouble) max_progress);
1422
1414
        }
 
1415
 
1423
1416
      band_y += band_height;
1424
1417
    }
1425
1418
 
1487
1480
static void
1488
1481
design_area_realize (GtkWidget *widget)
1489
1482
{
 
1483
  const gint cursors[3] =
 
1484
  {
 
1485
    GDK_FLEUR,     /* OP_TRANSLATE */
 
1486
    GDK_EXCHANGE,  /* OP_ROTATE    */
 
1487
    GDK_CROSSHAIR  /* OP_SHEAR     */
 
1488
  };
 
1489
 
1490
1490
  GdkDisplay *display = gtk_widget_get_display (widget);
1491
 
  GdkCursor  *cursor  = gdk_cursor_new_for_display (display, GDK_CROSSHAIR);
1492
 
 
 
1491
  GdkCursor  *cursor  = gdk_cursor_new_for_display (display,
 
1492
                                                    cursors[ifsDesign->op]);
1493
1493
  gdk_window_set_cursor (widget->window, cursor);
1494
1494
  gdk_cursor_unref (cursor);
1495
1495
}
2022
2022
                      FALSE, FALSE, 0);
2023
2023
  gtk_widget_show (color_map->button);
2024
2024
 
2025
 
  g_signal_connect (color_map->button, "color_changed",
 
2025
  g_signal_connect (color_map->button, "color-changed",
2026
2026
                    G_CALLBACK (gimp_color_button_get_color),
2027
2027
                    data);
2028
2028
 
2029
 
  g_signal_connect (color_map->button, "color_changed",
 
2029
  g_signal_connect (color_map->button, "color-changed",
2030
2030
                    G_CALLBACK (color_map_color_changed_cb),
2031
2031
                    color_map);
2032
2032
 
2111
2111
  value_pair->data.d = data;
2112
2112
  value_pair->type   = type;
2113
2113
 
2114
 
  value_pair->adjustment =
2115
 
    gtk_adjustment_new (1.0, lower, upper,
2116
 
                        (upper-lower) / 100, (upper-lower) / 10,
2117
 
                        0.0);
2118
 
  /* We need to sink the adjustment, since we may not create a scale for
2119
 
   * it, so nobody will assume the initial refcount
2120
 
   */
2121
 
  g_object_ref (value_pair->adjustment);
2122
 
  gtk_object_sink (value_pair->adjustment);
 
2114
  value_pair->spin = gimp_spin_button_new (&value_pair->adjustment,
 
2115
                                           1.0, lower, upper,
 
2116
                                           (upper - lower) / 100,
 
2117
                                           (upper - lower) / 10,
 
2118
                                           0.0, 1.0, 3);
 
2119
  gtk_widget_set_size_request (value_pair->spin, 72, -1);
 
2120
 
 
2121
  g_signal_connect (value_pair->adjustment, "value-changed",
 
2122
                    G_CALLBACK (value_pair_scale_callback),
 
2123
                    value_pair);
2123
2124
 
2124
2125
  if (create_scale)
2125
2126
    {
2126
2127
      value_pair->scale =
2127
2128
        gtk_hscale_new (GTK_ADJUSTMENT (value_pair->adjustment));
2128
 
      gtk_widget_ref (value_pair->scale);
2129
2129
 
2130
2130
      if (type == VALUE_PAIR_INT)
2131
 
          gtk_scale_set_digits (GTK_SCALE (value_pair->scale), 0);
 
2131
        gtk_scale_set_digits (GTK_SCALE (value_pair->scale), 0);
2132
2132
      else
2133
 
          gtk_scale_set_digits (GTK_SCALE (value_pair->scale), 3);
 
2133
        gtk_scale_set_digits (GTK_SCALE (value_pair->scale), 3);
2134
2134
 
2135
2135
      gtk_scale_set_draw_value (GTK_SCALE (value_pair->scale), FALSE);
2136
2136
      gtk_range_set_update_policy (GTK_RANGE (value_pair->scale),
2137
2137
                                   GTK_UPDATE_DELAYED);
2138
2138
    }
2139
2139
  else
2140
 
    value_pair->scale = NULL;
2141
 
 
2142
 
  /* We destroy the value pair when the spinbutton is destroyed, so
2143
 
   * we don't need to hold a refcount on the entry
2144
 
   */
2145
 
 
2146
 
  value_pair->spin
2147
 
    = gtk_spin_button_new (GTK_ADJUSTMENT (value_pair->adjustment),
2148
 
                           1.0, 3);
2149
 
  gtk_widget_set_size_request (value_pair->spin, 72, -1);
2150
 
  g_signal_connect (value_pair->spin, "destroy",
2151
 
                    G_CALLBACK (value_pair_destroy_callback),
2152
 
                    value_pair);
2153
 
  g_signal_connect (value_pair->adjustment, "value_changed",
2154
 
                    G_CALLBACK (value_pair_scale_callback),
2155
 
                    value_pair);
 
2140
    {
 
2141
      value_pair->scale = NULL;
 
2142
    }
2156
2143
 
2157
2144
  return value_pair;
2158
2145
}
2193
2180
    }
2194
2181
 
2195
2182
  if (changed)
2196
 
      val_changed_update ();
2197
 
}
2198
 
 
2199
 
static void
2200
 
value_pair_destroy_callback (GtkWidget *widget,
2201
 
                             ValuePair *value_pair)
2202
 
{
2203
 
  if (value_pair->scale)
2204
 
    g_object_unref (value_pair->scale);
2205
 
  g_object_unref (value_pair->adjustment);
 
2183
    val_changed_update ();
2206
2184
}
2207
2185
 
2208
2186
static void
2211
2189
                           gpointer        data)
2212
2190
{
2213
2191
  ifsDesign->op = gtk_radio_action_get_current_value (action);
 
2192
 
 
2193
  /* cursor switch */
 
2194
  if (GTK_WIDGET_REALIZED (ifsDesign->area))
 
2195
    design_area_realize (ifsDesign->area);
2214
2196
}
2215
2197
 
2216
2198
static void
2388
2370
 
2389
2371
      str = ifsvals_stringify (&ifsvals, elements);
2390
2372
 
2391
 
      fh = fopen (filename, "w");
 
2373
      fh = g_fopen (filename, "w");
2392
2374
      if (! fh)
2393
2375
        {
2394
2376
          gchar *message =
2526
2508
  if (! dialog)
2527
2509
    {
2528
2510
      dialog =
2529
 
        gtk_file_chooser_dialog_new (_("Save as IFS Fraktal file"),
 
2511
        gtk_file_chooser_dialog_new (_("Save as IFS Fractal file"),
2530
2512
                                     GTK_WINDOW (parent),
2531
2513
                                     GTK_FILE_CHOOSER_ACTION_SAVE,
2532
2514
 
2535
2517
 
2536
2518
                                     NULL);
2537
2519
 
 
2520
      gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
 
2521
                                               GTK_RESPONSE_OK,
 
2522
                                               GTK_RESPONSE_CANCEL,
 
2523
                                               -1);
2538
2524
      gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
2539
2525
 
 
2526
      gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
 
2527
                                                      TRUE);
 
2528
 
2540
2529
      g_signal_connect (dialog, "destroy",
2541
2530
                        G_CALLBACK (gtk_widget_destroyed),
2542
2531
                        &dialog);
2556
2545
  if (! dialog)
2557
2546
    {
2558
2547
      dialog =
2559
 
        gtk_file_chooser_dialog_new (_("Open IFS Fraktal file"),
 
2548
        gtk_file_chooser_dialog_new (_("Open IFS Fractal file"),
2560
2549
                                     GTK_WINDOW (parent),
2561
2550
                                     GTK_FILE_CHOOSER_ACTION_OPEN,
2562
2551
 
2565
2554
 
2566
2555
                                     NULL);
2567
2556
 
 
2557
      gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
 
2558
                                               GTK_RESPONSE_OK,
 
2559
                                               GTK_RESPONSE_CANCEL,
 
2560
                                               -1);
 
2561
 
2568
2562
      gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
2569
2563
 
2570
2564
      g_signal_connect (dialog, "destroy",