Commit 78262ef7 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

removed "gboolean hard" member/property...

2003-07-14  Michael Natterer  <mitch@gimp.org>

	* app/paint/gimperaseroptions.[ch]: removed "gboolean hard"
	member/property...

	* app/paint/gimppaintoptions.[ch]: ...and added it here. Added
	gimp_paint_options_get_brush_mode() utility function.

	* 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/gimppaintcore.h
	* app/paint/gimppencil.c
	* app/paint/gimpsmudge.c: use the new utility funtion where
	appropriate. Removed trailing whitespace.

	* app/tools/gimpdrawtool.[ch] (gimp_paint_tool_draw_boundary):
	changed offset parameters from gint to gdouble so we can show the
	brush preview at sub-pixel positions.

	* app/tools/gimppainttool.c: use sub-pixel coordinates for the
	brush preview if paint_options->hard is FALSE (doesn't work for
	the pencil yet).

	The new brush preview unveiled that the positioning of even-sized
	brushes if off by 0.5 for soft brush application mode and off by
	1.0 for hard application mode:

	* app/paint/gimppaintcore.[ch] (gimp_paint_core_subsample_mask):
	offset painting by 0.5 pixels on the brushes' even sized axes by
	shuffling the subsample matrices around.

	Added "subsampling" for HARD brush application mode since a pixel
	of an even sized brush can snap to up to four different image
	pixels depending on the sub-pixel coordinates of the stroke.
parent e47e8598
2003-07-14 Michael Natterer <mitch@gimp.org>
* app/paint/gimperaseroptions.[ch]: removed "gboolean hard"
member/property...
* app/paint/gimppaintoptions.[ch]: ...and added it here. Added
gimp_paint_options_get_brush_mode() utility function.
* 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/gimppaintcore.h
* app/paint/gimppencil.c
* app/paint/gimpsmudge.c: use the new utility funtion where
appropriate. Removed trailing whitespace.
* app/tools/gimpdrawtool.[ch] (gimp_paint_tool_draw_boundary):
changed offset parameters from gint to gdouble so we can show the
brush preview at sub-pixel positions.
* app/tools/gimppainttool.c: use sub-pixel coordinates for the
brush preview if paint_options->hard is FALSE (doesn't work for
the pencil yet).
The new brush preview unveiled that the positioning of even-sized
brushes if off by 0.5 for soft brush application mode and off by
1.0 for hard application mode:
* app/paint/gimppaintcore.[ch] (gimp_paint_core_subsample_mask):
offset painting by 0.5 pixels on the brushes' even sized axes by
shuffling the subsample matrices around.
Added "subsampling" for HARD brush application mode since a pixel
of an even sized brush can snap to up to four different image
pixels depending on the sub-pixel coordinates of the stroke.
2003-07-14 Michael Natterer <mitch@gimp.org>
* app/tools/gimppaintoptions-gui.c: removed double semicolons.
......@@ -110,7 +110,7 @@ gimp_airbrush_get_type (void)
return type;
}
static void
static void
gimp_airbrush_class_init (GimpAirbrushClass *klass)
{
GObjectClass *object_class;
......@@ -185,8 +185,8 @@ gimp_airbrush_paint (GimpPaintCore *paint_core,
airbrush_timeout.drawable = drawable;
airbrush_timeout.paint_options = paint_options;
timeout = (paint_options->pressure_options->rate ?
(10000 / (options->rate * 2.0 * paint_core->cur_coords.pressure)) :
timeout = (paint_options->pressure_options->rate ?
(10000 / (options->rate * 2.0 * paint_core->cur_coords.pressure)) :
(10000 / options->rate));
timeout_id = g_timeout_add (timeout,
......@@ -263,7 +263,7 @@ gimp_airbrush_motion (GimpPaintCore *paint_core,
paint_appl_mode = GIMP_PAINT_INCREMENTAL;
gimp_paint_core_color_area_with_pixmap (paint_core, gimage,
drawable, area,
drawable, area,
scale, GIMP_BRUSH_SOFT);
}
else
......@@ -310,7 +310,7 @@ gimp_airbrush_timeout (gpointer client_data)
timeout_id = g_timeout_add ((10000 /
(rate * 2.0 *
airbrush_timeout.paint_core->cur_coords.pressure)),
airbrush_timeout.paint_core->cur_coords.pressure)),
gimp_airbrush_timeout,
NULL);
return FALSE;
......
......@@ -422,7 +422,7 @@ gimp_clone_motion (GimpPaintCore *paint_core,
case GIMP_IMAGE_CLONE:
gimp_clone_line_image (gimage, src_gimage,
drawable, clone->src_drawable,
s, d, has_alpha,
s, d, has_alpha,
srcPR.bytes, destPR.bytes, destPR.w);
s += srcPR.rowstride;
break;
......@@ -430,7 +430,7 @@ gimp_clone_motion (GimpPaintCore *paint_core,
case GIMP_PATTERN_CLONE:
gimp_clone_line_pattern (gimage, drawable,
pattern, d,
area->x + offset_x,
area->x + offset_x,
area->y + y + offset_y,
destPR.bytes, destPR.w);
break;
......@@ -446,12 +446,11 @@ gimp_clone_motion (GimpPaintCore *paint_core,
opacity = opacity * 2.0 * paint_core->cur_coords.pressure;
/* paste the newly painted canvas to the gimage which is being worked on */
gimp_paint_core_paste_canvas (paint_core, drawable,
gimp_paint_core_paste_canvas (paint_core, drawable,
MIN (opacity, GIMP_OPACITY_OPAQUE),
gimp_context_get_opacity (context),
gimp_context_get_paint_mode (context),
(pressure_options->pressure ?
GIMP_BRUSH_PRESSURE : GIMP_BRUSH_SOFT),
gimp_paint_options_get_brush_mode (paint_options),
scale,
GIMP_PAINT_CONSTANT);
}
......@@ -514,7 +513,7 @@ gimp_clone_line_pattern (GimpImage *dest,
pat = temp_buf_data (pattern->mask) +
(y % pattern->mask->height) * pattern->mask->width * pattern->mask->bytes;
color_type = (pattern->mask->bytes == 3 ||
color_type = (pattern->mask->bytes == 3 ||
pattern->mask->bytes == 4) ? GIMP_RGB : GIMP_GRAY;
alpha = bytes - 1;
......@@ -553,7 +552,7 @@ gimp_clone_set_src_drawable (GimpClone *clone,
if (clone->src_drawable)
g_signal_handlers_disconnect_by_func (clone->src_drawable,
gimp_clone_src_drawable_disconnect_cb,
gimp_clone_src_drawable_disconnect_cb,
clone);
clone->src_drawable = drawable;
......
......@@ -44,7 +44,7 @@
#define MIN_SHARPEN -512
#define MAX_SHARPEN -64
/* Different clip relationships between a blur-blob and edges:
/* Different clip relationships between a blur-blob and edges:
* see convolve_motion
*/
typedef enum
......@@ -194,7 +194,7 @@ gimp_convolve_motion (GimpPaintCore *paint_core,
GimpContext *context;
TempBuf *area;
guchar *temp_data;
PixelRegion srcPR;
PixelRegion srcPR;
PixelRegion destPR;
gdouble scale;
ConvolveClipType area_hclip = CONVOLVE_NOT_CLIPPED;
......@@ -237,7 +237,7 @@ gimp_convolve_motion (GimpPaintCore *paint_core,
destPR.bytes = area->bytes;
destPR.tiles = NULL;
destPR.x = 0;
destPR.x = 0;
destPR.y = 0;
destPR.w = area->width;
destPR.h = area->height;
......@@ -247,7 +247,7 @@ gimp_convolve_motion (GimpPaintCore *paint_core,
if (pressure_options->rate)
options->rate = options->rate * 2.0 * paint_core->cur_coords.pressure;
gimp_convolve_calculate_matrix (options->type, options->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) */
......@@ -275,7 +275,7 @@ gimp_convolve_motion (GimpPaintCore *paint_core,
PixelRegion tempPR;
tempPR.x = 0;
tempPR.x = 0;
tempPR.y = 0;
tempPR.w = area->width;
tempPR.h = area->height;
......@@ -366,9 +366,9 @@ gimp_convolve_motion (GimpPaintCore *paint_core,
ovrsz1_data = g_malloc (ovrsz1PR.h * ovrsz1PR.rowstride);
ovrsz1PR.data = ovrsz1_data;
color_region (&ovrsz1PR, (const guchar *)fillcolor);
color_region (&ovrsz1PR, (const guchar *)fillcolor);
ovrsz1PR.x = (area_hclip == CONVOLVE_NCLIP)? marginx : 0;
ovrsz1PR.x = (area_hclip == CONVOLVE_NCLIP)? marginx : 0;
ovrsz1PR.y = (area_vclip == CONVOLVE_NCLIP)? marginy : 0;
ovrsz1PR.w = area->width;
ovrsz1PR.h = area->height;
......@@ -394,8 +394,8 @@ gimp_convolve_motion (GimpPaintCore *paint_core,
/* Crop and copy to destination */
ovrsz2PR.x = (area_hclip == CONVOLVE_NCLIP)? marginx : 0;
ovrsz2PR.y = (area_vclip == CONVOLVE_NCLIP)? marginy : 0;
ovrsz2PR.x = (area_hclip == CONVOLVE_NCLIP)? marginx : 0;
ovrsz2PR.y = (area_vclip == CONVOLVE_NCLIP)? marginy : 0;
ovrsz2PR.w = area->width;
ovrsz2PR.h = area->height;
ovrsz2PR.data = (ovrsz2_data +
......@@ -413,8 +413,7 @@ gimp_convolve_motion (GimpPaintCore *paint_core,
gimp_paint_core_replace_canvas (paint_core, drawable,
GIMP_OPACITY_OPAQUE,
gimp_context_get_opacity (context),
(pressure_options->pressure ?
GIMP_BRUSH_PRESSURE : GIMP_BRUSH_SOFT),
gimp_paint_options_get_brush_mode (paint_options),
scale,
GIMP_PAINT_INCREMENTAL);
}
......
......@@ -258,7 +258,7 @@ gimp_dodge_burn_motion (GimpPaintCore *paint_core,
orig = gimp_paint_core_get_orig_image (paint_core, drawable, x1, y1, x2, y2);
srcPR.bytes = orig->bytes;
srcPR.x = 0;
srcPR.x = 0;
srcPR.y = 0;
srcPR.w = x2 - x1;
srcPR.h = y2 - y1;
......@@ -268,7 +268,7 @@ gimp_dodge_burn_motion (GimpPaintCore *paint_core,
/* tempPR will hold the dodgeburned region*/
tempPR.bytes = srcPR.bytes;
tempPR.x = srcPR.x;
tempPR.x = srcPR.x;
tempPR.y = srcPR.y;
tempPR.w = srcPR.w;
tempPR.h = srcPR.h;
......@@ -280,7 +280,7 @@ gimp_dodge_burn_motion (GimpPaintCore *paint_core,
/* DodgeBurn the region */
gimp_lut_process (dodgeburn->lut, &srcPR, &tempPR);
/* The dest is the paint area we got above (= canvas_buf) */
/* The dest is the paint area we got above (= canvas_buf) */
destPR.bytes = area->bytes;
destPR.x = 0;
destPR.y = 0;
......@@ -289,8 +289,8 @@ gimp_dodge_burn_motion (GimpPaintCore *paint_core,
destPR.rowstride = area->width * destPR.bytes;
destPR.data = temp_buf_data (area);
/* Now add an alpha to the dodgeburned region
and put this in area = canvas_buf */
/* Now add an alpha to the dodgeburned region
and put this in area = canvas_buf */
if (! gimp_drawable_has_alpha (drawable))
add_alpha_region (&tempPR, &destPR);
else
......@@ -301,15 +301,14 @@ gimp_dodge_burn_motion (GimpPaintCore *paint_core,
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_core->cur_coords.pressure;
/* Replace the newly dodgedburned area (canvas_buf) to the gimage*/
gimp_paint_core_replace_canvas (paint_core, drawable,
/* Replace the newly dodgedburned area (canvas_buf) to the gimage*/
gimp_paint_core_replace_canvas (paint_core, drawable,
MIN (opacity, GIMP_OPACITY_OPAQUE),
GIMP_OPACITY_OPAQUE,
(pressure_options->pressure ?
GIMP_BRUSH_PRESSURE : GIMP_BRUSH_SOFT),
gimp_paint_options_get_brush_mode (paint_options),
scale,
GIMP_PAINT_CONSTANT);
g_free (temp_data);
}
......@@ -333,16 +332,16 @@ gimp_dodge_burn_make_luts (GimpDodgeBurn *dodgeburn,
switch (mode)
{
case GIMP_HIGHLIGHTS:
lut_func = gimp_dodge_burn_highlights_lut_func;
lut_func = gimp_dodge_burn_highlights_lut_func;
break;
case GIMP_MIDTONES:
lut_func = gimp_dodge_burn_midtones_lut_func;
lut_func = gimp_dodge_burn_midtones_lut_func;
break;
case GIMP_SHADOWS:
lut_func = gimp_dodge_burn_shadows_lut_func;
lut_func = gimp_dodge_burn_shadows_lut_func;
break;
default:
lut_func = NULL;
lut_func = NULL;
break;
}
......@@ -352,9 +351,9 @@ gimp_dodge_burn_make_luts (GimpDodgeBurn *dodgeburn,
}
static gfloat
gimp_dodge_burn_highlights_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gimp_dodge_burn_highlights_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value)
{
gfloat *exposure_ptr = (gfloat *) user_data;
......@@ -369,9 +368,9 @@ gimp_dodge_burn_highlights_lut_func (gpointer user_data,
}
static gfloat
gimp_dodge_burn_midtones_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gimp_dodge_burn_midtones_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value)
{
gfloat *exposure_ptr = (gfloat *) user_data;
......@@ -387,13 +386,13 @@ gimp_dodge_burn_midtones_lut_func (gpointer user_data,
else
factor = 1 / (1.0 + exposure);
return pow (value, factor);
return pow (value, factor);
}
static gfloat
gimp_dodge_burn_shadows_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gimp_dodge_burn_shadows_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value)
{
gfloat *exposure_ptr = (gfloat *) user_data;
......@@ -408,9 +407,9 @@ gimp_dodge_burn_shadows_lut_func (gpointer user_data,
if (exposure >= 0)
{
factor = 0.333333 * exposure;
new_value = factor + value - factor * value;
new_value = factor + value - factor * value;
}
else /* exposure < 0 */
else /* exposure < 0 */
{
factor = -0.333333 * exposure;
if (value < factor)
......@@ -419,5 +418,5 @@ gimp_dodge_burn_shadows_lut_func (gpointer user_data,
new_value = (value - factor)/(1 - factor);
}
return new_value;
return new_value;
}
......@@ -85,7 +85,7 @@ gimp_eraser_get_type (void)
};
type = g_type_register_static (GIMP_TYPE_PAINT_CORE,
"GimpEraser",
"GimpEraser",
&info, 0);
}
......@@ -136,15 +136,14 @@ gimp_eraser_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options)
{
GimpEraserOptions *options;
GimpPressureOptions *pressure_options;
GimpContext *context;
GimpImage *gimage;
gdouble opacity;
TempBuf *area;
guchar col[MAX_CHANNELS];
gdouble scale;
GimpBrushApplicationMode brush_mode;
GimpEraserOptions *options;
GimpPressureOptions *pressure_options;
GimpContext *context;
GimpImage *gimage;
gdouble opacity;
TempBuf *area;
guchar col[MAX_CHANNELS];
gdouble scale;
if (! (gimage = gimp_item_get_image (GIMP_ITEM (drawable))))
return;
......@@ -177,22 +176,12 @@ gimp_eraser_motion (GimpPaintCore *paint_core,
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
*/
if (options->hard)
brush_mode = GIMP_BRUSH_HARD;
else
brush_mode = (pressure_options->pressure ?
GIMP_BRUSH_PRESSURE : GIMP_BRUSH_SOFT);
gimp_paint_core_paste_canvas (paint_core, drawable,
gimp_paint_core_paste_canvas (paint_core, drawable,
MIN (opacity, GIMP_OPACITY_OPAQUE),
gimp_context_get_opacity (context),
(options->anti_erase ?
(options->anti_erase ?
GIMP_ANTI_ERASE_MODE : GIMP_ERASE_MODE),
brush_mode,
gimp_paint_options_get_brush_mode (paint_options),
scale,
paint_options->application_mode);
}
......@@ -27,14 +27,12 @@
#include "gimperaseroptions.h"
#define ERASER_DEFAULT_HARD FALSE
#define ERASER_DEFAULT_ANTI_ERASE FALSE
enum
{
PROP_0,
PROP_HARD,
PROP_ANTI_ERASE
};
......@@ -83,7 +81,7 @@ gimp_eraser_options_get_type (void)
return type;
}
static void
static void
gimp_eraser_options_class_init (GimpEraserOptionsClass *klass)
{
GObjectClass *object_class;
......@@ -95,10 +93,6 @@ gimp_eraser_options_class_init (GimpEraserOptionsClass *klass)
object_class->set_property = gimp_eraser_options_set_property;
object_class->get_property = gimp_eraser_options_get_property;
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_HARD,
"hard", NULL,
ERASER_DEFAULT_HARD,
0);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_ANTI_ERASE,
"anti-erase", NULL,
ERASER_DEFAULT_ANTI_ERASE,
......@@ -122,9 +116,6 @@ gimp_eraser_options_set_property (GObject *object,
switch (property_id)
{
case PROP_HARD:
options->hard = g_value_get_boolean (value);
break;
case PROP_ANTI_ERASE:
options->anti_erase = g_value_get_boolean (value);
break;
......@@ -146,9 +137,6 @@ gimp_eraser_options_get_property (GObject *object,
switch (property_id)
{
case PROP_HARD:
g_value_set_boolean (value, options->hard);
break;
case PROP_ANTI_ERASE:
g_value_set_boolean (value, options->anti_erase);
break;
......
......@@ -38,7 +38,6 @@ struct _GimpEraserOptions
{
GimpPaintOptions paint_options;
gboolean hard;
gboolean anti_erase;
};
......
......@@ -135,9 +135,9 @@ gimp_paintbrush_paint (GimpPaintCore *paint_core,
}
static void
gimp_paintbrush_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options)
gimp_paintbrush_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options)
{
GimpPressureOptions *pressure_options;
GimpGradientOptions *gradient_options;
......@@ -267,20 +267,22 @@ gimp_paintbrush_motion (GimpPaintCore *paint_core,
&col[BLUE_PIX]);
col[ALPHA_PIX] = OPAQUE_OPACITY;
/* always use incremental mode with gradients */
/* make the gui cool later */
paint_appl_mode = GIMP_PAINT_INCREMENTAL;
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
paint_appl_mode = GIMP_PAINT_INCREMENTAL;
}
/* we check to see if this is a pixmap, if so composite the
* pixmap image into the area instead of the color
*/
else if (paint_core->brush && paint_core->brush->pixmap)
{
/* if it's a pixmap, do pixmap stuff */
gimp_paint_core_color_area_with_pixmap (paint_core, gimage, drawable,
area,
scale, GIMP_BRUSH_SOFT);
scale,
gimp_paint_options_get_brush_mode (paint_options));
paint_appl_mode = GIMP_PAINT_INCREMENTAL;
}
else
......@@ -300,8 +302,7 @@ gimp_paintbrush_motion (GimpPaintCore *paint_core,
MIN (opacity, GIMP_OPACITY_OPAQUE),
gimp_context_get_opacity (context),
gimp_context_get_paint_mode (context),
(pressure_options->pressure ?
GIMP_BRUSH_PRESSURE : GIMP_BRUSH_SOFT),
gimp_paint_options_get_brush_mode (paint_options),
scale,
paint_appl_mode);
}
......
......@@ -81,7 +81,9 @@ static MaskBuf * gimp_paint_core_pressurize_mask (GimpPaintCore *core,
gdouble y,
gdouble pressure);
static MaskBuf * gimp_paint_core_solidify_mask (GimpPaintCore *core,
MaskBuf *brush_mask);
MaskBuf *brush_mask,
gdouble x,
gdouble y);
static MaskBuf * gimp_paint_core_scale_mask (GimpPaintCore *core,
MaskBuf *brush_mask,
gdouble scale);
......@@ -168,7 +170,7 @@ gimp_paint_core_get_type (void)
};
core_type = g_type_register_static (GIMP_TYPE_OBJECT,
"GimpPaintCore",
"GimpPaintCore",
&core_info, 0);
}
......@@ -216,8 +218,12 @@ gimp_paint_core_init (GimpPaintCore *core)
core->pressure_brush = NULL;
core->solid_brush = NULL;
for (i = 0; i < PAINT_CORE_SOLID_SUBSAMPLE; i++)
for (j = 0; j < PAINT_CORE_SOLID_SUBSAMPLE; j++)
core->solid_brushes[i][j] = NULL;
core->last_solid_brush = NULL;
core->solid_cache_invalid = FALSE;
core->scale_brush = NULL;
core->last_scale_brush = NULL;
......@@ -257,11 +263,13 @@ gimp_paint_core_finalize (GObject *object)
core->pressure_brush = NULL;
}
if (core->solid_brush)
{
temp_buf_free (core->solid_brush);
core->solid_brush = NULL;
}
for (i = 0; i < PAINT_CORE_SOLID_SUBSAMPLE; i++)
for (j = 0; j < PAINT_CORE_SOLID_SUBSAMPLE; j++)
if (core->solid_brushes[i][j])
{
temp_buf_free (core->solid_brushes[i][j]);
core->solid_brushes[i][j] = NULL;
}
if (core->scale_brush)
{
......@@ -1025,8 +1033,8 @@ gimp_paint_core_invalidate_cache (GimpBrush *brush,
{
/* Make sure we don't cache data for a brush that has changed */
if (core->last_brush_mask == brush->mask)
core->cache_invalid = TRUE;
core->cache_invalid = TRUE;
core->solid_cache_invalid = TRUE;
}
/************************************************************
......@@ -1074,19 +1082,45 @@ gimp_paint_core_subsample_mask (GimpPaintCore *core,
const gint *k;
gint index1;
gint index2;
gint dest_offset_x = 0;
gint dest_offset_y = 0;
const gint *kernel;
gint new_val;
gint i, j;
gint r, s;
x += (x < 0) ? mask->width : 0;
while (x < 0) x += mask->width;
left = x - floor (x);
index1 = (gint) (left * (gdouble) (KERNEL_SUBSAMPLE + 1));
y += (y < 0) ? mask->height : 0;
while (y < 0) y += mask->height;
left = y - floor (y);
index2 = (gint) (left * (gdouble) (KERNEL_SUBSAMPLE + 1));
if ((mask->width % 2) == 0)
{
index1 += KERNEL_SUBSAMPLE >> 1;
if (index1 > KERNEL_SUBSAMPLE)
{
index1 -= KERNEL_SUBSAMPLE + 1;
dest_offset_x = 1;
}
}
if ((mask->height % 2) == 0)
{
index2 += KERNEL_SUBSAMPLE >> 1;
if (index2 > KERNEL_SUBSAMPLE)
{
index2 -= KERNEL_SUBSAMPLE + 1;
dest_offset_y = 1;
}
}
kernel = subsample[index2][index1];
if (mask == core->last_brush_mask && ! core->cache_invalid)
......@@ -1096,15 +1130,13 @@ gimp_paint_core_subsample_mask (GimpPaintCore *core,
}
else
{
for (i = 0; i <= KERNEL_SUBSAMPLE; i++)
for (j = 0; j <= KERNEL_SUBSAMPLE; j++)
{
if (core->kernel_brushes[i][j])
{
mask_buf_free (core->kernel_brushes[i][j]);
core->kernel_brushes[i][j] = NULL;
}
}
for (i = 0; i < KERNEL_SUBSAMPLE + 1; i++)
for (j = 0; j < KERNEL_SUBSAMPLE + 1; j++)
if (core->kernel_brushes[i][j])
{
mask_buf_free (core->kernel_brushes[i][j]);
core->kernel_brushes[i][j] = NULL;
}
core->last_brush_mask = mask;
core->cache_invalid = FALSE;
......@@ -1123,7 +1155,10 @@ gimp_paint_core_subsample_mask (GimpPaintCore *core,
k = kernel;
for (r = 0; r < KERNEL_HEIGHT; r++)
{
d = mask_buf_data (dest) + (i+r) * dest->width + j;
d = (mask_buf_data (dest) +
(i + r + dest_offset_y) * dest->width +
j + dest_offset_x);
s = KERNEL_WIDTH;
while (s--)
{
......@@ -1246,44 +1281,73 @@ gimp_paint_core_pressurize_mask (GimpPaintCore *core,
static MaskBuf *
gimp_paint_core_solidify_mask (GimpPaintCore *core,
MaskBuf *brush_mask)
MaskBuf *brush_mask,
gdouble x,
gdouble y)
{
gint i;
gint j;
guchar *data;
guchar *src;
if (brush_mask == core->last_solid_brush &&
core->solid_brush &&
! core->cache_invalid)
MaskBuf *dest;
guchar *m;
guchar *d;
gint dest_offset_x = 0;
gint dest_offset_y = 0;
gint i, j;
if ((brush_mask->width % 2) == 0)
{
return core->solid_brush;
while (x < 0) x += brush_mask->width;
if ((x - floor (x)) >= 0.5)
dest_offset_x++;
}
core->last_solid_brush = brush_mask;
if ((brush_mask->height % 2) == 0)
{
while (y < 0) y += brush_mask->height;
if ((y - floor (y)) >= 0.5)
dest_offset_y++;
}
if (core->solid_brush)
mask_buf_free (core->solid_brush);
if (brush_mask == core->last_solid_brush && ! core->solid_cache_invalid)
{
if (core->solid_brushes[dest_offset_y][dest_offset_x])
return core->solid_brushes[dest_offset_y][dest_offset_x];
}
else
{
for (i = 0; i < PAINT_CORE_SOLID_SUBSAMPLE; i++)
for (j = 0; j < PAINT_CORE_SOLID_SUBSAMPLE; j++)
if (core->solid_brushes[i][j])
{
mask_buf_free (core->solid_brushes[i][j]);
core->solid_brushes[i][j] = NULL;
}
core->last_solid_brush = brush_mask;
core->solid_cache_invalid = FALSE;
}
core->solid_brush = mask_buf_new (brush_mask->width + 2,
brush_mask->height + 2);
dest = mask_buf_new (brush_mask->width + 2,
brush_mask->height + 2);
/* get the data and advance one line into it */
data = (mask_buf_data (core->solid_brush) +
core->solid_brush->width);
src = mask_buf_data (brush_mask);
core->solid_brushes[dest_offset_y][dest_offset_x] = dest;
m = mask_buf_data (brush_mask);
d = (mask_buf_data (dest) +
(dest_offset_y + 1) * dest->width +
(dest_offset_x + 1));
for (i = 0; i