mirror of https://github.com/GNOME/gimp.git
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:
parent
e47e8598af
commit
78262ef745
39
ChangeLog
39
ChangeLog
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
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? */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue