Paint cleanup:

2002-06-09  Michael Natterer  <mitch@gimp.org>

	Paint cleanup:

	* app/paint/gimpairbrush.c
	* app/paint/gimpclone.c
	* app/paint/gimpconvolve.c
	* app/paint/gimpdodgeburn.c
	* app/paint/gimperaser.c
	* app/paint/gimppaintbrush.c
	* app/paint/gimppencil.c
	* app/paint/gimpsmudge.c
	* app/tools/gimpblendtool.c: made all *_motion() functions take
	only (paint_core, drawable, paint_options) and get all parametrs
	from looking at paint_options. Reordered functions to be
	consistent. Indentation. Stuff...

	* app/paint/gimpdodgeburn.[ch]: moved the GimpLut from
	GimpDodgeBurnOptions to the GimpDodgeBurn object struct.

	* app/paint/gimpsmudge.[ch]: moved all global variables to the
	GimpSmudge object struct.
This commit is contained in:
Michael Natterer 2002-06-09 13:56:09 +00:00 committed by Michael Natterer
parent fd21daebdf
commit 4163623b27
12 changed files with 610 additions and 554 deletions

View File

@ -1,3 +1,26 @@
2002-06-09 Michael Natterer <mitch@gimp.org>
Paint cleanup:
* app/paint/gimpairbrush.c
* app/paint/gimpclone.c
* app/paint/gimpconvolve.c
* app/paint/gimpdodgeburn.c
* app/paint/gimperaser.c
* app/paint/gimppaintbrush.c
* app/paint/gimppencil.c
* app/paint/gimpsmudge.c
* app/tools/gimpblendtool.c: made all *_motion() functions take
only (paint_core, drawable, paint_options) and get all parametrs
from looking at paint_options. Reordered functions to be
consistent. Indentation. Stuff...
* app/paint/gimpdodgeburn.[ch]: moved the GimpLut from
GimpDodgeBurnOptions to the GimpDodgeBurn object struct.
* app/paint/gimpsmudge.[ch]: moved all global variables to the
GimpSmudge object struct.
2002-06-09 Sven Neumann <sven@gimp.org>
* app/undo.c

View File

@ -175,9 +175,7 @@ gimp_airbrush_paint (GimpPaintCore *paint_core,
timeout_id = 0;
}
gimp_airbrush_motion (paint_core,
drawable,
paint_options);
gimp_airbrush_motion (paint_core, drawable, paint_options);
if (options->rate != 0.0)
{
@ -210,41 +208,6 @@ gimp_airbrush_paint (GimpPaintCore *paint_core,
}
}
static gboolean
gimp_airbrush_timeout (gpointer client_data)
{
gdouble rate;
gimp_airbrush_motion (airbrush_timeout.paint_core,
airbrush_timeout.drawable,
airbrush_timeout.paint_options);
gimp_image_flush (gimp_item_get_image (GIMP_ITEM (airbrush_timeout.drawable)));
rate = ((GimpAirbrushOptions *) airbrush_timeout.paint_options)->rate;
/* restart the timer */
if (rate != 0.0)
{
if (airbrush_timeout.paint_options->pressure_options->rate)
{
if (timeout_id)
g_source_remove (timeout_id);
timeout_id = g_timeout_add ((10000 /
(rate * 2.0 *
airbrush_timeout.paint_core->cur_coords.pressure)),
gimp_airbrush_timeout,
NULL);
return FALSE;
}
return TRUE;
}
return FALSE;
}
static void
gimp_airbrush_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
@ -255,8 +218,8 @@ gimp_airbrush_motion (GimpPaintCore *paint_core,
TempBuf *area;
guchar col[MAX_CHANNELS];
gdouble scale;
GimpPaintApplicationMode paint_appl_mode;
gdouble pressure;
GimpPaintApplicationMode paint_appl_mode;
if (! (gimage = gimp_item_get_image (GIMP_ITEM (drawable))))
return;
@ -320,7 +283,44 @@ gimp_airbrush_motion (GimpPaintCore *paint_core,
MIN (pressure, GIMP_OPACITY_OPAQUE),
gimp_context_get_opacity (context),
gimp_context_get_paint_mode (context),
GIMP_BRUSH_SOFT, scale, paint_appl_mode);
GIMP_BRUSH_SOFT,
scale,
paint_appl_mode);
}
static gboolean
gimp_airbrush_timeout (gpointer client_data)
{
gdouble rate;
gimp_airbrush_motion (airbrush_timeout.paint_core,
airbrush_timeout.drawable,
airbrush_timeout.paint_options);
gimp_image_flush (gimp_item_get_image (GIMP_ITEM (airbrush_timeout.drawable)));
rate = ((GimpAirbrushOptions *) airbrush_timeout.paint_options)->rate;
/* restart the timer */
if (rate != 0.0)
{
if (airbrush_timeout.paint_options->pressure_options->rate)
{
if (timeout_id)
g_source_remove (timeout_id);
timeout_id = g_timeout_add ((10000 /
(rate * 2.0 *
airbrush_timeout.paint_core->cur_coords.pressure)),
gimp_airbrush_timeout,
NULL);
return FALSE;
}
return TRUE;
}
return FALSE;
}

View File

@ -51,11 +51,8 @@ static void gimp_clone_paint (GimpPaintCore *paint_core,
GimpPaintCoreState paint_state);
static void gimp_clone_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
GimpPressureOptions *pressure_options,
GimpCloneType type,
gint offset_x,
gint offset_y);
GimpPaintOptions *paint_options);
static void gimp_clone_line_image (GimpImage *dest,
GimpImage *src,
GimpDrawable *d_drawable,
@ -187,6 +184,32 @@ gimp_clone_paint (GimpPaintCore *paint_core,
clone->posttrace_callback (clone, clone->callback_data);
break;
case INIT_PAINT:
if (clone->set_source)
{
gimp_clone_set_src_drawable (clone, drawable);
clone->src_x = paint_core->cur_coords.x;
clone->src_y = paint_core->cur_coords.y;
clone->first_stroke = TRUE;
}
else if (options->aligned == GIMP_CLONE_ALIGN_NO)
{
orig_src_x = clone->src_x;
orig_src_y = clone->src_y;
clone->first_stroke = TRUE;
}
if (clone->init_callback)
clone->init_callback (clone, clone->callback_data);
if (options->type == GIMP_PATTERN_CLONE)
if (! gimp_context_get_pattern (context))
g_message (_("No patterns available for this operation."));
break;
case MOTION_PAINT:
if (clone->set_source)
{
@ -223,41 +246,10 @@ gimp_clone_paint (GimpPaintCore *paint_core,
clone->src_x = dest_x + clone->offset_x;
clone->src_y = dest_y + clone->offset_y;
gimp_clone_motion (paint_core, drawable,
clone->src_drawable,
options->paint_options.pressure_options,
options->type,
clone->offset_x,
clone->offset_y);
gimp_clone_motion (paint_core, drawable, paint_options);
}
break;
case INIT_PAINT:
if (clone->set_source)
{
gimp_clone_set_src_drawable (clone, drawable);
clone->src_x = paint_core->cur_coords.x;
clone->src_y = paint_core->cur_coords.y;
clone->first_stroke = TRUE;
}
else if (options->aligned == GIMP_CLONE_ALIGN_NO)
{
orig_src_x = clone->src_x;
orig_src_y = clone->src_y;
clone->first_stroke = TRUE;
}
if (clone->init_callback)
clone->init_callback (clone, clone->callback_data);
if (options->type == GIMP_PATTERN_CLONE)
if (! gimp_context_get_pattern (context))
g_message (_("No patterns available for this operation."));
break;
case FINISH_PAINT:
if (clone->finish_callback)
clone->finish_callback (clone, clone->callback_data);
@ -275,43 +267,51 @@ gimp_clone_paint (GimpPaintCore *paint_core,
}
static void
gimp_clone_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
GimpPressureOptions *pressure_options,
GimpCloneType type,
gint offset_x,
gint offset_y)
gimp_clone_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options)
{
GimpImage *gimage;
GimpImage *src_gimage = NULL;
GimpContext *context;
guchar *s;
guchar *d;
TempBuf *area;
gpointer pr;
gint y;
gint x1, y1, x2, y2;
gint has_alpha = -1;
PixelRegion srcPR, destPR;
GimpPattern *pattern;
gdouble opacity;
gdouble scale;
GimpClone *clone;
GimpCloneOptions *options;
GimpPressureOptions *pressure_options;
GimpImage *gimage;
GimpImage *src_gimage = NULL;
GimpContext *context;
guchar *s;
guchar *d;
TempBuf *area;
gpointer pr = NULL;
gint y;
gint x1, y1, x2, y2;
gint has_alpha = -1;
PixelRegion srcPR, destPR;
GimpPattern *pattern = NULL;
gdouble opacity;
gdouble scale;
gint offset_x;
gint offset_y;
pr = NULL;
pattern = NULL;
clone = GIMP_CLONE (paint_core);
options = (GimpCloneOptions *) paint_options;
pressure_options = paint_options->pressure_options;
/* make local copies because we change them */
offset_x = clone->offset_x;
offset_y = clone->offset_y;
/* Make sure we still have a source if we are doing image cloning */
if (type == GIMP_IMAGE_CLONE)
if (options->type == GIMP_IMAGE_CLONE)
{
if (!src_drawable)
if (! clone->src_drawable)
return;
if (! (src_gimage = gimp_item_get_image (GIMP_ITEM (src_drawable))))
if (! (src_gimage = gimp_item_get_image (GIMP_ITEM (clone->src_drawable))))
return;
/* Determine whether the source image has an alpha channel */
has_alpha = gimp_drawable_has_alpha (src_drawable);
has_alpha = gimp_drawable_has_alpha (clone->src_drawable);
}
/* We always need a destination image */
@ -329,18 +329,20 @@ gimp_clone_motion (GimpPaintCore *paint_core,
if (! (area = gimp_paint_core_get_paint_area (paint_core, drawable, scale)))
return;
switch (type)
switch (options->type)
{
case GIMP_IMAGE_CLONE:
/* Set the paint area to transparent */
temp_buf_data_clear (area);
x1 = CLAMP (area->x + offset_x, 0, gimp_drawable_width (src_drawable));
y1 = CLAMP (area->y + offset_y, 0, gimp_drawable_height (src_drawable));
x1 = CLAMP (area->x + offset_x,
0, gimp_drawable_width (clone->src_drawable));
y1 = CLAMP (area->y + offset_y,
0, gimp_drawable_height (clone->src_drawable));
x2 = CLAMP (area->x + offset_x + area->width,
0, gimp_drawable_width (src_drawable));
0, gimp_drawable_width (clone->src_drawable));
y2 = CLAMP (area->y + offset_y + area->height,
0, gimp_drawable_height (src_drawable));
0, gimp_drawable_height (clone->src_drawable));
if (!(x2 - x1) || !(y2 - y1))
return;
@ -351,9 +353,9 @@ gimp_clone_motion (GimpPaintCore *paint_core,
* Otherwise, we need a call to get_orig_image to make sure
* we get a copy of the unblemished (offset) image
*/
if (src_drawable != drawable)
if (clone->src_drawable != drawable)
{
pixel_region_init (&srcPR, gimp_drawable_data (src_drawable),
pixel_region_init (&srcPR, gimp_drawable_data (clone->src_drawable),
x1, y1, (x2 - x1), (y2 - y1), FALSE);
}
else
@ -361,7 +363,7 @@ gimp_clone_motion (GimpPaintCore *paint_core,
TempBuf *orig;
/* get the original image */
orig = gimp_paint_core_get_orig_image (paint_core, src_drawable,
orig = gimp_paint_core_get_orig_image (paint_core, clone->src_drawable,
x1, y1, x2, y2);
srcPR.bytes = orig->bytes;
@ -416,11 +418,11 @@ gimp_clone_motion (GimpPaintCore *paint_core,
for (y = 0; y < destPR.h; y++)
{
switch (type)
switch (options->type)
{
case GIMP_IMAGE_CLONE:
gimp_clone_line_image (gimage, src_gimage,
drawable, src_drawable,
drawable, clone->src_drawable,
s, d, has_alpha,
srcPR.bytes, destPR.bytes, destPR.w);
s += srcPR.rowstride;
@ -451,7 +453,8 @@ gimp_clone_motion (GimpPaintCore *paint_core,
gimp_context_get_paint_mode (context),
(pressure_options->pressure ?
GIMP_BRUSH_PRESSURE : GIMP_BRUSH_SOFT),
scale, GIMP_PAINT_CONSTANT);
scale,
GIMP_PAINT_CONSTANT);
}
static void

View File

@ -61,11 +61,8 @@ static void gimp_convolve_paint (GimpPaintCore *paint_core,
GimpPaintOptions *paint_options,
GimpPaintCoreState paint_state);
static void gimp_convolve_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPressureOptions *pressure_options,
GimpConvolveType type,
gdouble rate);
GimpDrawable *drawable,
GimpPaintOptions *paint_options);
static void gimp_convolve_calculate_matrix (GimpConvolveType type,
gdouble rate);
@ -171,18 +168,10 @@ gimp_convolve_paint (GimpPaintCore *paint_core,
GimpPaintOptions *paint_options,
GimpPaintCoreState paint_state)
{
GimpConvolveOptions *options;
options = (GimpConvolveOptions *) paint_options;
switch (paint_state)
{
case MOTION_PAINT:
gimp_convolve_motion (paint_core,
drawable,
paint_options->pressure_options,
options->type,
options->rate);
gimp_convolve_motion (paint_core, drawable, paint_options);
break;
default:
@ -191,22 +180,26 @@ gimp_convolve_paint (GimpPaintCore *paint_core,
}
static void
gimp_convolve_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPressureOptions *pressure_options,
GimpConvolveType type,
gdouble rate)
gimp_convolve_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options)
{
TempBuf *area;
guchar *temp_data;
PixelRegion srcPR;
PixelRegion destPR;
gdouble scale;
ConvolveClipType area_hclip = CONVOLVE_NOT_CLIPPED;
ConvolveClipType area_vclip = CONVOLVE_NOT_CLIPPED;
gint marginx = 0;
gint marginy = 0;
GimpContext *context;
GimpConvolveOptions *options;
GimpPressureOptions *pressure_options;
TempBuf *area;
guchar *temp_data;
PixelRegion srcPR;
PixelRegion destPR;
gdouble scale;
ConvolveClipType area_hclip = CONVOLVE_NOT_CLIPPED;
ConvolveClipType area_vclip = CONVOLVE_NOT_CLIPPED;
gint marginx = 0;
gint marginy = 0;
GimpContext *context;
options = (GimpConvolveOptions *) paint_options;
pressure_options = paint_options->pressure_options;
if (! gimp_item_get_image (GIMP_ITEM (drawable)))
return;
@ -246,9 +239,9 @@ gimp_convolve_motion (GimpPaintCore *paint_core,
destPR.data = temp_buf_data (area);
if (pressure_options->rate)
rate = rate * 2.0 * paint_core->cur_coords.pressure;
options->rate = options->rate * 2.0 * paint_core->cur_coords.pressure;
gimp_convolve_calculate_matrix (type, rate);
gimp_convolve_calculate_matrix (options->type, options->rate);
/* Image region near edges? If so, paint area will be clipped */
/* with respect to brush mask + 1 pixel border (# 19285) */

View File

@ -41,34 +41,34 @@
static void gimp_dodgeburn_class_init (GimpDodgeBurnClass *klass);
static void gimp_dodgeburn_init (GimpDodgeBurn *dodgeburn);
static void gimp_dodgeburn_make_luts (GimpPaintCore *paint_core,
gdouble db_exposure,
GimpDodgeBurnType type,
GimpTransferMode mode,
GimpLut *lut,
GimpDrawable *drawable);
static void gimp_dodgeburn_finalize (GObject *object);
static void gimp_dodgeburn_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpPaintCoreState paint_state);
static void gimp_dodgeburn_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options);
static gfloat gimp_dodgeburn_highlights_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value);
static gfloat gimp_dodgeburn_midtones_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value);
static gfloat gimp_dodgeburn_shadows_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value);
static void gimp_dodgeburn_make_luts (GimpDodgeBurn *dodgeburn,
gdouble db_exposure,
GimpDodgeBurnType type,
GimpTransferMode mode,
GimpDrawable *drawable);
static gfloat gimp_dodgeburn_highlights_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value);
static gfloat gimp_dodgeburn_midtones_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value);
static gfloat gimp_dodgeburn_shadows_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value);
static GimpPaintCoreClass *parent_class = NULL;
@ -112,12 +112,16 @@ gimp_dodgeburn_get_type (void)
static void
gimp_dodgeburn_class_init (GimpDodgeBurnClass *klass)
{
GObjectClass *object_class;
GimpPaintCoreClass *paint_core_class;
object_class = G_OBJECT_CLASS (klass);
paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gimp_dodgeburn_finalize;
paint_core_class->paint = gimp_dodgeburn_paint;
}
@ -131,43 +135,20 @@ gimp_dodgeburn_init (GimpDodgeBurn *dodgeburn)
paint_core->flags |= CORE_HANDLES_CHANGING_BRUSH;
}
static void
gimp_dodgeburn_make_luts (GimpPaintCore *paint_core,
gdouble db_exposure,
GimpDodgeBurnType type,
GimpTransferMode mode,
GimpLut *lut,
GimpDrawable *drawable)
static void
gimp_dodgeburn_finalize (GObject *object)
{
GimpLutFunc lut_func;
gint nchannels = gimp_drawable_bytes (drawable);
static gfloat exposure;
GimpDodgeBurn *dodgeburn;
exposure = db_exposure / 100.0;
dodgeburn = GIMP_DODGEBURN (object);
/* make the exposure negative if burn for luts*/
if (type == GIMP_BURN)
exposure = -exposure;
switch (mode)
if (dodgeburn->lut)
{
case GIMP_HIGHLIGHTS:
lut_func = gimp_dodgeburn_highlights_lut_func;
break;
case GIMP_MIDTONES:
lut_func = gimp_dodgeburn_midtones_lut_func;
break;
case GIMP_SHADOWS:
lut_func = gimp_dodgeburn_shadows_lut_func;
break;
default:
lut_func = NULL;
break;
gimp_lut_free (dodgeburn->lut);
dodgeburn->lut = NULL;
}
gimp_lut_setup_exact (lut,
lut_func, (gpointer) &exposure,
nchannels);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
@ -177,33 +158,33 @@ gimp_dodgeburn_paint (GimpPaintCore *paint_core,
GimpPaintCoreState paint_state)
{
GimpDodgeBurnOptions *options;
GimpDodgeBurn *dodgeburn;
options = (GimpDodgeBurnOptions *) paint_options;
dodgeburn = GIMP_DODGEBURN (paint_core);
switch (paint_state)
{
case INIT_PAINT:
options->lut = gimp_lut_new ();
dodgeburn->lut = gimp_lut_new ();
gimp_dodgeburn_make_luts (paint_core,
gimp_dodgeburn_make_luts (dodgeburn,
options->exposure,
options->type,
options->mode,
options->lut,
drawable);
break;
case MOTION_PAINT:
gimp_dodgeburn_motion (paint_core,
drawable,
paint_options);
gimp_dodgeburn_motion (paint_core, drawable, paint_options);
break;
case FINISH_PAINT:
if (options->lut)
if (dodgeburn->lut)
{
gimp_lut_free (options->lut);
options->lut = NULL;
gimp_lut_free (dodgeburn->lut);
dodgeburn->lut = NULL;
}
break;
@ -217,6 +198,7 @@ gimp_dodgeburn_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options)
{
GimpDodgeBurn *dodgeburn;
GimpDodgeBurnOptions *options;
GimpPressureOptions *pressure_options;
GimpImage *gimage;
@ -227,6 +209,12 @@ gimp_dodgeburn_motion (GimpPaintCore *paint_core,
gdouble opacity;
gdouble scale;
dodgeburn = GIMP_DODGEBURN (paint_core);
options = (GimpDodgeBurnOptions *) paint_options;
pressure_options = paint_options->pressure_options;
if (! (gimage = gimp_item_get_image (GIMP_ITEM (drawable))))
return;
@ -235,10 +223,6 @@ gimp_dodgeburn_motion (GimpPaintCore *paint_core,
(gimp_drawable_type (drawable) == GIMP_INDEXEDA_IMAGE))
return;
options = (GimpDodgeBurnOptions *) paint_options;
pressure_options = paint_options->pressure_options;
if (pressure_options->size)
scale = paint_core->cur_coords.pressure;
else
@ -286,7 +270,7 @@ gimp_dodgeburn_motion (GimpPaintCore *paint_core,
temp_data = tempPR.data;
/* DodgeBurn the region */
gimp_lut_process (options->lut, &srcPR, &tempPR);
gimp_lut_process (dodgeburn->lut, &srcPR, &tempPR);
/* The dest is the paint area we got above (= canvas_buf) */
destPR.bytes = area->bytes;
@ -315,11 +299,50 @@ gimp_dodgeburn_motion (GimpPaintCore *paint_core,
GIMP_OPACITY_OPAQUE,
(pressure_options->pressure ?
GIMP_BRUSH_PRESSURE : GIMP_BRUSH_SOFT),
scale, GIMP_PAINT_CONSTANT);
scale,
GIMP_PAINT_CONSTANT);
g_free (temp_data);
}
static void
gimp_dodgeburn_make_luts (GimpDodgeBurn *dodgeburn,
gdouble db_exposure,
GimpDodgeBurnType type,
GimpTransferMode mode,
GimpDrawable *drawable)
{
GimpLutFunc lut_func;
gint nchannels = gimp_drawable_bytes (drawable);
static gfloat exposure;
exposure = db_exposure / 100.0;
/* make the exposure negative if burn for luts*/
if (type == GIMP_BURN)
exposure = -exposure;
switch (mode)
{
case GIMP_HIGHLIGHTS:
lut_func = gimp_dodgeburn_highlights_lut_func;
break;
case GIMP_MIDTONES:
lut_func = gimp_dodgeburn_midtones_lut_func;
break;
case GIMP_SHADOWS:
lut_func = gimp_dodgeburn_shadows_lut_func;
break;
default:
lut_func = NULL;
break;
}
gimp_lut_setup_exact (dodgeburn->lut,
lut_func, (gpointer) &exposure,
nchannels);
}
static gfloat
gimp_dodgeburn_highlights_lut_func (gpointer user_data,
gint nchannels,
@ -410,7 +433,6 @@ gimp_dodgeburn_options_new (void)
options->type = options->type_d = DODGEBURN_DEFAULT_TYPE;
options->exposure = options->exposure_d = DODGEBURN_DEFAULT_EXPOSURE;
options->mode = options->mode_d = DODGEBURN_DEFAULT_MODE;
options->lut = NULL;
return options;
}

View File

@ -36,7 +36,9 @@ typedef struct _GimpDodgeBurnClass GimpDodgeBurnClass;
struct _GimpDodgeBurn
{
GimpPaintCore parent_instance;
GimpPaintCore parent_instance;
GimpLut *lut;
};
struct _GimpDodgeBurnClass
@ -62,8 +64,6 @@ struct _GimpDodgeBurnOptions
gdouble exposure;
gdouble exposure_d;
GtkObject *exposure_w;
GimpLut *lut;
};

View File

@ -117,16 +117,8 @@ gimp_eraser_paint (GimpPaintCore *paint_core,
{
switch (paint_state)
{
case INIT_PAINT:
break;
case MOTION_PAINT:
gimp_eraser_motion (paint_core,
drawable,
paint_options);
break;
case FINISH_PAINT:
gimp_eraser_motion (paint_core, drawable, paint_options);
break;
default:
@ -139,15 +131,16 @@ gimp_eraser_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options)
{
GimpEraserOptions *options;
GimpPressureOptions *pressure_options;
GimpImage *gimage;
GimpContext *context;
gdouble opacity;
TempBuf *area;
guchar col[MAX_CHANNELS];
gdouble scale;
GimpEraserOptions *options;
GimpPressureOptions *pressure_options;
GimpImage *gimage;
GimpContext *context;
gdouble opacity;
TempBuf *area;
guchar col[MAX_CHANNELS];
gdouble scale;
GimpBrushApplicationMode brush_mode;
GimpPaintApplicationMode paint_appl_mode;
if (! (gimage = gimp_item_get_image (GIMP_ITEM (drawable))))
return;
@ -160,6 +153,9 @@ gimp_eraser_motion (GimpPaintCore *paint_core,
context = gimp_get_current_context (gimage->gimp);
paint_appl_mode = (paint_options->incremental ?
GIMP_PAINT_INCREMENTAL : GIMP_PAINT_CONSTANT);
if (pressure_options->size)
scale = paint_core->cur_coords.pressure;
else
@ -198,8 +194,7 @@ gimp_eraser_motion (GimpPaintCore *paint_core,
GIMP_ANTI_ERASE_MODE : GIMP_ERASE_MODE),
brush_mode,
scale,
(paint_options->incremental ?
GIMP_PAINT_INCREMENTAL : GIMP_PAINT_CONSTANT));
paint_appl_mode);
}

View File

@ -41,22 +41,16 @@
#include "gimppaintoptions.h"
static void gimp_paintbrush_class_init (GimpPaintbrushClass *klass);
static void gimp_paintbrush_init (GimpPaintbrush *paintbrush);
static void gimp_paintbrush_class_init (GimpPaintbrushClass *klass);
static void gimp_paintbrush_init (GimpPaintbrush *paintbrush);
static void gimp_paintbrush_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpPaintCoreState paint_state);
static void gimp_paintbrush_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPressureOptions *pressure_options,
GimpGradientOptions *gradient_options,
gdouble fade_out,
gdouble gradient_length,
gboolean incremental,
GimpGradientPaintMode gradient_type);
static void gimp_paintbrush_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpPaintCoreState paint_state);
static void gimp_paintbrush_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options);
static GimpPaintCoreClass *parent_class = NULL;
@ -125,70 +119,10 @@ gimp_paintbrush_paint (GimpPaintCore *paint_core,
GimpPaintOptions *paint_options,
GimpPaintCoreState paint_state)
{
GimpPressureOptions *pressure_options;
GimpGradientOptions *gradient_options;
gboolean incremental;
GimpImage *gimage;
gdouble fade_out;
gdouble gradient_length;
gdouble unit_factor;
gimage = gimp_item_get_image (GIMP_ITEM (drawable));
pressure_options = paint_options->pressure_options;
gradient_options = paint_options->gradient_options;
incremental = paint_options->incremental;
switch (paint_state)
{
case INIT_PAINT:
break;
case MOTION_PAINT:
switch (gradient_options->fade_unit)
{
case GIMP_UNIT_PIXEL:
fade_out = gradient_options->fade_out;
break;
case GIMP_UNIT_PERCENT:
fade_out = (MAX (gimage->width, gimage->height) *
gradient_options->fade_out / 100);
break;
default:
unit_factor = gimp_unit_get_factor (gradient_options->fade_unit);
fade_out = (gradient_options->fade_out *
MAX (gimage->xresolution,
gimage->yresolution) / unit_factor);
break;
}
switch (gradient_options->gradient_unit)
{
case GIMP_UNIT_PIXEL:
gradient_length = gradient_options->gradient_length;
break;
case GIMP_UNIT_PERCENT:
gradient_length = (MAX (gimage->width, gimage->height) *
gradient_options->gradient_length / 100);
break;
default:
unit_factor = gimp_unit_get_factor (gradient_options->gradient_unit);
gradient_length = (gradient_options->gradient_length *
MAX (gimage->xresolution,
gimage->yresolution) / unit_factor);
break;
}
gimp_paintbrush_motion (paint_core, drawable,
pressure_options,
gradient_options,
gradient_options->use_fade ? fade_out : 0,
gradient_options->use_gradient ? gradient_length : 0,
incremental,
gradient_options->gradient_type);
break;
case FINISH_PAINT:
gimp_paintbrush_motion (paint_core, drawable, paint_options);
break;
default:
@ -199,61 +133,115 @@ gimp_paintbrush_paint (GimpPaintCore *paint_core,
static void
gimp_paintbrush_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPressureOptions *pressure_options,
GimpGradientOptions *gradient_options,
gdouble fade_out,
gdouble gradient_length,
gboolean incremental,
GimpGradientPaintMode gradient_type)
GimpPaintOptions *paint_options)
{
GimpImage *gimage;
GimpContext *context;
TempBuf *area;
gdouble x, paint_left;
guchar local_blend = OPAQUE_OPACITY;
guchar temp_blend = OPAQUE_OPACITY;
guchar col[MAX_CHANNELS];
GimpRGB color;
gdouble opacity;
gdouble scale;
GimpPressureOptions *pressure_options;
GimpGradientOptions *gradient_options;
GimpImage *gimage;
GimpContext *context;
TempBuf *area;
gdouble gradient_length;
guchar local_blend = OPAQUE_OPACITY;
guchar col[MAX_CHANNELS];
gdouble opacity;
gdouble scale;
GimpPaintApplicationMode paint_appl_mode;
GimpPaintApplicationMode paint_appl_mode = (incremental ?
GIMP_PAINT_INCREMENTAL :
GIMP_PAINT_CONSTANT);
if (! (gimage = gimp_item_get_image (GIMP_ITEM (drawable))))
return;
gimage = gimp_item_get_image (GIMP_ITEM (drawable));
pressure_options = paint_options->pressure_options;
gradient_options = paint_options->gradient_options;
context = gimp_get_current_context (gimage->gimp);
paint_appl_mode = (paint_options->incremental ?
GIMP_PAINT_INCREMENTAL : GIMP_PAINT_CONSTANT);
if (gradient_options->use_fade)
{
gdouble fade_out = 0.0;
gdouble unit_factor;
switch (gradient_options->fade_unit)
{
case GIMP_UNIT_PIXEL:
fade_out = gradient_options->fade_out;
break;
case GIMP_UNIT_PERCENT:
fade_out = (MAX (gimage->width, gimage->height) *
gradient_options->fade_out / 100);
break;
default:
unit_factor = gimp_unit_get_factor (gradient_options->fade_unit);
fade_out = (gradient_options->fade_out *
MAX (gimage->xresolution,
gimage->yresolution) / unit_factor);
break;
}
/* factor in the fade out value */
if (fade_out)
{
gdouble x, paint_left;
/* Model the amount of paint left as a gaussian curve */
x = ((gdouble) paint_core->pixel_dist / fade_out);
paint_left = exp (- x * x * 5.541); /* ln (1/255) */
local_blend = (gint) (255 * paint_left);
}
}
if (gradient_options->use_gradient)
{
gdouble unit_factor;
switch (gradient_options->gradient_unit)
{
case GIMP_UNIT_PIXEL:
gradient_length = gradient_options->gradient_length;
break;
case GIMP_UNIT_PERCENT:
gradient_length = (MAX (gimage->width, gimage->height) *
gradient_options->gradient_length / 100);
break;
default:
unit_factor = gimp_unit_get_factor (gradient_options->gradient_unit);
gradient_length = (gradient_options->gradient_length *
MAX (gimage->xresolution,
gimage->yresolution) / unit_factor);
break;
}
}
else
{
gradient_length = 0.0;
}
if (pressure_options->color)
gradient_length = 1.0; /* not really used, only for if cases */
if (pressure_options->size)
scale = paint_core->cur_coords.pressure;
else
scale = 1.0;
if (pressure_options->color)
gradient_length = 1.0; /* not really used, only for if cases */
/* Get a region which can be used to paint to */
if (! (area = gimp_paint_core_get_paint_area (paint_core, drawable, scale)))
return;
/* factor in the fade out value */
if (fade_out)
{
/* Model the amount of paint left as a gaussian curve */
x = ((double) paint_core->pixel_dist / fade_out);
paint_left = exp (- x * x * 5.541); /* ln (1/255) */
local_blend = (int) (255 * paint_left);
}
if (local_blend)
{
guchar temp_blend;
/* set the alpha channel */
temp_blend = local_blend;
if (gradient_length)
{
GimpGradient *gradient;
GimpRGB color;
gradient = gimp_context_get_gradient (context);
@ -266,7 +254,7 @@ gimp_paintbrush_motion (GimpPaintCore *paint_core,
gradient,
gradient_length,
&color,
gradient_type);
gradient_options->gradient_type);
temp_blend = (gint) ((color.a * local_blend));
@ -311,6 +299,7 @@ gimp_paintbrush_motion (GimpPaintCore *paint_core,
gimp_context_get_paint_mode (context),
(pressure_options->pressure ?
GIMP_BRUSH_PRESSURE : GIMP_BRUSH_SOFT),
scale, paint_appl_mode);
scale,
paint_appl_mode);
}
}

View File

@ -120,16 +120,10 @@ gimp_pencil_paint (GimpPaintCore *paint_core,
{
switch (paint_state)
{
case INIT_PAINT:
break;
case MOTION_PAINT:
gimp_pencil_motion (paint_core, drawable, paint_options);
break;
case FINISH_PAINT:
break;
default:
break;
}
@ -140,14 +134,17 @@ gimp_pencil_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options)
{
GimpImage *gimage;
GimpContext *context;
TempBuf *area;
guchar col[MAX_CHANNELS];
gdouble opacity;
gdouble scale;
GimpPressureOptions *pressure_options;
GimpImage *gimage;
GimpContext *context;
TempBuf *area;
guchar col[MAX_CHANNELS];
gdouble opacity;
gdouble scale;
GimpPaintApplicationMode paint_appl_mode;
pressure_options = paint_options->pressure_options;
gimage = gimp_item_get_image (GIMP_ITEM (drawable));
context = gimp_get_current_context (gimage->gimp);
@ -155,7 +152,7 @@ gimp_pencil_motion (GimpPaintCore *paint_core,
paint_appl_mode = (paint_options->incremental ?
GIMP_PAINT_INCREMENTAL : GIMP_PAINT_CONSTANT);
if (paint_options->pressure_options->size)
if (pressure_options->size)
scale = paint_core->cur_coords.pressure;
else
scale = 1.0;
@ -165,7 +162,7 @@ gimp_pencil_motion (GimpPaintCore *paint_core,
return;
/* color the pixels */
if (paint_options->pressure_options->color)
if (pressure_options->color)
{
GimpRGB color;
@ -203,7 +200,7 @@ gimp_pencil_motion (GimpPaintCore *paint_core,
opacity = gimp_context_get_opacity (context);
if (paint_options->pressure_options->opacity)
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_core->cur_coords.pressure;
/* paste the newly painted canvas to the gimage which is being worked on */
@ -211,5 +208,7 @@ gimp_pencil_motion (GimpPaintCore *paint_core,
MIN (opacity, GIMP_OPACITY_OPAQUE),
gimp_context_get_opacity (context),
gimp_context_get_paint_mode (context),
GIMP_BRUSH_HARD, scale, paint_appl_mode);
GIMP_BRUSH_HARD,
scale,
paint_appl_mode);
}

View File

@ -41,34 +41,30 @@
static void gimp_smudge_class_init (GimpSmudgeClass *klass);
static void gimp_smudge_init (GimpSmudge *smudge);
static void gimp_smudge_finalize (GObject *object);
static void gimp_smudge_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpPaintCoreState paint_state);
static gboolean gimp_smudge_start (GimpPaintCore *paint_core,
GimpDrawable *drawable);
static void gimp_smudge_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPressureOptions *pressure_options,
gdouble smudge_rate);
static void gimp_smudge_finish (GimpPaintCore *paint_core,
GimpDrawable *drawable);
GimpPaintOptions *paint_options);
static void gimp_smudge_nonclipped_painthit_coords (GimpPaintCore *paint_core,
gint *x,
gint *y,
gint *w,
gint *h);
static void gimp_smudge_allocate_accum_buffer (gint w,
static void gimp_smudge_allocate_accum_buffer (GimpSmudge *smudge,
gint w,
gint h,
gint bytes,
guchar *do_fill);
static PixelRegion accumPR;
static guchar *accum_data = NULL;
static GimpPaintCoreClass *parent_class = NULL;
@ -110,12 +106,16 @@ gimp_smudge_get_type (void)
static void
gimp_smudge_class_init (GimpSmudgeClass *klass)
{
GObjectClass *object_class;
GimpPaintCoreClass *paint_core_class;
object_class = G_OBJECT_CLASS (klass);
paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gimp_smudge_finalize;
paint_core_class->paint = gimp_smudge_paint;
}
@ -127,6 +127,25 @@ gimp_smudge_init (GimpSmudge *smudge)
paint_core = GIMP_PAINT_CORE (smudge);
paint_core->flags |= CORE_HANDLES_CHANGING_BRUSH;
smudge->initialized = FALSE;
smudge->accum_data = NULL;
}
static void
gimp_smudge_finalize (GObject *object)
{
GimpSmudge *smudge;
smudge = GIMP_SMUDGE (object);
if (smudge->accum_data)
{
g_free (smudge->accum_data);
smudge->accum_data = NULL;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
@ -135,29 +154,28 @@ gimp_smudge_paint (GimpPaintCore *paint_core,
GimpPaintOptions *paint_options,
GimpPaintCoreState paint_state)
{
GimpSmudgeOptions *options;
GimpSmudge *smudge;
/* initialization fails if the user starts outside the drawable */
static gboolean initialized = FALSE;
options = (GimpSmudgeOptions *) paint_options;
smudge = GIMP_SMUDGE (paint_core);
switch (paint_state)
{
case MOTION_PAINT:
if (! initialized)
initialized = gimp_smudge_start (paint_core, drawable);
/* initialization fails if the user starts outside the drawable */
if (! smudge->initialized)
smudge->initialized = gimp_smudge_start (paint_core, drawable);
if (initialized)
gimp_smudge_motion (paint_core,
drawable,
paint_options->pressure_options,
options->rate);
if (smudge->initialized)
gimp_smudge_motion (paint_core, drawable, paint_options);
break;
case FINISH_PAINT:
gimp_smudge_finish (paint_core, drawable);
initialized = FALSE;
if (smudge->accum_data)
{
g_free (smudge->accum_data);
smudge->accum_data = NULL;
}
smudge->initialized = FALSE;
break;
default:
@ -171,6 +189,7 @@ static gboolean
gimp_smudge_start (GimpPaintCore *paint_core,
GimpDrawable *drawable)
{
GimpSmudge *smudge;
GimpImage *gimage;
TempBuf *area;
PixelRegion srcPR;
@ -178,6 +197,8 @@ gimp_smudge_start (GimpPaintCore *paint_core,
gint was_clipped;
guchar *do_fill = NULL;
smudge = GIMP_SMUDGE (paint_core);
gimage = gimp_item_get_image (GIMP_ITEM (drawable));
/* If the image type is indexed, don't smudge */
@ -213,53 +234,62 @@ gimp_smudge_start (GimpPaintCore *paint_core,
CLAMP ((gint) paint_core->cur_coords.y,
0, gimp_drawable_height (drawable) - 1));
gimp_smudge_allocate_accum_buffer (w, h,
gimp_drawable_bytes (drawable),
do_fill);
gimp_smudge_allocate_accum_buffer (smudge,
w, h,
gimp_drawable_bytes (drawable),
do_fill);
accumPR.x = area->x - x;
accumPR.y = area->y - y;
accumPR.w = area->width;
accumPR.h = area->height;
accumPR.rowstride = accumPR.bytes * w;
accumPR.data = accum_data
+ accumPR.rowstride * accumPR.y
+ accumPR.x * accumPR.bytes;
smudge->accumPR.x = area->x - x;
smudge->accumPR.y = area->y - y;
smudge->accumPR.w = area->width;
smudge->accumPR.h = area->height;
smudge->accumPR.rowstride = smudge->accumPR.bytes * w;
smudge->accumPR.data = (smudge->accum_data +
smudge->accumPR.rowstride * smudge->accumPR.y +
smudge->accumPR.x * smudge->accumPR.bytes);
pixel_region_init (&srcPR, gimp_drawable_data (drawable),
area->x, area->y, area->width, area->height, FALSE);
/* copy the region under the original painthit. */
copy_region (&srcPR, &accumPR);
copy_region (&srcPR, &smudge->accumPR);
accumPR.x = area->x - x;
accumPR.y = area->y - y;
accumPR.w = area->width;
accumPR.h = area->height;
accumPR.rowstride = accumPR.bytes * w;
accumPR.data = accum_data
+ accumPR.rowstride * accumPR.y
+ accumPR.x * accumPR.bytes;
smudge->accumPR.x = area->x - x;
smudge->accumPR.y = area->y - y;
smudge->accumPR.w = area->width;
smudge->accumPR.h = area->height;
smudge->accumPR.rowstride = smudge->accumPR.bytes * w;
smudge->accumPR.data = (smudge->accum_data +
smudge->accumPR.rowstride * smudge->accumPR.y +
smudge->accumPR.x * smudge->accumPR.bytes);
if (do_fill)
g_free(do_fill);
if (do_fill)
g_free (do_fill);
return TRUE;
}
static void
gimp_smudge_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPressureOptions *pressure_options,
gdouble smudge_rate)
gimp_smudge_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options)
{
GimpImage *gimage;
GimpContext *context;
TempBuf *area;
PixelRegion srcPR, destPR, tempPR;
gdouble rate;
gdouble opacity;
gint x, y, w, h;
GimpSmudge *smudge;
GimpSmudgeOptions *options;
GimpPressureOptions *pressure_options;
GimpImage *gimage;
GimpContext *context;
TempBuf *area;
PixelRegion srcPR, destPR, tempPR;
gdouble rate;
gdouble opacity;
gint x, y, w, h;
smudge = GIMP_SMUDGE (paint_core);
options = (GimpSmudgeOptions *) paint_options;
pressure_options = paint_options->pressure_options;
gimage = gimp_item_get_image (GIMP_ITEM (drawable));
@ -284,55 +314,56 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
/* Enable pressure sensitive rate */
if (pressure_options->rate)
rate = MIN (smudge_rate / 100.0 * paint_core->cur_coords.pressure * 2.0, 1.0);
rate = MIN (options->rate / 100.0 * paint_core->cur_coords.pressure * 2.0, 1.0);
else
rate = smudge_rate / 100.0;
rate = options->rate / 100.0;
/* The tempPR will be the built up buffer (for smudge) */
tempPR.bytes = accumPR.bytes;
tempPR.rowstride = accumPR.rowstride;
tempPR.x = area->x - x;
tempPR.y = area->y - y;
tempPR.w = area->width;
tempPR.h = area->height;
tempPR.data = accum_data +
tempPR.rowstride * tempPR.y + tempPR.x * tempPR.bytes;
tempPR.x = area->x - x;
tempPR.y = area->y - y;
tempPR.w = area->width;
tempPR.h = area->height;
tempPR.bytes = smudge->accumPR.bytes;
tempPR.rowstride = smudge->accumPR.rowstride;
tempPR.data = (smudge->accum_data +
tempPR.y * tempPR.rowstride +
tempPR.x * tempPR.bytes);
/* The dest will be the paint area we got above (= canvas_buf) */
destPR.bytes = area->bytes;
destPR.x = 0; destPR.y = 0;
destPR.w = area->width;
destPR.h = area->height;
destPR.x = 0;
destPR.y = 0;
destPR.w = area->width;
destPR.h = area->height;
destPR.bytes = area->bytes;
destPR.rowstride = area->width * area->bytes;
destPR.data = temp_buf_data (area);
destPR.data = temp_buf_data (area);
/*
Smudge uses the buffer Accum.
For each successive painthit Accum is built like this
Accum = rate*Accum + (1-rate)*I.
where I is the pixels under the current painthit.
Then the paint area (canvas_buf) is built as
(Accum,1) (if no alpha),
*/
/* Smudge uses the buffer Accum.
* For each successive painthit Accum is built like this
* Accum = rate*Accum + (1-rate)*I.
* where I is the pixels under the current painthit.
* Then the paint area (canvas_buf) is built as
* (Accum,1) (if no alpha),
*/
blend_region (&srcPR, &tempPR, &tempPR, ROUND (rate * 255.0));
/* re-init the tempPR */
tempPR.bytes = accumPR.bytes;
tempPR.rowstride = accumPR.rowstride;
tempPR.x = area->x - x;
tempPR.y = area->y - y;
tempPR.w = area->width;
tempPR.h = area->height;
tempPR.data = accum_data
+ tempPR.rowstride * tempPR.y
+ tempPR.x * tempPR.bytes;
tempPR.x = area->x - x;
tempPR.y = area->y - y;
tempPR.w = area->width;
tempPR.h = area->height;
tempPR.bytes = smudge->accumPR.bytes;
tempPR.rowstride = smudge->accumPR.rowstride;
tempPR.data = (smudge->accum_data +
tempPR.y * tempPR.rowstride +
tempPR.x * tempPR.bytes);
if (! gimp_drawable_has_alpha (drawable))
add_alpha_region (&tempPR, &destPR);
else
if (! gimp_drawable_has_alpha (drawable))
add_alpha_region (&tempPR, &destPR);
else
copy_region (&tempPR, &destPR);
opacity = gimp_context_get_opacity (context);
@ -346,18 +377,8 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
GIMP_OPACITY_OPAQUE,
(pressure_options->pressure ?
GIMP_BRUSH_PRESSURE : GIMP_BRUSH_SOFT),
1.0, GIMP_PAINT_INCREMENTAL);
}
static void
gimp_smudge_finish (GimpPaintCore *paint_core,
GimpDrawable *drawable)
{
if (accum_data)
{
g_free (accum_data);
accum_data = NULL;
}
1.0,
GIMP_PAINT_INCREMENTAL);
}
static void
@ -368,32 +389,34 @@ gimp_smudge_nonclipped_painthit_coords (GimpPaintCore *paint_core,
gint *h)
{
/* Note: these are the brush mask size plus a border of 1 pixel */
*x = (gint) paint_core->cur_coords.x - paint_core->brush->mask->width/2 - 1;
*y = (gint) paint_core->cur_coords.y - paint_core->brush->mask->height/2 - 1;
*x = (gint) paint_core->cur_coords.x - paint_core->brush->mask->width / 2 - 1;
*y = (gint) paint_core->cur_coords.y - paint_core->brush->mask->height / 2 - 1;
*w = paint_core->brush->mask->width + 2;
*h = paint_core->brush->mask->height + 2;
}
static void
gimp_smudge_allocate_accum_buffer (gint w,
gint h,
gint bytes,
guchar *do_fill)
gimp_smudge_allocate_accum_buffer (GimpSmudge *smudge,
gint w,
gint h,
gint bytes,
guchar *do_fill)
{
/* Allocate the accumulation buffer */
accumPR.bytes = bytes;
accum_data = g_malloc (w * h * bytes);
smudge->accumPR.bytes = bytes;
smudge->accum_data = g_malloc (w * h * bytes);
if (do_fill != NULL)
{
/* guchar color[3] = {0,0,0}; */
accumPR.x = 0;
accumPR.y = 0;
accumPR.w = w;
accumPR.h = h;
accumPR.rowstride = accumPR.bytes * w;
accumPR.data = accum_data;
color_region (&accumPR, (const guchar*)do_fill);
smudge->accumPR.x = 0;
smudge->accumPR.y = 0;
smudge->accumPR.w = w;
smudge->accumPR.h = h;
smudge->accumPR.rowstride = smudge->accumPR.bytes * w;
smudge->accumPR.data = smudge->accum_data;
color_region (&smudge->accumPR, (const guchar *) do_fill);
}
}

View File

@ -20,6 +20,8 @@
#define __GIMP_SMUDGE_H__
#include "base/pixel-region.h"
#include "gimppaintcore.h"
#include "gimppaintoptions.h"
@ -37,7 +39,11 @@ typedef struct _GimpSmudgeClass GimpSmudgeClass;
struct _GimpSmudge
{
GimpPaintCore parent_instance;
GimpPaintCore parent_instance;
gboolean initialized;
PixelRegion accumPR;
guchar *accum_data;
};
struct _GimpSmudgeClass

View File

@ -51,11 +51,8 @@ static void gimp_clone_paint (GimpPaintCore *paint_core,
GimpPaintCoreState paint_state);
static void gimp_clone_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
GimpPressureOptions *pressure_options,
GimpCloneType type,
gint offset_x,
gint offset_y);
GimpPaintOptions *paint_options);
static void gimp_clone_line_image (GimpImage *dest,
GimpImage *src,
GimpDrawable *d_drawable,
@ -187,6 +184,32 @@ gimp_clone_paint (GimpPaintCore *paint_core,
clone->posttrace_callback (clone, clone->callback_data);
break;
case INIT_PAINT:
if (clone->set_source)
{
gimp_clone_set_src_drawable (clone, drawable);
clone->src_x = paint_core->cur_coords.x;
clone->src_y = paint_core->cur_coords.y;
clone->first_stroke = TRUE;
}
else if (options->aligned == GIMP_CLONE_ALIGN_NO)
{
orig_src_x = clone->src_x;
orig_src_y = clone->src_y;
clone->first_stroke = TRUE;
}
if (clone->init_callback)
clone->init_callback (clone, clone->callback_data);
if (options->type == GIMP_PATTERN_CLONE)
if (! gimp_context_get_pattern (context))
g_message (_("No patterns available for this operation."));
break;
case MOTION_PAINT:
if (clone->set_source)
{
@ -223,41 +246,10 @@ gimp_clone_paint (GimpPaintCore *paint_core,
clone->src_x = dest_x + clone->offset_x;
clone->src_y = dest_y + clone->offset_y;
gimp_clone_motion (paint_core, drawable,
clone->src_drawable,
options->paint_options.pressure_options,
options->type,
clone->offset_x,
clone->offset_y);
gimp_clone_motion (paint_core, drawable, paint_options);
}
break;
case INIT_PAINT:
if (clone->set_source)
{
gimp_clone_set_src_drawable (clone, drawable);
clone->src_x = paint_core->cur_coords.x;
clone->src_y = paint_core->cur_coords.y;
clone->first_stroke = TRUE;
}
else if (options->aligned == GIMP_CLONE_ALIGN_NO)
{
orig_src_x = clone->src_x;
orig_src_y = clone->src_y;
clone->first_stroke = TRUE;
}
if (clone->init_callback)
clone->init_callback (clone, clone->callback_data);
if (options->type == GIMP_PATTERN_CLONE)
if (! gimp_context_get_pattern (context))
g_message (_("No patterns available for this operation."));
break;
case FINISH_PAINT:
if (clone->finish_callback)
clone->finish_callback (clone, clone->callback_data);
@ -275,43 +267,51 @@ gimp_clone_paint (GimpPaintCore *paint_core,
}
static void
gimp_clone_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
GimpPressureOptions *pressure_options,
GimpCloneType type,
gint offset_x,
gint offset_y)
gimp_clone_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options)
{
GimpImage *gimage;
GimpImage *src_gimage = NULL;
GimpContext *context;
guchar *s;
guchar *d;
TempBuf *area;
gpointer pr;
gint y;
gint x1, y1, x2, y2;
gint has_alpha = -1;
PixelRegion srcPR, destPR;
GimpPattern *pattern;
gdouble opacity;
gdouble scale;
GimpClone *clone;
GimpCloneOptions *options;
GimpPressureOptions *pressure_options;
GimpImage *gimage;
GimpImage *src_gimage = NULL;
GimpContext *context;
guchar *s;
guchar *d;
TempBuf *area;
gpointer pr = NULL;
gint y;
gint x1, y1, x2, y2;
gint has_alpha = -1;
PixelRegion srcPR, destPR;
GimpPattern *pattern = NULL;
gdouble opacity;
gdouble scale;
gint offset_x;
gint offset_y;
pr = NULL;
pattern = NULL;
clone = GIMP_CLONE (paint_core);
options = (GimpCloneOptions *) paint_options;
pressure_options = paint_options->pressure_options;
/* make local copies because we change them */
offset_x = clone->offset_x;
offset_y = clone->offset_y;
/* Make sure we still have a source if we are doing image cloning */
if (type == GIMP_IMAGE_CLONE)
if (options->type == GIMP_IMAGE_CLONE)
{
if (!src_drawable)
if (! clone->src_drawable)
return;
if (! (src_gimage = gimp_item_get_image (GIMP_ITEM (src_drawable))))
if (! (src_gimage = gimp_item_get_image (GIMP_ITEM (clone->src_drawable))))
return;
/* Determine whether the source image has an alpha channel */
has_alpha = gimp_drawable_has_alpha (src_drawable);
has_alpha = gimp_drawable_has_alpha (clone->src_drawable);
}
/* We always need a destination image */
@ -329,18 +329,20 @@ gimp_clone_motion (GimpPaintCore *paint_core,
if (! (area = gimp_paint_core_get_paint_area (paint_core, drawable, scale)))
return;
switch (type)
switch (options->type)
{
case GIMP_IMAGE_CLONE:
/* Set the paint area to transparent */
temp_buf_data_clear (area);
x1 = CLAMP (area->x + offset_x, 0, gimp_drawable_width (src_drawable));
y1 = CLAMP (area->y + offset_y, 0, gimp_drawable_height (src_drawable));
x1 = CLAMP (area->x + offset_x,
0, gimp_drawable_width (clone->src_drawable));
y1 = CLAMP (area->y + offset_y,
0, gimp_drawable_height (clone->src_drawable));
x2 = CLAMP (area->x + offset_x + area->width,
0, gimp_drawable_width (src_drawable));
0, gimp_drawable_width (clone->src_drawable));
y2 = CLAMP (area->y + offset_y + area->height,
0, gimp_drawable_height (src_drawable));
0, gimp_drawable_height (clone->src_drawable));
if (!(x2 - x1) || !(y2 - y1))
return;
@ -351,9 +353,9 @@ gimp_clone_motion (GimpPaintCore *paint_core,
* Otherwise, we need a call to get_orig_image to make sure
* we get a copy of the unblemished (offset) image
*/
if (src_drawable != drawable)
if (clone->src_drawable != drawable)
{
pixel_region_init (&srcPR, gimp_drawable_data (src_drawable),
pixel_region_init (&srcPR, gimp_drawable_data (clone->src_drawable),
x1, y1, (x2 - x1), (y2 - y1), FALSE);
}
else
@ -361,7 +363,7 @@ gimp_clone_motion (GimpPaintCore *paint_core,
TempBuf *orig;
/* get the original image */
orig = gimp_paint_core_get_orig_image (paint_core, src_drawable,
orig = gimp_paint_core_get_orig_image (paint_core, clone->src_drawable,
x1, y1, x2, y2);
srcPR.bytes = orig->bytes;
@ -416,11 +418,11 @@ gimp_clone_motion (GimpPaintCore *paint_core,
for (y = 0; y < destPR.h; y++)
{
switch (type)
switch (options->type)
{
case GIMP_IMAGE_CLONE:
gimp_clone_line_image (gimage, src_gimage,
drawable, src_drawable,
drawable, clone->src_drawable,
s, d, has_alpha,
srcPR.bytes, destPR.bytes, destPR.w);
s += srcPR.rowstride;
@ -451,7 +453,8 @@ gimp_clone_motion (GimpPaintCore *paint_core,
gimp_context_get_paint_mode (context),
(pressure_options->pressure ?
GIMP_BRUSH_PRESSURE : GIMP_BRUSH_SOFT),
scale, GIMP_PAINT_CONSTANT);
scale,
GIMP_PAINT_CONSTANT);
}
static void