app: add opacity and paint_mode to gimp_edit_fill[_full]()

and use it instead of bucket-fill in the non-seed-fill case.
This commit is contained in:
Michael Natterer 2012-03-18 23:05:44 +01:00
parent cdf503ab96
commit 3ec245a991
8 changed files with 232 additions and 159 deletions

View File

@ -483,7 +483,7 @@ edit_fill_cmd_callback (GtkAction *action,
fill_type = (GimpFillType) value;
gimp_edit_fill (image, drawable, action_data_get_context (data),
fill_type);
fill_type, GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
gimp_image_flush (image);
}

View File

@ -55,18 +55,11 @@
/* local function protypes */
static GimpBuffer * gimp_edit_extract (GimpImage *image,
GimpPickable *pickable,
GimpContext *context,
gboolean cut_pixels,
GError **error);
static gboolean gimp_edit_fill_internal (GimpImage *image,
GimpDrawable *drawable,
const GimpRGB *color,
GimpPattern *pattern,
gdouble opacity,
GimpLayerModeEffects paint_mode,
const gchar *undo_desc);
static GimpBuffer * gimp_edit_extract (GimpImage *image,
GimpPickable *pickable,
GimpContext *context,
gboolean cut_pixels,
GError **error);
/* public functions */
@ -391,17 +384,19 @@ gimp_edit_clear (GimpImage *image,
gimp_context_get_background (context, &background);
return gimp_edit_fill_internal (image, drawable,
&background, NULL,
GIMP_OPACITY_OPAQUE, GIMP_ERASE_MODE,
C_("undo-type", "Clear"));
return gimp_edit_fill_full (image, drawable,
&background, NULL,
GIMP_OPACITY_OPAQUE, GIMP_ERASE_MODE,
C_("undo-type", "Clear"));
}
gboolean
gimp_edit_fill (GimpImage *image,
GimpDrawable *drawable,
GimpContext *context,
GimpFillType fill_type)
gimp_edit_fill (GimpImage *image,
GimpDrawable *drawable,
GimpContext *context,
GimpFillType fill_type,
gdouble opacity,
GimpLayerModeEffects paint_mode)
{
GimpRGB color;
GimpPattern *pattern = NULL;
@ -444,31 +439,90 @@ gimp_edit_fill (GimpImage *image,
default:
g_warning ("%s: unknown fill type", G_STRFUNC);
return gimp_edit_fill (image, drawable, context, GIMP_BACKGROUND_FILL);
return gimp_edit_fill (image, drawable,
context, GIMP_BACKGROUND_FILL,
GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
}
return gimp_edit_fill_internal (image, drawable,
&color, pattern,
GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE,
undo_desc);
return gimp_edit_fill_full (image, drawable,
&color, pattern,
opacity, paint_mode,
undo_desc);
}
gboolean
gimp_edit_fill_full (GimpImage *image,
GimpDrawable *drawable,
const GimpRGB *color,
GimpPattern *pattern,
const gchar *undo_desc)
gimp_edit_fill_full (GimpImage *image,
GimpDrawable *drawable,
const GimpRGB *color,
GimpPattern *pattern,
gdouble opacity,
GimpLayerModeEffects paint_mode,
const gchar *undo_desc)
{
TileManager *buf_tiles;
GeglBuffer *dest_buffer;
PixelRegion bufPR;
gint x, y, width, height;
gint tiles_bytes;
const Babl *format;
g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), FALSE);
g_return_val_if_fail (color != NULL || pattern != NULL, FALSE);
return gimp_edit_fill_internal (image, drawable,
color, pattern,
GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE,
undo_desc);
if (! gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height))
return TRUE; /* nothing to do, but the fill succeded */
tiles_bytes = gimp_drawable_bytes (drawable);
format = gimp_drawable_get_format (drawable);
if (pattern)
{
if (! gimp_drawable_has_alpha (drawable) &&
(pattern->mask->bytes == 2 || pattern->mask->bytes == 4))
{
tiles_bytes++;
format = gimp_drawable_get_format_with_alpha (drawable);
}
}
buf_tiles = tile_manager_new (width, height, tiles_bytes);
dest_buffer = gimp_tile_manager_create_buffer (buf_tiles, format, TRUE);
if (pattern)
{
GeglBuffer *src_buffer = gimp_pattern_create_buffer (pattern);
gegl_buffer_set_pattern (dest_buffer, NULL, src_buffer, 0, 0);
g_object_unref (src_buffer);
}
else
{
GeglColor *gegl_color = gegl_color_new (NULL);
gimp_gegl_color_set_rgba (gegl_color, color);
gegl_buffer_set_color (dest_buffer, NULL, gegl_color);
g_object_unref (gegl_color);
}
g_object_unref (dest_buffer);
pixel_region_init (&bufPR, buf_tiles, 0, 0, width, height, FALSE);
gimp_drawable_apply_region (drawable, &bufPR,
TRUE, undo_desc,
opacity, paint_mode,
NULL, NULL, x, y);
tile_manager_unref (buf_tiles);
gimp_drawable_update (drawable, x, y, width, height);
return TRUE;
}
gboolean
@ -562,72 +616,3 @@ gimp_edit_extract (GimpImage *image,
return NULL;
}
static gboolean
gimp_edit_fill_internal (GimpImage *image,
GimpDrawable *drawable,
const GimpRGB *color,
GimpPattern *pattern,
gdouble opacity,
GimpLayerModeEffects paint_mode,
const gchar *undo_desc)
{
TileManager *buf_tiles;
GeglBuffer *dest_buffer;
PixelRegion bufPR;
gint x, y, width, height;
gint tiles_bytes;
const Babl *format;
if (! gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height))
return TRUE; /* nothing to do, but the fill succeded */
tiles_bytes = gimp_drawable_bytes (drawable);
format = gimp_drawable_get_format (drawable);
if (pattern)
{
if (! gimp_drawable_has_alpha (drawable) &&
(pattern->mask->bytes == 2 || pattern->mask->bytes == 4))
{
tiles_bytes++;
format = gimp_drawable_get_format_with_alpha (drawable);
}
}
buf_tiles = tile_manager_new (width, height, tiles_bytes);
dest_buffer = gimp_tile_manager_create_buffer (buf_tiles, format, TRUE);
if (pattern)
{
GeglBuffer *src_buffer = gimp_pattern_create_buffer (pattern);
gegl_buffer_set_pattern (dest_buffer, NULL, src_buffer, 0, 0);
g_object_unref (src_buffer);
}
else
{
GeglColor *gegl_color = gegl_color_new (NULL);
gimp_gegl_color_set_rgba (gegl_color, color);
gegl_buffer_set_color (dest_buffer, NULL, gegl_color);
g_object_unref (gegl_color);
}
g_object_unref (dest_buffer);
pixel_region_init (&bufPR, buf_tiles, 0, 0, width, height, FALSE);
gimp_drawable_apply_region (drawable, &bufPR,
TRUE, undo_desc,
opacity, paint_mode,
NULL, NULL, x, y);
tile_manager_unref (buf_tiles);
gimp_drawable_update (drawable, x, y, width, height);
return TRUE;
}

View File

@ -60,11 +60,16 @@ gboolean gimp_edit_clear (GimpImage *image,
gboolean gimp_edit_fill (GimpImage *image,
GimpDrawable *drawable,
GimpContext *context,
GimpFillType fill_type);
GimpFillType fill_type,
gdouble opacity,
GimpLayerModeEffects paint_mode);
gboolean gimp_edit_fill_full (GimpImage *image,
GimpDrawable *drawable,
const GimpRGB *color,
GimpPattern *pattern,
gdouble opacity,
GimpLayerModeEffects paint_mode,
const gchar *undo_desc);
gboolean gimp_edit_fade (GimpImage *image,

View File

@ -368,6 +368,7 @@ gimp_display_shell_dnd_bucket_fill (GimpDisplayShell *shell,
{
gimp_edit_fill_full (image, drawable,
color, pattern,
GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE,
pattern ?
C_("undo-type", "Drop pattern to layer") :
C_("undo-type", "Drop color to layer"));

View File

@ -542,7 +542,8 @@ edit_fill_invoker (GimpProcedure *procedure,
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
success = gimp_edit_fill (image, drawable, context,
(GimpFillType) fill_type);
(GimpFillType) fill_type,
GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
}
else
success = FALSE;
@ -585,17 +586,31 @@ edit_bucket_fill_invoker (GimpProcedure *procedure,
gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
{
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
gboolean do_seed_fill;
do_seed_fill = gimp_channel_is_empty (gimp_image_get_mask (image));
if (! gimp_channel_is_empty (gimp_image_get_mask (image)))
{
GimpFillType fill_type;
success = gimp_drawable_bucket_fill (drawable, context, fill_mode,
paint_mode, opacity / 100.0,
do_seed_fill,
FALSE /* don't fill transparent */,
GIMP_SELECT_CRITERION_COMPOSITE,
threshold, sample_merged, x, y,
error);
switch (fill_mode)
{
case GIMP_FG_BUCKET_FILL: fill_type = GIMP_FOREGROUND_FILL;
case GIMP_BG_BUCKET_FILL: fill_type = GIMP_BACKGROUND_FILL;
case GIMP_PATTERN_BUCKET_FILL: fill_type = GIMP_PATTERN_FILL;
}
success = gimp_edit_fill (image, drawable, context, fill_type,
GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
}
else
{
success = gimp_drawable_bucket_fill (drawable, context, fill_mode,
paint_mode, opacity / 100.0,
TRUE,
FALSE /* don't fill transparent */,
GIMP_SELECT_CRITERION_COMPOSITE,
threshold, sample_merged, x, y,
error);
}
}
else
success = FALSE;
@ -642,17 +657,31 @@ edit_bucket_fill_full_invoker (GimpProcedure *procedure,
gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
{
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
gboolean do_seed_fill;
do_seed_fill = gimp_channel_is_empty (gimp_image_get_mask (image));
if (! gimp_channel_is_empty (gimp_image_get_mask (image)))
{
GimpFillType fill_type;
success = gimp_drawable_bucket_fill (drawable, context, fill_mode,
paint_mode, opacity / 100.0,
do_seed_fill,
fill_transparent,
select_criterion,
threshold, sample_merged, x, y,
error);
switch (fill_mode)
{
case GIMP_FG_BUCKET_FILL: fill_type = GIMP_FOREGROUND_FILL;
case GIMP_BG_BUCKET_FILL: fill_type = GIMP_BACKGROUND_FILL;
case GIMP_PATTERN_BUCKET_FILL: fill_type = GIMP_PATTERN_FILL;
}
success = gimp_edit_fill (image, drawable, context, fill_type,
GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
}
else
{
success = gimp_drawable_bucket_fill (drawable, context, fill_mode,
paint_mode, opacity / 100.0,
TRUE,
fill_transparent,
select_criterion,
threshold, sample_merged, x, y,
error);
}
}
else
success = FALSE;

View File

@ -25,6 +25,7 @@
#include "tools-types.h"
#include "core/gimp.h"
#include "core/gimp-edit.h"
#include "core/gimpdrawable-bucket-fill.h"
#include "core/gimperror.h"
#include "core/gimpimage.h"
@ -166,7 +167,6 @@ gimp_bucket_fill_tool_button_release (GimpTool *tool,
GimpDrawable *drawable = gimp_image_get_active_drawable (image);
GimpContext *context = GIMP_CONTEXT (options);
gint x, y;
GError *error = NULL;
x = coords->x;
y = coords->y;
@ -181,25 +181,46 @@ gimp_bucket_fill_tool_button_release (GimpTool *tool,
y -= off_y;
}
if (! gimp_drawable_bucket_fill (drawable,
context,
options->fill_mode,
gimp_context_get_paint_mode (context),
gimp_context_get_opacity (context),
! options->fill_selection,
options->fill_transparent,
options->fill_criterion,
options->threshold,
options->sample_merged,
x, y, &error))
if (options->fill_selection)
{
gimp_message_literal (display->gimp, G_OBJECT (display),
GIMP_MESSAGE_WARNING, error->message);
g_clear_error (&error);
GimpFillType fill_type;
switch (options->fill_mode)
{
case GIMP_FG_BUCKET_FILL: fill_type = GIMP_FOREGROUND_FILL;
case GIMP_BG_BUCKET_FILL: fill_type = GIMP_BACKGROUND_FILL;
case GIMP_PATTERN_BUCKET_FILL: fill_type = GIMP_PATTERN_FILL;
}
gimp_edit_fill (image, drawable, context, fill_type,
gimp_context_get_opacity (context),
gimp_context_get_paint_mode (context));
gimp_image_flush (image);
}
else
{
gimp_image_flush (image);
GError *error = NULL;
if (! gimp_drawable_bucket_fill (drawable,
context,
options->fill_mode,
gimp_context_get_paint_mode (context),
gimp_context_get_opacity (context),
TRUE,
options->fill_transparent,
options->fill_criterion,
options->threshold,
options->sample_merged,
x, y, &error))
{
gimp_message_literal (display->gimp, G_OBJECT (display),
GIMP_MESSAGE_WARNING, error->message);
g_clear_error (&error);
}
else
{
gimp_image_flush (image);
}
}
}

View File

@ -237,6 +237,7 @@ gimp_drawable_tree_view_drop_viewable (GimpContainerTreeView *view,
gimp_edit_fill_full (gimp_item_get_image (GIMP_ITEM (dest_viewable)),
GIMP_DRAWABLE (dest_viewable),
NULL, GIMP_PATTERN (src_viewable),
GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE,
C_("undo-type", "Drop pattern to layer"));
gimp_image_flush (gimp_item_get_image (GIMP_ITEM (dest_viewable)));
@ -260,6 +261,7 @@ gimp_drawable_tree_view_drop_color (GimpContainerTreeView *view,
gimp_edit_fill_full (gimp_item_get_image (GIMP_ITEM (dest_viewable)),
GIMP_DRAWABLE (dest_viewable),
color, NULL,
GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE,
C_("undo-type", "Drop color to layer"));
gimp_image_flush (gimp_item_get_image (GIMP_ITEM (dest_viewable)));
@ -322,6 +324,7 @@ gimp_drawable_tree_view_new_dropped (GimpItemTreeView *view,
gimp_edit_fill_full (gimp_item_get_image (item),
GIMP_DRAWABLE (item),
color, pattern,
GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE,
pattern ?
C_("undo-type", "Drop pattern to layer") :
C_("undo-type", "Drop color to layer"));

View File

@ -562,7 +562,8 @@ HELP
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
success = gimp_edit_fill (image, drawable, context,
(GimpFillType) fill_type);
(GimpFillType) fill_type,
GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
}
else
success = FALSE;
@ -629,17 +630,31 @@ HELP
gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
{
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
gboolean do_seed_fill;
do_seed_fill = gimp_channel_is_empty (gimp_image_get_mask (image));
if (! gimp_channel_is_empty (gimp_image_get_mask (image)))
{
GimpFillType fill_type;
success = gimp_drawable_bucket_fill (drawable, context, fill_mode,
paint_mode, opacity / 100.0,
do_seed_fill,
FALSE /* don't fill transparent */,
GIMP_SELECT_CRITERION_COMPOSITE,
threshold, sample_merged, x, y,
error);
switch (fill_mode)
{
case GIMP_FG_BUCKET_FILL: fill_type = GIMP_FOREGROUND_FILL;
case GIMP_BG_BUCKET_FILL: fill_type = GIMP_BACKGROUND_FILL;
case GIMP_PATTERN_BUCKET_FILL: fill_type = GIMP_PATTERN_FILL;
}
success = gimp_edit_fill (image, drawable, context, fill_type,
GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
}
else
{
success = gimp_drawable_bucket_fill (drawable, context, fill_mode,
paint_mode, opacity / 100.0,
TRUE,
FALSE /* don't fill transparent */,
GIMP_SELECT_CRITERION_COMPOSITE,
threshold, sample_merged, x, y,
error);
}
}
else
success = FALSE;
@ -714,17 +729,31 @@ HELP
gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
{
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
gboolean do_seed_fill;
do_seed_fill = gimp_channel_is_empty (gimp_image_get_mask (image));
if (! gimp_channel_is_empty (gimp_image_get_mask (image)))
{
GimpFillType fill_type;
success = gimp_drawable_bucket_fill (drawable, context, fill_mode,
paint_mode, opacity / 100.0,
do_seed_fill,
fill_transparent,
select_criterion,
threshold, sample_merged, x, y,
error);
switch (fill_mode)
{
case GIMP_FG_BUCKET_FILL: fill_type = GIMP_FOREGROUND_FILL;
case GIMP_BG_BUCKET_FILL: fill_type = GIMP_BACKGROUND_FILL;
case GIMP_PATTERN_BUCKET_FILL: fill_type = GIMP_PATTERN_FILL;
}
success = gimp_edit_fill (image, drawable, context, fill_type,
GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
}
else
{
success = gimp_drawable_bucket_fill (drawable, context, fill_mode,
paint_mode, opacity / 100.0,
TRUE,
fill_transparent,
select_criterion,
threshold, sample_merged, x, y,
error);
}
}
else
success = FALSE;