2004-02-01 Michael Natterer <mitch@gimp.org> Reworked random seed handling once more: * libgimpwidgets/gimpwidgets.c (gimp_random_seed_new): make sure the displayed random seed value is always the one which will be used, whether "Randomize" is checked or not. * plug-ins/common/blur.c * plug-ins/common/plasma.c * plug-ins/common/randomize.c * plug-ins/common/sinus.c * plug-ins/common/snoise.c * plug-ins/maze/algorithms.c * plug-ins/maze/maze.c: if running interactively, always take the seed value produced by the gimp_random_seed widget and don't touch it because the widgets honors the "randomize" toggle correctly now. For noninteractive and last_vals runs, look at the "randomize" boolean and generate a seed if it is TRUE. Initialize the random number generators from the seed determined by either of the above ways and don't fiddle with it in the inner algorithms itself. * plug-ins/gflare/gflare.c (plugin_run): initialize the GRand from the seed unconditionally. (ed_make_page_sflare): no need to get the entry from the random seed widget to get its adjustment. Instead get the adjustment directly. (The random handling code of gflare looks somewhat broken, but that applies to the whole plug-in).
688 lines
16 KiB
C
688 lines
16 KiB
C
/*
|
|
* This is a plugin for the GIMP.
|
|
*
|
|
* Copyright (C) 1996 Stephen Norris
|
|
*
|
|
* 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
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* This plug-in produces plasma fractal images. The algorithm is losely
|
|
* based on a description of the fractint algorithm, but completely
|
|
* re-implemented because the fractint code was too ugly to read :)
|
|
*
|
|
* Please send any patches or suggestions to me: srn@flibble.cs.su.oz.au.
|
|
*/
|
|
|
|
/*
|
|
* TODO:
|
|
* - The progress bar sucks.
|
|
* - It writes some pixels more than once.
|
|
*/
|
|
|
|
/* Version 1.01 */
|
|
|
|
/*
|
|
* Ported to GIMP Plug-in API 1.0
|
|
* by Eiichi Takamori <taka@ma1.seikyou.ne.jp>
|
|
*
|
|
* $Id$
|
|
*
|
|
* A few functions names and their order are changed :)
|
|
* Plasma implementation almost hasn't been changed.
|
|
*
|
|
* Feel free to correct my WRONG English, or to modify Plug-in Path,
|
|
* and so on. ;-)
|
|
*
|
|
* Version 1.02
|
|
*
|
|
* May 2000
|
|
* tim copperfield [timecop@japan.co.jp]
|
|
* Added dynamic preview mode.
|
|
*
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include <libgimp/gimp.h>
|
|
#include <libgimp/gimpui.h>
|
|
|
|
#include "libgimp/stdplugins-intl.h"
|
|
|
|
#include "gimpoldpreview.h"
|
|
|
|
/* Some useful macros */
|
|
|
|
#define ENTRY_WIDTH 75
|
|
#define SCALE_WIDTH 128
|
|
#define TILE_CACHE_SIZE 32
|
|
|
|
typedef struct
|
|
{
|
|
guint32 seed;
|
|
gdouble turbulence;
|
|
gboolean random_seed;
|
|
} PlasmaValues;
|
|
|
|
|
|
/*
|
|
* Function prototypes.
|
|
*/
|
|
|
|
static void query (void);
|
|
static void run (const gchar *name,
|
|
gint nparams,
|
|
const GimpParam *param,
|
|
gint *nreturn_vals,
|
|
GimpParam **return_vals);
|
|
|
|
static gboolean plasma_dialog (GimpDrawable *drawable,
|
|
GimpImageType drawable_type);
|
|
static void plasma_seed_changed_callback (GimpDrawable *drawable,
|
|
gpointer data);
|
|
|
|
static void plasma (GimpDrawable *drawable,
|
|
gboolean preview_mode);
|
|
static void random_rgb (GRand *gr,
|
|
guchar *pixel);
|
|
static void add_random (GRand *gr,
|
|
guchar *pixel,
|
|
gint amount);
|
|
static GimpPixelFetcher *init_plasma (GimpDrawable *drawable,
|
|
gboolean preview_mode,
|
|
GRand *gr);
|
|
static void end_plasma (GimpDrawable *drawable,
|
|
GimpPixelFetcher *pft,
|
|
GRand *gr);
|
|
static void get_pixel (GimpPixelFetcher *pft,
|
|
gint x,
|
|
gint y,
|
|
guchar *pixel);
|
|
static void put_pixel (GimpPixelFetcher *pft,
|
|
gint x,
|
|
gint y,
|
|
guchar *pixel);
|
|
static gboolean do_plasma (GimpPixelFetcher *pft,
|
|
gint x1,
|
|
gint y1,
|
|
gint x2,
|
|
gint y2,
|
|
gint depth,
|
|
gint scale_depth,
|
|
GRand *gr);
|
|
|
|
|
|
/***** Local vars *****/
|
|
|
|
GimpPlugInInfo PLUG_IN_INFO =
|
|
{
|
|
NULL, /* init_proc */
|
|
NULL, /* quit_proc */
|
|
query, /* query_proc */
|
|
run, /* run_proc */
|
|
};
|
|
|
|
static PlasmaValues pvals =
|
|
{
|
|
0, /* seed */
|
|
1.0, /* turbulence */
|
|
FALSE, /* Use random seed */
|
|
};
|
|
|
|
/*
|
|
* Some globals to save passing too many paramaters that don't change.
|
|
*/
|
|
|
|
static GimpOldPreview *preview;
|
|
static gint ix1, iy1, ix2, iy2; /* Selected image size. */
|
|
static gint bpp, alpha;
|
|
static gboolean has_alpha;
|
|
static gdouble turbulence;
|
|
static glong max_progress, progress;
|
|
|
|
|
|
/***** Functions *****/
|
|
|
|
MAIN ()
|
|
|
|
static void
|
|
query (void)
|
|
{
|
|
static GimpParamDef args[]=
|
|
{
|
|
{ GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
|
|
{ GIMP_PDB_IMAGE, "image", "Input image (unused)" },
|
|
{ GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
|
|
{ GIMP_PDB_INT32, "seed", "Random seed" },
|
|
{ GIMP_PDB_FLOAT, "turbulence", "Turbulence of plasma" }
|
|
};
|
|
|
|
gimp_install_procedure ("plug_in_plasma",
|
|
"Create a plasma cloud like image on the specified drawable",
|
|
"More help",
|
|
"Stephen Norris & (ported to 1.0 by) Eiichi Takamori",
|
|
"Stephen Norris",
|
|
"May 2000",
|
|
N_("<Image>/Filters/Render/Clouds/_Plasma..."),
|
|
"RGB*, GRAY*",
|
|
GIMP_PLUGIN,
|
|
G_N_ELEMENTS (args), 0,
|
|
args, NULL);
|
|
}
|
|
|
|
static void
|
|
run (const gchar *name,
|
|
gint nparams,
|
|
const GimpParam *param,
|
|
gint *nreturn_vals,
|
|
GimpParam **return_vals)
|
|
{
|
|
static GimpParam values[1];
|
|
GimpDrawable *drawable;
|
|
GimpImageType drawable_type;
|
|
GimpRunMode run_mode;
|
|
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
|
|
|
|
run_mode = param[0].data.d_int32;
|
|
|
|
INIT_I18N ();
|
|
|
|
*nreturn_vals = 1;
|
|
*return_vals = values;
|
|
|
|
values[0].type = GIMP_PDB_STATUS;
|
|
values[0].data.d_status = status;
|
|
|
|
/* Get the specified drawable */
|
|
drawable = gimp_drawable_get (param[2].data.d_drawable);
|
|
drawable_type = gimp_drawable_type (param[2].data.d_drawable);
|
|
|
|
switch (run_mode)
|
|
{
|
|
case GIMP_RUN_INTERACTIVE:
|
|
/* Possibly retrieve data */
|
|
gimp_get_data ("plug_in_plasma", &pvals);
|
|
|
|
/* First acquire information with a dialog */
|
|
if (! plasma_dialog (drawable, drawable_type))
|
|
{
|
|
gimp_drawable_detach (drawable);
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case GIMP_RUN_NONINTERACTIVE:
|
|
/* Make sure all the arguments are there! */
|
|
if (nparams != 5)
|
|
{
|
|
status = GIMP_PDB_CALLING_ERROR;
|
|
}
|
|
else
|
|
{
|
|
pvals.seed = (guint32) param[3].data.d_int32;
|
|
pvals.turbulence = (gdouble) param[4].data.d_float;
|
|
|
|
if (pvals.turbulence <= 0)
|
|
status = GIMP_PDB_CALLING_ERROR;
|
|
}
|
|
break;
|
|
|
|
case GIMP_RUN_WITH_LAST_VALS:
|
|
/* Possibly retrieve data */
|
|
gimp_get_data ("plug_in_plasma", &pvals);
|
|
|
|
if (pvals.random_seed)
|
|
pvals.seed = g_random_int ();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (status == GIMP_PDB_SUCCESS)
|
|
{
|
|
/* Make sure that the drawable is gray or RGB color */
|
|
if (gimp_drawable_is_rgb (drawable->drawable_id) ||
|
|
gimp_drawable_is_gray (drawable->drawable_id))
|
|
{
|
|
gimp_progress_init (_("Plasma..."));
|
|
gimp_tile_cache_ntiles (TILE_CACHE_SIZE);
|
|
|
|
plasma (drawable, FALSE);
|
|
|
|
if (run_mode != GIMP_RUN_NONINTERACTIVE)
|
|
gimp_displays_flush ();
|
|
|
|
/* Store data */
|
|
if (run_mode == GIMP_RUN_INTERACTIVE ||
|
|
(run_mode == GIMP_RUN_WITH_LAST_VALS))
|
|
gimp_set_data ("plug_in_plasma", &pvals, sizeof (PlasmaValues));
|
|
}
|
|
else
|
|
{
|
|
/* gimp_message ("plasma: cannot operate on indexed color images"); */
|
|
status = GIMP_PDB_EXECUTION_ERROR;
|
|
}
|
|
}
|
|
|
|
values[0].data.d_status = status;
|
|
gimp_drawable_detach (drawable);
|
|
}
|
|
|
|
static gboolean
|
|
plasma_dialog (GimpDrawable *drawable,
|
|
GimpImageType drawable_type)
|
|
{
|
|
GtkWidget *dlg;
|
|
GtkWidget *main_vbox;
|
|
GtkWidget *frame;
|
|
GtkWidget *label;
|
|
GtkWidget *table;
|
|
GtkWidget *seed;
|
|
GtkObject *adj;
|
|
gboolean run;
|
|
|
|
gimp_ui_init ("plasma", TRUE);
|
|
|
|
dlg = gimp_dialog_new (_("Plasma"), "plasma",
|
|
NULL, 0,
|
|
gimp_standard_help_func, "plug-in-plasma",
|
|
|
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
|
GTK_STOCK_OK, GTK_RESPONSE_OK,
|
|
|
|
NULL);
|
|
|
|
main_vbox = gtk_vbox_new (FALSE, 4);
|
|
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 6);
|
|
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
|
|
main_vbox, TRUE, TRUE, 0);
|
|
gtk_widget_show (main_vbox);
|
|
|
|
preview = gimp_old_preview_new2 (drawable_type, TRUE);
|
|
gtk_box_pack_start (GTK_BOX (main_vbox), preview->frame, FALSE, FALSE, 0);
|
|
|
|
plasma_seed_changed_callback (drawable, NULL); /* preview image */
|
|
|
|
gtk_widget_show (preview->widget);
|
|
|
|
/* parameter settings */
|
|
frame = gtk_frame_new (_("Parameter Settings"));
|
|
gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
|
|
gtk_widget_show (frame);
|
|
|
|
table = gtk_table_new (2, 3, FALSE);
|
|
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
|
|
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
|
|
gtk_container_set_border_width (GTK_CONTAINER (table), 4);
|
|
gtk_container_add (GTK_CONTAINER (frame), table);
|
|
gtk_widget_show (table);
|
|
|
|
seed = gimp_random_seed_new (&pvals.seed, &pvals.random_seed);
|
|
label = gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
|
|
_("Random _Seed:"), 1.0, 0.5,
|
|
seed, 1, TRUE);
|
|
gtk_label_set_mnemonic_widget (GTK_LABEL (label),
|
|
GIMP_RANDOM_SEED_SPINBUTTON (seed));
|
|
|
|
g_signal_connect_swapped (GIMP_RANDOM_SEED_SPINBUTTON_ADJ (seed),
|
|
"value_changed",
|
|
G_CALLBACK (plasma_seed_changed_callback),
|
|
drawable);
|
|
|
|
adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 1,
|
|
_("T_urbulence:"), SCALE_WIDTH, 0,
|
|
pvals.turbulence,
|
|
0.1, 7.0, 0.1, 1.0, 1,
|
|
TRUE, 0, 0,
|
|
NULL, NULL);
|
|
g_signal_connect (adj, "value_changed",
|
|
G_CALLBACK (gimp_double_adjustment_update),
|
|
&pvals.turbulence);
|
|
g_signal_connect_swapped (adj, "value_changed",
|
|
G_CALLBACK (plasma_seed_changed_callback),
|
|
NULL);
|
|
|
|
gtk_widget_show (dlg);
|
|
|
|
run = (gimp_dialog_run (GIMP_DIALOG (dlg)) == GTK_RESPONSE_OK);
|
|
|
|
gtk_widget_destroy (dlg);
|
|
|
|
return run;
|
|
}
|
|
|
|
static void
|
|
plasma_seed_changed_callback (GimpDrawable *drawable,
|
|
gpointer data)
|
|
{
|
|
plasma (drawable, TRUE);
|
|
}
|
|
|
|
/*
|
|
* The setup function.
|
|
*/
|
|
|
|
static void
|
|
plasma (GimpDrawable *drawable,
|
|
gboolean preview_mode)
|
|
{
|
|
GimpPixelFetcher *pft;
|
|
gint depth;
|
|
GRand *gr;
|
|
|
|
gr = g_rand_new ();
|
|
|
|
pft = init_plasma (drawable, preview_mode, gr);
|
|
|
|
/*
|
|
* This first time only puts in the seed pixels - one in each
|
|
* corner, and one in the center of each edge, plus one in the
|
|
* center of the image.
|
|
*/
|
|
|
|
do_plasma (pft, ix1, iy1, ix2 - 1, iy2 - 1, -1, 0, gr);
|
|
|
|
/*
|
|
* Now we recurse through the images, going further each time.
|
|
*/
|
|
depth = 1;
|
|
while (!do_plasma (pft, ix1, iy1, ix2 - 1, iy2 - 1, depth, 0, gr))
|
|
{
|
|
depth++;
|
|
}
|
|
|
|
end_plasma (drawable, pft, gr);
|
|
}
|
|
|
|
static GimpPixelFetcher*
|
|
init_plasma (GimpDrawable *drawable,
|
|
gboolean preview_mode,
|
|
GRand *gr)
|
|
{
|
|
GimpPixelFetcher *pft;
|
|
|
|
g_rand_set_seed (gr, pvals.seed);
|
|
|
|
turbulence = pvals.turbulence;
|
|
|
|
if (preview_mode)
|
|
{
|
|
ix1 = iy1 = 0;
|
|
ix2 = preview->width;
|
|
iy2 = preview->height;
|
|
|
|
bpp = (preview->is_gray) ? 1 : 3;
|
|
alpha = bpp;
|
|
has_alpha = FALSE;
|
|
|
|
pft = NULL;
|
|
}
|
|
else
|
|
{
|
|
gimp_drawable_mask_bounds (drawable->drawable_id,
|
|
&ix1, &iy1, &ix2, &iy2);
|
|
|
|
bpp = drawable->bpp;
|
|
has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
|
|
alpha = (has_alpha) ? bpp - 1 : bpp;
|
|
|
|
pft = gimp_pixel_fetcher_new (drawable);
|
|
gimp_pixel_fetcher_set_shadow (pft, TRUE);
|
|
}
|
|
|
|
progress = 0;
|
|
max_progress = (ix2 - ix1) * (iy2 - iy1);
|
|
|
|
return pft;
|
|
}
|
|
|
|
static void
|
|
end_plasma (GimpDrawable *drawable,
|
|
GimpPixelFetcher *pft,
|
|
GRand *gr)
|
|
{
|
|
if (pft)
|
|
{
|
|
gimp_pixel_fetcher_destroy (pft);
|
|
|
|
gimp_drawable_flush (drawable);
|
|
gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
|
|
gimp_drawable_update (drawable->drawable_id,
|
|
ix1, iy1, ix2 - ix1, iy2 - iy1);
|
|
}
|
|
else
|
|
{
|
|
gtk_widget_queue_draw (preview->widget);
|
|
}
|
|
|
|
g_rand_free (gr);
|
|
}
|
|
|
|
static void
|
|
get_pixel (GimpPixelFetcher *pft,
|
|
gint x,
|
|
gint y,
|
|
guchar *pixel)
|
|
{
|
|
if (pft)
|
|
{
|
|
gimp_pixel_fetcher_get_pixel (pft, x, y, pixel);
|
|
}
|
|
else
|
|
{
|
|
gimp_old_preview_get_pixel (preview, x, y, pixel);
|
|
}
|
|
}
|
|
|
|
static void
|
|
put_pixel (GimpPixelFetcher *pft,
|
|
gint x,
|
|
gint y,
|
|
guchar *pixel)
|
|
{
|
|
if (pft)
|
|
{
|
|
gimp_pixel_fetcher_put_pixel (pft, x, y, pixel);
|
|
progress++;
|
|
}
|
|
else
|
|
{
|
|
gimp_old_preview_put_pixel (preview, x, y, pixel);
|
|
}
|
|
}
|
|
|
|
static void
|
|
average_pixel (guchar *dest,
|
|
const guchar *src1,
|
|
const guchar *src2,
|
|
gint bpp)
|
|
{
|
|
for (; bpp; bpp--)
|
|
{
|
|
*dest++ = (*src1++ + *src2++) / 2;
|
|
}
|
|
}
|
|
|
|
static void
|
|
random_rgb (GRand *gr,
|
|
guchar *pixel)
|
|
{
|
|
gint i;
|
|
|
|
for (i = 0; i < alpha; i++)
|
|
pixel[i] = g_rand_int_range (gr, 0, 256);
|
|
|
|
if (has_alpha)
|
|
pixel[alpha] = 255;
|
|
}
|
|
|
|
static void
|
|
add_random (GRand *gr,
|
|
guchar *pixel,
|
|
gint amount)
|
|
{
|
|
gint i, tmp;
|
|
|
|
amount /= 2;
|
|
|
|
for (i = 0; i < alpha; i++)
|
|
{
|
|
tmp = pixel[i] + g_rand_int_range (gr, - amount, amount);
|
|
pixel[i] = CLAMP0255 (tmp);
|
|
}
|
|
}
|
|
|
|
static gboolean
|
|
do_plasma (GimpPixelFetcher *pft,
|
|
gint x1,
|
|
gint y1,
|
|
gint x2,
|
|
gint y2,
|
|
gint depth,
|
|
gint scale_depth,
|
|
GRand *gr)
|
|
{
|
|
guchar tl[4], ml[4], bl[4], mt[4], mm[4], mb[4], tr[4], mr[4], br[4];
|
|
guchar tmp[4];
|
|
gint xm, ym;
|
|
|
|
static gint count = 0;
|
|
|
|
/* Initial pass through - no averaging. */
|
|
|
|
if (depth == -1)
|
|
{
|
|
random_rgb (gr, tl);
|
|
put_pixel (pft, x1, y1, tl);
|
|
random_rgb (gr, tr);
|
|
put_pixel (pft, x2, y1, tr);
|
|
random_rgb (gr, bl);
|
|
put_pixel (pft, x1, y2, bl);
|
|
random_rgb (gr, br);
|
|
put_pixel (pft, x2, y2, br);
|
|
random_rgb (gr, mm);
|
|
put_pixel (pft, (x1 + x2) / 2, (y1 + y2) / 2, mm);
|
|
random_rgb (gr, ml);
|
|
put_pixel (pft, x1, (y1 + y2) / 2, ml);
|
|
random_rgb (gr, mr);
|
|
put_pixel (pft, x2, (y1 + y2) / 2, mr);
|
|
random_rgb (gr, mt);
|
|
put_pixel (pft, (x1 + x2) / 2, y1, mt);
|
|
random_rgb (gr, mb);
|
|
put_pixel (pft, (x1 + x2) / 2, y2, mb);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* Some later pass, at the bottom of this pass,
|
|
* with averaging at this depth.
|
|
*/
|
|
if (depth == 0)
|
|
{
|
|
gint ran;
|
|
gint xave, yave;
|
|
|
|
if (x1 == x2 && y1 == y2)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
get_pixel (pft, x1, y1, tl);
|
|
get_pixel (pft, x1, y2, bl);
|
|
get_pixel (pft, x2, y1, tr);
|
|
get_pixel (pft, x2, y2, br);
|
|
|
|
ran = (gint) ((256.0 / (2.0 * scale_depth)) * turbulence);
|
|
|
|
xave = (x1 + x2) / 2;
|
|
yave = (y1 + y2) / 2;
|
|
|
|
if (xave != x1 || xave != x2)
|
|
{
|
|
/* Left. */
|
|
average_pixel (ml, tl, bl, bpp);
|
|
add_random (gr, ml, ran);
|
|
put_pixel (pft, x1, yave, ml);
|
|
|
|
if (x1 != x2)
|
|
{
|
|
/* Right. */
|
|
average_pixel (mr, tr, br, bpp);
|
|
add_random (gr, mr, ran);
|
|
put_pixel (pft, x2, yave, mr);
|
|
}
|
|
}
|
|
|
|
if (yave != y1 || yave != y2)
|
|
{
|
|
if (x1 != xave || yave != y2)
|
|
{
|
|
/* Bottom. */
|
|
average_pixel (mb, bl, br, bpp);
|
|
add_random (gr, mb, ran);
|
|
put_pixel (pft, xave, y2, mb);
|
|
}
|
|
|
|
if (y1 != y2)
|
|
{
|
|
/* Top. */
|
|
average_pixel (mt, tl, tr, bpp);
|
|
add_random (gr, mt, ran);
|
|
put_pixel (pft, xave, y1, mt);
|
|
}
|
|
}
|
|
|
|
if (y1 != y2 || x1 != x2)
|
|
{
|
|
/* Middle pixel. */
|
|
average_pixel (mm, tl, br, bpp);
|
|
average_pixel (tmp, bl, tr, bpp);
|
|
average_pixel (mm, mm, tmp, bpp);
|
|
|
|
add_random (gr, mm, ran);
|
|
put_pixel (pft, xave, yave, mm);
|
|
}
|
|
|
|
count++;
|
|
|
|
if (!(count % 2000) && pft)
|
|
{
|
|
gimp_progress_update ((gdouble) progress / (gdouble) max_progress);
|
|
}
|
|
|
|
return x2 - x1 < 3 && y2 - y1 < 3;
|
|
}
|
|
|
|
xm = (x1 + x2) >> 1;
|
|
ym = (y1 + y2) >> 1;
|
|
|
|
/* Top left. */
|
|
do_plasma (pft, x1, y1, xm, ym, depth - 1, scale_depth + 1, gr);
|
|
/* Bottom left. */
|
|
do_plasma (pft, x1, ym, xm ,y2, depth - 1, scale_depth + 1, gr);
|
|
/* Top right. */
|
|
do_plasma (pft, xm, y1, x2 , ym, depth - 1, scale_depth + 1, gr);
|
|
/* Bottom right. */
|
|
return do_plasma (pft, xm, ym, x2, y2, depth - 1, scale_depth + 1, gr);
|
|
}
|
|
|