app: Fix smudge so it can cope with dynamic brushes
This commit is contained in:
@ -59,12 +59,13 @@ static void gimp_smudge_motion (GimpPaintCore *paint_core,
|
|||||||
GimpPaintOptions *paint_options,
|
GimpPaintOptions *paint_options,
|
||||||
const GimpCoords *coords);
|
const GimpCoords *coords);
|
||||||
|
|
||||||
static void gimp_smudge_brush_coords (GimpPaintCore *paint_core,
|
static void gimp_smudge_accumulator_coords (GimpPaintCore *paint_core,
|
||||||
const GimpCoords *coords,
|
const GimpCoords *coords,
|
||||||
gint *x,
|
gint *x,
|
||||||
gint *y,
|
gint *y);
|
||||||
gint *w,
|
|
||||||
gint *h);
|
static void gimp_smudge_accumulator_size (GimpPaintOptions *paint_options,
|
||||||
|
gint *accumulator_size);
|
||||||
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (GimpSmudge, gimp_smudge, GIMP_TYPE_BRUSH_CORE)
|
G_DEFINE_TYPE (GimpSmudge, gimp_smudge, GIMP_TYPE_BRUSH_CORE)
|
||||||
@ -96,7 +97,7 @@ gimp_smudge_class_init (GimpSmudgeClass *klass)
|
|||||||
paint_core_class->paint = gimp_smudge_paint;
|
paint_core_class->paint = gimp_smudge_paint;
|
||||||
|
|
||||||
brush_core_class->handles_transforming_brush = TRUE;
|
brush_core_class->handles_transforming_brush = TRUE;
|
||||||
brush_core_class->handles_dynamic_transforming_brush = FALSE;
|
brush_core_class->handles_dynamic_transforming_brush = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -104,6 +105,7 @@ gimp_smudge_init (GimpSmudge *smudge)
|
|||||||
{
|
{
|
||||||
smudge->initialized = FALSE;
|
smudge->initialized = FALSE;
|
||||||
smudge->accum_data = NULL;
|
smudge->accum_data = NULL;
|
||||||
|
smudge->accum_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -117,6 +119,8 @@ gimp_smudge_finalize (GObject *object)
|
|||||||
smudge->accum_data = NULL;
|
smudge->accum_data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smudge->accum_size = 0;
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +170,7 @@ gimp_smudge_start (GimpPaintCore *paint_core,
|
|||||||
TempBuf *area;
|
TempBuf *area;
|
||||||
PixelRegion srcPR;
|
PixelRegion srcPR;
|
||||||
gint bytes;
|
gint bytes;
|
||||||
gint x, y, w, h;
|
gint x, y;
|
||||||
|
|
||||||
if (gimp_drawable_is_indexed (drawable))
|
if (gimp_drawable_is_indexed (drawable))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -176,17 +180,22 @@ gimp_smudge_start (GimpPaintCore *paint_core,
|
|||||||
if (! area)
|
if (! area)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* adjust the x and y coordinates to the upper left corner of the brush */
|
gimp_smudge_accumulator_size(paint_options, &smudge->accum_size);
|
||||||
gimp_smudge_brush_coords (paint_core, coords, &x, &y, &w, &h);
|
|
||||||
|
/* adjust the x and y coordinates to the upper left corner of the accumulator */
|
||||||
|
gimp_smudge_accumulator_coords (paint_core, coords, &x, &y);
|
||||||
|
|
||||||
/* Allocate the accumulation buffer */
|
/* Allocate the accumulation buffer */
|
||||||
bytes = gimp_drawable_bytes (drawable);
|
bytes = gimp_drawable_bytes (drawable);
|
||||||
smudge->accum_data = g_malloc (w * h * bytes);
|
smudge->accum_data = g_malloc (SQR (smudge->accum_size) * bytes);
|
||||||
|
|
||||||
/* If clipped, prefill the smudge buffer with the color at the
|
/* If clipped, prefill the smudge buffer with the color at the
|
||||||
* brush position.
|
* brush position.
|
||||||
*/
|
*/
|
||||||
if (x != area->x || y != area->y || w != area->width || h != area->height)
|
if (x != area->x ||
|
||||||
|
y != area->y ||
|
||||||
|
smudge->accum_size != area->width ||
|
||||||
|
smudge->accum_size != area->height)
|
||||||
{
|
{
|
||||||
guchar fill[4];
|
guchar fill[4];
|
||||||
|
|
||||||
@ -200,8 +209,8 @@ gimp_smudge_start (GimpPaintCore *paint_core,
|
|||||||
fill);
|
fill);
|
||||||
|
|
||||||
pixel_region_init_data (&srcPR, smudge->accum_data,
|
pixel_region_init_data (&srcPR, smudge->accum_data,
|
||||||
bytes, bytes * w,
|
bytes, bytes * smudge->accum_size,
|
||||||
0, 0, w, h);
|
0, 0, smudge->accum_size, smudge->accum_size);
|
||||||
|
|
||||||
color_region (&srcPR, fill);
|
color_region (&srcPR, fill);
|
||||||
}
|
}
|
||||||
@ -210,7 +219,7 @@ gimp_smudge_start (GimpPaintCore *paint_core,
|
|||||||
area->x, area->y, area->width, area->height, FALSE);
|
area->x, area->y, area->width, area->height, FALSE);
|
||||||
|
|
||||||
pixel_region_init_data (&smudge->accumPR, smudge->accum_data,
|
pixel_region_init_data (&smudge->accumPR, smudge->accum_data,
|
||||||
bytes, bytes * w,
|
bytes, bytes * smudge->accum_size,
|
||||||
area->x - x,
|
area->x - x,
|
||||||
area->y - y,
|
area->y - y,
|
||||||
area->width,
|
area->width,
|
||||||
@ -220,7 +229,7 @@ gimp_smudge_start (GimpPaintCore *paint_core,
|
|||||||
copy_region (&srcPR, &smudge->accumPR);
|
copy_region (&srcPR, &smudge->accumPR);
|
||||||
|
|
||||||
pixel_region_init_data (&smudge->accumPR, smudge->accum_data,
|
pixel_region_init_data (&smudge->accumPR, smudge->accum_data,
|
||||||
bytes, bytes * w,
|
bytes, bytes * smudge->accum_size,
|
||||||
area->x - x,
|
area->x - x,
|
||||||
area->y - y,
|
area->y - y,
|
||||||
area->width,
|
area->width,
|
||||||
@ -249,7 +258,7 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
|
|||||||
gdouble opacity;
|
gdouble opacity;
|
||||||
gdouble rate;
|
gdouble rate;
|
||||||
gdouble dynamic_rate;
|
gdouble dynamic_rate;
|
||||||
gint x, y, w, h;
|
gint x, y;
|
||||||
gdouble hardness;
|
gdouble hardness;
|
||||||
|
|
||||||
if (gimp_drawable_is_indexed (drawable))
|
if (gimp_drawable_is_indexed (drawable))
|
||||||
@ -275,8 +284,8 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
|
|||||||
if (! area)
|
if (! area)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Get the unclipped brush coordinates */
|
/* Get the unclipped acumulator coordinates */
|
||||||
gimp_smudge_brush_coords (paint_core, coords, &x, &y, &w, &h);
|
gimp_smudge_accumulator_coords (paint_core, coords, &x, &y);
|
||||||
|
|
||||||
/* srcPR will be the pixels under the current painthit from the drawable */
|
/* srcPR will be the pixels under the current painthit from the drawable */
|
||||||
pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable),
|
pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable),
|
||||||
@ -348,26 +357,22 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_smudge_brush_coords (GimpPaintCore *paint_core,
|
gimp_smudge_accumulator_coords (GimpPaintCore *paint_core,
|
||||||
const GimpCoords *coords,
|
const GimpCoords *coords,
|
||||||
gint *x,
|
gint *x,
|
||||||
gint *y,
|
gint *y)
|
||||||
gint *w,
|
|
||||||
gint *h)
|
|
||||||
{
|
{
|
||||||
GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_core);
|
GimpSmudge *smudge = GIMP_SMUDGE (paint_core);
|
||||||
gint width;
|
|
||||||
gint height;
|
|
||||||
|
|
||||||
gimp_brush_transform_size (brush_core->brush,
|
*x = (gint) coords->x - smudge->accum_size / 2;
|
||||||
brush_core->scale,
|
*y = (gint) coords->y - smudge->accum_size / 2;
|
||||||
brush_core->aspect_ratio,
|
|
||||||
brush_core->angle,
|
|
||||||
&width, &height);
|
|
||||||
|
|
||||||
/* Note: these are the brush mask size plus a border of 1 pixel */
|
|
||||||
*x = (gint) coords->x - width / 2 - 1;
|
|
||||||
*y = (gint) coords->y - height / 2 - 1;
|
|
||||||
*w = width + 2;
|
|
||||||
*h = height + 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_smudge_accumulator_size (GimpPaintOptions *paint_options,
|
||||||
|
gint *accumulator_size)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Note: the max brush mask size plus a border of 1 pixel */
|
||||||
|
*accumulator_size = ceil (sqrt (2 * SQR(paint_options->brush_size + 1)));
|
||||||
|
}
|
@ -41,6 +41,7 @@ struct _GimpSmudge
|
|||||||
gboolean initialized;
|
gboolean initialized;
|
||||||
PixelRegion accumPR;
|
PixelRegion accumPR;
|
||||||
guchar *accum_data;
|
guchar *accum_data;
|
||||||
|
gint accum_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GimpSmudgeClass
|
struct _GimpSmudgeClass
|
||||||
|
Reference in New Issue
Block a user