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.
This commit is contained in:
Michael Natterer 2003-07-14 14:50:41 +00:00 committed by Michael Natterer
parent e47e8598af
commit 78262ef745
20 changed files with 361 additions and 230 deletions

View File

@ -1,3 +1,42 @@
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.

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;

View File

@ -38,7 +38,6 @@ struct _GimpEraserOptions
{
GimpPaintOptions paint_options;
gboolean hard;
gboolean anti_erase;
};

View File

@ -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);
}

View File

@ -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;
MaskBuf *dest;
guchar *m;
guchar *d;
gint dest_offset_x = 0;
gint dest_offset_y = 0;
gint i, j;
if (brush_mask == core->last_solid_brush &&
core->solid_brush &&
! core->cache_invalid)
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 (core->solid_brush)
mask_buf_free (core->solid_brush);
if ((y - floor (y)) >= 0.5)
dest_offset_y++;
}
core->solid_brush = mask_buf_new (brush_mask->width + 2,
brush_mask->height + 2);
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;
}
/* 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->last_solid_brush = brush_mask;
core->solid_cache_invalid = FALSE;
}
dest = mask_buf_new (brush_mask->width + 2,
brush_mask->height + 2);
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 < brush_mask->height; i++)
{
data++;
for (j = 0; j < brush_mask->width; j++)
{
*data++ = (*src++) ? OPAQUE_OPACITY : TRANSPARENT_OPACITY;
*d++ = (*m++) ? OPAQUE_OPACITY : TRANSPARENT_OPACITY;
}
data++;
d += 2;
}
return core->solid_brush;
return dest;
}
static MaskBuf *
@ -1398,7 +1462,9 @@ gimp_paint_core_get_brush_mask (GimpPaintCore *core,
break;
case GIMP_BRUSH_HARD:
mask = gimp_paint_core_solidify_mask (core, mask);
mask = gimp_paint_core_solidify_mask (core, mask,
core->cur_coords.x,
core->cur_coords.y);
break;
case GIMP_BRUSH_PRESSURE:
@ -1662,6 +1728,7 @@ brush_to_canvas_tiles (GimpPaintCore *core,
x = (gint) floor (core->cur_coords.x) - (brush_mask->width >> 1);
y = (gint) floor (core->cur_coords.y) - (brush_mask->height >> 1);
xoff = (x < 0) ? -x : 0;
yoff = (y < 0) ? -y : 0;
@ -1692,6 +1759,7 @@ brush_to_canvas_buf (GimpPaintCore *core,
x = (gint) floor (core->cur_coords.x) - (brush_mask->width >> 1);
y = (gint) floor (core->cur_coords.y) - (brush_mask->height >> 1);
xoff = (x < 0) ? -x : 0;
yoff = (y < 0) ? -y : 0;
@ -1817,7 +1885,7 @@ gimp_paint_core_color_area_with_pixmap (GimpPaintCore *core,
if (!pixmap_mask)
return;
if (mode == GIMP_BRUSH_SOFT)
if (mode != GIMP_BRUSH_HARD)
brush_mask = gimp_paint_core_scale_mask (core,
core->brush->mask,
scale);
@ -1831,13 +1899,12 @@ gimp_paint_core_color_area_with_pixmap (GimpPaintCore *core,
destPR.h = area->height;
destPR.rowstride = destPR.bytes * area->width;
destPR.data = temp_buf_data (area);
pr = pixel_regions_register (1, &destPR);
/* Calculate upper left corner of brush as in
* gimp_paint_core_get_paint_area. Ugly to have to do this here, too.
*/
ulx = (gint) floor (core->cur_coords.x) - (pixmap_mask->width >> 1);
uly = (gint) floor (core->cur_coords.y) - (pixmap_mask->height >> 1);
@ -1886,10 +1953,10 @@ paint_line_pixmap_mask (GimpImage *dest,
/* Point to the approriate scanline */
b = temp_buf_data (pixmap_mask) +
(y % pixmap_mask->height) * pixmap_mask->width * pixmap_mask->bytes;
if (mode == GIMP_BRUSH_SOFT && brush_mask)
{
/* ditto, except for the brush mask,
/* ditto, except for the brush mask,
so we can pre-multiply the alpha value */
mask = temp_buf_data (brush_mask) +
(y % brush_mask->height) * brush_mask->width;
@ -1899,14 +1966,14 @@ paint_line_pixmap_mask (GimpImage *dest,
x_index = ((i + x) % pixmap_mask->width);
p = b + x_index * pixmap_mask->bytes;
d[bytes-1] = mask[x_index];
/* multiply alpha into the pixmap data
* maybe we could do this at tool creation or brush switch time?
* and compute it for the whole brush at once and cache it?
*/
alpha = d[bytes-1] * factor;
if (alpha)
for (byte_loop = 0; byte_loop < bytes - 1; byte_loop++)
for (byte_loop = 0; byte_loop < bytes - 1; byte_loop++)
d[byte_loop] *= alpha;
/* printf("i: %i d->r: %i d->g: %i d->b: %i d->a: %i\n",i,(int)d[0], (int)d[1], (int)d[2], (int)d[3]); */
@ -1922,7 +1989,7 @@ paint_line_pixmap_mask (GimpImage *dest,
x_index = ((i + x) % pixmap_mask->width);
p = b + x_index * pixmap_mask->bytes;
d[bytes-1] = 255;
/* multiply alpha into the pixmap data */
/* maybe we could do this at tool creation or brush switch time? */
/* and compute it for the whole brush at once and cache it? */

View File

@ -23,7 +23,8 @@
#include "core/gimpobject.h"
#define PAINT_CORE_SUBSAMPLE 4
#define PAINT_CORE_SUBSAMPLE 4
#define PAINT_CORE_SOLID_SUBSAMPLE 2
/* the different states that the painting function can be called with */
@ -78,7 +79,7 @@ struct _GimpPaintCore
GimpCoords last_coords; /* last coords */
GimpVector2 last_paint; /* last point that was painted */
gdouble distance; /* distance traveled by brush */
gdouble pixel_dist; /* distance in pixels */
gdouble spacing; /* spacing */
@ -102,8 +103,9 @@ struct _GimpPaintCore
/* brush buffers */
MaskBuf *pressure_brush;
MaskBuf *solid_brush;
MaskBuf *solid_brushes[PAINT_CORE_SOLID_SUBSAMPLE][PAINT_CORE_SOLID_SUBSAMPLE];;
MaskBuf *last_solid_brush;
gboolean solid_cache_invalid;
MaskBuf *scale_brush;
MaskBuf *last_scale_brush;
@ -161,7 +163,7 @@ void gimp_paint_core_interpolate (GimpPaintCore *core,
/* protected functions */
void gimp_paint_core_get_color_from_gradient
void gimp_paint_core_get_color_from_gradient
(GimpPaintCore *core,
GimpGradient *gradient,
gdouble gradient_length,
@ -192,12 +194,12 @@ void gimp_paint_core_replace_canvas (GimpPaintCore *core,
GimpBrushApplicationMode brush_hardness,
gdouble brush_scale,
GimpPaintApplicationMode mode);
void gimp_paint_core_color_area_with_pixmap
void gimp_paint_core_color_area_with_pixmap
(GimpPaintCore *core,
GimpImage *dest,
GimpImage *dest,
GimpDrawable *drawable,
TempBuf *area,
gdouble scale,
TempBuf *area,
gdouble scale,
GimpBrushApplicationMode mode);

View File

@ -32,6 +32,7 @@
#define DEFAULT_APPLICATION_MODE GIMP_PAINT_CONSTANT
#define DEFAULT_HARD FALSE
#define DEFAULT_PRESSURE_OPACITY TRUE
#define DEFAULT_PRESSURE_PRESSURE TRUE
@ -52,6 +53,7 @@ enum
{
PROP_0,
PROP_APPLICATION_MODE,
PROP_HARD,
PROP_PRESSURE_OPACITY,
PROP_PRESSURE_PRESSURE,
PROP_PRESSURE_RATE,
@ -113,7 +115,7 @@ gimp_paint_options_get_type (void)
return type;
}
static void
static void
gimp_paint_options_class_init (GimpPaintOptionsClass *klass)
{
GObjectClass *object_class;
@ -131,6 +133,10 @@ gimp_paint_options_class_init (GimpPaintOptionsClass *klass)
GIMP_TYPE_PAINT_APPLICATION_MODE,
DEFAULT_APPLICATION_MODE,
0);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_HARD,
"hard", NULL,
DEFAULT_HARD,
0);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_PRESSURE_OPACITY,
"pressure-opacity", NULL,
@ -213,6 +219,9 @@ gimp_paint_options_set_property (GObject *object,
case PROP_APPLICATION_MODE:
options->application_mode = g_value_get_enum (value);
break;
case PROP_HARD:
options->hard = g_value_get_boolean (value);
break;
case PROP_PRESSURE_OPACITY:
pressure_options->opacity = g_value_get_boolean (value);
@ -279,6 +288,9 @@ gimp_paint_options_get_property (GObject *object,
case PROP_APPLICATION_MODE:
g_value_set_enum (value, options->application_mode);
break;
case PROP_HARD:
g_value_set_boolean (value, options->hard);
break;
case PROP_PRESSURE_OPACITY:
g_value_set_boolean (value, pressure_options->opacity);
@ -368,3 +380,17 @@ gimp_paint_options_new (Gimp *gimp,
return options;
}
GimpBrushApplicationMode
gimp_paint_options_get_brush_mode (GimpPaintOptions *paint_options)
{
g_return_val_if_fail (GIMP_IS_PAINT_OPTIONS (paint_options), GIMP_BRUSH_SOFT);
if (paint_options->hard)
return GIMP_BRUSH_HARD;
if (paint_options->pressure_options->pressure)
return GIMP_BRUSH_PRESSURE;
return GIMP_BRUSH_SOFT;
}

View File

@ -70,6 +70,8 @@ struct _GimpPaintOptions
GimpPaintApplicationMode application_mode;
GimpPaintApplicationMode application_mode_save;
gboolean hard;
GimpPressureOptions *pressure_options;
GimpGradientOptions *gradient_options;
};
@ -85,5 +87,8 @@ GType gimp_paint_options_get_type (void) G_GNUC_CONST;
GimpPaintOptions * gimp_paint_options_new (Gimp *gimp,
GType options_type);
GimpBrushApplicationMode
gimp_paint_options_get_brush_mode (GimpPaintOptions *paint_options);
#endif /* __GIMP_PAINT_OPTIONS_H__ */

View File

@ -87,16 +87,16 @@ gimp_pencil_get_type (void)
};
type = g_type_register_static (GIMP_TYPE_PAINT_CORE,
"GimpPencil",
"GimpPencil",
&info, 0);
}
return type;
}
static void
static void
gimp_pencil_class_init (GimpPencilClass *klass)
{
{
GimpPaintCoreClass *paint_core_class;
paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
@ -115,7 +115,7 @@ gimp_pencil_init (GimpPencil *pencil)
paint_core->flags |= CORE_HANDLES_CHANGING_BRUSH;
}
static void
gimp_pencil_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
@ -179,17 +179,19 @@ gimp_pencil_motion (GimpPaintCore *paint_core,
&col[BLUE_PIX],
&col[ALPHA_PIX]);
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;
}
else if (paint_core->brush && paint_core->brush->pixmap)
{
/* if its a pixmap, do pixmap stuff */
/* if it's a pixmap, do pixmap stuff */
gimp_paint_core_color_area_with_pixmap (paint_core,
gimage, drawable,
gimage, drawable,
area, scale, GIMP_BRUSH_HARD);
paint_appl_mode = GIMP_PAINT_INCREMENTAL;
}
else
@ -207,7 +209,7 @@ gimp_pencil_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),

View File

@ -57,7 +57,7 @@ static void gimp_smudge_motion (GimpPaintCore *paint_core,
static void gimp_smudge_nonclipped_painthit_coords (GimpPaintCore *paint_core,
gint *x,
gint *y,
gint *y,
gint *w,
gint *h);
@ -205,7 +205,7 @@ gimp_smudge_start (GimpPaintCore *paint_core,
area = gimp_paint_core_get_paint_area (paint_core, drawable, 1.0);
if (!area)
if (!area)
return FALSE;
/* adjust the x and y coordinates to the upper left corner of the brush */
@ -233,27 +233,27 @@ gimp_smudge_start (GimpPaintCore *paint_core,
srcPR.bytes = smudge->accumPR.bytes;
srcPR.rowstride = srcPR.bytes * w;
srcPR.data = smudge->accum_data;
color_region (&srcPR, fill);
g_free (fill);
}
smudge->accumPR.x = area->x - x;
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.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),
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, &smudge->accumPR);
smudge->accumPR.x = area->x - x;
smudge->accumPR.x = area->x - x;
smudge->accumPR.y = area->y - y;
smudge->accumPR.w = area->width;
smudge->accumPR.h = area->height;
@ -301,7 +301,7 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
return;
/* srcPR will be the pixels under the current painthit from the drawable */
pixel_region_init (&srcPR, gimp_drawable_data (drawable),
pixel_region_init (&srcPR, gimp_drawable_data (drawable),
area->x, area->y, area->width, area->height, FALSE);
/* Enable pressure sensitive rate */
@ -311,8 +311,8 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
else
rate = options->rate / 100.0;
/* The tempPR will be the built up buffer (for smudge) */
tempPR.x = area->x - x;
/* The tempPR will be the built up buffer (for smudge) */
tempPR.x = area->x - x;
tempPR.y = area->y - y;
tempPR.w = area->width;
tempPR.h = area->height;
@ -322,21 +322,21 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
tempPR.y * tempPR.rowstride +
tempPR.x * tempPR.bytes);
/* The dest will be the paint area we got above (= canvas_buf) */
/* The dest will be the paint area we got above (= canvas_buf) */
destPR.x = 0;
destPR.y = 0;
destPR.w = area->width;
destPR.h = area->height;
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.rowstride = area->width * area->bytes;
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
* where I is the pixels under the current painthit.
* Then the paint area (canvas_buf) is built as
* (Accum,1) (if no alpha),
*/
@ -364,21 +364,20 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_core->cur_coords.pressure;
/*Replace the newly made paint area to the gimage*/
gimp_paint_core_replace_canvas (paint_core, drawable,
/*Replace the newly made paint area 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),
1.0,
GIMP_PAINT_INCREMENTAL);
}
static void
static void
gimp_smudge_nonclipped_painthit_coords (GimpPaintCore *paint_core,
gint *x,
gint *y,
gint *w,
gint *x,
gint *y,
gint *w,
gint *h)
{
/* Note: these are the brush mask size plus a border of 1 pixel */

View File

@ -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;

View File

@ -719,15 +719,24 @@ gimp_paint_tool_draw (GimpDrawTool *draw_tool)
WithinBounds,
0, 0,
PR.w, PR.h,
1);
0);
}
if (paint_tool->brush_bound_segs)
{
gint brush_x, brush_y;
GimpPaintOptions *paint_options;
gdouble brush_x, brush_y;
brush_x = floor (paint_tool->brush_x) - (mask->width >> 1);
brush_y = floor (paint_tool->brush_y) - (mask->height >> 1);
paint_options = GIMP_PAINT_OPTIONS (context);
brush_x = paint_tool->brush_x - ((gdouble) mask->width / 2.0);
brush_y = paint_tool->brush_y - ((gdouble) mask->height / 2.0);
if (paint_options->hard)
{
brush_x = RINT (brush_x);
brush_y = RINT (brush_y);
}
gimp_draw_tool_draw_boundary (draw_tool,
paint_tool->brush_bound_segs,

View File

@ -86,7 +86,7 @@ gimp_draw_tool_get_type (void)
};
tool_type = g_type_register_static (GIMP_TYPE_TOOL,
"GimpDrawTool",
"GimpDrawTool",
&tool_info, 0);
}
@ -806,14 +806,14 @@ void
gimp_draw_tool_draw_boundary (GimpDrawTool *draw_tool,
BoundSeg *bound_segs,
gint n_bound_segs,
gint offset_x,
gint offset_y)
gdouble offset_x,
gdouble offset_y)
{
GimpDisplayShell *shell;
GdkSegment *gdk_segs;
gint n_gdk_segs;
gint xclamp, yclamp;
gint x, y;
gint xmax, ymax;
gdouble x, y;
gint i;
g_return_if_fail (GIMP_IS_DRAW_TOOL (draw_tool));
@ -824,28 +824,28 @@ gimp_draw_tool_draw_boundary (GimpDrawTool *draw_tool,
gdk_segs = g_new0 (GdkSegment, n_bound_segs);
n_gdk_segs = 0;
xclamp = shell->disp_width + 1;
yclamp = shell->disp_height + 1;
xmax = shell->disp_width + 1;
ymax = shell->disp_height + 1;
for (i = 0; i < n_bound_segs; i++)
{
gimp_display_shell_transform_xy (shell,
bound_segs[i].x1 + offset_x,
bound_segs[i].y1 + offset_y,
&x, &y,
FALSE);
gimp_display_shell_transform_xy_f (shell,
bound_segs[i].x1 + offset_x,
bound_segs[i].y1 + offset_y,
&x, &y,
FALSE);
gdk_segs[n_gdk_segs].x1 = CLAMP (x, -1, xclamp);
gdk_segs[n_gdk_segs].y1 = CLAMP (y, -1, yclamp);
gdk_segs[n_gdk_segs].x1 = floor (CLAMP (x, -1, xmax));
gdk_segs[n_gdk_segs].y1 = floor (CLAMP (y, -1, ymax));
gimp_display_shell_transform_xy (shell,
bound_segs[i].x2 + offset_x,
bound_segs[i].y2 + offset_y,
&x, &y,
FALSE);
gimp_display_shell_transform_xy_f (shell,
bound_segs[i].x2 + offset_x,
bound_segs[i].y2 + offset_y,
&x, &y,
FALSE);
gdk_segs[n_gdk_segs].x2 = CLAMP (x, -1, xclamp);
gdk_segs[n_gdk_segs].y2 = CLAMP (y, -1, yclamp);
gdk_segs[n_gdk_segs].x2 = floor (CLAMP (x, -1, xmax));
gdk_segs[n_gdk_segs].y2 = floor (CLAMP (y, -1, ymax));
if (gdk_segs[n_gdk_segs].x1 == gdk_segs[n_gdk_segs].x2 &&
gdk_segs[n_gdk_segs].y1 == gdk_segs[n_gdk_segs].y2)

View File

@ -180,8 +180,8 @@ void gimp_draw_tool_draw_strokes (GimpDrawTool *draw_tool,
void gimp_draw_tool_draw_boundary (GimpDrawTool *draw_tool,
BoundSeg *bound_segs,
gint n_bound_segs,
gint offset_x,
gint offset_y);
gdouble offset_x,
gdouble offset_y);
#endif /* __GIMP_DRAW_TOOL_H__ */

View File

@ -719,15 +719,24 @@ gimp_paint_tool_draw (GimpDrawTool *draw_tool)
WithinBounds,
0, 0,
PR.w, PR.h,
1);
0);
}
if (paint_tool->brush_bound_segs)
{
gint brush_x, brush_y;
GimpPaintOptions *paint_options;
gdouble brush_x, brush_y;
brush_x = floor (paint_tool->brush_x) - (mask->width >> 1);
brush_y = floor (paint_tool->brush_y) - (mask->height >> 1);
paint_options = GIMP_PAINT_OPTIONS (context);
brush_x = paint_tool->brush_x - ((gdouble) mask->width / 2.0);
brush_y = paint_tool->brush_y - ((gdouble) mask->height / 2.0);
if (paint_options->hard)
{
brush_x = RINT (brush_x);
brush_y = RINT (brush_y);
}
gimp_draw_tool_draw_boundary (draw_tool,
paint_tool->brush_bound_segs,