added new pure virtual function GimpDrawable::invalidate_boundary().

2003-09-04  Michael Natterer  <mitch@gimp.org>

	* app/core/gimpdrawable.[ch]: added new pure virtual function
	GimpDrawable::invalidate_boundary().

	* app/core/gimplayer.[ch]: implement it and removed public
	function gimp_layer_invalidate_boundary().

	* app/core/gimpchannel.[ch]: implement it.

	* app/core/gimpselection.[ch]: implement it and removed public
	function gimp_selection_invalidate().

	* app/core/gimpimage-mask.c (gimp_image_mask_invalidate)
	* app/core/gimpimage-undo-push.c
	* app/core/gimpimage.c
	* app/core/gimplayer-floating-sel.c
	* app/text/gimptextlayer.c: changed accordingly.

	* app/core/gimpchannel.[ch]: made gimp_channel_push_undo() a
	public function and made it call
	gimp_drawable_invalidate_boundary(). Added undo_desc strings for
	all undo pushing functions to GimpChannelClass.

	* app/core/gimpselection.[ch]: removed gimp_selection_push_undo()
	since after the change above it was identical to
	gimp_channel_push_undo().  Don't push any undo here since
	upchaining does the right thing now.  Override GimpChannelClass'
	undo_desc strings to say "Selection".

	* app/core/gimpimage-mask.c (gimp_image_mask_push_undo): changed
	accordingly.
This commit is contained in:
Michael Natterer 2003-09-04 11:33:06 +00:00 committed by Michael Natterer
parent 2f6b6b5886
commit f9f5089f91
16 changed files with 507 additions and 385 deletions

View File

@ -1,3 +1,36 @@
2003-09-04 Michael Natterer <mitch@gimp.org>
* app/core/gimpdrawable.[ch]: added new pure virtual function
GimpDrawable::invalidate_boundary().
* app/core/gimplayer.[ch]: implement it and removed public
function gimp_layer_invalidate_boundary().
* app/core/gimpchannel.[ch]: implement it.
* app/core/gimpselection.[ch]: implement it and removed public
function gimp_selection_invalidate().
* app/core/gimpimage-mask.c (gimp_image_mask_invalidate)
* app/core/gimpimage-undo-push.c
* app/core/gimpimage.c
* app/core/gimplayer-floating-sel.c
* app/text/gimptextlayer.c: changed accordingly.
* app/core/gimpchannel.[ch]: made gimp_channel_push_undo() a
public function and made it call
gimp_drawable_invalidate_boundary(). Added undo_desc strings for
all undo pushing functions to GimpChannelClass.
* app/core/gimpselection.[ch]: removed gimp_selection_push_undo()
since after the change above it was identical to
gimp_channel_push_undo(). Don't push any undo here since
upchaining does the right thing now. Override GimpChannelClass'
undo_desc strings to say "Selection".
* app/core/gimpimage-mask.c (gimp_image_mask_push_undo): changed
accordingly.
2003-09-04 Sven Neumann <sven@gimp.org>
* tools/pdbgen/pdb/paths.pdb (path_get_points): lookup the vectors

View File

@ -99,6 +99,8 @@ static gboolean gimp_channel_stroke (GimpItem *item,
GimpDrawable *drawable,
GimpPaintInfo *paint_info);
static void gimp_channel_invalidate_boundary (GimpDrawable *drawable);
static gboolean gimp_channel_real_boundary (GimpChannel *channel,
const BoundSeg **segs_in,
const BoundSeg **segs_out,
@ -144,8 +146,6 @@ static void gimp_channel_real_shrink (GimpChannel *channel,
gboolean edge_lock,
gboolean push_undo);
static void gimp_channel_push_undo (GimpChannel *mask,
const gchar *undo_desc);
static void gimp_channel_validate (TileManager *tm,
Tile *tile);
@ -188,43 +188,57 @@ gimp_channel_class_init (GimpChannelClass *klass)
GimpObjectClass *gimp_object_class;
GimpViewableClass *viewable_class;
GimpItemClass *item_class;
GimpDrawableClass *drawable_class;
object_class = G_OBJECT_CLASS (klass);
gimp_object_class = GIMP_OBJECT_CLASS (klass);
viewable_class = GIMP_VIEWABLE_CLASS (klass);
item_class = GIMP_ITEM_CLASS (klass);
drawable_class = GIMP_DRAWABLE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gimp_channel_finalize;
object_class->finalize = gimp_channel_finalize;
gimp_object_class->get_memsize = gimp_channel_get_memsize;
gimp_object_class->get_memsize = gimp_channel_get_memsize;
viewable_class->default_stock_id = "gimp-channel";
viewable_class->default_stock_id = "gimp-channel";
item_class->duplicate = gimp_channel_duplicate;
item_class->translate = gimp_channel_translate;
item_class->scale = gimp_channel_scale;
item_class->resize = gimp_channel_resize;
item_class->flip = gimp_channel_flip;
item_class->rotate = gimp_channel_rotate;
item_class->transform = gimp_channel_transform;
item_class->stroke = gimp_channel_stroke;
item_class->default_name = _("Channel");
item_class->rename_desc = _("Rename Channel");
item_class->duplicate = gimp_channel_duplicate;
item_class->translate = gimp_channel_translate;
item_class->scale = gimp_channel_scale;
item_class->resize = gimp_channel_resize;
item_class->flip = gimp_channel_flip;
item_class->rotate = gimp_channel_rotate;
item_class->transform = gimp_channel_transform;
item_class->stroke = gimp_channel_stroke;
item_class->default_name = _("Channel");
item_class->rename_desc = _("Rename Channel");
klass->boundary = gimp_channel_real_boundary;
klass->bounds = gimp_channel_real_bounds;
klass->value = gimp_channel_real_value;
klass->is_empty = gimp_channel_real_is_empty;
klass->feather = gimp_channel_real_feather;
klass->sharpen = gimp_channel_real_sharpen;
klass->clear = gimp_channel_real_clear;
klass->all = gimp_channel_real_all;
klass->invert = gimp_channel_real_invert;
klass->border = gimp_channel_real_border;
klass->grow = gimp_channel_real_grow;
klass->shrink = gimp_channel_real_shrink;
drawable_class->invalidate_boundary = gimp_channel_invalidate_boundary;
klass->boundary = gimp_channel_real_boundary;
klass->bounds = gimp_channel_real_bounds;
klass->value = gimp_channel_real_value;
klass->is_empty = gimp_channel_real_is_empty;
klass->feather = gimp_channel_real_feather;
klass->sharpen = gimp_channel_real_sharpen;
klass->clear = gimp_channel_real_clear;
klass->all = gimp_channel_real_all;
klass->invert = gimp_channel_real_invert;
klass->border = gimp_channel_real_border;
klass->grow = gimp_channel_real_grow;
klass->shrink = gimp_channel_real_shrink;
klass->translate_desc = _("Move Channel");
klass->feather_desc = _("Feather Channel");
klass->sharpen_desc = _("Sharpen Channel");
klass->clear_desc = _("Clear Channel");
klass->all_desc = _("Fill Channel");
klass->invert_desc = _("Invert Channel");
klass->border_desc = _("Border Channel");
klass->grow_desc = _("Grow Channel");
klass->shrink_desc = _("Shrink Channel");
}
static void
@ -329,33 +343,38 @@ gimp_channel_translate (GimpItem *item,
gint off_y,
gboolean push_undo)
{
GimpChannel *mask;
GimpChannel *channel;
GimpChannel *tmp_mask = NULL;
gint width, height;
PixelRegion srcPR, destPR;
guchar empty = TRANSPARENT_OPACITY;
gint x1, y1, x2, y2;
mask = GIMP_CHANNEL (item);
channel = GIMP_CHANNEL (item);
gimp_channel_bounds (mask, &x1, &y1, &x2, &y2);
x1 = CLAMP ((x1 + off_x), 0, GIMP_ITEM (mask)->width);
y1 = CLAMP ((y1 + off_y), 0, GIMP_ITEM (mask)->height);
x2 = CLAMP ((x2 + off_x), 0, GIMP_ITEM (mask)->width);
y2 = CLAMP ((y2 + off_y), 0, GIMP_ITEM (mask)->height);
gimp_channel_bounds (channel, &x1, &y1, &x2, &y2);
x1 = CLAMP ((x1 + off_x), 0, GIMP_ITEM (channel)->width);
y1 = CLAMP ((y1 + off_y), 0, GIMP_ITEM (channel)->height);
x2 = CLAMP ((x2 + off_x), 0, GIMP_ITEM (channel)->width);
y2 = CLAMP ((y2 + off_y), 0, GIMP_ITEM (channel)->height);
width = x2 - x1;
height = y2 - y1;
if (push_undo)
{
gimp_channel_push_undo (mask, _("Move Channel"));
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->translate_desc);
/* update the old area */
gimp_drawable_update (GIMP_DRAWABLE (item),
x1, y1,
x2 - x1, y2 - y1);
}
else
{
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
}
/* make sure width and height are non-zero */
if (width != 0 && height != 0)
@ -363,10 +382,10 @@ gimp_channel_translate (GimpItem *item,
/* copy the portion of the mask we will keep to a
* temporary buffer
*/
tmp_mask = gimp_channel_new_mask (gimp_item_get_image (GIMP_ITEM (mask)),
tmp_mask = gimp_channel_new_mask (gimp_item_get_image (item),
width, height);
pixel_region_init (&srcPR, GIMP_DRAWABLE (mask)->tiles,
pixel_region_init (&srcPR, GIMP_DRAWABLE (channel)->tiles,
x1 - off_x, y1 - off_y, width, height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE (tmp_mask)->tiles,
0, 0, width, height, TRUE);
@ -374,10 +393,10 @@ gimp_channel_translate (GimpItem *item,
}
/* clear the mask */
pixel_region_init (&srcPR, GIMP_DRAWABLE (mask)->tiles,
pixel_region_init (&srcPR, GIMP_DRAWABLE (channel)->tiles,
0, 0,
GIMP_ITEM (mask)->width,
GIMP_ITEM (mask)->height, TRUE);
GIMP_ITEM (channel)->width,
GIMP_ITEM (channel)->height, TRUE);
color_region (&srcPR, &empty);
if (width != 0 && height != 0)
@ -385,7 +404,7 @@ gimp_channel_translate (GimpItem *item,
/* copy the temp mask back to the mask */
pixel_region_init (&srcPR, GIMP_DRAWABLE (tmp_mask)->tiles,
0, 0, width, height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE (mask)->tiles,
pixel_region_init (&destPR, GIMP_DRAWABLE (channel)->tiles,
x1, y1, width, height, TRUE);
copy_region (&srcPR, &destPR);
@ -396,26 +415,27 @@ gimp_channel_translate (GimpItem *item,
/* calculate new bounds */
if (width == 0 || height == 0)
{
mask->empty = TRUE;
mask->x1 = 0;
mask->y1 = 0;
mask->x2 = GIMP_ITEM (mask)->width;
mask->y2 = GIMP_ITEM (mask)->height;
channel->empty = TRUE;
channel->x1 = 0;
channel->y1 = 0;
channel->x2 = GIMP_ITEM (channel)->width;
channel->y2 = GIMP_ITEM (channel)->height;
}
else
{
mask->x1 = x1;
mask->y1 = y1;
mask->x2 = x2;
mask->y2 = y2;
channel->x1 = x1;
channel->y1 = y1;
channel->x2 = x2;
channel->y2 = y2;
}
if (push_undo)
{
/* update the new area */
gimp_drawable_update (GIMP_DRAWABLE (item),
mask->x1, mask->y1,
mask->x2 - mask->x1, mask->y2 - mask->y1);
channel->x1, channel->y1,
channel->x2 - channel->x1,
channel->y2 - channel->y1);
gimp_viewable_size_changed (GIMP_VIEWABLE (item));
}
@ -609,6 +629,14 @@ gimp_channel_stroke (GimpItem *item,
return retval;
}
static void
gimp_channel_invalidate_boundary (GimpDrawable *drawable)
{
GimpChannel *channel = GIMP_CHANNEL (drawable);
channel->boundary_known = FALSE;
}
static gboolean
gimp_channel_real_boundary (GimpChannel *channel,
const BoundSeg **segs_in,
@ -898,7 +926,10 @@ gimp_channel_real_feather (GimpChannel *channel,
PixelRegion srcPR;
if (push_undo)
gimp_channel_push_undo (channel, _("Feather Channel"));
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->feather_desc);
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
pixel_region_init (&srcPR, GIMP_DRAWABLE (channel)->tiles,
0, 0,
@ -918,7 +949,10 @@ gimp_channel_real_sharpen (GimpChannel *channel,
GimpLut *lut;
if (push_undo)
gimp_channel_push_undo (channel, _("Sharpen Channel"));
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->sharpen_desc);
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
pixel_region_init (&maskPR, GIMP_DRAWABLE (channel)->tiles,
0, 0,
@ -945,10 +979,14 @@ gimp_channel_real_clear (GimpChannel *channel,
if (push_undo)
{
if (! undo_desc)
undo_desc = _("Clear Channel");
undo_desc = GIMP_CHANNEL_GET_CLASS (channel)->clear_desc;
gimp_channel_push_undo (channel, undo_desc);
}
else
{
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
}
if (channel->bounds_known && !channel->empty)
{
@ -984,7 +1022,10 @@ gimp_channel_real_all (GimpChannel *channel,
guchar bg = OPAQUE_OPACITY;
if (push_undo)
gimp_channel_push_undo (channel, _("Fill Channel"));
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->all_desc);
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
/* clear the channel */
pixel_region_init (&maskPR, GIMP_DRAWABLE (channel)->tiles,
@ -1007,7 +1048,10 @@ gimp_channel_real_invert (GimpChannel *channel,
gboolean push_undo)
{
if (push_undo)
gimp_channel_push_undo (channel, _("Invert Channel"));
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->invert_desc);
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
if (channel->bounds_known && channel->empty)
{
@ -1071,7 +1115,10 @@ gimp_channel_real_border (GimpChannel *channel,
y2 += radius_y;
if (push_undo)
gimp_channel_push_undo (channel, _("Border Channel"));
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->border_desc);
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
pixel_region_init (&bPR, GIMP_DRAWABLE (channel)->tiles, x1, y1,
(x2-x1), (y2-y1), TRUE);
@ -1126,7 +1173,10 @@ gimp_channel_real_grow (GimpChannel *channel,
y2 = GIMP_ITEM (channel)->height;
if (push_undo)
gimp_channel_push_undo (channel, _("Grow Channel"));
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->grow_desc);
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
/* need full extents for grow, not! */
pixel_region_init (&bPR, GIMP_DRAWABLE (channel)->tiles, x1, y1, (x2 - x1),
@ -1175,7 +1225,10 @@ gimp_channel_real_shrink (GimpChannel *channel,
y2++;
if (push_undo)
gimp_channel_push_undo (channel, _("Shrink Channel"));
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->shrink_desc);
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
pixel_region_init (&bPR, GIMP_DRAWABLE (channel)->tiles, x1, y1, (x2 - x1),
(y2 - y1), TRUE);
@ -1185,24 +1238,6 @@ gimp_channel_real_shrink (GimpChannel *channel,
channel->bounds_known = FALSE;
}
static void
gimp_channel_push_undo (GimpChannel *mask,
const gchar *undo_desc)
{
GimpImage *gimage;
gimage = gimp_item_get_image (GIMP_ITEM (mask));
g_return_if_fail (gimage != NULL);
gimp_image_undo_push_mask (gimage, undo_desc, mask);
mask->boundary_known = FALSE;
/* invalidate the preview */
GIMP_DRAWABLE (mask)->preview_valid = FALSE;
}
static void
gimp_channel_validate (TileManager *tm,
Tile *tile)
@ -1434,6 +1469,23 @@ gimp_channel_set_show_masked (GimpChannel *channel,
}
}
void
gimp_channel_push_undo (GimpChannel *channel,
const gchar *undo_desc)
{
GimpImage *gimage;
g_return_if_fail (GIMP_IS_CHANNEL (channel));
gimage = gimp_item_get_image (GIMP_ITEM (channel));
g_return_if_fail (GIMP_IS_IMAGE (gimage));
gimp_image_undo_push_mask (gimage, undo_desc, channel);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
}
/******************************/
/* selection mask functions */
@ -2073,6 +2125,8 @@ gimp_channel_load (GimpChannel *mask,
if (push_undo)
gimp_channel_push_undo (mask, _("Channel Load"));
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (mask));
/* copy the channel to the mask */
pixel_region_init (&srcPR, GIMP_DRAWABLE (channel)->tiles,

View File

@ -104,6 +104,16 @@ struct _GimpChannelClass
gint radius_y,
gboolean edge_lock,
gboolean push_undo);
const gchar *translate_desc;
const gchar *feather_desc;
const gchar *sharpen_desc;
const gchar *clear_desc;
const gchar *all_desc;
const gchar *invert_desc;
const gchar *border_desc;
const gchar *grow_desc;
const gchar *shrink_desc;
};
@ -141,6 +151,9 @@ gboolean gimp_channel_get_show_masked (GimpChannel *channel);
void gimp_channel_set_show_masked (GimpChannel *channel,
gboolean show_masked);
void gimp_channel_push_undo (GimpChannel *mask,
const gchar *undo_desc);
/* selection mask functions */

View File

@ -99,6 +99,8 @@ static gboolean gimp_channel_stroke (GimpItem *item,
GimpDrawable *drawable,
GimpPaintInfo *paint_info);
static void gimp_channel_invalidate_boundary (GimpDrawable *drawable);
static gboolean gimp_channel_real_boundary (GimpChannel *channel,
const BoundSeg **segs_in,
const BoundSeg **segs_out,
@ -144,8 +146,6 @@ static void gimp_channel_real_shrink (GimpChannel *channel,
gboolean edge_lock,
gboolean push_undo);
static void gimp_channel_push_undo (GimpChannel *mask,
const gchar *undo_desc);
static void gimp_channel_validate (TileManager *tm,
Tile *tile);
@ -188,43 +188,57 @@ gimp_channel_class_init (GimpChannelClass *klass)
GimpObjectClass *gimp_object_class;
GimpViewableClass *viewable_class;
GimpItemClass *item_class;
GimpDrawableClass *drawable_class;
object_class = G_OBJECT_CLASS (klass);
gimp_object_class = GIMP_OBJECT_CLASS (klass);
viewable_class = GIMP_VIEWABLE_CLASS (klass);
item_class = GIMP_ITEM_CLASS (klass);
drawable_class = GIMP_DRAWABLE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gimp_channel_finalize;
object_class->finalize = gimp_channel_finalize;
gimp_object_class->get_memsize = gimp_channel_get_memsize;
gimp_object_class->get_memsize = gimp_channel_get_memsize;
viewable_class->default_stock_id = "gimp-channel";
viewable_class->default_stock_id = "gimp-channel";
item_class->duplicate = gimp_channel_duplicate;
item_class->translate = gimp_channel_translate;
item_class->scale = gimp_channel_scale;
item_class->resize = gimp_channel_resize;
item_class->flip = gimp_channel_flip;
item_class->rotate = gimp_channel_rotate;
item_class->transform = gimp_channel_transform;
item_class->stroke = gimp_channel_stroke;
item_class->default_name = _("Channel");
item_class->rename_desc = _("Rename Channel");
item_class->duplicate = gimp_channel_duplicate;
item_class->translate = gimp_channel_translate;
item_class->scale = gimp_channel_scale;
item_class->resize = gimp_channel_resize;
item_class->flip = gimp_channel_flip;
item_class->rotate = gimp_channel_rotate;
item_class->transform = gimp_channel_transform;
item_class->stroke = gimp_channel_stroke;
item_class->default_name = _("Channel");
item_class->rename_desc = _("Rename Channel");
klass->boundary = gimp_channel_real_boundary;
klass->bounds = gimp_channel_real_bounds;
klass->value = gimp_channel_real_value;
klass->is_empty = gimp_channel_real_is_empty;
klass->feather = gimp_channel_real_feather;
klass->sharpen = gimp_channel_real_sharpen;
klass->clear = gimp_channel_real_clear;
klass->all = gimp_channel_real_all;
klass->invert = gimp_channel_real_invert;
klass->border = gimp_channel_real_border;
klass->grow = gimp_channel_real_grow;
klass->shrink = gimp_channel_real_shrink;
drawable_class->invalidate_boundary = gimp_channel_invalidate_boundary;
klass->boundary = gimp_channel_real_boundary;
klass->bounds = gimp_channel_real_bounds;
klass->value = gimp_channel_real_value;
klass->is_empty = gimp_channel_real_is_empty;
klass->feather = gimp_channel_real_feather;
klass->sharpen = gimp_channel_real_sharpen;
klass->clear = gimp_channel_real_clear;
klass->all = gimp_channel_real_all;
klass->invert = gimp_channel_real_invert;
klass->border = gimp_channel_real_border;
klass->grow = gimp_channel_real_grow;
klass->shrink = gimp_channel_real_shrink;
klass->translate_desc = _("Move Channel");
klass->feather_desc = _("Feather Channel");
klass->sharpen_desc = _("Sharpen Channel");
klass->clear_desc = _("Clear Channel");
klass->all_desc = _("Fill Channel");
klass->invert_desc = _("Invert Channel");
klass->border_desc = _("Border Channel");
klass->grow_desc = _("Grow Channel");
klass->shrink_desc = _("Shrink Channel");
}
static void
@ -329,33 +343,38 @@ gimp_channel_translate (GimpItem *item,
gint off_y,
gboolean push_undo)
{
GimpChannel *mask;
GimpChannel *channel;
GimpChannel *tmp_mask = NULL;
gint width, height;
PixelRegion srcPR, destPR;
guchar empty = TRANSPARENT_OPACITY;
gint x1, y1, x2, y2;
mask = GIMP_CHANNEL (item);
channel = GIMP_CHANNEL (item);
gimp_channel_bounds (mask, &x1, &y1, &x2, &y2);
x1 = CLAMP ((x1 + off_x), 0, GIMP_ITEM (mask)->width);
y1 = CLAMP ((y1 + off_y), 0, GIMP_ITEM (mask)->height);
x2 = CLAMP ((x2 + off_x), 0, GIMP_ITEM (mask)->width);
y2 = CLAMP ((y2 + off_y), 0, GIMP_ITEM (mask)->height);
gimp_channel_bounds (channel, &x1, &y1, &x2, &y2);
x1 = CLAMP ((x1 + off_x), 0, GIMP_ITEM (channel)->width);
y1 = CLAMP ((y1 + off_y), 0, GIMP_ITEM (channel)->height);
x2 = CLAMP ((x2 + off_x), 0, GIMP_ITEM (channel)->width);
y2 = CLAMP ((y2 + off_y), 0, GIMP_ITEM (channel)->height);
width = x2 - x1;
height = y2 - y1;
if (push_undo)
{
gimp_channel_push_undo (mask, _("Move Channel"));
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->translate_desc);
/* update the old area */
gimp_drawable_update (GIMP_DRAWABLE (item),
x1, y1,
x2 - x1, y2 - y1);
}
else
{
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
}
/* make sure width and height are non-zero */
if (width != 0 && height != 0)
@ -363,10 +382,10 @@ gimp_channel_translate (GimpItem *item,
/* copy the portion of the mask we will keep to a
* temporary buffer
*/
tmp_mask = gimp_channel_new_mask (gimp_item_get_image (GIMP_ITEM (mask)),
tmp_mask = gimp_channel_new_mask (gimp_item_get_image (item),
width, height);
pixel_region_init (&srcPR, GIMP_DRAWABLE (mask)->tiles,
pixel_region_init (&srcPR, GIMP_DRAWABLE (channel)->tiles,
x1 - off_x, y1 - off_y, width, height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE (tmp_mask)->tiles,
0, 0, width, height, TRUE);
@ -374,10 +393,10 @@ gimp_channel_translate (GimpItem *item,
}
/* clear the mask */
pixel_region_init (&srcPR, GIMP_DRAWABLE (mask)->tiles,
pixel_region_init (&srcPR, GIMP_DRAWABLE (channel)->tiles,
0, 0,
GIMP_ITEM (mask)->width,
GIMP_ITEM (mask)->height, TRUE);
GIMP_ITEM (channel)->width,
GIMP_ITEM (channel)->height, TRUE);
color_region (&srcPR, &empty);
if (width != 0 && height != 0)
@ -385,7 +404,7 @@ gimp_channel_translate (GimpItem *item,
/* copy the temp mask back to the mask */
pixel_region_init (&srcPR, GIMP_DRAWABLE (tmp_mask)->tiles,
0, 0, width, height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE (mask)->tiles,
pixel_region_init (&destPR, GIMP_DRAWABLE (channel)->tiles,
x1, y1, width, height, TRUE);
copy_region (&srcPR, &destPR);
@ -396,26 +415,27 @@ gimp_channel_translate (GimpItem *item,
/* calculate new bounds */
if (width == 0 || height == 0)
{
mask->empty = TRUE;
mask->x1 = 0;
mask->y1 = 0;
mask->x2 = GIMP_ITEM (mask)->width;
mask->y2 = GIMP_ITEM (mask)->height;
channel->empty = TRUE;
channel->x1 = 0;
channel->y1 = 0;
channel->x2 = GIMP_ITEM (channel)->width;
channel->y2 = GIMP_ITEM (channel)->height;
}
else
{
mask->x1 = x1;
mask->y1 = y1;
mask->x2 = x2;
mask->y2 = y2;
channel->x1 = x1;
channel->y1 = y1;
channel->x2 = x2;
channel->y2 = y2;
}
if (push_undo)
{
/* update the new area */
gimp_drawable_update (GIMP_DRAWABLE (item),
mask->x1, mask->y1,
mask->x2 - mask->x1, mask->y2 - mask->y1);
channel->x1, channel->y1,
channel->x2 - channel->x1,
channel->y2 - channel->y1);
gimp_viewable_size_changed (GIMP_VIEWABLE (item));
}
@ -609,6 +629,14 @@ gimp_channel_stroke (GimpItem *item,
return retval;
}
static void
gimp_channel_invalidate_boundary (GimpDrawable *drawable)
{
GimpChannel *channel = GIMP_CHANNEL (drawable);
channel->boundary_known = FALSE;
}
static gboolean
gimp_channel_real_boundary (GimpChannel *channel,
const BoundSeg **segs_in,
@ -898,7 +926,10 @@ gimp_channel_real_feather (GimpChannel *channel,
PixelRegion srcPR;
if (push_undo)
gimp_channel_push_undo (channel, _("Feather Channel"));
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->feather_desc);
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
pixel_region_init (&srcPR, GIMP_DRAWABLE (channel)->tiles,
0, 0,
@ -918,7 +949,10 @@ gimp_channel_real_sharpen (GimpChannel *channel,
GimpLut *lut;
if (push_undo)
gimp_channel_push_undo (channel, _("Sharpen Channel"));
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->sharpen_desc);
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
pixel_region_init (&maskPR, GIMP_DRAWABLE (channel)->tiles,
0, 0,
@ -945,10 +979,14 @@ gimp_channel_real_clear (GimpChannel *channel,
if (push_undo)
{
if (! undo_desc)
undo_desc = _("Clear Channel");
undo_desc = GIMP_CHANNEL_GET_CLASS (channel)->clear_desc;
gimp_channel_push_undo (channel, undo_desc);
}
else
{
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
}
if (channel->bounds_known && !channel->empty)
{
@ -984,7 +1022,10 @@ gimp_channel_real_all (GimpChannel *channel,
guchar bg = OPAQUE_OPACITY;
if (push_undo)
gimp_channel_push_undo (channel, _("Fill Channel"));
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->all_desc);
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
/* clear the channel */
pixel_region_init (&maskPR, GIMP_DRAWABLE (channel)->tiles,
@ -1007,7 +1048,10 @@ gimp_channel_real_invert (GimpChannel *channel,
gboolean push_undo)
{
if (push_undo)
gimp_channel_push_undo (channel, _("Invert Channel"));
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->invert_desc);
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
if (channel->bounds_known && channel->empty)
{
@ -1071,7 +1115,10 @@ gimp_channel_real_border (GimpChannel *channel,
y2 += radius_y;
if (push_undo)
gimp_channel_push_undo (channel, _("Border Channel"));
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->border_desc);
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
pixel_region_init (&bPR, GIMP_DRAWABLE (channel)->tiles, x1, y1,
(x2-x1), (y2-y1), TRUE);
@ -1126,7 +1173,10 @@ gimp_channel_real_grow (GimpChannel *channel,
y2 = GIMP_ITEM (channel)->height;
if (push_undo)
gimp_channel_push_undo (channel, _("Grow Channel"));
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->grow_desc);
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
/* need full extents for grow, not! */
pixel_region_init (&bPR, GIMP_DRAWABLE (channel)->tiles, x1, y1, (x2 - x1),
@ -1175,7 +1225,10 @@ gimp_channel_real_shrink (GimpChannel *channel,
y2++;
if (push_undo)
gimp_channel_push_undo (channel, _("Shrink Channel"));
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->shrink_desc);
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
pixel_region_init (&bPR, GIMP_DRAWABLE (channel)->tiles, x1, y1, (x2 - x1),
(y2 - y1), TRUE);
@ -1185,24 +1238,6 @@ gimp_channel_real_shrink (GimpChannel *channel,
channel->bounds_known = FALSE;
}
static void
gimp_channel_push_undo (GimpChannel *mask,
const gchar *undo_desc)
{
GimpImage *gimage;
gimage = gimp_item_get_image (GIMP_ITEM (mask));
g_return_if_fail (gimage != NULL);
gimp_image_undo_push_mask (gimage, undo_desc, mask);
mask->boundary_known = FALSE;
/* invalidate the preview */
GIMP_DRAWABLE (mask)->preview_valid = FALSE;
}
static void
gimp_channel_validate (TileManager *tm,
Tile *tile)
@ -1434,6 +1469,23 @@ gimp_channel_set_show_masked (GimpChannel *channel,
}
}
void
gimp_channel_push_undo (GimpChannel *channel,
const gchar *undo_desc)
{
GimpImage *gimage;
g_return_if_fail (GIMP_IS_CHANNEL (channel));
gimage = gimp_item_get_image (GIMP_ITEM (channel));
g_return_if_fail (GIMP_IS_IMAGE (gimage));
gimp_image_undo_push_mask (gimage, undo_desc, channel);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
}
/******************************/
/* selection mask functions */
@ -2073,6 +2125,8 @@ gimp_channel_load (GimpChannel *mask,
if (push_undo)
gimp_channel_push_undo (mask, _("Channel Load"));
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (mask));
/* copy the channel to the mask */
pixel_region_init (&srcPR, GIMP_DRAWABLE (channel)->tiles,

View File

@ -104,6 +104,16 @@ struct _GimpChannelClass
gint radius_y,
gboolean edge_lock,
gboolean push_undo);
const gchar *translate_desc;
const gchar *feather_desc;
const gchar *sharpen_desc;
const gchar *clear_desc;
const gchar *all_desc;
const gchar *invert_desc;
const gchar *border_desc;
const gchar *grow_desc;
const gchar *shrink_desc;
};
@ -141,6 +151,9 @@ gboolean gimp_channel_get_show_masked (GimpChannel *channel);
void gimp_channel_set_show_masked (GimpChannel *channel,
gboolean show_masked);
void gimp_channel_push_undo (GimpChannel *mask,
const gchar *undo_desc);
/* selection mask functions */

View File

@ -192,6 +192,7 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
klass->visibility_changed = NULL;
klass->alpha_changed = NULL;
klass->invalidate_boundary = NULL;
}
static void
@ -963,6 +964,19 @@ gimp_drawable_alpha_changed (GimpDrawable *drawable)
g_signal_emit (drawable, gimp_drawable_signals[ALPHA_CHANGED], 0);
}
void
gimp_drawable_invalidate_boundary (GimpDrawable *drawable)
{
GimpDrawableClass *drawable_class;
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
drawable_class = GIMP_DRAWABLE_GET_CLASS (drawable);
if (drawable_class->invalidate_boundary)
drawable_class->invalidate_boundary (drawable);
}
guchar *
gimp_drawable_cmap (const GimpDrawable *drawable)
{

View File

@ -53,8 +53,12 @@ struct _GimpDrawableClass
{
GimpItemClass parent_class;
void (* visibility_changed) (GimpDrawable *drawable);
void (* alpha_changed) (GimpDrawable *drawable);
/* signals */
void (* visibility_changed) (GimpDrawable *drawable);
void (* alpha_changed) (GimpDrawable *drawable);
/* virtual functions */
void (* invalidate_boundary) (GimpDrawable *drawable);
};
@ -120,6 +124,8 @@ void gimp_drawable_set_visible (GimpDrawable *drawable,
void gimp_drawable_alpha_changed (GimpDrawable *drawable);
void gimp_drawable_invalidate_boundary (GimpDrawable *drawable);
guchar * gimp_drawable_cmap (const GimpDrawable *drawable);
guchar * gimp_drawable_get_color_at (GimpDrawable *drawable,

View File

@ -52,8 +52,7 @@ gimp_image_mask_push_undo (GimpImage *gimage,
{
g_return_if_fail (GIMP_IS_IMAGE (gimage));
gimp_selection_push_undo (gimp_image_get_mask (gimage),
undo_desc);
gimp_channel_push_undo (gimp_image_get_mask (gimage), undo_desc);
}
void
@ -61,7 +60,7 @@ gimp_image_mask_invalidate (GimpImage *gimage)
{
g_return_if_fail (GIMP_IS_IMAGE (gimage));
gimp_selection_invalidate (gimp_image_get_mask (gimage));
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (gimp_image_get_mask (gimage)));
}

View File

@ -1528,7 +1528,7 @@ undo_pop_layer (GimpUndo *undo,
undo->size += gimp_object_get_memsize (GIMP_OBJECT (layer), NULL);
/* Make sure we're not caching any old selection info */
gimp_layer_invalidate_boundary (layer);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
/* record the current position */
lu->prev_position = gimp_image_get_layer_index (undo->gimage, layer);
@ -1588,7 +1588,7 @@ undo_pop_layer (GimpUndo *undo,
/* hide the current selection--for all views */
if (lu->prev_layer)
gimp_layer_invalidate_boundary (lu->prev_layer);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (lu->prev_layer));
/* if this is a floating selection, set the fs pointer */
if (gimp_layer_is_floating_sel (layer))
@ -1716,7 +1716,7 @@ undo_pop_layer_mod (GimpUndo *undo,
lmu->offset_y = GIMP_ITEM (layer)->offset_y;
/* Make sure we're not caching any old selection info */
gimp_layer_invalidate_boundary (layer);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
GIMP_DRAWABLE (layer)->tiles = tiles;
GIMP_DRAWABLE (layer)->bytes = tile_manager_bpp (tiles);
@ -2973,7 +2973,7 @@ undo_pop_fs_to_layer (GimpUndo *undo,
fsu->floating_layer->fs.initial = TRUE;
/* clear the selection */
gimp_layer_invalidate_boundary (fsu->floating_layer);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (fsu->floating_layer));
/* Update the preview for the gimage and underlying drawable */
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (fsu->floating_layer));
@ -2991,7 +2991,7 @@ undo_pop_fs_to_layer (GimpUndo *undo,
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (fsu->floating_layer));
/* clear the selection */
gimp_layer_invalidate_boundary (fsu->floating_layer);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (fsu->floating_layer));
/* update the pointers */
fsu->floating_layer->fs.drawable = NULL;

View File

@ -2203,7 +2203,7 @@ gimp_image_set_active_layer (GimpImage *gimage,
gimage->layer_stack = g_slist_prepend (gimage->layer_stack, layer);
/* Don't cache selection info for the previous active layer */
gimp_layer_invalidate_boundary (layer);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
}
gimage->active_layer = layer;
@ -2248,7 +2248,7 @@ gimp_image_set_active_channel (GimpImage *gimage,
if (gimage->active_layer)
{
/* Don't cache selection info for the previous active layer */
gimp_layer_invalidate_boundary (gimage->active_layer);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (gimage->active_layer));
gimage->active_layer = NULL;
@ -2581,7 +2581,7 @@ gimp_image_remove_layer (GimpImage *gimage,
g_object_ref (layer);
/* Make sure we're not caching any old selection info */
gimp_layer_invalidate_boundary (layer);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
gimp_container_remove (gimage->layers, GIMP_OBJECT (layer));
gimage->layer_stack = g_slist_remove (gimage->layer_stack, layer);

View File

@ -225,7 +225,7 @@ floating_sel_to_layer (GimpLayer *layer)
layer, layer->fs.drawable);
/* clear the selection */
gimp_layer_invalidate_boundary (layer);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
/* Set pointers */
layer->fs.drawable = NULL;

View File

@ -112,6 +112,8 @@ static void gimp_layer_transform (GimpItem *item,
GimpProgressFunc progress_callback,
gpointer progress_data);
static void gimp_layer_invalidate_boundary (GimpDrawable *drawable);
static void gimp_layer_transform_color (GimpImage *gimage,
PixelRegion *layerPR,
PixelRegion *bufPR,
@ -159,11 +161,13 @@ gimp_layer_class_init (GimpLayerClass *klass)
GimpObjectClass *gimp_object_class;
GimpViewableClass *viewable_class;
GimpItemClass *item_class;
GimpDrawableClass *drawable_class;
object_class = G_OBJECT_CLASS (klass);
gimp_object_class = GIMP_OBJECT_CLASS (klass);
viewable_class = GIMP_VIEWABLE_CLASS (klass);
item_class = GIMP_ITEM_CLASS (klass);
drawable_class = GIMP_DRAWABLE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
@ -203,29 +207,31 @@ gimp_layer_class_init (GimpLayerClass *klass)
gimp_marshal_VOID__VOID,
G_TYPE_NONE, 0);
object_class->finalize = gimp_layer_finalize;
object_class->finalize = gimp_layer_finalize;
gimp_object_class->get_memsize = gimp_layer_get_memsize;
gimp_object_class->get_memsize = gimp_layer_get_memsize;
viewable_class->default_stock_id = "gimp-layer";
viewable_class->invalidate_preview = gimp_layer_invalidate_preview;
viewable_class->default_stock_id = "gimp-layer";
viewable_class->invalidate_preview = gimp_layer_invalidate_preview;
item_class->duplicate = gimp_layer_duplicate;
item_class->convert = gimp_layer_convert;
item_class->rename = gimp_layer_rename;
item_class->translate = gimp_layer_translate;
item_class->scale = gimp_layer_scale;
item_class->resize = gimp_layer_resize;
item_class->flip = gimp_layer_flip;
item_class->rotate = gimp_layer_rotate;
item_class->transform = gimp_layer_transform;
item_class->default_name = _("Layer");
item_class->rename_desc = _("Rename Layer");
item_class->duplicate = gimp_layer_duplicate;
item_class->convert = gimp_layer_convert;
item_class->rename = gimp_layer_rename;
item_class->translate = gimp_layer_translate;
item_class->scale = gimp_layer_scale;
item_class->resize = gimp_layer_resize;
item_class->flip = gimp_layer_flip;
item_class->rotate = gimp_layer_rotate;
item_class->transform = gimp_layer_transform;
item_class->default_name = _("Layer");
item_class->rename_desc = _("Rename Layer");
klass->opacity_changed = NULL;
klass->mode_changed = NULL;
klass->preserve_trans_changed = NULL;
klass->mask_changed = NULL;
drawable_class->invalidate_boundary = gimp_layer_invalidate_boundary;
klass->opacity_changed = NULL;
klass->mode_changed = NULL;
klass->preserve_trans_changed = NULL;
klass->mask_changed = NULL;
}
static void
@ -487,7 +493,7 @@ gimp_layer_translate (GimpItem *item,
gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, item->width, item->height);
/* invalidate the selection boundary because of a layer modification */
gimp_layer_invalidate_boundary (layer);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
GIMP_ITEM_CLASS (parent_class)->translate (item, offset_x, offset_y,
push_undo);
@ -541,7 +547,7 @@ gimp_layer_scale (GimpItem *item,
}
/* Make sure we're not caching any old selection info */
gimp_layer_invalidate_boundary (layer);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
}
static void
@ -575,7 +581,7 @@ gimp_layer_resize (GimpItem *item,
}
/* Make sure we're not caching any old selection info */
gimp_layer_invalidate_boundary (layer);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
}
static void
@ -603,7 +609,7 @@ gimp_layer_flip (GimpItem *item,
gimp_image_undo_group_end (gimage);
/* Make sure we're not caching any old selection info */
gimp_layer_invalidate_boundary (layer);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
}
static void
@ -634,7 +640,7 @@ gimp_layer_rotate (GimpItem *item,
gimp_image_undo_group_end (gimage);
/* Make sure we're not caching any old selection info */
gimp_layer_invalidate_boundary (layer);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
}
static void
@ -669,7 +675,39 @@ gimp_layer_transform (GimpItem *item,
gimp_image_undo_group_end (gimage);
/* Make sure we're not caching any old selection info */
gimp_layer_invalidate_boundary (layer);
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
}
static void
gimp_layer_invalidate_boundary (GimpDrawable *drawable)
{
GimpLayer *layer;
GimpImage *gimage;
GimpChannel *mask;
layer = GIMP_LAYER (drawable);
if (! (gimage = gimp_item_get_image (GIMP_ITEM (layer))))
return;
/* Turn the current selection off */
gimp_image_selection_control (gimage, GIMP_SELECTION_OFF);
/* clear the affected region surrounding the layer */
gimp_image_selection_control (gimage, GIMP_SELECTION_LAYER_OFF);
/* get the selection mask channel */
mask = gimp_image_get_mask (gimage);
/* Only bother with the bounds if there is a selection */
if (! gimp_channel_is_empty (mask))
{
mask->bounds_known = FALSE;
mask->boundary_known = FALSE;
}
if (gimp_layer_is_floating_sel (layer))
floating_sel_invalidate (layer);
}
static void
@ -1289,37 +1327,6 @@ gimp_layer_boundary (GimpLayer *layer,
return new_segs;
}
void
gimp_layer_invalidate_boundary (GimpLayer *layer)
{
GimpImage *gimage;
GimpChannel *mask;
g_return_if_fail (GIMP_IS_LAYER (layer));
if (! (gimage = gimp_item_get_image (GIMP_ITEM (layer))))
return;
/* Turn the current selection off */
gimp_image_selection_control (gimage, GIMP_SELECTION_OFF);
/* clear the affected region surrounding the layer */
gimp_image_selection_control (gimage, GIMP_SELECTION_LAYER_OFF);
/* get the selection mask channel */
mask = gimp_image_get_mask (gimage);
/* Only bother with the bounds if there is a selection */
if (! gimp_channel_is_empty (mask))
{
mask->bounds_known = FALSE;
mask->boundary_known = FALSE;
}
if (gimp_layer_is_floating_sel (layer))
floating_sel_invalidate (layer);
}
gboolean
gimp_layer_pick_correlate (GimpLayer *layer,
gint x,

View File

@ -99,7 +99,6 @@ void gimp_layer_add_alpha (GimpLayer *layer);
void gimp_layer_resize_to_image (GimpLayer *layer);
BoundSeg * gimp_layer_boundary (GimpLayer *layer,
gint *num_segs);
void gimp_layer_invalidate_boundary (GimpLayer *layer);
gboolean gimp_layer_pick_correlate (GimpLayer *layer,
gint x,
gint y);

View File

@ -68,6 +68,8 @@ static gboolean gimp_selection_stroke (GimpItem *item,
GimpDrawable *drawable,
GimpPaintInfo *paint_info);
static void gimp_selection_invalidate_boundary (GimpDrawable *drawable);
static gboolean gimp_selection_boundary (GimpChannel *channel,
const BoundSeg **segs_in,
const BoundSeg **segs_out,
@ -152,33 +154,47 @@ gimp_selection_get_type (void)
static void
gimp_selection_class_init (GimpSelectionClass *klass)
{
GimpItemClass *item_class;
GimpChannelClass *channel_class;
GimpItemClass *item_class;
GimpDrawableClass *drawable_class;
GimpChannelClass *channel_class;
item_class = GIMP_ITEM_CLASS (klass);
channel_class = GIMP_CHANNEL_CLASS (klass);
item_class = GIMP_ITEM_CLASS (klass);
drawable_class = GIMP_DRAWABLE_CLASS (klass);
channel_class = GIMP_CHANNEL_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
item_class->translate = gimp_selection_translate;
item_class->scale = gimp_selection_scale;
item_class->resize = gimp_selection_resize;
item_class->flip = gimp_selection_flip;
item_class->rotate = gimp_selection_rotate;
item_class->stroke = gimp_selection_stroke;
item_class->translate = gimp_selection_translate;
item_class->scale = gimp_selection_scale;
item_class->resize = gimp_selection_resize;
item_class->flip = gimp_selection_flip;
item_class->rotate = gimp_selection_rotate;
item_class->stroke = gimp_selection_stroke;
channel_class->boundary = gimp_selection_boundary;
channel_class->bounds = gimp_selection_bounds;
channel_class->value = gimp_selection_value;
channel_class->is_empty = gimp_selection_is_empty;
channel_class->feather = gimp_selection_feather;
channel_class->sharpen = gimp_selection_sharpen;
channel_class->clear = gimp_selection_clear;
channel_class->all = gimp_selection_all;
channel_class->invert = gimp_selection_invert;
channel_class->border = gimp_selection_border;
channel_class->grow = gimp_selection_grow;
channel_class->shrink = gimp_selection_shrink;
drawable_class->invalidate_boundary = gimp_selection_invalidate_boundary;
channel_class->boundary = gimp_selection_boundary;
channel_class->bounds = gimp_selection_bounds;
channel_class->value = gimp_selection_value;
channel_class->is_empty = gimp_selection_is_empty;
channel_class->feather = gimp_selection_feather;
channel_class->sharpen = gimp_selection_sharpen;
channel_class->clear = gimp_selection_clear;
channel_class->all = gimp_selection_all;
channel_class->invert = gimp_selection_invert;
channel_class->border = gimp_selection_border;
channel_class->grow = gimp_selection_grow;
channel_class->shrink = gimp_selection_shrink;
channel_class->translate_desc = _("Move Selection");
channel_class->feather_desc = _("Feather Selection");
channel_class->sharpen_desc = _("Sharpen Selection");
channel_class->clear_desc = _("Select None");
channel_class->all_desc = _("Select All");
channel_class->invert_desc = _("Invert Selection");
channel_class->border_desc = _("Border Selection");
channel_class->grow_desc = _("Grow Selection");
channel_class->shrink_desc = _("Shrink Selection");
}
static void
@ -193,16 +209,10 @@ gimp_selection_translate (GimpItem *item,
gint offset_y,
gboolean push_undo)
{
GimpChannel *selection = GIMP_CHANNEL (item);
GIMP_ITEM_CLASS (parent_class)->translate (item, offset_x, offset_y,
push_undo);
if (push_undo)
gimp_selection_push_undo (selection, _("Move Selection"));
else
gimp_selection_invalidate (selection);
GIMP_ITEM_CLASS (parent_class)->translate (item, offset_x, offset_y, FALSE);
gimp_selection_changed (selection);
gimp_selection_changed (GIMP_CHANNEL (item));
}
static void
@ -213,10 +223,6 @@ gimp_selection_scale (GimpItem *item,
gint new_offset_y,
GimpInterpolationType interp_type)
{
GimpChannel *selection = GIMP_CHANNEL (item);
gimp_selection_invalidate (selection);
GIMP_ITEM_CLASS (parent_class)->scale (item, new_width, new_height,
new_offset_x, new_offset_y,
interp_type);
@ -224,7 +230,7 @@ gimp_selection_scale (GimpItem *item,
item->offset_x = 0;
item->offset_y = 0;
gimp_selection_changed (selection);
gimp_selection_changed (GIMP_CHANNEL (item));
}
static void
@ -234,17 +240,13 @@ gimp_selection_resize (GimpItem *item,
gint off_x,
gint off_y)
{
GimpChannel *selection = GIMP_CHANNEL (item);
gimp_selection_invalidate (selection);
GIMP_ITEM_CLASS (parent_class)->resize (item, new_width, new_height,
off_x, off_y);
item->offset_x = 0;
item->offset_y = 0;
gimp_selection_changed (selection);
gimp_selection_changed (GIMP_CHANNEL (item));
}
static void
@ -253,13 +255,9 @@ gimp_selection_flip (GimpItem *item,
gdouble axis,
gboolean clip_result)
{
GimpChannel *selection = GIMP_CHANNEL (item);
gimp_selection_invalidate (selection);
GIMP_ITEM_CLASS (parent_class)->flip (item, flip_type, axis, TRUE);
gimp_selection_changed (selection);
gimp_selection_changed (GIMP_CHANNEL (item));
}
static void
@ -269,15 +267,11 @@ gimp_selection_rotate (GimpItem *item,
gdouble center_y,
gboolean clip_result)
{
GimpChannel *selection = GIMP_CHANNEL (item);
gimp_selection_invalidate (selection);
GIMP_ITEM_CLASS (parent_class)->rotate (item, rotation_type,
center_x, center_y,
clip_result);
gimp_selection_changed (selection);
gimp_selection_changed (GIMP_CHANNEL (item));
}
static gboolean
@ -320,6 +314,40 @@ gimp_selection_stroke (GimpItem *item,
return retval;
}
static void
gimp_selection_invalidate_boundary (GimpDrawable *drawable)
{
GimpChannel *selection;
GimpLayer *layer;
GimpImage *gimage;
selection = GIMP_CHANNEL (drawable);
gimage = gimp_item_get_image (GIMP_ITEM (drawable));
g_return_if_fail (GIMP_IS_IMAGE (gimage));
/* Turn the current selection off */
gimp_image_selection_control (gimage, GIMP_SELECTION_OFF);
GIMP_DRAWABLE_CLASS (parent_class)->invalidate_boundary (drawable);
/* If there is a floating selection, update it's area...
* we need to do this since this selection mask can act as an additional
* mask in the composition of the floating selection
*/
layer = gimp_image_get_active_layer (gimage);
if (layer && gimp_layer_is_floating_sel (layer))
gimp_drawable_update (GIMP_DRAWABLE (layer),
0, 0,
GIMP_ITEM (layer)->width,
GIMP_ITEM (layer)->height);
/* invalidate the preview */
drawable->preview_valid = FALSE;
}
static gboolean
gimp_selection_boundary (GimpChannel *channel,
const BoundSeg **segs_in,
@ -445,13 +473,8 @@ gimp_selection_feather (GimpChannel *channel,
gdouble radius_y,
gboolean push_undo)
{
if (push_undo)
gimp_selection_push_undo (channel, _("Feather Selection"));
else
gimp_selection_invalidate (channel);
GIMP_CHANNEL_CLASS (parent_class)->feather (channel, radius_x, radius_y,
FALSE);
push_undo);
gimp_selection_changed (channel);
}
@ -460,12 +483,7 @@ static void
gimp_selection_sharpen (GimpChannel *channel,
gboolean push_undo)
{
if (push_undo)
gimp_selection_push_undo (channel, _("Sharpen Selection"));
else
gimp_selection_invalidate (channel);
GIMP_CHANNEL_CLASS (parent_class)->sharpen (channel, FALSE);
GIMP_CHANNEL_CLASS (parent_class)->sharpen (channel, push_undo);
gimp_selection_changed (channel);
}
@ -475,17 +493,7 @@ gimp_selection_clear (GimpChannel *channel,
const gchar *undo_desc,
gboolean push_undo)
{
if (push_undo)
{
if (! undo_desc)
undo_desc = _("Select None");
gimp_selection_push_undo (channel, undo_desc);
}
else
gimp_selection_invalidate (channel);
GIMP_CHANNEL_CLASS (parent_class)->clear (channel, NULL, FALSE);
GIMP_CHANNEL_CLASS (parent_class)->clear (channel, undo_desc, push_undo);
gimp_selection_changed (channel);
}
@ -494,12 +502,7 @@ static void
gimp_selection_all (GimpChannel *channel,
gboolean push_undo)
{
if (push_undo)
gimp_selection_push_undo (channel, _("Select All"));
else
gimp_selection_invalidate (channel);
GIMP_CHANNEL_CLASS (parent_class)->all (channel, FALSE);
GIMP_CHANNEL_CLASS (parent_class)->all (channel, push_undo);
gimp_selection_changed (channel);
}
@ -508,12 +511,7 @@ static void
gimp_selection_invert (GimpChannel *channel,
gboolean push_undo)
{
if (push_undo)
gimp_selection_push_undo (channel, _("Invert Selection"));
else
gimp_selection_invalidate (channel);
GIMP_CHANNEL_CLASS (parent_class)->invert (channel, FALSE);
GIMP_CHANNEL_CLASS (parent_class)->invert (channel, push_undo);
gimp_selection_changed (channel);
}
@ -524,13 +522,8 @@ gimp_selection_border (GimpChannel *channel,
gint radius_y,
gboolean push_undo)
{
if (push_undo)
gimp_selection_push_undo (channel, _("Border Selection"));
else
gimp_selection_invalidate (channel);
GIMP_CHANNEL_CLASS (parent_class)->border (channel, radius_x, radius_y,
FALSE);
push_undo);
gimp_selection_changed (channel);
}
@ -541,13 +534,8 @@ gimp_selection_grow (GimpChannel *channel,
gint radius_y,
gboolean push_undo)
{
if (push_undo)
gimp_selection_push_undo (channel, _("Grow Selection"));
else
gimp_selection_invalidate (channel);
GIMP_CHANNEL_CLASS (parent_class)->grow (channel, radius_x, radius_y,
FALSE);
push_undo);
gimp_selection_changed (channel);
}
@ -559,13 +547,8 @@ gimp_selection_shrink (GimpChannel *channel,
gboolean edge_lock,
gboolean push_undo)
{
if (push_undo)
gimp_selection_push_undo (channel, _("Shrink Selection"));
else
gimp_selection_invalidate (channel);
GIMP_CHANNEL_CLASS (parent_class)->shrink (channel, radius_x, radius_y,
edge_lock, FALSE);
edge_lock, push_undo);
gimp_selection_changed (channel);
}
@ -617,53 +600,3 @@ gimp_selection_new (GimpImage *gimage,
return channel;
}
void
gimp_selection_push_undo (GimpChannel *selection,
const gchar *undo_desc)
{
GimpImage *gimage;
g_return_if_fail (GIMP_IS_SELECTION (selection));
gimage = gimp_item_get_image (GIMP_ITEM (selection));
g_return_if_fail (GIMP_IS_IMAGE (gimage));
gimp_image_undo_push_mask (gimage, undo_desc, selection);
gimp_selection_invalidate (selection);
}
void
gimp_selection_invalidate (GimpChannel *selection)
{
GimpLayer *layer;
GimpImage *gimage;
g_return_if_fail (GIMP_IS_SELECTION (selection));
gimage = gimp_item_get_image (GIMP_ITEM (selection));
g_return_if_fail (GIMP_IS_IMAGE (gimage));
/* Turn the current selection off */
gimp_image_selection_control (gimage, GIMP_SELECTION_OFF);
selection->boundary_known = FALSE;
/* If there is a floating selection, update it's area...
* we need to do this since this selection mask can act as an additional
* mask in the composition of the floating selection
*/
layer = gimp_image_get_active_layer (gimage);
if (layer && gimp_layer_is_floating_sel (layer))
gimp_drawable_update (GIMP_DRAWABLE (layer),
0, 0,
GIMP_ITEM (layer)->width,
GIMP_ITEM (layer)->height);
/* invalidate the preview */
GIMP_DRAWABLE (selection)->preview_valid = FALSE;
}

View File

@ -51,9 +51,6 @@ GType gimp_selection_get_type (void) G_GNUC_CONST;
GimpChannel * gimp_selection_new (GimpImage *gimage,
gint width,
gint height);
void gimp_selection_push_undo (GimpChannel *selection,
const gchar *undo_desc);
void gimp_selection_invalidate (GimpChannel *selection);
#endif /* __GIMP_SELECTION_H__ */

View File

@ -433,7 +433,7 @@ gimp_text_layer_render_now (GimpTextLayer *layer)
gimp_item_height (item));
/* Make sure we're not caching any old selection info */
gimp_layer_invalidate_boundary (GIMP_LAYER (layer));
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
GIMP_ITEM (drawable)->width = width;
GIMP_ITEM (drawable)->height = height;