Move the shadow tiles from the image to the drawable. Fixes bug #100469.

2008-04-21  Michael Natterer  <mitch@gimp.org>

	Move the shadow tiles from the image to the drawable.
	Fixes bug #100469.

	* app/core/Makefile.am
	* app/core/gimpdrawable-shadow.[ch]: new files implementing
	the shadow tiles.

	* app/core/gimpimage.[ch]: remove the shadow tile manager from the
	GimpImage struct. Remove gimp_image_get_shadow_tiles() and
	_free_shadow_tiles().

	* app/core/gimpdrawable.[ch]: add the shadow tile manager
	here. Remove get_shadow_tiles() and merge_shadow(). Free the
	shadow tiles in finalize and when the drawable gets removed from
	the image.

	* app/core/gimpdrawable-brightness-contrast.c
	* app/core/gimpdrawable-color-balance.c
	* app/core/gimpdrawable-colorize.c
	* app/core/gimpdrawable-curves.c
	* app/core/gimpdrawable-desaturate.c
	* app/core/gimpdrawable-equalize.c
	* app/core/gimpdrawable-hue-saturation.c
	* app/core/gimpdrawable-invert.c
	* app/core/gimpdrawable-levels.c
	* app/core/gimpdrawable-operation.c
	* app/core/gimpdrawable-posterize.c
	* app/core/gimpdrawable-threshold.c
	* app/core/gimpimagemap.c: changed accordingly. Free the shadow tiles
	after using them.

	* app/plug-in/gimpplugin-cleanup.[ch]: add
	gimp_plug_in_cleanup_add_shadow() and _remove_shadow() which keep
	track of whether shadow tiles were created on behalf of a plug-in
	procedure.

	(gimp_plug_in_cleanup): free shadow tiles which were created but
	not destroyed by a plug-in procedure.

	* app/plug-in/gimpplugin-message.c (plug_in_handle_tile_request):
	call gimp_plug_in_cleanup_add_shadow() whenever a plug-in requests
	shadow tiles.

	* tools/pdbgen/pdb/drawable.pdb: use the new drawable shadow
	API. Add new procedure gimp-drawable-free-shadow. Call
	gimp_plug_in_cleaup_remove_shadow() when it gets called.

	* tools/pdbgen/pdb/image.pdb: deprecate gimp-image-free-shadow.
	Calling it has no effect any longer.

	* app/pdb/drawable-cmds.c
	* app/pdb/image-cmds.c
	* app/pdb/internal-procs.c
	* libgimp/gimpimage_pdb.[ch]
	* libgimp/gimpdrawable_pdb.[ch]: regenerated.


svn path=/trunk/; revision=25510
This commit is contained in:
Michael Natterer 2008-04-21 17:20:51 +00:00 committed by Michael Natterer
parent fb80396583
commit e5be5664ed
33 changed files with 504 additions and 179 deletions

View File

@ -1,3 +1,61 @@
2008-04-21 Michael Natterer <mitch@gimp.org>
Move the shadow tiles from the image to the drawable.
Fixes bug #100469.
* app/core/Makefile.am
* app/core/gimpdrawable-shadow.[ch]: new files implementing
the shadow tiles.
* app/core/gimpimage.[ch]: remove the shadow tile manager from the
GimpImage struct. Remove gimp_image_get_shadow_tiles() and
_free_shadow_tiles().
* app/core/gimpdrawable.[ch]: add the shadow tile manager
here. Remove get_shadow_tiles() and merge_shadow(). Free the
shadow tiles in finalize and when the drawable gets removed from
the image.
* app/core/gimpdrawable-brightness-contrast.c
* app/core/gimpdrawable-color-balance.c
* app/core/gimpdrawable-colorize.c
* app/core/gimpdrawable-curves.c
* app/core/gimpdrawable-desaturate.c
* app/core/gimpdrawable-equalize.c
* app/core/gimpdrawable-hue-saturation.c
* app/core/gimpdrawable-invert.c
* app/core/gimpdrawable-levels.c
* app/core/gimpdrawable-operation.c
* app/core/gimpdrawable-posterize.c
* app/core/gimpdrawable-threshold.c
* app/core/gimpimagemap.c: changed accordingly. Free the shadow tiles
after using them.
* app/plug-in/gimpplugin-cleanup.[ch]: add
gimp_plug_in_cleanup_add_shadow() and _remove_shadow() which keep
track of whether shadow tiles were created on behalf of a plug-in
procedure.
(gimp_plug_in_cleanup): free shadow tiles which were created but
not destroyed by a plug-in procedure.
* app/plug-in/gimpplugin-message.c (plug_in_handle_tile_request):
call gimp_plug_in_cleanup_add_shadow() whenever a plug-in requests
shadow tiles.
* tools/pdbgen/pdb/drawable.pdb: use the new drawable shadow
API. Add new procedure gimp-drawable-free-shadow. Call
gimp_plug_in_cleaup_remove_shadow() when it gets called.
* tools/pdbgen/pdb/image.pdb: deprecate gimp-image-free-shadow.
Calling it has no effect any longer.
* app/pdb/drawable-cmds.c
* app/pdb/image-cmds.c
* app/pdb/internal-procs.c
* libgimp/gimpimage_pdb.[ch]
* libgimp/gimpdrawable_pdb.[ch]: regenerated.
2008-04-21 Sven Neumann <sven@gimp.org>
* plug-ins/common/psp.c: applied patch from Christoph Brill which

View File

@ -143,6 +143,8 @@ libappcore_a_sources = \
gimpdrawable-posterize.h \
gimpdrawable-preview.c \
gimpdrawable-preview.h \
gimpdrawable-shadow.c \
gimpdrawable-shadow.h \
gimpdrawable-stroke.c \
gimpdrawable-stroke.h \
gimpdrawable-threshold.c \

View File

@ -36,6 +36,7 @@
#include "gimpdrawable.h"
#include "gimpdrawable-brightness-contrast.h"
#include "gimpdrawable-operation.h"
#include "gimpdrawable-shadow.h"
#include "gimp-intl.h"
@ -98,8 +99,10 @@ gimp_drawable_brightness_contrast (GimpDrawable *drawable,
gimp_lut_free (lut);
gimp_drawable_merge_shadow (drawable, TRUE,
_("Brightness-Contrast"));
gimp_drawable_merge_shadow_tiles (drawable, TRUE,
_("Brightness-Contrast"));
gimp_drawable_free_shadow_tiles (drawable);
gimp_drawable_update (drawable, x, y, width, height);
}
}

View File

@ -35,6 +35,7 @@
#include "gimpdrawable.h"
#include "gimpdrawable-color-balance.h"
#include "gimpdrawable-operation.h"
#include "gimpdrawable-shadow.h"
#include "gimp-intl.h"
@ -103,7 +104,9 @@ gimp_drawable_color_balance (GimpDrawable *drawable,
pixel_regions_process_parallel ((PixelProcessorFunc) color_balance,
&cruft, 2, &srcPR, &destPR);
gimp_drawable_merge_shadow (drawable, TRUE, _("Color Balance"));
gimp_drawable_merge_shadow_tiles (drawable, TRUE, _("Color Balance"));
gimp_drawable_free_shadow_tiles (drawable);
gimp_drawable_update (drawable, x, y, width, height);
}
}

View File

@ -35,6 +35,7 @@
#include "gimpdrawable.h"
#include "gimpdrawable-operation.h"
#include "gimpdrawable-colorize.h"
#include "gimpdrawable-shadow.h"
#include "gimp-intl.h"
@ -96,7 +97,9 @@ gimp_drawable_colorize (GimpDrawable *drawable,
pixel_regions_process_parallel ((PixelProcessorFunc) colorize,
&cruft, 2, &srcPR, &destPR);
gimp_drawable_merge_shadow (drawable, TRUE, _("Colorize"));
gimp_drawable_merge_shadow_tiles (drawable, TRUE, _("Colorize"));
gimp_drawable_free_shadow_tiles (drawable);
gimp_drawable_update (drawable, x, y, width, height);
}
}

View File

@ -37,6 +37,7 @@
#include "gimpdrawable.h"
#include "gimpdrawable-curves.h"
#include "gimpdrawable-operation.h"
#include "gimpdrawable-shadow.h"
#include "gimp-intl.h"
@ -200,7 +201,9 @@ gimp_drawable_curves (GimpDrawable *drawable,
gimp_lut_free (lut);
gimp_drawable_merge_shadow (drawable, TRUE, _("Curves"));
gimp_drawable_merge_shadow_tiles (drawable, TRUE, _("Curves"));
gimp_drawable_free_shadow_tiles (drawable);
gimp_drawable_update (drawable, x, y, width, height);
}
}

View File

@ -34,6 +34,7 @@
#include "gimpdrawable.h"
#include "gimpdrawable-desaturate.h"
#include "gimpdrawable-operation.h"
#include "gimpdrawable-shadow.h"
#include "gimp-intl.h"
@ -117,7 +118,8 @@ gimp_drawable_desaturate (GimpDrawable *drawable,
pixel_regions_process_parallel (function, GINT_TO_POINTER (has_alpha),
2, &srcPR, &destPR);
gimp_drawable_merge_shadow (drawable, TRUE, _("Desaturate"));
gimp_drawable_merge_shadow_tiles (drawable, TRUE, _("Desaturate"));
gimp_drawable_free_shadow_tiles (drawable);
gimp_drawable_update (drawable, x, y, width, height);
}

View File

@ -32,6 +32,7 @@
#include "gimpdrawable.h"
#include "gimpdrawable-equalize.h"
#include "gimpdrawable-histogram.h"
#include "gimpdrawable-shadow.h"
#include "gimpimage.h"
#include "gimp-intl.h"
@ -74,7 +75,8 @@ gimp_drawable_equalize (GimpDrawable *drawable,
gimp_lut_free (lut);
gimp_histogram_unref (hist);
gimp_drawable_merge_shadow (drawable, TRUE, _("Equalize"));
gimp_drawable_merge_shadow_tiles (drawable, TRUE, _("Equalize"));
gimp_drawable_free_shadow_tiles (drawable);
gimp_drawable_update (drawable, x, y, width, height);
}

View File

@ -33,8 +33,9 @@
#include "gimpimage.h"
#include "gimpdrawable.h"
#include "gimpdrawable-operation.h"
#include "gimpdrawable-hue-saturation.h"
#include "gimpdrawable-operation.h"
#include "gimpdrawable-shadow.h"
#include "gimp-intl.h"
@ -101,7 +102,10 @@ gimp_drawable_hue_saturation (GimpDrawable *drawable,
pixel_regions_process_parallel ((PixelProcessorFunc) hue_saturation,
&cruft, 2, &srcPR, &destPR);
gimp_drawable_merge_shadow (drawable, TRUE, _("Hue_Saturation"));
gimp_drawable_merge_shadow_tiles (drawable, TRUE,
_("Hue_Saturation"));
gimp_drawable_free_shadow_tiles (drawable);
gimp_drawable_update (drawable, x, y, width, height);
}
}

View File

@ -34,6 +34,7 @@
#include "gimpdrawable.h"
#include "gimpdrawable-invert.h"
#include "gimpdrawable-operation.h"
#include "gimpdrawable-shadow.h"
#include "gimpprogress.h"
#include "gimp-intl.h"
@ -81,7 +82,8 @@ gimp_drawable_invert (GimpDrawable *drawable,
gimp_lut_free (lut);
gimp_drawable_merge_shadow (drawable, TRUE, _("Invert"));
gimp_drawable_merge_shadow_tiles (drawable, TRUE, _("Invert"));
gimp_drawable_free_shadow_tiles (drawable);
gimp_drawable_update (drawable, x, y, width, height);
}

View File

@ -38,6 +38,7 @@
#include "gimpdrawable-histogram.h"
#include "gimpdrawable-levels.h"
#include "gimpdrawable-operation.h"
#include "gimpdrawable-shadow.h"
#include "gimp-intl.h"
@ -184,7 +185,8 @@ gimp_drawable_levels_internal (GimpDrawable *drawable,
gimp_lut_free (lut);
gimp_drawable_merge_shadow (drawable, TRUE, _("Levels"));
gimp_drawable_merge_shadow_tiles (drawable, TRUE, _("Levels"));
gimp_drawable_free_shadow_tiles (drawable);
gimp_drawable_update (drawable, x, y, width, height);
}

View File

@ -29,6 +29,7 @@
#include "gimpdrawable.h"
#include "gimpdrawable-operation.h"
#include "gimpdrawable-shadow.h"
#include "gimpprogress.h"
#ifdef __GNUC__
@ -75,10 +76,6 @@ gimp_drawable_apply_operation (GimpDrawable *drawable,
"linear", linear,
NULL);
#ifdef __GNUC__
#warning FIXME: gegl_node_add_child() is not public API
#endif
gegl_node_add_child (gegl, operation);
gegl_node_link_many (input, operation, output, NULL);
@ -94,7 +91,9 @@ gimp_drawable_apply_operation (GimpDrawable *drawable,
g_object_unref (processor);
gimp_drawable_merge_shadow (drawable, TRUE, undo_desc);
gimp_drawable_merge_shadow_tiles (drawable, TRUE, undo_desc);
gimp_drawable_free_shadow_tiles (drawable);
gimp_drawable_update (drawable, rect.x, rect.y, rect.width, rect.height);
if (progress)

View File

@ -36,6 +36,7 @@
#include "gimpdrawable.h"
#include "gimpdrawable-operation.h"
#include "gimpdrawable-posterize.h"
#include "gimpdrawable-shadow.h"
#include "gimp-intl.h"
@ -96,7 +97,9 @@ gimp_drawable_posterize (GimpDrawable *drawable,
gimp_lut_free (lut);
gimp_drawable_merge_shadow (drawable, TRUE, _("Posterize"));
gimp_drawable_merge_shadow_tiles (drawable, TRUE, _("Posterize"));
gimp_drawable_free_shadow_tiles (drawable);
gimp_drawable_update (drawable, x, y, width, height);
}
}

View File

@ -0,0 +1,104 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <glib-object.h>
#include "core-types.h"
#include "base/pixel-region.h"
#include "base/tile-manager.h"
#include "gimpdrawable.h"
#include "gimpdrawable-shadow.h"
#include "gimpimage.h"
TileManager *
gimp_drawable_get_shadow_tiles (GimpDrawable *drawable)
{
GimpItem *item;
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
item = GIMP_ITEM (drawable);
g_return_val_if_fail (gimp_item_is_attached (item), NULL);
if (drawable->shadow)
{
if ((gimp_item_width (item) != tile_manager_width (drawable->shadow)) ||
(gimp_item_height (item) != tile_manager_height (drawable->shadow)) ||
(drawable->bytes != tile_manager_bpp (drawable->shadow)))
{
gimp_drawable_free_shadow_tiles (drawable);
}
else
{
return drawable->shadow;
}
}
drawable->shadow = tile_manager_new (gimp_item_width (item),
gimp_item_height (item),
drawable->bytes);
return drawable->shadow;
}
void
gimp_drawable_free_shadow_tiles (GimpDrawable *drawable)
{
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
if (drawable->shadow)
{
tile_manager_unref (drawable->shadow);
drawable->shadow = NULL;
}
}
void
gimp_drawable_merge_shadow_tiles (GimpDrawable *drawable,
gboolean push_undo,
const gchar *undo_desc)
{
gint x, y;
gint width, height;
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
g_return_if_fail (drawable->shadow != NULL);
/* A useful optimization here is to limit the update to the
* extents of the selection mask, as it cannot extend beyond
* them.
*/
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
PixelRegion shadowPR;
pixel_region_init (&shadowPR, drawable->shadow,
x, y, width, height, FALSE);
gimp_drawable_apply_region (drawable, &shadowPR,
push_undo, undo_desc,
GIMP_OPACITY_OPAQUE, GIMP_REPLACE_MODE,
NULL, x, y);
}
}

View File

@ -0,0 +1,33 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpdrawable-shadow.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_DRAWABLE_SHADOW_H__
#define __GIMP_DRAWABLE_SHADOW_H__
TileManager * gimp_drawable_get_shadow_tiles (GimpDrawable *drawable);
void gimp_drawable_free_shadow_tiles (GimpDrawable *drawable);
void gimp_drawable_merge_shadow_tiles (GimpDrawable *drawable,
gboolean push_undo,
const gchar *undo_desc);
#endif /* __GIMP_DRAWABLE_SHADOW_H__ */

View File

@ -35,6 +35,7 @@
#include "gimpdrawable.h"
#include "gimpdrawable-operation.h"
#include "gimpdrawable-threshold.h"
#include "gimpdrawable-shadow.h"
#include "gimp-intl.h"
@ -95,7 +96,9 @@ gimp_drawable_threshold (GimpDrawable *drawable,
pixel_regions_process_parallel ((PixelProcessorFunc) threshold,
&cruft, 2, &srcPR, &destPR);
gimp_drawable_merge_shadow (drawable, TRUE, _("Threshold"));
gimp_drawable_merge_shadow_tiles (drawable, TRUE, _("Threshold"));
gimp_drawable_free_shadow_tiles (drawable);
gimp_drawable_update (drawable, x, y, width, height);
}
}

View File

@ -37,6 +37,7 @@
#include "gimpcontext.h"
#include "gimpdrawable-combine.h"
#include "gimpdrawable-preview.h"
#include "gimpdrawable-shadow.h"
#include "gimpdrawable-transform.h"
#include "gimpimage.h"
#include "gimpimage-colormap.h"
@ -74,6 +75,7 @@ static gboolean gimp_drawable_get_size (GimpViewable *viewable,
gint *height);
static void gimp_drawable_invalidate_preview (GimpViewable *viewable);
static void gimp_drawable_removed (GimpItem *item);
static GimpItem * gimp_drawable_duplicate (GimpItem *item,
GType new_type);
static void gimp_drawable_translate (GimpItem *item,
@ -200,6 +202,7 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
viewable_class->invalidate_preview = gimp_drawable_invalidate_preview;
viewable_class->get_preview = gimp_drawable_get_preview;
item_class->removed = gimp_drawable_removed;
item_class->duplicate = gimp_drawable_duplicate;
item_class->translate = gimp_drawable_translate;
item_class->scale = gimp_drawable_scale;
@ -225,6 +228,7 @@ static void
gimp_drawable_init (GimpDrawable *drawable)
{
drawable->tiles = NULL;
drawable->shadow = NULL;
drawable->bytes = 0;
drawable->type = -1;
drawable->has_alpha = FALSE;
@ -255,6 +259,8 @@ gimp_drawable_finalize (GObject *object)
drawable->tiles = NULL;
}
gimp_drawable_free_shadow_tiles (drawable);
if (drawable->preview_cache)
gimp_preview_cache_invalidate (&drawable->preview_cache);
@ -270,6 +276,7 @@ gimp_drawable_get_memsize (GimpObject *object,
memsize += tile_manager_get_memsize (gimp_drawable_get_tiles (drawable),
FALSE);
memsize += tile_manager_get_memsize (drawable->shadow, FALSE);
*gui_size += gimp_preview_cache_get_memsize (drawable->preview_cache);
@ -304,6 +311,17 @@ gimp_drawable_invalidate_preview (GimpViewable *viewable)
gimp_preview_cache_invalidate (&drawable->preview_cache);
}
static void
gimp_drawable_removed (GimpItem *item)
{
GimpDrawable *drawable = GIMP_DRAWABLE (item);
gimp_drawable_free_shadow_tiles (drawable);
if (GIMP_ITEM_CLASS (parent_class)->removed)
GIMP_ITEM_CLASS (parent_class)->removed (item);
}
static GimpItem *
gimp_drawable_duplicate (GimpItem *item,
GType new_type)
@ -1056,55 +1074,6 @@ gimp_drawable_push_undo (GimpDrawable *drawable,
x, y, width, height);
}
TileManager *
gimp_drawable_get_shadow_tiles (GimpDrawable *drawable)
{
GimpItem *item;
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
item = GIMP_ITEM (drawable);
g_return_val_if_fail (gimp_item_is_attached (item), NULL);
return gimp_image_get_shadow_tiles (gimp_item_get_image (item),
gimp_item_width (item),
gimp_item_height (item),
drawable->bytes);
}
void
gimp_drawable_merge_shadow (GimpDrawable *drawable,
gboolean push_undo,
const gchar *undo_desc)
{
GimpImage *image;
gint x, y, width, height;
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
image = gimp_item_get_image (GIMP_ITEM (drawable));
g_return_if_fail (image->shadow != NULL);
/* A useful optimization here is to limit the update to the
* extents of the selection mask, as it cannot extend beyond
* them.
*/
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
PixelRegion shadowPR;
pixel_region_init (&shadowPR, image->shadow,
x, y, width, height, FALSE);
gimp_drawable_apply_region (drawable, &shadowPR,
push_undo, undo_desc,
GIMP_OPACITY_OPAQUE, GIMP_REPLACE_MODE,
NULL, x, y);
}
}
void
gimp_drawable_fill (GimpDrawable *drawable,
const GimpRGB *color,

View File

@ -38,6 +38,7 @@ struct _GimpDrawable
GimpItem parent_instance;
TileManager *tiles; /* tiles for drawable data */
TileManager *shadow; /* shadow buffer tiles */
gint bytes; /* bytes per pixel */
GimpImageType type; /* type of drawable */
@ -185,11 +186,6 @@ void gimp_drawable_push_undo (GimpDrawable *drawable,
TileManager *tiles,
gboolean sparse);
TileManager * gimp_drawable_get_shadow_tiles (GimpDrawable *drawable);
void gimp_drawable_merge_shadow (GimpDrawable *drawable,
gboolean push_undo,
const gchar *undo_desc);
void gimp_drawable_fill (GimpDrawable *drawable,
const GimpRGB *color,
const GimpPattern *pattern);

View File

@ -31,7 +31,6 @@
#include "core-types.h"
#include "base/temp-buf.h"
#include "base/tile-manager.h"
#include "config/gimpcoreconfig.h"
@ -588,8 +587,6 @@ gimp_image_init (GimpImage *image)
image->tattoo_state = 0;
image->shadow = NULL;
image->projection = gimp_projection_new (image);
image->guides = NULL;
@ -869,9 +866,6 @@ gimp_image_finalize (GObject *object)
image->projection = NULL;
}
if (image->shadow)
gimp_image_free_shadow_tiles (image);
if (image->colormap)
{
g_free (image->colormap);
@ -986,8 +980,6 @@ gimp_image_get_memsize (GimpObject *object,
if (gimp_image_get_colormap (image))
memsize += GIMP_IMAGE_COLORMAP_SIZE;
memsize += tile_manager_get_memsize (image->shadow, FALSE);
memsize += gimp_object_get_memsize (GIMP_OBJECT (image->projection),
gui_size);
@ -2263,48 +2255,6 @@ gimp_image_transform_temp_buf (const GimpImage *dest_image,
}
/* shadow tiles */
TileManager *
gimp_image_get_shadow_tiles (GimpImage *image,
gint width,
gint height,
gint bpp)
{
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
if (image->shadow)
{
if ((width != tile_manager_width (image->shadow)) ||
(height != tile_manager_height (image->shadow)) ||
(bpp != tile_manager_bpp (image->shadow)))
{
gimp_image_free_shadow_tiles (image);
}
else
{
return image->shadow;
}
}
image->shadow = tile_manager_new (width, height, bpp);
return image->shadow;
}
void
gimp_image_free_shadow_tiles (GimpImage *image)
{
g_return_if_fail (GIMP_IS_IMAGE (image));
if (image->shadow)
{
tile_manager_unref (image->shadow);
image->shadow = NULL;
}
}
/* parasites */
const GimpParasite *

View File

@ -125,8 +125,6 @@ struct _GimpImage
GimpTattoo tattoo_state; /* the last used tattoo */
TileManager *shadow; /* shadow buffer tiles */
GimpProjection *projection; /* projection layers & channels */
GList *guides; /* guides */
@ -379,15 +377,6 @@ TempBuf * gimp_image_transform_temp_buf (const GimpImage *dest_image
gboolean *new_buf);
/* shadow tiles */
TileManager * gimp_image_get_shadow_tiles (GimpImage *image,
gint width,
gint height,
gint bpp);
void gimp_image_free_shadow_tiles (GimpImage *image);
/* parasites */
const GimpParasite * gimp_image_parasite_find (const GimpImage *image,

View File

@ -30,6 +30,7 @@
#include "paint-funcs/paint-funcs.h"
#include "gimpdrawable.h"
#include "gimpdrawable-shadow.h"
#include "gimpimage.h"
#include "gimpimagemap.h"
#include "gimpmarshal.h"
@ -216,6 +217,8 @@ gimp_image_map_finalize (GObject *object)
if (image_map->drawable)
{
gimp_drawable_free_shadow_tiles (image_map->drawable);
g_object_unref (image_map->drawable);
image_map->drawable = NULL;
}
@ -687,8 +690,6 @@ gimp_image_map_abort (GimpImageMap *image_map)
static gboolean
gimp_image_map_do (GimpImageMap *image_map)
{
GimpImage *image;
if (! gimp_item_is_attached (GIMP_ITEM (image_map->drawable)))
{
image_map->idle_id = 0;
@ -708,8 +709,6 @@ gimp_image_map_do (GimpImageMap *image_map)
return FALSE;
}
image = gimp_item_get_image (GIMP_ITEM (image_map->drawable));
if (image_map->gegl)
{
if (! gegl_processor_work (image_map->processor, NULL))
@ -758,7 +757,9 @@ gimp_image_map_do (GimpImageMap *image_map)
&image_map->destPR);
pixel_region_init (&srcPR, image->shadow, x, y, w, h, FALSE);
pixel_region_init (&srcPR,
gimp_drawable_get_shadow_tiles (image_map->drawable),
x, y, w, h, FALSE);
gimp_drawable_apply_region (image_map->drawable, &srcPR,
FALSE, NULL,
@ -791,17 +792,14 @@ gimp_image_map_data_written (GObject *operation,
const GeglRectangle *extent,
GimpImageMap *image_map)
{
GimpImage *image;
PixelRegion srcPR;
PixelRegion destPR;
PixelRegion srcPR;
PixelRegion destPR;
#if 0
g_print ("%s: rect = { %d, %d, %d, %d }\n",
G_STRFUNC, extent->x, extent->y, extent->width, extent->height);
#endif
image = gimp_item_get_image (GIMP_ITEM (image_map->drawable));
/* Reset to initial drawable conditions. */
pixel_region_init (&srcPR, image_map->undo_tiles,
extent->x - image_map->undo_offset_x,
@ -818,7 +816,8 @@ gimp_image_map_data_written (GObject *operation,
copy_region (&srcPR, &destPR);
/* Apply the result of the gegl graph. */
pixel_region_init (&srcPR, image->shadow,
pixel_region_init (&srcPR,
gimp_drawable_get_shadow_tiles (image_map->drawable),
extent->x,
extent->y,
extent->width,

View File

@ -32,11 +32,13 @@
#include "core/gimpdrawable-foreground-extract.h"
#include "core/gimpdrawable-offset.h"
#include "core/gimpdrawable-preview.h"
#include "core/gimpdrawable-shadow.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimplayer.h"
#include "core/gimplayermask.h"
#include "core/gimpparamspecs.h"
#include "plug-in/gimpplugin-cleanup.h"
#include "plug-in/gimpplugin.h"
#include "plug-in/gimppluginmanager.h"
#include "text/gimptextlayer.h"
@ -851,7 +853,7 @@ drawable_merge_shadow_invoker (GimpProcedure *procedure,
if (gimp->plug_in_manager->current_plug_in)
undo_desc = gimp_plug_in_get_undo_desc (gimp->plug_in_manager->current_plug_in);
gimp_drawable_merge_shadow (drawable, undo, undo_desc);
gimp_drawable_merge_shadow_tiles (drawable, undo, undo_desc);
}
else
success = FALSE;
@ -860,6 +862,31 @@ drawable_merge_shadow_invoker (GimpProcedure *procedure,
return gimp_procedure_get_return_values (procedure, success);
}
static GValueArray *
drawable_free_shadow_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GValueArray *args,
GError **error)
{
gboolean success = TRUE;
GimpDrawable *drawable;
drawable = gimp_value_get_drawable (&args->values[0], gimp);
if (success)
{
if (gimp->plug_in_manager->current_plug_in)
gimp_plug_in_cleanup_remove_shadow (gimp->plug_in_manager->current_plug_in,
drawable);
gimp_drawable_free_shadow_tiles (drawable);
}
return gimp_procedure_get_return_values (procedure, success);
}
static GValueArray *
drawable_update_invoker (GimpProcedure *procedure,
Gimp *gimp,
@ -2128,7 +2155,7 @@ register_drawable_procs (GimpPDB *pdb)
gimp_procedure_set_static_strings (procedure,
"gimp-drawable-merge-shadow",
"Merge the shadow buffer with the specified drawable.",
"This procedure combines the contents of the image's shadow buffer (for temporary processing) with the specified drawable. The 'undo' parameter specifies whether to add an undo step for the operation. Requesting no undo is useful for such applications as 'auto-apply'.",
"This procedure combines the contents of the drawable's shadow buffer (for temporary processing) with the specified drawable. The 'undo' parameter specifies whether to add an undo step for the operation. Requesting no undo is useful for such applications as 'auto-apply'.",
"Spencer Kimball & Peter Mattis",
"Spencer Kimball & Peter Mattis",
"1995-1996",
@ -2148,6 +2175,29 @@ register_drawable_procs (GimpPDB *pdb)
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-drawable-free-shadow
*/
procedure = gimp_procedure_new (drawable_free_shadow_invoker);
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-drawable-free-shadow");
gimp_procedure_set_static_strings (procedure,
"gimp-drawable-free-shadow",
"Free the specified drawable's shadow data (if it exists).",
"This procedure is intended as a memory saving device. If any shadow memory has been allocated, it will be freed automatically when the drawable is removed from the image, or when the plug-in procedure which allocated it returns.",
"Michael Natterer <mitch@gimp.org>",
"Michael Natterer",
"2008",
NULL);
gimp_procedure_add_argument (procedure,
gimp_param_spec_drawable_id ("drawable",
"drawable",
"The drawable",
pdb->gimp, FALSE,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-drawable-update
*/

View File

@ -316,7 +316,6 @@ image_free_shadow_invoker (GimpProcedure *procedure,
if (success)
{
gimp_image_free_shadow_tiles (image);
}
return gimp_procedure_get_return_values (procedure, success);
@ -2595,12 +2594,12 @@ register_image_procs (GimpPDB *pdb)
"gimp-image-free-shadow");
gimp_procedure_set_static_strings (procedure,
"gimp-image-free-shadow",
"Free the specified image's shadow data (if it exists).",
"This procedure is intended as a memory saving device. If any shadow memory has been allocated, it will be freed automatically on a call to 'gimp-image-delete'.",
"Spencer Kimball & Peter Mattis",
"Spencer Kimball & Peter Mattis",
"1995-1996",
NULL);
"This procedure is deprecated! Use 'gimp-drawable-free-shadow' instead.",
"This procedure is deprecated! Use 'gimp-drawable-free-shadow' instead.",
"",
"",
"",
"gimp-drawable-free-shadow");
gimp_procedure_add_argument (procedure,
gimp_param_spec_image_id ("image",
"image",

View File

@ -29,7 +29,7 @@
#include "internal-procs.h"
/* 584 procedures registered total */
/* 585 procedures registered total */
void
internal_procs_init (GimpPDB *pdb)

View File

@ -26,9 +26,10 @@
#include "core/gimp.h"
#include "core/gimpcontainer.h"
#include "core/gimpdrawable.h"
#include "core/gimpdrawable-shadow.h"
#include "core/gimpimage.h"
#include "core/gimpimage-undo.h"
#include "core/gimpitem.h"
#include "core/gimpundostack.h"
#include "gimpplugin.h"
@ -54,6 +55,8 @@ struct _GimpPlugInCleanupItem
{
GimpItem *item;
gint item_ID;
gboolean shadow_tiles;
};
@ -128,6 +131,58 @@ gimp_plug_in_cleanup_undo_group_end (GimpPlugIn *plug_in,
return TRUE;
}
gboolean
gimp_plug_in_cleanup_add_shadow (GimpPlugIn *plug_in,
GimpDrawable *drawable)
{
GimpPlugInProcFrame *proc_frame;
GimpPlugInCleanupItem *cleanup;
g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE);
proc_frame = gimp_plug_in_get_proc_frame (plug_in);
cleanup = gimp_plug_in_cleanup_item_get (proc_frame, GIMP_ITEM (drawable));
if (! cleanup)
{
cleanup = gimp_plug_in_cleanup_item_new (GIMP_ITEM (drawable));
proc_frame->item_cleanups = g_list_prepend (proc_frame->item_cleanups,
cleanup);
}
cleanup->shadow_tiles = TRUE;
return TRUE;
}
gboolean
gimp_plug_in_cleanup_remove_shadow (GimpPlugIn *plug_in,
GimpDrawable *drawable)
{
GimpPlugInProcFrame *proc_frame;
GimpPlugInCleanupItem *cleanup;
g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE);
proc_frame = gimp_plug_in_get_proc_frame (plug_in);
cleanup = gimp_plug_in_cleanup_item_get (proc_frame, GIMP_ITEM (drawable));
if (! cleanup)
return FALSE;
if (! cleanup->shadow_tiles)
return FALSE;
proc_frame->item_cleanups = g_list_remove (proc_frame->item_cleanups,
cleanup);
gimp_plug_in_cleanup_item_free (cleanup);
return TRUE;
}
void
gimp_plug_in_cleanup (GimpPlugIn *plug_in,
GimpPlugInProcFrame *proc_frame)
@ -181,6 +236,17 @@ gimp_plug_in_cleanup (GimpPlugIn *plug_in,
cleanup->item_ID) != item)
goto free_item_cleanup;
if (cleanup->shadow_tiles)
{
GimpProcedure *proc = proc_frame->procedure;
g_printerr ("Plug-In '%s' didn't free shadow tiles of drawable '%s'.\n",
gimp_plug_in_procedure_get_label (GIMP_PLUG_IN_PROCEDURE (proc)),
gimp_object_get_name (GIMP_OBJECT (item)));
gimp_drawable_free_shadow_tiles (GIMP_DRAWABLE (item));
}
free_item_cleanup:
gimp_plug_in_cleanup_item_free (cleanup);
}

View File

@ -27,6 +27,11 @@ gboolean gimp_plug_in_cleanup_undo_group_start (GimpPlugIn *plug_in,
gboolean gimp_plug_in_cleanup_undo_group_end (GimpPlugIn *plug_in,
GimpImage *image);
gboolean gimp_plug_in_cleanup_add_shadow (GimpPlugIn *plug_in,
GimpDrawable *drawable);
gboolean gimp_plug_in_cleanup_remove_shadow (GimpPlugIn *plug_in,
GimpDrawable *drawable);
void gimp_plug_in_cleanup (GimpPlugIn *plug_in,
GimpPlugInProcFrame *proc_frame);

View File

@ -35,11 +35,13 @@
#include "core/gimp.h"
#include "core/gimpdrawable.h"
#include "core/gimpdrawable-shadow.h"
#include "pdb/gimppdb.h"
#include "pdb/gimp-pdb-compat.h"
#include "gimpplugin.h"
#include "gimpplugin-cleanup.h"
#include "gimpplugin-message.h"
#include "gimppluginmanager.h"
#include "gimpplugindef.h"
@ -244,9 +246,15 @@ gimp_plug_in_handle_tile_request (GimpPlugIn *plug_in,
}
if (tile_info->shadow)
tm = gimp_drawable_get_shadow_tiles (drawable);
{
tm = gimp_drawable_get_shadow_tiles (drawable);
gimp_plug_in_cleanup_add_shadow (plug_in, drawable);
}
else
tm = gimp_drawable_get_tiles (drawable);
{
tm = gimp_drawable_get_tiles (drawable);
}
tile = tile_manager_get (tm, tile_info->tile_num, TRUE, TRUE);
@ -313,9 +321,15 @@ gimp_plug_in_handle_tile_request (GimpPlugIn *plug_in,
}
if (request->shadow)
tm = gimp_drawable_get_shadow_tiles (drawable);
{
tm = gimp_drawable_get_shadow_tiles (drawable);
gimp_plug_in_cleanup_add_shadow (plug_in, drawable);
}
else
tm = gimp_drawable_get_tiles (drawable);
{
tm = gimp_drawable_get_tiles (drawable);
}
tile = tile_manager_get (tm, request->tile_num, TRUE, FALSE);

View File

@ -971,7 +971,7 @@ gimp_drawable_mask_intersect (gint32 drawable_ID,
*
* Merge the shadow buffer with the specified drawable.
*
* This procedure combines the contents of the image's shadow buffer
* This procedure combines the contents of the drawable's shadow buffer
* (for temporary processing) with the specified drawable. The 'undo'
* parameter specifies whether to add an undo step for the operation.
* Requesting no undo is useful for such applications as 'auto-apply'.
@ -999,6 +999,40 @@ gimp_drawable_merge_shadow (gint32 drawable_ID,
return success;
}
/**
* gimp_drawable_free_shadow:
* @drawable_ID: The drawable.
*
* Free the specified drawable's shadow data (if it exists).
*
* This procedure is intended as a memory saving device. If any shadow
* memory has been allocated, it will be freed automatically when the
* drawable is removed from the image, or when the plug-in procedure
* which allocated it returns.
*
* Returns: TRUE on success.
*
* Since: GIMP 2.6
*/
gboolean
gimp_drawable_free_shadow (gint32 drawable_ID)
{
GimpParam *return_vals;
gint nreturn_vals;
gboolean success = TRUE;
return_vals = gimp_run_procedure ("gimp-drawable-free-shadow",
&nreturn_vals,
GIMP_PDB_DRAWABLE, drawable_ID,
GIMP_PDB_END);
success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;
gimp_destroy_params (return_vals, nreturn_vals);
return success;
}
/**
* gimp_drawable_update:
* @drawable_ID: The drawable.

View File

@ -76,6 +76,7 @@ gboolean gimp_drawable_mask_intersect (gint32
gint *height);
gboolean gimp_drawable_merge_shadow (gint32 drawable_ID,
gboolean undo);
gboolean gimp_drawable_free_shadow (gint32 drawable_ID);
gboolean gimp_drawable_update (gint32 drawable_ID,
gint x,
gint y,

View File

@ -26,6 +26,9 @@
#include <string.h>
#include "gimp.h"
#undef GIMP_DISABLE_DEPRECATED
#undef __GIMP_IMAGE_PDB_H__
#include "gimpimage_pdb.h"
/**
* gimp_image_is_valid:
@ -300,11 +303,8 @@ gimp_image_height (gint32 image_ID)
* gimp_image_free_shadow:
* @image_ID: The image.
*
* Free the specified image's shadow data (if it exists).
*
* This procedure is intended as a memory saving device. If any shadow
* memory has been allocated, it will be freed automatically on a call
* to gimp_image_delete().
* This procedure is deprecated! Use gimp_drawable_free_shadow()
* instead.
*
* Returns: TRUE on success.
*/

View File

@ -39,7 +39,9 @@ gboolean gimp_image_delete (gint32
GimpImageBaseType gimp_image_base_type (gint32 image_ID);
gint gimp_image_width (gint32 image_ID);
gint gimp_image_height (gint32 image_ID);
#ifndef GIMP_DISABLE_DEPRECATED
gboolean gimp_image_free_shadow (gint32 image_ID);
#endif /* GIMP_DISABLE_DEPRECATED */
gboolean gimp_image_resize (gint32 image_ID,
gint new_width,
gint new_height,

View File

@ -51,8 +51,8 @@ sub drawable_merge_shadow {
$blurb = 'Merge the shadow buffer with the specified drawable.';
$help = <<'HELP';
This procedure combines the contents of the image's shadow buffer (for
temporary processing) with the specified drawable. The 'undo'
This procedure combines the contents of the drawable's shadow buffer
(for temporary processing) with the specified drawable. The 'undo'
parameter specifies whether to add an undo step for the operation.
Requesting no undo is useful for such applications as 'auto-apply'.
HELP
@ -67,7 +67,9 @@ HELP
);
%invoke = (
headers => [ qw("plug-in/gimpplugin.h" "plug-in/gimppluginmanager.h") ],
headers => [ qw("core/gimpdrawable-shadow.h"
"plug-in/gimpplugin.h"
"plug-in/gimppluginmanager.h") ],
code => <<'CODE'
{
if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), error))
@ -77,7 +79,7 @@ HELP
if (gimp->plug_in_manager->current_plug_in)
undo_desc = gimp_plug_in_get_undo_desc (gimp->plug_in_manager->current_plug_in);
gimp_drawable_merge_shadow (drawable, undo, undo_desc);
gimp_drawable_merge_shadow_tiles (drawable, undo, undo_desc);
}
else
success = FALSE;
@ -86,6 +88,37 @@ CODE
);
}
sub drawable_free_shadow {
$blurb = "Free the specified drawable's shadow data (if it exists).";
$help = <<'HELP';
This procedure is intended as a memory saving device. If any shadow
memory has been allocated, it will be freed automatically when the
drawable is removed from the image, or when the plug-in procedure
which allocated it returns.
HELP
&mitch_pdb_misc('2008', '2.6');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
%invoke = (
headers => [ qw("plug-in/gimpplugin-cleanup.h") ],
code => <<'CODE'
{
if (gimp->plug_in_manager->current_plug_in)
gimp_plug_in_cleanup_remove_shadow (gimp->plug_in_manager->current_plug_in,
drawable);
gimp_drawable_free_shadow_tiles (drawable);
}
CODE
);
}
sub drawable_fill {
$blurb = 'Fill the drawable with the specified fill mode.';
@ -1322,6 +1355,7 @@ CODE
drawable_mask_bounds
drawable_mask_intersect
drawable_merge_shadow
drawable_free_shadow
drawable_update
drawable_get_pixel drawable_set_pixel
drawable_fill

View File

@ -385,15 +385,7 @@ CODE
}
sub image_free_shadow {
$blurb = "Free the specified image's shadow data (if it exists).";
$help = <<'HELP';
This procedure is intended as a memory saving device. If any shadow memory has
been allocated, it will be freed automatically on a call to
gimp_image_delete().
HELP
&std_pdb_misc;
&std_pdb_deprecated ('gimp-drawable-free-shadow');
@inargs = (
{ name => 'image', type => 'image',
@ -403,7 +395,6 @@ HELP
%invoke = (
code => <<'CODE'
{
gimp_image_free_shadow_tiles (image);
}
CODE
);