Commit 33bba657 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer
Browse files

Make sure the selection (gimpimage-mask.c) functionality is really built

2002-08-20  Michael Natterer  <mitch@gimp.org>

	Make sure the selection (gimpimage-mask.c) functionality is really
	built *on top* of the GimpChannel functionality:

	* app/undo.[ch]: renamed undo_push_image_mask() to
	undo_push_mask() and generalized it's API to take a GimpChannel
	param so undos can be pushed for channels which are not the
	image's selection. Simplified the API and added code which copies
	the region of interest instead of leaving this to callers.

	* app/undo_types.h: s/IMAGE_MASK_UNDO/MASK_UNDO/

	* app/undo_history.c: changed accordingly.

	* app/core/gimpchannel.[ch]: don't #include "gimpimage-mask.h".
	Changed gimp_channel_push_undo() to really push a channel undo,
	not a selection undo. Added "gboolean push_undo" params to all
	functions which are called from gimpimage-mask.c. Various cleanups
	and optimizations. Added /*< proxy-foo >*/ stuff to the header so
	we export just the struct itself to libgimpproxy. Added accessors
	gimp_channel_[get|set]_show_masked().

	* app/core/gimpimage-mask.[ch]: renamed gimp_image_mask_undo() to
	gimp_image_mask_push_undo(). Call it before calling GimpChannel
	functions which modify the mask, also call all GimpChannel
	functions with push_undo = FALSE. Emit gimp_image_mask_changed()
	after each operation instead of calling it in
	gimp_image_mask_invalidate(). Removed gimp_image_mask_none()
	because it is the same as gimp_image_mask_clear().
	General cleanup.

	* app/core/gimpimage-mask-select.c
	* app/core/gimpimage-qmask.c: changed accordingly.

	* app/core/gimpedit.c: call gimp_image_mask_clear(), not
	gimp_channel_clear (gimp_image_get_mask()).

	* app/core/gimpimage-crop.c
	* app/core/gimpimage-resize.c
	* app/core/gimpimage-scale.c: call gimp_image_mask_changed()

	* app/gui/channels-commands.c
	* app/gui/select-commands.c
	* app/tools/gimptexttool.c
	* tools/pdbgen/pdb/channel.pdb
	* tools/pdbgen/pdb/selection.pdb: follow GimpChannel and
	gimp_image_mask* API changes.

	* app/pdb/channel_cmds.c
	* app/pdb/selection_cmds.c
	* libgimpproxy/gimpchannel.h: regenerated.

	Unrelated:

	* app/core/gimpimage.c: call gimp_drawable_push_undo() instead of
	undo_push_image() directly.
parent 68820735
2002-08-20 Michael Natterer <mitch@gimp.org>
Make sure the selection (gimpimage-mask.c) functionality is really
built *on top* of the GimpChannel functionality:
* app/undo.[ch]: renamed undo_push_image_mask() to
undo_push_mask() and generalized it's API to take a GimpChannel
param so undos can be pushed for channels which are not the
image's selection. Simplified the API and added code which copies
the region of interest instead of leaving this to callers.
* app/undo_types.h: s/IMAGE_MASK_UNDO/MASK_UNDO/
* app/undo_history.c: changed accordingly.
* app/core/gimpchannel.[ch]: don't #include "gimpimage-mask.h".
Changed gimp_channel_push_undo() to really push a channel undo,
not a selection undo. Added "gboolean push_undo" params to all
functions which are called from gimpimage-mask.c. Various cleanups
and optimizations. Added /*< proxy-foo >*/ stuff to the header so
we export just the struct itself to libgimpproxy. Added accessors
gimp_channel_[get|set]_show_masked().
* app/core/gimpimage-mask.[ch]: renamed gimp_image_mask_undo() to
gimp_image_mask_push_undo(). Call it before calling GimpChannel
functions which modify the mask, also call all GimpChannel
functions with push_undo = FALSE. Emit gimp_image_mask_changed()
after each operation instead of calling it in
gimp_image_mask_invalidate(). Removed gimp_image_mask_none()
because it is the same as gimp_image_mask_clear().
General cleanup.
* app/core/gimpimage-mask-select.c
* app/core/gimpimage-qmask.c: changed accordingly.
* app/core/gimpedit.c: call gimp_image_mask_clear(), not
gimp_channel_clear (gimp_image_get_mask()).
* app/core/gimpimage-crop.c
* app/core/gimpimage-resize.c
* app/core/gimpimage-scale.c: call gimp_image_mask_changed()
* app/gui/channels-commands.c
* app/gui/select-commands.c
* app/tools/gimptexttool.c
* tools/pdbgen/pdb/channel.pdb
* tools/pdbgen/pdb/selection.pdb: follow GimpChannel and
gimp_image_mask* API changes.
* app/pdb/channel_cmds.c
* app/pdb/selection_cmds.c
* libgimpproxy/gimpchannel.h: regenerated.
Unrelated:
* app/core/gimpimage.c: call gimp_drawable_push_undo() instead of
undo_push_image() directly.
2002-08-18 Manish Singh <yosh@gimp.org> 2002-08-18 Manish Singh <yosh@gimp.org>
   
* autogen.sh: remove bashism (function keyword) * autogen.sh: remove bashism (function keyword)
......
...@@ -274,7 +274,7 @@ channels_new_channel_query (GimpImage *gimage, ...@@ -274,7 +274,7 @@ channels_new_channel_query (GimpImage *gimage,
gimp_drawable_fill_by_type (GIMP_DRAWABLE (new_channel), gimp_drawable_fill_by_type (GIMP_DRAWABLE (new_channel),
gimp_get_user_context (gimage->gimp), gimp_get_user_context (gimage->gimp),
GIMP_TRANSPARENT_FILL); GIMP_TRANSPARENT_FILL);
gimp_channel_translate (new_channel, off_x, off_y); gimp_channel_translate (new_channel, off_x, off_y, FALSE);
gimp_image_add_channel (gimage, new_channel, -1); gimp_image_add_channel (gimage, new_channel, -1);
undo_push_group_end (gimage); undo_push_group_end (gimage);
......
...@@ -105,7 +105,7 @@ select_none_cmd_callback (GtkWidget *widget, ...@@ -105,7 +105,7 @@ select_none_cmd_callback (GtkWidget *widget,
GimpImage *gimage; GimpImage *gimage;
return_if_no_image (gimage, data); return_if_no_image (gimage, data);
gimp_image_mask_none (gimage); gimp_image_mask_clear (gimage);
gimp_image_flush (gimage); gimp_image_flush (gimage);
} }
......
...@@ -212,7 +212,7 @@ gimp_edit_paste (GimpImage *gimage, ...@@ -212,7 +212,7 @@ gimp_edit_paste (GimpImage *gimage,
* it seems like the correct behavior. * it seems like the correct behavior.
*/ */
if (! gimp_image_mask_is_empty (gimage) && ! paste_into) if (! gimp_image_mask_is_empty (gimage) && ! paste_into)
gimp_channel_clear (gimp_image_get_mask (gimage)); gimp_image_mask_clear (gimage);
/* if there's a drawable, add a new floating selection */ /* if there's a drawable, add a new floating selection */
if (drawable != NULL) if (drawable != NULL)
......
...@@ -33,14 +33,12 @@ ...@@ -33,14 +33,12 @@
#include "base/lut-funcs.h" #include "base/lut-funcs.h"
#include "base/pixel-processor.h" #include "base/pixel-processor.h"
#include "base/pixel-region.h" #include "base/pixel-region.h"
#include "base/temp-buf.h"
#include "base/tile.h" #include "base/tile.h"
#include "base/tile-manager.h" #include "base/tile-manager.h"
#include "paint-funcs/paint-funcs.h" #include "paint-funcs/paint-funcs.h"
#include "gimpimage.h" #include "gimpimage.h"
#include "gimpimage-mask.h"
#include "gimpchannel.h" #include "gimpchannel.h"
#include "gimplayer.h" #include "gimplayer.h"
#include "gimpparasitelist.h" #include "gimpparasitelist.h"
...@@ -57,6 +55,10 @@ static void gimp_channel_finalize (GObject *object); ...@@ -57,6 +55,10 @@ static void gimp_channel_finalize (GObject *object);
static gsize gimp_channel_get_memsize (GimpObject *object); static gsize gimp_channel_get_memsize (GimpObject *object);
static void gimp_channel_push_undo (GimpChannel *mask);
static void gimp_channel_validate (TileManager *tm,
Tile *tile);
static GimpDrawableClass * parent_class = NULL; static GimpDrawableClass * parent_class = NULL;
...@@ -164,6 +166,21 @@ gimp_channel_get_memsize (GimpObject *object) ...@@ -164,6 +166,21 @@ gimp_channel_get_memsize (GimpObject *object)
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object); return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object);
} }
static void
gimp_channel_push_undo (GimpChannel *mask)
{
GimpImage *gimage;
gimage = gimp_item_get_image (GIMP_ITEM (mask));
undo_push_mask (gimage, mask);
mask->boundary_known = FALSE;
/* invalidate the preview */
GIMP_DRAWABLE (mask)->preview_valid = FALSE;
}
static void static void
gimp_channel_validate (TileManager *tm, gimp_channel_validate (TileManager *tm,
Tile *tile) Tile *tile)
...@@ -173,6 +190,9 @@ gimp_channel_validate (TileManager *tm, ...@@ -173,6 +190,9 @@ gimp_channel_validate (TileManager *tm,
TRANSPARENT_OPACITY, tile_size (tile)); TRANSPARENT_OPACITY, tile_size (tile));
} }
/* public functions */
GimpChannel * GimpChannel *
gimp_channel_new (GimpImage *gimage, gimp_channel_new (GimpImage *gimage,
gint width, gint width,
...@@ -268,7 +288,7 @@ gimp_channel_get_opacity (const GimpChannel *channel) ...@@ -268,7 +288,7 @@ gimp_channel_get_opacity (const GimpChannel *channel)
return channel->color.a; return channel->color.a;
} }
void void
gimp_channel_set_opacity (GimpChannel *channel, gimp_channel_set_opacity (GimpChannel *channel,
gdouble opacity) gdouble opacity)
{ {
...@@ -279,6 +299,31 @@ gimp_channel_set_opacity (GimpChannel *channel, ...@@ -279,6 +299,31 @@ gimp_channel_set_opacity (GimpChannel *channel,
channel->color.a = opacity; channel->color.a = opacity;
} }
gboolean
gimp_channel_get_show_masked (GimpChannel *channel)
{
g_return_val_if_fail (GIMP_IS_CHANNEL (channel), FALSE);
return channel->show_masked;
}
void
gimp_channel_set_show_masked (GimpChannel *channel,
gboolean show_masked)
{
g_return_if_fail (GIMP_IS_CHANNEL (channel));
if (show_masked != channel->show_masked)
{
channel->show_masked = show_masked ? TRUE : FALSE;
gimp_drawable_update (GIMP_DRAWABLE (channel),
0, 0,
GIMP_DRAWABLE (channel)->width,
GIMP_DRAWABLE (channel)->height);
}
}
void void
gimp_channel_scale (GimpChannel *channel, gimp_channel_scale (GimpChannel *channel,
gint new_width, gint new_width,
...@@ -525,6 +570,7 @@ gimp_channel_boundary (GimpChannel *mask, ...@@ -525,6 +570,7 @@ gimp_channel_boundary (GimpChannel *mask,
mask->num_segs_in = 0; mask->num_segs_in = 0;
mask->num_segs_out = 0; mask->num_segs_out = 0;
} }
mask->boundary_known = TRUE; mask->boundary_known = TRUE;
} }
...@@ -674,6 +720,7 @@ gimp_channel_bounds (GimpChannel *mask, ...@@ -674,6 +720,7 @@ gimp_channel_bounds (GimpChannel *mask,
mask->x2 = tx2; mask->x2 = tx2;
mask->y2 = ty2; mask->y2 = ty2;
} }
mask->bounds_known = TRUE; mask->bounds_known = TRUE;
*x1 = tx1; *x1 = tx1;
...@@ -701,6 +748,7 @@ gimp_channel_is_empty (GimpChannel *mask) ...@@ -701,6 +748,7 @@ gimp_channel_is_empty (GimpChannel *mask)
0, 0, 0, 0,
GIMP_DRAWABLE (mask)->width, GIMP_DRAWABLE (mask)->width,
GIMP_DRAWABLE (mask)->height, FALSE); GIMP_DRAWABLE (mask)->height, FALSE);
for (pr = pixel_regions_register (1, &maskPR); for (pr = pixel_regions_register (1, &maskPR);
pr != NULL; pr != NULL;
pr = pixel_regions_process (pr)) pr = pixel_regions_process (pr))
...@@ -1207,15 +1255,16 @@ gimp_channel_feather (GimpChannel *mask, ...@@ -1207,15 +1255,16 @@ gimp_channel_feather (GimpChannel *mask,
} }
void void
gimp_channel_sharpen (GimpChannel *mask) gimp_channel_sharpen (GimpChannel *mask,
gboolean push_undo)
{ {
PixelRegion maskPR; PixelRegion maskPR;
GimpLut *lut; GimpLut *lut;
g_return_if_fail (GIMP_IS_CHANNEL (mask)); g_return_if_fail (GIMP_IS_CHANNEL (mask));
/* push the current channel onto the undo stack */ if (push_undo)
gimp_channel_push_undo (mask); gimp_channel_push_undo (mask);
pixel_region_init (&maskPR, GIMP_DRAWABLE (mask)->tiles, pixel_region_init (&maskPR, GIMP_DRAWABLE (mask)->tiles,
0, 0, 0, 0,
...@@ -1229,44 +1278,16 @@ gimp_channel_sharpen (GimpChannel *mask) ...@@ -1229,44 +1278,16 @@ gimp_channel_sharpen (GimpChannel *mask)
} }
void void
gimp_channel_push_undo (GimpChannel *mask) gimp_channel_clear (GimpChannel *mask,
{ gboolean push_undo)
gint x1, y1, x2, y2;
TileManager *undo_tiles;
PixelRegion srcPR, destPR;
GimpImage *gimage;
if (gimp_channel_bounds (mask, &x1, &y1, &x2, &y2))
{
undo_tiles = tile_manager_new ((x2 - x1), (y2 - y1), 1);
pixel_region_init (&srcPR, GIMP_DRAWABLE (mask)->tiles,
x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, undo_tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
copy_region (&srcPR, &destPR);
}
else
undo_tiles = NULL;
gimage = gimp_item_get_image (GIMP_ITEM (mask));
undo_push_image_mask (gimage, undo_tiles, x1, y1);
gimp_image_mask_invalidate (gimage);
/* invalidate the preview */
GIMP_DRAWABLE (mask)->preview_valid = FALSE;
}
void
gimp_channel_clear (GimpChannel *mask)
{ {
PixelRegion maskPR; PixelRegion maskPR;
guchar bg = 0; guchar bg = 0;
g_return_if_fail (GIMP_IS_CHANNEL (mask)); g_return_if_fail (GIMP_IS_CHANNEL (mask));
/* push the current channel onto the undo stack */ if (push_undo)
gimp_channel_push_undo (mask); gimp_channel_push_undo (mask);
if (mask->bounds_known && !mask->empty) if (mask->bounds_known && !mask->empty)
{ {
...@@ -1295,15 +1316,16 @@ gimp_channel_clear (GimpChannel *mask) ...@@ -1295,15 +1316,16 @@ gimp_channel_clear (GimpChannel *mask)
} }
void void
gimp_channel_all (GimpChannel *mask) gimp_channel_all (GimpChannel *mask,
gboolean push_undo)
{ {
PixelRegion maskPR; PixelRegion maskPR;
guchar bg = 255; guchar bg = 255;
g_return_if_fail (GIMP_IS_CHANNEL (mask)); g_return_if_fail (GIMP_IS_CHANNEL (mask));
/* push the current channel onto the undo stack */ if (push_undo)
gimp_channel_push_undo (mask); gimp_channel_push_undo (mask);
/* clear the mask */ /* clear the mask */
pixel_region_init (&maskPR, GIMP_DRAWABLE (mask)->tiles, pixel_region_init (&maskPR, GIMP_DRAWABLE (mask)->tiles,
...@@ -1325,32 +1347,41 @@ void ...@@ -1325,32 +1347,41 @@ void
gimp_channel_invert (GimpChannel *mask, gimp_channel_invert (GimpChannel *mask,
gboolean push_undo) gboolean push_undo)
{ {
PixelRegion maskPR;
GimpLut *lut;
g_return_if_fail (GIMP_IS_CHANNEL (mask)); g_return_if_fail (GIMP_IS_CHANNEL (mask));
if (push_undo) if (push_undo)
gimp_channel_push_undo (mask); gimp_channel_push_undo (mask);
pixel_region_init (&maskPR, GIMP_DRAWABLE (mask)->tiles, if (mask->bounds_known && mask->empty)
0, 0, {
GIMP_DRAWABLE (mask)->width, gimp_channel_all (mask, FALSE);
GIMP_DRAWABLE (mask)->height, TRUE); }
else
{
PixelRegion maskPR;
GimpLut *lut;
pixel_region_init (&maskPR, GIMP_DRAWABLE (mask)->tiles,
0, 0,
GIMP_DRAWABLE (mask)->width,
GIMP_DRAWABLE (mask)->height, TRUE);
lut = invert_lut_new (1); lut = invert_lut_new (1);
pixel_regions_process_parallel ((p_func) gimp_lut_process_inline, lut, pixel_regions_process_parallel ((p_func) gimp_lut_process_inline, lut,
1, &maskPR); 1, &maskPR);
gimp_lut_free (lut); gimp_lut_free (lut);
mask->bounds_known = FALSE;
mask->bounds_known = FALSE;
}
} }
void void
gimp_channel_border (GimpChannel *mask, gimp_channel_border (GimpChannel *mask,
gint radius_x, gint radius_x,
gint radius_y) gint radius_y,
gboolean push_undo)
{ {
PixelRegion bPR; PixelRegion bPR;
gint x1, y1, x2, y2; gint x1, y1, x2, y2;
...@@ -1362,6 +1393,7 @@ gimp_channel_border (GimpChannel *mask, ...@@ -1362,6 +1393,7 @@ gimp_channel_border (GimpChannel *mask,
if (! gimp_channel_bounds (mask, &x1, &y1, &x2, &y2)) if (! gimp_channel_bounds (mask, &x1, &y1, &x2, &y2))
return; return;
if (gimp_channel_is_empty (mask)) if (gimp_channel_is_empty (mask))
return; return;
...@@ -1383,8 +1415,8 @@ gimp_channel_border (GimpChannel *mask, ...@@ -1383,8 +1415,8 @@ gimp_channel_border (GimpChannel *mask,
else else
y2 += radius_y; y2 += radius_y;
/* push the current channel onto the undo stack */ if (push_undo)
gimp_channel_push_undo (mask); gimp_channel_push_undo (mask);
pixel_region_init (&bPR, GIMP_DRAWABLE (mask)->tiles, x1, y1, pixel_region_init (&bPR, GIMP_DRAWABLE (mask)->tiles, x1, y1,
(x2-x1), (y2-y1), TRUE); (x2-x1), (y2-y1), TRUE);
...@@ -1397,7 +1429,8 @@ gimp_channel_border (GimpChannel *mask, ...@@ -1397,7 +1429,8 @@ gimp_channel_border (GimpChannel *mask,
void void
gimp_channel_grow (GimpChannel *mask, gimp_channel_grow (GimpChannel *mask,
gint radius_x, gint radius_x,
gint radius_y) gint radius_y,
gboolean push_undo)
{ {
PixelRegion bPR; PixelRegion bPR;
gint x1, y1, x2, y2; gint x1, y1, x2, y2;
...@@ -1409,7 +1442,7 @@ gimp_channel_grow (GimpChannel *mask, ...@@ -1409,7 +1442,7 @@ gimp_channel_grow (GimpChannel *mask,
if (radius_x <= 0 && radius_y <= 0) if (radius_x <= 0 && radius_y <= 0)
{ {
gimp_channel_shrink (mask, -radius_x, -radius_y, FALSE); gimp_channel_shrink (mask, -radius_x, -radius_y, FALSE, push_undo);
return; return;
} }
...@@ -1418,6 +1451,7 @@ gimp_channel_grow (GimpChannel *mask, ...@@ -1418,6 +1451,7 @@ gimp_channel_grow (GimpChannel *mask,
if (! gimp_channel_bounds (mask, &x1, &y1, &x2, &y2)) if (! gimp_channel_bounds (mask, &x1, &y1, &x2, &y2))
return; return;
if (gimp_channel_is_empty (mask)) if (gimp_channel_is_empty (mask))
return; return;
...@@ -1438,8 +1472,8 @@ gimp_channel_grow (GimpChannel *mask, ...@@ -1438,8 +1472,8 @@ gimp_channel_grow (GimpChannel *mask,
else else
y2 = GIMP_DRAWABLE (mask)->height; y2 = GIMP_DRAWABLE (mask)->height;
/* push the current channel onto the undo stack */ if (push_undo)
gimp_channel_push_undo (mask); gimp_channel_push_undo (mask);
/* need full extents for grow, not! */ /* need full extents for grow, not! */
pixel_region_init (&bPR, GIMP_DRAWABLE (mask)->tiles, x1, y1, (x2 - x1), pixel_region_init (&bPR, GIMP_DRAWABLE (mask)->tiles, x1, y1, (x2 - x1),
...@@ -1454,7 +1488,8 @@ void ...@@ -1454,7 +1488,8 @@ void
gimp_channel_shrink (GimpChannel *mask, gimp_channel_shrink (GimpChannel *mask,
gint radius_x, gint radius_x,
gint radius_y, gint radius_y,
gboolean edge_lock) gboolean edge_lock,
gboolean push_undo)
{ {
PixelRegion bPR; PixelRegion bPR;
gint x1, y1, x2, y2; gint x1, y1, x2, y2;
...@@ -1466,7 +1501,7 @@ gimp_channel_shrink (GimpChannel *mask, ...@@ -1466,7 +1501,7 @@ gimp_channel_shrink (GimpChannel *mask,
if (radius_x <= 0 && radius_y <= 0) if (radius_x <= 0 && radius_y <= 0)
{ {
gimp_channel_grow (mask, -radius_x, -radius_y); gimp_channel_grow (mask, -radius_x, -radius_y, push_undo);
return; return;
} }
...@@ -1475,6 +1510,7 @@ gimp_channel_shrink (GimpChannel *mask, ...@@ -1475,6 +1510,7 @@ gimp_channel_shrink (GimpChannel *mask,
if (! gimp_channel_bounds (mask, &x1, &y1, &x2, &y2)) if (! gimp_channel_bounds (mask, &x1, &y1, &x2, &y2))
return; return;
if (gimp_channel_is_empty (mask)) if (gimp_channel_is_empty (mask))
return; return;
...@@ -1487,8 +1523,8 @@ gimp_channel_shrink (GimpChannel *mask, ...@@ -1487,8 +1523,8 @@ gimp_channel_shrink (GimpChannel *mask,
if (y2 < GIMP_DRAWABLE (mask)->height) if (y2 < GIMP_DRAWABLE (mask)->height)
y2++; y2++;
/* push the current channel onto the undo stack */ if (push_undo)
gimp_channel_push_undo (mask); gimp_channel_push_undo (mask);
pixel_region_init (&bPR, GIMP_DRAWABLE (mask)->tiles, x1, y1, (x2 - x1), pixel_region_init (&bPR, GIMP_DRAWABLE (mask)->tiles, x1, y1, (x2 - x1),
(y2 - y1), TRUE); (y2 - y1), TRUE);
...@@ -1501,7 +1537,8 @@ gimp_channel_shrink (GimpChannel *mask, ...@@ -1501,7 +1537,8 @@ gimp_channel_shrink (GimpChannel *mask,
void void
gimp_channel_translate (GimpChannel *mask, gimp_channel_translate (GimpChannel *mask,
gint off_x, gint off_x,
gint off_y) gint off_y,
gboolean push_undo)
{ {
gint width, height; gint width, height;
GimpChannel *tmp_mask; GimpChannel *tmp_mask;
...@@ -1513,8 +1550,8 @@ gimp_channel_translate (GimpChannel *mask, ...@@ -1513,8 +1550,8 @@ gimp_channel_translate (GimpChannel *mask,
tmp_mask = NULL; tmp_mask = NULL;
/* push the current channel onto the undo stack */ if (push_undo)
gimp_channel_push_undo (mask); gimp_channel_push_undo (mask);
gimp_channel_bounds (mask, &x1, &y1, &x2, &y2);