mirror of https://github.com/GNOME/gimp.git
do a lot of stuff that was duplicated in clone and heal. Added lots of
2006-09-05 Michael Natterer <mitch@gimp.org> * app/paint/gimpsourcecore.[ch] (gimp_source_core_motion): do a lot of stuff that was duplicated in clone and heal. Added lots of parameters to GimpSourceCore::motion() to get the stuff down to clone and heal. * app/paint/gimpclone.c (gimp_clone_motion): changed accordingly. * app/paint/gimpheal.c (gimp_heal_motion): ditto. Made it work for dest_drawable != src_pickable. Always add alpha to all buffers and convert the source buffer to the dest drawable's color space because the algorithm works only on buffers of same depth.
This commit is contained in:
parent
b99586a7d0
commit
9ecec01da2
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
2006-09-05 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* app/paint/gimpsourcecore.[ch] (gimp_source_core_motion): do a
|
||||
lot of stuff that was duplicated in clone and heal. Added lots of
|
||||
parameters to GimpSourceCore::motion() to get the stuff down to
|
||||
clone and heal.
|
||||
|
||||
* app/paint/gimpclone.c (gimp_clone_motion): changed accordingly.
|
||||
|
||||
* app/paint/gimpheal.c (gimp_heal_motion): ditto. Made it work for
|
||||
dest_drawable != src_pickable. Always add alpha to all buffers and
|
||||
convert the source buffer to the dest drawable's color space
|
||||
because the algorithm works only on buffers of same depth.
|
||||
|
||||
2006-09-04 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/display/gimpdisplayshell.c
|
||||
|
|
|
@ -53,7 +53,14 @@ static void gimp_clone_paint (GimpPaintCore *paint_core,
|
|||
|
||||
static void gimp_clone_motion (GimpSourceCore *source_core,
|
||||
GimpDrawable *drawable,
|
||||
GimpPaintOptions *paint_options);
|
||||
GimpPaintOptions *paint_options,
|
||||
gdouble opacity,
|
||||
GimpImage *src_image,
|
||||
GimpPickable *src_pickable,
|
||||
PixelRegion *srcPR,
|
||||
TempBuf *paint_area,
|
||||
gint paint_area_offset_x,
|
||||
gint paint_area_offset_y);
|
||||
|
||||
static void gimp_clone_line_image (GimpImage *dest,
|
||||
GimpImage *src,
|
||||
|
@ -136,141 +143,46 @@ gimp_clone_paint (GimpPaintCore *paint_core,
|
|||
static void
|
||||
gimp_clone_motion (GimpSourceCore *source_core,
|
||||
GimpDrawable *drawable,
|
||||
GimpPaintOptions *paint_options)
|
||||
GimpPaintOptions *paint_options,
|
||||
gdouble opacity,
|
||||
GimpImage *src_image,
|
||||
GimpPickable *src_pickable,
|
||||
PixelRegion *srcPR,
|
||||
TempBuf *paint_area,
|
||||
gint paint_area_offset_x,
|
||||
gint paint_area_offset_y)
|
||||
{
|
||||
GimpPaintCore *paint_core = GIMP_PAINT_CORE (source_core);
|
||||
GimpCloneOptions *options = GIMP_CLONE_OPTIONS (paint_options);
|
||||
GimpSourceOptions *source_options = GIMP_SOURCE_OPTIONS (paint_options);
|
||||
GimpContext *context = GIMP_CONTEXT (paint_options);
|
||||
GimpPressureOptions *pressure_options = paint_options->pressure_options;
|
||||
GimpPaintCore *paint_core = GIMP_PAINT_CORE (source_core);
|
||||
GimpCloneOptions *options = GIMP_CLONE_OPTIONS (paint_options);
|
||||
GimpSourceOptions *source_options = GIMP_SOURCE_OPTIONS (paint_options);
|
||||
GimpContext *context = GIMP_CONTEXT (paint_options);
|
||||
GimpImage *image;
|
||||
GimpImage *src_image = NULL;
|
||||
GimpPickable *src_pickable = NULL;
|
||||
guchar *s;
|
||||
guchar *d;
|
||||
TempBuf *area;
|
||||
gpointer pr = NULL;
|
||||
gint y;
|
||||
gint x1, y1, x2, y2;
|
||||
TileManager *src_tiles;
|
||||
PixelRegion srcPR, destPR;
|
||||
PixelRegion destPR;
|
||||
GimpPattern *pattern = NULL;
|
||||
gdouble opacity;
|
||||
gint offset_x;
|
||||
gint offset_y;
|
||||
|
||||
image = gimp_item_get_image (GIMP_ITEM (drawable));
|
||||
|
||||
opacity = gimp_paint_options_get_fade (paint_options, image,
|
||||
paint_core->pixel_dist);
|
||||
if (opacity == 0.0)
|
||||
return;
|
||||
|
||||
/* make local copies because we change them */
|
||||
offset_x = source_core->offset_x;
|
||||
offset_y = source_core->offset_y;
|
||||
|
||||
/* Make sure we still have a source if we are doing image cloning */
|
||||
if (options->clone_type == GIMP_IMAGE_CLONE)
|
||||
{
|
||||
if (! source_core->src_drawable)
|
||||
return;
|
||||
|
||||
src_pickable = GIMP_PICKABLE (source_core->src_drawable);
|
||||
src_image = gimp_pickable_get_image (src_pickable);
|
||||
|
||||
if (source_options->sample_merged)
|
||||
{
|
||||
gint off_x, off_y;
|
||||
|
||||
src_pickable = GIMP_PICKABLE (src_image->projection);
|
||||
|
||||
gimp_item_offsets (GIMP_ITEM (source_core->src_drawable),
|
||||
&off_x, &off_y);
|
||||
|
||||
offset_x += off_x;
|
||||
offset_y += off_y;
|
||||
}
|
||||
|
||||
gimp_pickable_flush (src_pickable);
|
||||
}
|
||||
|
||||
area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options);
|
||||
if (! area)
|
||||
return;
|
||||
|
||||
/* configure the destination */
|
||||
switch (options->clone_type)
|
||||
{
|
||||
case GIMP_IMAGE_CLONE:
|
||||
/* Set the paint area to transparent */
|
||||
temp_buf_data_clear (area);
|
||||
pixel_region_init_temp_buf (&destPR, paint_area,
|
||||
paint_area_offset_x, paint_area_offset_y,
|
||||
srcPR->w, srcPR->h);
|
||||
|
||||
src_tiles = gimp_pickable_get_tiles (src_pickable);
|
||||
|
||||
x1 = CLAMP (area->x + offset_x,
|
||||
0, tile_manager_width (src_tiles));
|
||||
y1 = CLAMP (area->y + offset_y,
|
||||
0, tile_manager_height (src_tiles));
|
||||
x2 = CLAMP (area->x + offset_x + area->width,
|
||||
0, tile_manager_width (src_tiles));
|
||||
y2 = CLAMP (area->y + offset_y + area->height,
|
||||
0, tile_manager_height (src_tiles));
|
||||
|
||||
if (!(x2 - x1) || !(y2 - y1))
|
||||
return;
|
||||
|
||||
/* If the source image is different from the destination,
|
||||
* then we should copy straight from the destination image
|
||||
* to the canvas.
|
||||
* Otherwise, we need a call to get_orig_image to make sure
|
||||
* we get a copy of the unblemished (offset) image
|
||||
*/
|
||||
if ((source_options->sample_merged &&
|
||||
(src_image != image)) ||
|
||||
|
||||
(! source_options->sample_merged &&
|
||||
(source_core->src_drawable != drawable)))
|
||||
{
|
||||
pixel_region_init (&srcPR, src_tiles,
|
||||
x1, y1, x2 - x1, y2 - y1, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
TempBuf *orig;
|
||||
|
||||
/* get the original image */
|
||||
if (source_options->sample_merged)
|
||||
orig = gimp_paint_core_get_orig_proj (paint_core,
|
||||
src_pickable,
|
||||
x1, y1, x2, y2);
|
||||
else
|
||||
orig = gimp_paint_core_get_orig_image (paint_core,
|
||||
GIMP_DRAWABLE (src_pickable),
|
||||
x1, y1, x2, y2);
|
||||
|
||||
pixel_region_init_temp_buf (&srcPR, orig,
|
||||
0, 0, x2 - x1, y2 - y1);
|
||||
}
|
||||
|
||||
offset_x = x1 - (area->x + offset_x);
|
||||
offset_y = y1 - (area->y + offset_y);
|
||||
|
||||
/* configure the destination */
|
||||
pixel_region_init_temp_buf (&destPR, area,
|
||||
offset_x, offset_y, srcPR.w, srcPR.h);
|
||||
|
||||
pr = pixel_regions_register (2, &srcPR, &destPR);
|
||||
pr = pixel_regions_register (2, srcPR, &destPR);
|
||||
break;
|
||||
|
||||
case GIMP_PATTERN_CLONE:
|
||||
pattern = gimp_context_get_pattern (context);
|
||||
|
||||
if (!pattern)
|
||||
if (! pattern)
|
||||
return;
|
||||
|
||||
/* configure the destination */
|
||||
pixel_region_init_temp_buf (&destPR, area,
|
||||
0, 0, area->width, area->height);
|
||||
pixel_region_init_temp_buf (&destPR, paint_area,
|
||||
0, 0,
|
||||
paint_area->width, paint_area->height);
|
||||
|
||||
pr = pixel_regions_register (1, &destPR);
|
||||
break;
|
||||
|
@ -278,8 +190,8 @@ gimp_clone_motion (GimpSourceCore *source_core,
|
|||
|
||||
for (; pr != NULL; pr = pixel_regions_process (pr))
|
||||
{
|
||||
s = srcPR.data;
|
||||
d = destPR.data;
|
||||
guchar *s = srcPR->data;
|
||||
guchar *d = destPR.data;
|
||||
|
||||
for (y = 0; y < destPR.h; y++)
|
||||
{
|
||||
|
@ -289,15 +201,15 @@ gimp_clone_motion (GimpSourceCore *source_core,
|
|||
gimp_clone_line_image (image, src_image,
|
||||
drawable, src_pickable,
|
||||
s, d,
|
||||
srcPR.bytes, destPR.bytes, destPR.w);
|
||||
s += srcPR.rowstride;
|
||||
srcPR->bytes, destPR.bytes, destPR.w);
|
||||
s += srcPR->rowstride;
|
||||
break;
|
||||
|
||||
case GIMP_PATTERN_CLONE:
|
||||
gimp_clone_line_pattern (image, drawable,
|
||||
pattern, d,
|
||||
area->x + offset_x,
|
||||
area->y + y + offset_y,
|
||||
paint_area->x + paint_area_offset_x,
|
||||
paint_area->y + y + paint_area_offset_y,
|
||||
destPR.bytes, destPR.w);
|
||||
break;
|
||||
}
|
||||
|
@ -306,7 +218,7 @@ gimp_clone_motion (GimpSourceCore *source_core,
|
|||
}
|
||||
}
|
||||
|
||||
if (pressure_options->opacity)
|
||||
if (paint_options->pressure_options->opacity)
|
||||
opacity *= PRESSURE_SCALE * paint_core->cur_coords.pressure;
|
||||
|
||||
gimp_brush_core_paste_canvas (GIMP_BRUSH_CORE (paint_core), drawable,
|
||||
|
|
|
@ -51,7 +51,14 @@
|
|||
|
||||
static void gimp_heal_motion (GimpSourceCore *source_core,
|
||||
GimpDrawable *drawable,
|
||||
GimpPaintOptions *paint_options);
|
||||
GimpPaintOptions *paint_options,
|
||||
gdouble opacity,
|
||||
GimpImage *src_image,
|
||||
GimpPickable *src_pickable,
|
||||
PixelRegion *srcPR,
|
||||
TempBuf *paint_area,
|
||||
gint paint_area_offset_x,
|
||||
gint paint_area_offset_y);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpHeal, gimp_heal, GIMP_TYPE_SOURCE_CORE)
|
||||
|
@ -329,75 +336,45 @@ gimp_heal_region (PixelRegion *tempPR,
|
|||
static void
|
||||
gimp_heal_motion (GimpSourceCore *source_core,
|
||||
GimpDrawable *drawable,
|
||||
GimpPaintOptions *paint_options)
|
||||
GimpPaintOptions *paint_options,
|
||||
gdouble opacity,
|
||||
GimpImage *src_image,
|
||||
GimpPickable *src_pickable,
|
||||
PixelRegion *srcPR,
|
||||
TempBuf *paint_area,
|
||||
gint paint_area_offset_x,
|
||||
gint paint_area_offset_y)
|
||||
{
|
||||
GimpPaintCore *paint_core = GIMP_PAINT_CORE (source_core);
|
||||
GimpSourceOptions *options = GIMP_SOURCE_OPTIONS (paint_options);
|
||||
GimpContext *context = GIMP_CONTEXT (paint_options);
|
||||
GimpPressureOptions *pressure_options = paint_options->pressure_options;
|
||||
GimpImage *image;
|
||||
GimpImage *src_image = NULL;
|
||||
GimpPickable *src_pickable = NULL;
|
||||
TileManager *src_tiles;
|
||||
TempBuf *area;
|
||||
TempBuf *temp;
|
||||
gdouble opacity;
|
||||
PixelRegion tempPR;
|
||||
PixelRegion srcPR;
|
||||
PixelRegion destPR;
|
||||
gint offset_x;
|
||||
gint offset_y;
|
||||
GimpPaintCore *paint_core = GIMP_PAINT_CORE (source_core);
|
||||
GimpContext *context = GIMP_CONTEXT (paint_options);
|
||||
TempBuf *src;
|
||||
TempBuf *temp;
|
||||
PixelRegion origPR;
|
||||
PixelRegion tempPR;
|
||||
PixelRegion destPR;
|
||||
GimpImageType src_type;
|
||||
|
||||
/* get the image */
|
||||
image = gimp_item_get_image (GIMP_ITEM (drawable));
|
||||
|
||||
/* display a warning about indexed images and return */
|
||||
if (GIMP_IMAGE_TYPE_IS_INDEXED (drawable->type))
|
||||
if (gimp_drawable_is_indexed (drawable))
|
||||
{
|
||||
g_message (_("Indexed images are not currently supported."));
|
||||
return;
|
||||
}
|
||||
|
||||
opacity = gimp_paint_options_get_fade (paint_options, image,
|
||||
paint_core->pixel_dist);
|
||||
src_type = gimp_pickable_get_image_type (src_pickable);
|
||||
|
||||
if (opacity == 0.0)
|
||||
return;
|
||||
/* we need the source area with alpha and we modify it, so make a copy */
|
||||
src = temp_buf_new (srcPR->w, srcPR->h,
|
||||
GIMP_IMAGE_TYPE_BYTES (GIMP_IMAGE_TYPE_WITH_ALPHA (src_type)),
|
||||
0, 0, NULL);
|
||||
pixel_region_init_temp_buf (&tempPR, src, 0, 0, src->width, src->height);
|
||||
|
||||
if (! source_core->src_drawable)
|
||||
return;
|
||||
if (GIMP_IMAGE_TYPE_HAS_ALPHA (src_type))
|
||||
copy_region (srcPR, &tempPR);
|
||||
else
|
||||
add_alpha_region (srcPR, &tempPR);
|
||||
|
||||
/* prepare the regions to get data from */
|
||||
src_pickable = GIMP_PICKABLE (source_core->src_drawable);
|
||||
src_image = gimp_pickable_get_image (src_pickable);
|
||||
|
||||
/* make local copies */
|
||||
offset_x = source_core->offset_x;
|
||||
offset_y = source_core->offset_y;
|
||||
|
||||
/* adjust offsets and pickable if we are merging layers */
|
||||
if (options->sample_merged)
|
||||
{
|
||||
gint off_x, off_y;
|
||||
|
||||
src_pickable = GIMP_PICKABLE (src_image->projection);
|
||||
|
||||
gimp_item_offsets (GIMP_ITEM (source_core->src_drawable), &off_x, &off_y);
|
||||
|
||||
offset_x += off_x;
|
||||
offset_y += off_y;
|
||||
}
|
||||
|
||||
/* get the canvas area */
|
||||
area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options);
|
||||
if (!area)
|
||||
return;
|
||||
|
||||
/* clear the area where we want to paint */
|
||||
temp_buf_data_clear (area);
|
||||
|
||||
/* get the source tiles */
|
||||
src_tiles = gimp_pickable_get_tiles (src_pickable);
|
||||
/* reinitialize srcPR */
|
||||
pixel_region_init_temp_buf (srcPR, src, 0, 0, src->width, src->height);
|
||||
|
||||
/* FIXME: the area under the cursor and the source area should be x% larger
|
||||
* than the brush size. Otherwise the brush must be a lot bigger than the
|
||||
|
@ -406,107 +383,91 @@ gimp_heal_motion (GimpSourceCore *source_core,
|
|||
|
||||
/* Get the area underneath the cursor */
|
||||
{
|
||||
TempBuf *orig;
|
||||
gint x1, x2, y1, y2;
|
||||
TileManager *tiles = gimp_drawable_get_tiles (drawable);
|
||||
TempBuf *orig;
|
||||
gint x1, x2, y1, y2;
|
||||
|
||||
x1 = CLAMP (area->x,
|
||||
0, tile_manager_width (src_tiles));
|
||||
y1 = CLAMP (area->y,
|
||||
0, tile_manager_height (src_tiles));
|
||||
x2 = CLAMP (area->x + area->width,
|
||||
0, tile_manager_width (src_tiles));
|
||||
y2 = CLAMP (area->y + area->height,
|
||||
0, tile_manager_height (src_tiles));
|
||||
x1 = CLAMP (paint_area->x,
|
||||
0, tile_manager_width (tiles));
|
||||
y1 = CLAMP (paint_area->y,
|
||||
0, tile_manager_height (tiles));
|
||||
x2 = CLAMP (paint_area->x + paint_area->width,
|
||||
0, tile_manager_width (tiles));
|
||||
y2 = CLAMP (paint_area->y + paint_area->height,
|
||||
0, tile_manager_height (tiles));
|
||||
|
||||
if (! (x2 - x1) || (! (y2 - y1)))
|
||||
return;
|
||||
{
|
||||
temp_buf_free (src);
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the original image data at the cursor location */
|
||||
if (options->sample_merged)
|
||||
orig = gimp_paint_core_get_orig_proj (paint_core,
|
||||
src_pickable,
|
||||
x1, y1, x2, y2);
|
||||
else
|
||||
orig = gimp_paint_core_get_orig_image (paint_core,
|
||||
GIMP_DRAWABLE (src_pickable),
|
||||
x1, y1, x2, y2);
|
||||
orig = gimp_paint_core_get_orig_image (paint_core, drawable,
|
||||
x1, y1, x2, y2);
|
||||
|
||||
pixel_region_init_temp_buf (&srcPR, orig, 0, 0, x2 - x1, y2 - y1);
|
||||
pixel_region_init_temp_buf (&origPR, orig, 0, 0, x2 - x1, y2 - y1);
|
||||
}
|
||||
|
||||
temp = temp_buf_new (srcPR.w, srcPR.h, srcPR.bytes, 0, 0, NULL);
|
||||
temp = temp_buf_new (origPR.w, origPR.h,
|
||||
gimp_drawable_bytes_with_alpha (drawable),
|
||||
0, 0, NULL);
|
||||
pixel_region_init_temp_buf (&tempPR, temp, 0, 0, origPR.w, origPR.h);
|
||||
|
||||
pixel_region_init_temp_buf (&tempPR, temp, 0, 0, srcPR.w, srcPR.h);
|
||||
if (gimp_drawable_has_alpha (drawable))
|
||||
copy_region (&origPR, &tempPR);
|
||||
else
|
||||
add_alpha_region (&origPR, &tempPR);
|
||||
|
||||
copy_region (&srcPR, &tempPR);
|
||||
if (tempPR.bytes != srcPR->bytes)
|
||||
{
|
||||
TempBuf *temp2;
|
||||
gboolean new_buf;
|
||||
|
||||
/* now tempPR holds the data under the cursor */
|
||||
temp2 = gimp_image_transform_temp_buf (gimp_item_get_image (GIMP_ITEM (drawable)),
|
||||
drawable,
|
||||
temp, &new_buf);
|
||||
|
||||
/* get a copy of the location we will sample from */
|
||||
{
|
||||
TempBuf *orig;
|
||||
gint x1, x2, y1, y2;
|
||||
if (new_buf)
|
||||
temp_buf_free (temp);
|
||||
|
||||
x1 = CLAMP (area->x + offset_x,
|
||||
0, tile_manager_width (src_tiles));
|
||||
y1 = CLAMP (area->y + offset_y,
|
||||
0, tile_manager_height (src_tiles));
|
||||
x2 = CLAMP (area->x + offset_x + area->width,
|
||||
0, tile_manager_width (src_tiles));
|
||||
y2 = CLAMP (area->y + offset_y + area->height,
|
||||
0, tile_manager_height (src_tiles));
|
||||
temp = temp2;
|
||||
}
|
||||
|
||||
if (! (x2 - x1) || (! (y2 - y1)))
|
||||
return;
|
||||
/* reinitialize tempPR */
|
||||
pixel_region_init_temp_buf (&tempPR, temp, 0, 0, temp->width, temp->height);
|
||||
|
||||
/* get the original image data at the sample location */
|
||||
if (options->sample_merged)
|
||||
orig = gimp_paint_core_get_orig_proj (paint_core,
|
||||
src_pickable,
|
||||
x1, y1, x2, y2);
|
||||
else
|
||||
orig = gimp_paint_core_get_orig_image (paint_core,
|
||||
GIMP_DRAWABLE (src_pickable),
|
||||
x1, y1, x2, y2);
|
||||
|
||||
pixel_region_init_temp_buf (&srcPR, orig, 0, 0, x2 - x1, y2 - y1);
|
||||
|
||||
/* set the proper offset */
|
||||
offset_x = x1 - (area->x + offset_x);
|
||||
offset_y = y1 - (area->y + offset_y);
|
||||
}
|
||||
|
||||
/* now srcPR holds the source area to sample from */
|
||||
/* now tempPR holds the data under the cursor and
|
||||
* srcPR holds the area to sample from
|
||||
*/
|
||||
|
||||
/* get the destination to paint to */
|
||||
pixel_region_init_temp_buf (&destPR, area, offset_x, offset_y, srcPR.w, srcPR.h);
|
||||
pixel_region_init_temp_buf (&destPR, paint_area,
|
||||
paint_area_offset_x, paint_area_offset_y,
|
||||
srcPR->w, srcPR->h);
|
||||
|
||||
/* FIXME: Can we ensure that this is true in the code above?
|
||||
* Is it already guaranteed to be true before we get here? */
|
||||
/* check that srcPR, tempPR, and destPR are the same size */
|
||||
if ((srcPR.w != tempPR.w ) || (srcPR.w != destPR.w ) ||
|
||||
(srcPR.h != tempPR.h ) || (srcPR.h != destPR.h ))
|
||||
if ((srcPR->w != tempPR.w) || (srcPR->w != destPR.w) ||
|
||||
(srcPR->h != tempPR.h) || (srcPR->h != destPR.h))
|
||||
{
|
||||
g_message (_("Source and destination regions are not the same size."));
|
||||
temp_buf_free (src);
|
||||
temp_buf_free (temp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* heal tempPR using srcPR */
|
||||
gimp_heal_region (&tempPR, &srcPR);
|
||||
gimp_heal_region (&tempPR, srcPR);
|
||||
|
||||
/* re-initialize tempPR so that it can be used within copy_region */
|
||||
pixel_region_init_data (&tempPR, tempPR.data, tempPR.bytes, tempPR.rowstride,
|
||||
0, 0, tempPR.w, tempPR.h);
|
||||
/* reinitialize tempPR */
|
||||
pixel_region_init_temp_buf (&tempPR, temp, 0, 0, temp->width, temp->height);
|
||||
|
||||
/* add an alpha region to the area if necessary.
|
||||
* sample_merged doesn't need an alpha because its always 4 bpp */
|
||||
if ((! gimp_drawable_has_alpha (drawable)) && (! options->sample_merged))
|
||||
add_alpha_region (&tempPR, &destPR);
|
||||
else
|
||||
copy_region (&tempPR, &destPR);
|
||||
copy_region (&tempPR, &destPR);
|
||||
|
||||
/* check the brush pressure */
|
||||
if (pressure_options->opacity)
|
||||
if (paint_options->pressure_options->opacity)
|
||||
opacity *= PRESSURE_SCALE * paint_core->cur_coords.pressure;
|
||||
|
||||
/* replace the canvas with our healed data */
|
||||
|
@ -516,4 +477,7 @@ gimp_heal_motion (GimpSourceCore *source_core,
|
|||
gimp_context_get_opacity (context),
|
||||
gimp_paint_options_get_brush_mode (paint_options),
|
||||
GIMP_PAINT_CONSTANT);
|
||||
|
||||
temp_buf_free (src);
|
||||
temp_buf_free (temp);
|
||||
}
|
||||
|
|
|
@ -24,9 +24,14 @@
|
|||
|
||||
#include "paint-types.h"
|
||||
|
||||
#include "base/temp-buf.h"
|
||||
#include "base/tile-manager.h"
|
||||
#include "base/pixel-region.h"
|
||||
|
||||
#include "core/gimp.h"
|
||||
#include "core/gimpdrawable.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimppickable.h"
|
||||
|
||||
#include "gimpsourcecore.h"
|
||||
#include "gimpsourceoptions.h"
|
||||
|
@ -269,9 +274,118 @@ gimp_source_core_motion (GimpSourceCore *source_core,
|
|||
GimpDrawable *drawable,
|
||||
GimpPaintOptions *paint_options)
|
||||
{
|
||||
GimpPaintCore *paint_core = GIMP_PAINT_CORE (source_core);
|
||||
GimpSourceOptions *options = GIMP_SOURCE_OPTIONS (paint_options);
|
||||
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
|
||||
GimpImage *src_image = NULL;
|
||||
GimpPickable *src_pickable = NULL;
|
||||
PixelRegion srcPR;
|
||||
TempBuf *paint_area;
|
||||
gint offset_x;
|
||||
gint offset_y;
|
||||
gdouble opacity;
|
||||
|
||||
opacity = gimp_paint_options_get_fade (paint_options, image,
|
||||
paint_core->pixel_dist);
|
||||
if (opacity == 0.0)
|
||||
return;
|
||||
|
||||
offset_x = source_core->offset_x;
|
||||
offset_y = source_core->offset_y;
|
||||
|
||||
if (options->use_source)
|
||||
{
|
||||
if (! source_core->src_drawable)
|
||||
return;
|
||||
|
||||
src_pickable = GIMP_PICKABLE (source_core->src_drawable);
|
||||
src_image = gimp_pickable_get_image (src_pickable);
|
||||
|
||||
if (options->sample_merged)
|
||||
{
|
||||
gint off_x, off_y;
|
||||
|
||||
src_pickable = GIMP_PICKABLE (src_image->projection);
|
||||
|
||||
gimp_item_offsets (GIMP_ITEM (source_core->src_drawable),
|
||||
&off_x, &off_y);
|
||||
|
||||
offset_x += off_x;
|
||||
offset_y += off_y;
|
||||
}
|
||||
|
||||
gimp_pickable_flush (src_pickable);
|
||||
}
|
||||
|
||||
paint_area = gimp_paint_core_get_paint_area (paint_core, drawable,
|
||||
paint_options);
|
||||
if (! paint_area)
|
||||
return;
|
||||
|
||||
if (options->use_source)
|
||||
{
|
||||
TileManager *src_tiles = gimp_pickable_get_tiles (src_pickable);
|
||||
gint x1, y1;
|
||||
gint x2, y2;
|
||||
|
||||
x1 = CLAMP (paint_area->x + offset_x,
|
||||
0, tile_manager_width (src_tiles));
|
||||
y1 = CLAMP (paint_area->y + offset_y,
|
||||
0, tile_manager_height (src_tiles));
|
||||
x2 = CLAMP (paint_area->x + offset_x + paint_area->width,
|
||||
0, tile_manager_width (src_tiles));
|
||||
y2 = CLAMP (paint_area->y + offset_y + paint_area->height,
|
||||
0, tile_manager_height (src_tiles));
|
||||
|
||||
if (!(x2 - x1) || !(y2 - y1))
|
||||
return;
|
||||
|
||||
/* If the source image is different from the destination,
|
||||
* then we should copy straight from the source image
|
||||
* to the canvas.
|
||||
* Otherwise, we need a call to get_orig_image to make sure
|
||||
* we get a copy of the unblemished (offset) image
|
||||
*/
|
||||
if (( options->sample_merged && (src_image != image)) ||
|
||||
(! options->sample_merged && (source_core->src_drawable != drawable)))
|
||||
{
|
||||
pixel_region_init (&srcPR, src_tiles,
|
||||
x1, y1, x2 - x1, y2 - y1, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
TempBuf *orig;
|
||||
|
||||
/* get the original image */
|
||||
if (options->sample_merged)
|
||||
orig = gimp_paint_core_get_orig_proj (paint_core,
|
||||
src_pickable,
|
||||
x1, y1, x2, y2);
|
||||
else
|
||||
orig = gimp_paint_core_get_orig_image (paint_core,
|
||||
GIMP_DRAWABLE (src_pickable),
|
||||
x1, y1, x2, y2);
|
||||
|
||||
pixel_region_init_temp_buf (&srcPR, orig,
|
||||
0, 0, x2 - x1, y2 - y1);
|
||||
}
|
||||
|
||||
offset_x = x1 - (paint_area->x + offset_x);
|
||||
offset_y = y1 - (paint_area->y + offset_y);
|
||||
}
|
||||
|
||||
/* Set the paint area to transparent */
|
||||
temp_buf_data_clear (paint_area);
|
||||
|
||||
GIMP_SOURCE_CORE_GET_CLASS (source_core)->motion (source_core,
|
||||
drawable,
|
||||
paint_options);
|
||||
paint_options,
|
||||
opacity,
|
||||
src_image,
|
||||
src_pickable,
|
||||
&srcPR,
|
||||
paint_area,
|
||||
offset_x, offset_y);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -58,7 +58,14 @@ struct _GimpSourceCoreClass
|
|||
|
||||
void (* motion) (GimpSourceCore *source_core,
|
||||
GimpDrawable *drawable,
|
||||
GimpPaintOptions *paint_options);
|
||||
GimpPaintOptions *paint_options,
|
||||
gdouble opacity,
|
||||
GimpImage *src_image,
|
||||
GimpPickable *src_pickable,
|
||||
PixelRegion *srcPR,
|
||||
TempBuf *paint_area,
|
||||
gint paint_area_offset_x,
|
||||
gint paint_area_offset_y);
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue