Commit 855b114f authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

Bye bye floating_sel_rigor() and floating_sel_relax():

2008-11-09  Michael Natterer  <mitch@gimp.org>

	Bye bye floating_sel_rigor() and floating_sel_relax():

	* app/core/gimpdrawable.[ch] (gimp_drawable_init_src_region):
	implement compositing the floating selection on the fly. Add
	return parameter "TileManager **temp_tiles" which returns the temp
	buffer used for compositing; the caller has to unref the tiles.

	* app/core/gimpchannel-project.c
	* app/core/gimplayer-project.c: unref the temp_tiles.

	* app/core/gimplayer.[ch]: remove members fs.backing_store and
	fs.initial.

	* app/core/gimplayer-floating-sel.[ch]: remove functions rigor(),
	relax(), store() and restore(), they are not needed any longer.
	Some minor cleanup, more to come.

	* app/core/gimpprojection-construct.c: don't composite the
	floating selection before projecting because that happens on the
	fly now.

	* app/core/core-enums.[ch]
	* app/core/gimpfloatingselundo.c
	* app/core/gimpimage-undo-push.[ch]: remove the rigor and relax
	undos.

	* app/core/gimpdrawable.c
	* app/core/gimpimage-convert.c
	* app/core/gimpimage-duplicate.c
	* app/core/gimpimage.c
	* app/core/gimplayer.c
	* app/xcf/xcf-save.c: remove all calls to rigor and relax and all
	implementations of virtual functions that were just there to
	rigor/releax around chaining up.

	* tools/pdbgen/pdb/floating_sel.pdb: remove all code from the
	rigor and relax wrappers and deprecate the API.

	* app/pdb/floating-sel-cmds.c
	* libgimp/gimpfloatingsel_pdb.[ch]: regenerated.

	* plug-ins/file-xjt/xjt.c: don't call rigor and relax.


svn path=/trunk/; revision=27579
parent b2379f44
2008-11-09 Michael Natterer <mitch@gimp.org>
Bye bye floating_sel_rigor() and floating_sel_relax():
* app/core/gimpdrawable.[ch] (gimp_drawable_init_src_region):
implement compositing the floating selection on the fly. Add
return parameter "TileManager **temp_tiles" which returns the temp
buffer used for compositing; the caller has to unref the tiles.
* app/core/gimpchannel-project.c
* app/core/gimplayer-project.c: unref the temp_tiles.
* app/core/gimplayer.[ch]: remove members fs.backing_store and
fs.initial.
* app/core/gimplayer-floating-sel.[ch]: remove functions rigor(),
relax(), store() and restore(), they are not needed any longer.
Some minor cleanup, more to come.
* app/core/gimpprojection-construct.c: don't composite the
floating selection before projecting because that happens on the
fly now.
* app/core/core-enums.[ch]
* app/core/gimpfloatingselundo.c
* app/core/gimpimage-undo-push.[ch]: remove the rigor and relax
undos.
* app/core/gimpdrawable.c
* app/core/gimpimage-convert.c
* app/core/gimpimage-duplicate.c
* app/core/gimpimage.c
* app/core/gimplayer.c
* app/xcf/xcf-save.c: remove all calls to rigor and relax and all
implementations of virtual functions that were just there to
rigor/releax around chaining up.
* tools/pdbgen/pdb/floating_sel.pdb: remove all code from the
rigor and relax wrappers and deprecate the API.
* app/pdb/floating-sel-cmds.c
* libgimp/gimpfloatingsel_pdb.[ch]: regenerated.
* plug-ins/file-xjt/xjt.c: don't call rigor and relax.
2008-11-09 Martin Nordholts <martinn@svn.gnome.org>
* app/widgets/gimpcursorview.[ch]: Don't expose implementation
......
......@@ -855,8 +855,6 @@ gimp_undo_type_get_type (void)
{ GIMP_UNDO_VECTORS_MOD, "GIMP_UNDO_VECTORS_MOD", "vectors-mod" },
{ GIMP_UNDO_VECTORS_REPOSITION, "GIMP_UNDO_VECTORS_REPOSITION", "vectors-reposition" },
{ GIMP_UNDO_FS_TO_LAYER, "GIMP_UNDO_FS_TO_LAYER", "fs-to-layer" },
{ GIMP_UNDO_FS_RIGOR, "GIMP_UNDO_FS_RIGOR", "fs-rigor" },
{ GIMP_UNDO_FS_RELAX, "GIMP_UNDO_FS_RELAX", "fs-relax" },
{ GIMP_UNDO_TRANSFORM, "GIMP_UNDO_TRANSFORM", "transform" },
{ GIMP_UNDO_PAINT, "GIMP_UNDO_PAINT", "paint" },
{ GIMP_UNDO_INK, "GIMP_UNDO_INK", "ink" },
......@@ -943,8 +941,6 @@ gimp_undo_type_get_type (void)
{ GIMP_UNDO_VECTORS_MOD, NC_("undo-type", "Path modification"), NULL },
{ GIMP_UNDO_VECTORS_REPOSITION, NC_("undo-type", "Reposition path"), NULL },
{ GIMP_UNDO_FS_TO_LAYER, NC_("undo-type", "Floating selection to layer"), NULL },
{ GIMP_UNDO_FS_RIGOR, NC_("undo-type", "Rigor floating selection"), NULL },
{ GIMP_UNDO_FS_RELAX, NC_("undo-type", "Relax floating selection"), NULL },
{ GIMP_UNDO_TRANSFORM, NC_("undo-type", "Transform"), NULL },
{ GIMP_UNDO_PAINT, NC_("undo-type", "Paint"), NULL },
{ GIMP_UNDO_INK, NC_("undo-type", "Ink"), NULL },
......
......@@ -437,8 +437,6 @@ typedef enum /*< pdb-skip >*/
GIMP_UNDO_VECTORS_MOD, /*< desc="Path modification" >*/
GIMP_UNDO_VECTORS_REPOSITION, /*< desc="Reposition path" >*/
GIMP_UNDO_FS_TO_LAYER, /*< desc="Floating selection to layer" >*/
GIMP_UNDO_FS_RIGOR, /*< desc="Rigor floating selection" >*/
GIMP_UNDO_FS_RELAX, /*< desc="Relax floating selection" >*/
GIMP_UNDO_TRANSFORM, /*< desc="Transform" >*/
GIMP_UNDO_PAINT, /*< desc="Paint" >*/
GIMP_UNDO_INK, /*< desc="Ink" >*/
......
......@@ -27,6 +27,7 @@
#include "core-types.h"
#include "base/pixel-region.h"
#include "base/tile-manager.h"
#include "paint-funcs/paint-funcs.h"
......@@ -45,6 +46,7 @@ gimp_channel_project_region (GimpDrawable *drawable,
{
GimpChannel *channel = GIMP_CHANNEL (drawable);
PixelRegion srcPR;
TileManager *temp_tiles;
guchar col[3];
guchar opacity;
......@@ -52,7 +54,8 @@ gimp_channel_project_region (GimpDrawable *drawable,
&col[0], &col[1], &col[2], &opacity);
gimp_drawable_init_src_region (drawable, &srcPR,
x, y, width, height);
x, y, width, height,
&temp_tiles);
if (combine)
{
......@@ -74,4 +77,7 @@ gimp_channel_project_region (GimpDrawable *drawable,
INITIAL_CHANNEL_MASK :
INITIAL_CHANNEL_SELECTION));
}
if (temp_tiles)
tile_manager_unref (temp_tiles);
}
......@@ -79,10 +79,6 @@ static void gimp_drawable_removed (GimpItem *item);
static void gimp_drawable_visibility_changed (GimpItem *item);
static GimpItem * gimp_drawable_duplicate (GimpItem *item,
GType new_type);
static void gimp_drawable_translate (GimpItem *item,
gint offset_x,
gint offset_y,
gboolean push_undo);
static void gimp_drawable_scale (GimpItem *item,
gint new_width,
gint new_height,
......@@ -207,7 +203,6 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
item_class->removed = gimp_drawable_removed;
item_class->visibility_changed = gimp_drawable_visibility_changed;
item_class->duplicate = gimp_drawable_duplicate;
item_class->translate = gimp_drawable_translate;
item_class->scale = gimp_drawable_scale;
item_class->resize = gimp_drawable_resize;
item_class->flip = gimp_drawable_flip;
......@@ -410,25 +405,6 @@ gimp_drawable_duplicate (GimpItem *item,
return new_item;
}
static void
gimp_drawable_translate (GimpItem *item,
gint offset_x,
gint offset_y,
gboolean push_undo)
{
GimpDrawable *drawable = GIMP_DRAWABLE (item);
GimpImage *image = gimp_item_get_image (item);
if (gimp_drawable_has_floating_sel (drawable))
floating_sel_relax (gimp_image_floating_sel (image), FALSE);
GIMP_ITEM_CLASS (parent_class)->translate (item, offset_x, offset_y,
push_undo);
if (gimp_drawable_has_floating_sel (drawable))
floating_sel_rigor (gimp_image_floating_sel (image), FALSE);
}
static void
gimp_drawable_scale (GimpItem *item,
gint new_width,
......@@ -1059,32 +1035,111 @@ gimp_drawable_project_region (GimpDrawable *drawable,
}
void
gimp_drawable_init_src_region (GimpDrawable *drawable,
PixelRegion *srcPR,
gint x,
gint y,
gint width,
gint height)
gimp_drawable_init_src_region (GimpDrawable *drawable,
PixelRegion *srcPR,
gint x,
gint y,
gint width,
gint height,
TileManager **temp_tiles)
{
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
g_return_if_fail (srcPR != NULL);
g_return_if_fail (temp_tiles != NULL);
if (gimp_drawable_has_floating_sel (drawable))
{
/* FIXME: return the composite of the layer and the floating
* selection.
*/
pixel_region_init (srcPR, gimp_drawable_get_tiles (drawable),
x, y, width, height,
FALSE);
}
else
{
pixel_region_init (srcPR, gimp_drawable_get_tiles (drawable),
x, y, width, height,
FALSE);
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
GimpLayer *fs = gimp_image_floating_sel (image);
gint off_x, off_y;
gint fs_off_x, fs_off_y;
gint combine_x, combine_y;
gint combine_width, combine_height;
gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
gimp_item_get_offset (GIMP_ITEM (fs), &fs_off_x, &fs_off_y);
if (gimp_item_get_visible (GIMP_ITEM (fs)) &&
gimp_rectangle_intersect (x + off_x, y + off_y,
width, height,
fs_off_x, fs_off_y,
gimp_item_get_width (GIMP_ITEM (fs)),
gimp_item_get_height (GIMP_ITEM (fs)),
&combine_x, &combine_y,
&combine_width, &combine_height))
{
PixelRegion tempPR;
PixelRegion destPR;
PixelRegion fsPR;
gboolean lock_alpha = FALSE;
/* a temporary buffer for the compisition of the drawable and
* its floating selection
*/
*temp_tiles = tile_manager_new (width, height,
gimp_drawable_bytes (drawable));
/* first, initialize the entire buffer with the drawable's
* contents
*/
pixel_region_init (&tempPR, gimp_drawable_get_tiles (drawable),
x, y, width, height,
FALSE);
pixel_region_init (&destPR, *temp_tiles,
0, 0, width, height,
TRUE);
copy_region (&tempPR, &destPR);
/* then, apply the floating selection onto the buffer just as
* we apply it onto the drawable when anchoring the floating
* selection
*/
pixel_region_init (&fsPR,
gimp_drawable_get_tiles (GIMP_DRAWABLE (fs)),
combine_x - fs_off_x,
combine_y - fs_off_y,
combine_width, combine_height,
FALSE);
pixel_region_init (&destPR, *temp_tiles,
combine_x - x - off_x, combine_y - y - off_y,
combine_width, combine_height,
TRUE);
if (GIMP_IS_LAYER (drawable))
{
lock_alpha = gimp_layer_get_lock_alpha (GIMP_LAYER (drawable));
if (lock_alpha)
gimp_layer_set_lock_alpha (GIMP_LAYER (drawable), FALSE, FALSE);
}
gimp_drawable_apply_region (drawable, &fsPR,
FALSE, NULL,
gimp_layer_get_opacity (fs),
gimp_layer_get_mode (fs),
NULL, &destPR,
combine_x - off_y,
combine_y - off_y);
if (lock_alpha)
gimp_layer_set_lock_alpha (GIMP_LAYER (drawable), TRUE, FALSE);
/* finally, return a PixelRegion on the composited buffer instead
* of the drawable's tiles
*/
pixel_region_init (srcPR, *temp_tiles,
0, 0, width, height,
FALSE);
return;
}
}
pixel_region_init (srcPR, gimp_drawable_get_tiles (drawable),
x, y, width, height,
FALSE);
*temp_tiles = NULL;
}
TileManager *
......@@ -1149,17 +1204,11 @@ gimp_drawable_set_tiles_full (GimpDrawable *drawable,
gimp_item_get_height (item));
}
if (gimp_drawable_has_floating_sel (drawable))
floating_sel_relax (gimp_image_floating_sel (image), FALSE);
GIMP_DRAWABLE_GET_CLASS (drawable)->set_tiles (drawable,
push_undo, undo_desc,
tiles, type,
offset_x, offset_y);
if (gimp_drawable_has_floating_sel (drawable))
floating_sel_rigor (gimp_image_floating_sel (image), FALSE);
gimp_drawable_update (drawable,
0, 0,
gimp_item_get_width (item),
......
......@@ -179,7 +179,8 @@ void gimp_drawable_init_src_region (GimpDrawable *drawable,
gint x,
gint y,
gint width,
gint height);
gint height,
TileManager **temp_tiles);
TileManager * gimp_drawable_get_tiles (GimpDrawable *drawable);
void gimp_drawable_set_tiles (GimpDrawable *drawable,
......
......@@ -37,8 +37,6 @@ static GObject * gimp_floating_sel_undo_constructor (GType type
static void gimp_floating_sel_undo_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void gimp_floating_sel_undo_free (GimpUndo *undo,
GimpUndoMode undo_mode);
G_DEFINE_TYPE (GimpFloatingSelUndo, gimp_floating_sel_undo, GIMP_TYPE_ITEM_UNDO)
......@@ -55,7 +53,6 @@ gimp_floating_sel_undo_class_init (GimpFloatingSelUndoClass *klass)
object_class->constructor = gimp_floating_sel_undo_constructor;
undo_class->pop = gimp_floating_sel_undo_pop;
undo_class->free = gimp_floating_sel_undo_free;
}
static void
......@@ -82,10 +79,6 @@ gimp_floating_sel_undo_constructor (GType type,
switch (GIMP_UNDO (object)->undo_type)
{
case GIMP_UNDO_FS_RIGOR:
case GIMP_UNDO_FS_RELAX:
break;
case GIMP_UNDO_FS_TO_LAYER:
floating_sel_undo->drawable = layer->fs.drawable;
break;
......@@ -109,24 +102,6 @@ gimp_floating_sel_undo_pop (GimpUndo *undo,
switch (undo->undo_type)
{
case GIMP_UNDO_FS_RIGOR:
case GIMP_UNDO_FS_RELAX:
if (! gimp_layer_is_floating_sel (floating_layer))
return;
if ((undo_mode == GIMP_UNDO_MODE_UNDO &&
undo->undo_type == GIMP_UNDO_FS_RIGOR) ||
(undo_mode == GIMP_UNDO_MODE_REDO &&
undo->undo_type == GIMP_UNDO_FS_RELAX))
{
floating_sel_relax (floating_layer, FALSE);
}
else
{
floating_sel_rigor (floating_layer, FALSE);
}
break;
case GIMP_UNDO_FS_TO_LAYER:
if (undo_mode == GIMP_UNDO_MODE_UNDO)
{
......@@ -137,26 +112,11 @@ gimp_floating_sel_undo_pop (GimpUndo *undo,
gimp_image_set_active_layer (undo->image, floating_layer);
undo->image->floating_sel = floating_layer;
/* store the contents of the drawable */
floating_sel_store (floating_layer,
GIMP_ITEM (floating_layer)->offset_x,
GIMP_ITEM (floating_layer)->offset_y,
gimp_item_get_width (GIMP_ITEM (floating_layer)),
gimp_item_get_height (GIMP_ITEM (floating_layer)));
floating_layer->fs.initial = TRUE;
/* clear the selection */
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (floating_layer));
}
else
{
/* restore the contents of the drawable */
floating_sel_restore (floating_layer,
GIMP_ITEM (floating_layer)->offset_x,
GIMP_ITEM (floating_layer)->offset_y,
gimp_item_get_width (GIMP_ITEM (floating_layer)),
gimp_item_get_height (GIMP_ITEM (floating_layer)));
/* Update the preview for the underlying drawable */
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (floating_layer));
......@@ -182,19 +142,3 @@ gimp_floating_sel_undo_pop (GimpUndo *undo,
g_assert_not_reached ();
}
}
static void
gimp_floating_sel_undo_free (GimpUndo *undo,
GimpUndoMode undo_mode)
{
GimpLayer *floating_layer = GIMP_LAYER (GIMP_ITEM_UNDO (undo)->item);
if (undo->undo_type == GIMP_UNDO_FS_TO_LAYER &&
undo_mode == GIMP_UNDO_MODE_UNDO)
{
tile_manager_unref (floating_layer->fs.backing_store);
floating_layer->fs.backing_store = NULL;
}
GIMP_UNDO_CLASS (parent_class)->free (undo, undo_mode);
}
......@@ -820,9 +820,6 @@ gimp_image_convert (GimpImage *image,
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_CONVERT,
undo_desc);
if (gimp_image_floating_sel (image))
floating_sel_relax (gimp_image_floating_sel (image), TRUE);
/* Push the image type to the stack */
gimp_image_undo_push_image_type (image, NULL);
......@@ -1070,9 +1067,6 @@ gimp_image_convert (GimpImage *image,
if (quantobj)
quantobj->delete_func (quantobj);
if (gimp_image_floating_sel (image))
floating_sel_rigor (gimp_image_floating_sel (image), TRUE);
gimp_image_undo_group_end (image);
gimp_image_mode_changed (image);
......
......@@ -97,8 +97,6 @@ gimp_image_duplicate (GimpImage *image)
floating_layer = gimp_image_floating_sel (image);
if (floating_layer)
{
floating_sel_relax (floating_layer, FALSE);
floating_sel_drawable = floating_layer->fs.drawable;
floating_layer = NULL;
}
......
......@@ -807,45 +807,9 @@ gimp_image_undo_push_fs_to_layer (GimpImage *image,
"item", floating_layer,
NULL);
if (! undo)
{
tile_manager_unref (floating_layer->fs.backing_store);
floating_layer->fs.backing_store = NULL;
}
return undo;
}
GimpUndo *
gimp_image_undo_push_fs_rigor (GimpImage *image,
const gchar *undo_desc,
GimpLayer *floating_layer)
{
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_LAYER (floating_layer), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_FLOATING_SEL_UNDO,
GIMP_UNDO_FS_RIGOR, undo_desc,
GIMP_DIRTY_NONE,
"item", floating_layer,
NULL);
}
GimpUndo *
gimp_image_undo_push_fs_relax (GimpImage *image,
const gchar *undo_desc,
GimpLayer *floating_layer)
{
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_LAYER (floating_layer), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_FLOATING_SEL_UNDO,
GIMP_UNDO_FS_RELAX, undo_desc,
GIMP_DIRTY_NONE,
"item", floating_layer,
NULL);
}
/******************************************************************************/
/* Something for which programmer is too lazy to write an undo function for */
......
......@@ -200,12 +200,6 @@ GimpUndo * gimp_image_undo_push_vectors_reposition (GimpImage *image,
GimpUndo * gimp_image_undo_push_fs_to_layer (GimpImage *image,
const gchar *undo_desc,
GimpLayer *floating_layer);
GimpUndo * gimp_image_undo_push_fs_rigor (GimpImage *image,
const gchar *undo_desc,
GimpLayer *floating_layer);
GimpUndo * gimp_image_undo_push_fs_relax (GimpImage *image,
const gchar *undo_desc,
GimpLayer *floating_layer);
/* EEK undo */
......
......@@ -1665,19 +1665,13 @@ gimp_image_set_component_active (GimpImage *image,
{
GimpLayer *floating_sel = gimp_image_floating_sel (image);
if (floating_sel)
floating_sel_relax (floating_sel, FALSE);
image->active[index] = active ? TRUE : FALSE;
if (floating_sel)
{
floating_sel_rigor (floating_sel, FALSE);
gimp_drawable_update (GIMP_DRAWABLE (floating_sel),
0, 0,
gimp_item_get_width (GIMP_ITEM (floating_sel)),
gimp_item_get_height (GIMP_ITEM (floating_sel)));
}
gimp_drawable_update (GIMP_DRAWABLE (floating_sel),
0, 0,
gimp_item_get_width (GIMP_ITEM (floating_sel)),
gimp_item_get_height (GIMP_ITEM (floating_sel)));
/* If there is an active channel and we mess with the components,
* the active channel gets unset...
......
......@@ -73,16 +73,10 @@ floating_sel_attach (GimpLayer *layer,
/* set the drawable and allocate a backing store */
gimp_layer_set_lock_alpha (layer, TRUE, FALSE);
layer->fs.drawable = drawable;
layer->fs.backing_store = tile_manager_new (gimp_item_get_width (GIMP_ITEM (layer)),
gimp_item_get_height (GIMP_ITEM (layer)),
gimp_drawable_bytes (drawable));
layer->fs.drawable = drawable;
/* add the layer to the image */
gimp_image_add_layer (image, layer, 0, TRUE);
/* store the affected area from the drawable in the backing store */
floating_sel_rigor (layer, TRUE);
}
void
......@@ -98,9 +92,6 @@ floating_sel_remove (GimpLayer *layer)
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_FS_REMOVE,
_("Remove Floating Selection"));
/* restore the affected area in the drawable from the backing store */
floating_sel_relax (layer, TRUE);
/* Invalidate the preview of the obscured drawable. We do this here
* because it will not be done until the floating selection is removed,
* at which point the obscured drawable's preview will not be declared
......@@ -134,9 +125,6 @@ floating_sel_anchor (GimpLayer *layer)
*/
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (layer->fs.drawable));
/* Relax the floating selection */
floating_sel_relax (layer, TRUE);
/* Composite the floating selection contents */
floating_sel_composite (layer,
GIMP_ITEM (layer)->offset_x,
......@@ -211,20 +199,13 @@ floating_sel_to_layer (GimpLayer *layer,
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_FS_TO_LAYER,
_("Floating Selection to Layer"));
/* restore the contents of the drawable */
floating_sel_restore (layer,
item->offset_x,
item->offset_y,
gimp_item_get_width (item),
gimp_item_get_height (item));
gimp_image_undo_push_fs_to_layer (image, NULL, layer);
/* clear the selection */
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
/* Set pointers */
layer->fs.drawable = NULL;
layer->fs.drawable = NULL;
image->floating_sel = NULL;
gimp_item_set_visible (item, TRUE, TRUE);
......@@ -244,162 +225,6 @@ floating_sel_to_layer (GimpLayer *layer,
return TRUE;
}
void
floating_sel_store (GimpLayer *layer,
gint x,
gint y,
gint w,
gint h)
{
PixelRegion srcPR, destPR;
gint offx, offy;
gint x1, y1, x2, y2;
g_return_if_fail (GIMP_IS_LAYER (layer));
g_return_if_fail (gimp_layer_is_floating_sel (layer));
/* Check the backing store & make sure it has the correct dimensions */
if ((tile_manager_width (layer->fs.backing_store) !=
gimp_item_get_width (GIMP_ITEM(layer))) ||
(tile_manager_height (layer->fs.backing_store) !=
gimp_item_get_height (GIMP_ITEM(layer))) ||
(tile_manager_bpp (layer->fs.backing_store) !=
gimp_drawable_bytes (layer->fs.drawable)))
{
/* free the backing store and allocate anew */
tile_manager_unref (layer->fs.backing_store);
layer->fs.backing_store =
tile_manager_new (gimp_item_get_width (GIMP_ITEM (layer)),
gimp_item_get_height (GIMP_ITEM (layer)),
gimp_drawable_bytes (layer->fs.drawable));
}
/* What this function does is save the specified area of the
* drawable that this floating selection obscures. We do this so
* that it will be possible to subsequently restore the drawable's area
*/
gimp_item_get_offset (GIMP_ITEM (layer->fs.drawable), &offx, &offy);
/* Find the minimum area we need to uncover -- in image space */
x1 = MAX (GIMP_ITEM (layer)->offset_x, offx);
y1 = MAX (GIMP_ITEM (layer)->offset_y, offy);
x2 = MIN (GIMP_ITEM (layer)->offset_x + gimp_item_get_width (GIMP_ITEM (layer)),
offx + gimp_item_get_width (GIMP_ITEM (layer->fs.drawable)));
y2 = MIN (GIMP_ITEM (layer)->offset_y + gimp_item_get_height (GIMP_ITEM (layer)),
offy + gimp_item_get_height (GIMP_ITEM (layer->fs.drawable)));
x1 = CLAMP (x, x1, x2);
y1 = CLAMP (y, y1, y2);
x2 = CLAMP (x + w, x1, x2);
y2 = CLAMP (y + h, y1, y2);
if ((x2 - x1) > 0 && (y2 - y1) > 0)
{
/* Copy the area from the drawable to the backing store */
pixel_region_init (&srcPR, gimp_drawable_get_tiles (layer->fs.drawable),
(x1 - offx), (y1 - offy), (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, layer->fs.backing_store,
(x1 - GIMP_ITEM (layer)->offset_x),
(y1 - GIMP_ITEM (layer)->offset_y),
(x2 - x1), (y2 - y1), TRUE);
copy_region (&srcPR, &destPR);
}
}
void
floating_sel_restore (GimpLayer *layer,
gint x,
gint y,
gint w,
gint h)
{
PixelRegion srcPR, destPR;
gint offx, offy;
gint x1, y1, x2, y2;
g_return_if_fail (GIMP_IS_LAYER (layer));
g_return_if_fail (gimp_layer_is_floating_sel (layer));
/* What this function does is "uncover" the specified area in the
* drawable that this floating selection obscures. We do this so
* that either the floating selection can be removed or it can be
* translated
*/
/* Find the minimum area we need to uncover -- in image space */
gimp_item_get_offset (GIMP_ITEM (layer->fs.drawable), &offx, &offy);
x1 = MAX (GIMP_ITEM (layer)->offset_x, offx);
y1 = MAX (GIMP_ITEM (layer)->offset_y, offy);
x2 = MIN (GIMP_ITEM (layer)->offset_x + gimp_item_get_width (GIMP_ITEM (layer)),
offx + gimp_item_get_width (GIMP_ITEM (layer->fs.drawable)));
y2 = MIN (GIMP_ITEM (layer)->offset_y + gimp_item_get_height (GIMP_ITEM (layer)),