added new methods ::get_bytes() and ::flush()

2006-03-02  Michael Natterer  <mitch@gimp.org>

	* app/core/gimppickable.[ch]: added new methods ::get_bytes() and
	::flush()

	* app/core/gimpchannel.c
	* app/core/gimpdrawable.c
	* app/core/gimpimagemap.c
	* app/core/gimpprojection.c: implement ::get_bytes()

	* app/core/gimpprojection.c: implement ::flush() (immediately
	process both the idle renderer's queue and the unflushed update
	areas, to make sure that any reading from the projection will
	re-construct it).

	* app/core/gimp-edit.c
	* app/core/gimpchannel.c
	* app/core/gimpimage-contiguous-region.c
	* app/core/gimpimage-crop.c
	* app/core/gimppalette-import.c
	* app/paint/gimpclone.c
	* app/tools/gimpbycolorselecttool.c
	* app/tools/gimpiscissorstool.c
	* tools/pdbgen/pdb/image.pdb: use the pickable interface more
	consistently when reading from any drawable or the projection, and
	call gimp_pickable_flush() before doing so. Fixes bug #332933.

	* app/core/gimpimage-pick-color.c: added comment why the we don't
	call gimp_pickable_flush() here.

	* app/pdb/image_cmds.c
	* libgimp/gimpimage_pdb.c: regenerated.
This commit is contained in:
Michael Natterer 2006-03-02 19:30:59 +00:00 committed by Michael Natterer
parent 342a7ee9db
commit b55ce9ea2d
19 changed files with 195 additions and 60 deletions

View File

@ -1,3 +1,36 @@
2006-03-02 Michael Natterer <mitch@gimp.org>
* app/core/gimppickable.[ch]: added new methods ::get_bytes() and
::flush()
* app/core/gimpchannel.c
* app/core/gimpdrawable.c
* app/core/gimpimagemap.c
* app/core/gimpprojection.c: implement ::get_bytes()
* app/core/gimpprojection.c: implement ::flush() (immediately
process both the idle renderer's queue and the unflushed update
areas, to make sure that any reading from the projection will
re-construct it).
* app/core/gimp-edit.c
* app/core/gimpchannel.c
* app/core/gimpimage-contiguous-region.c
* app/core/gimpimage-crop.c
* app/core/gimppalette-import.c
* app/paint/gimpclone.c
* app/tools/gimpbycolorselecttool.c
* app/tools/gimpiscissorstool.c
* tools/pdbgen/pdb/image.pdb: use the pickable interface more
consistently when reading from any drawable or the projection, and
call gimp_pickable_flush() before doing so. Fixes bug #332933.
* app/core/gimpimage-pick-color.c: added comment why the we don't
call gimp_pickable_flush() here.
* app/pdb/image_cmds.c
* libgimp/gimpimage_pdb.c: regenerated.
2006-03-02 Sven Neumann <sven@gimp.org>
* tools/pdbgen/pdb/image.pdb: corrected documentation for

View File

@ -43,7 +43,7 @@
#include "gimplayer-floating-sel.h"
#include "gimplist.h"
#include "gimppattern.h"
#include "gimpprojection.h"
#include "gimppickable.h"
#include "gimpselection.h"
#include "gimp-intl.h"
@ -508,10 +508,11 @@ static GimpBuffer *
gimp_edit_extract_visible (GimpImage *gimage,
GimpContext *context)
{
PixelRegion srcPR, destPR;
TileManager *tiles;
gboolean non_empty;
gint x1, y1, x2, y2;
GimpPickable *pickable;
TileManager *tiles;
PixelRegion srcPR, destPR;
gboolean non_empty;
gint x1, y1, x2, y2;
non_empty = gimp_channel_bounds (gimp_image_get_mask (gimage),
&x1, &y1, &x2, &y2);
@ -522,11 +523,15 @@ gimp_edit_extract_visible (GimpImage *gimage,
return NULL;
}
pickable = GIMP_PICKABLE (gimage->projection);
gimp_pickable_flush (pickable);
tiles = tile_manager_new (x2 - x1, y2 - y1,
gimp_projection_get_bytes (gimage->projection));
gimp_pickable_get_bytes (pickable));
tile_manager_set_offsets (tiles, x1, y1);
pixel_region_init (&srcPR, gimp_projection_get_tiles (gimage->projection),
pixel_region_init (&srcPR, gimp_pickable_get_tiles (pickable),
x1, y1,
x2 - x1, y2 - y1,
FALSE);

View File

@ -53,7 +53,6 @@
#include "gimpmarshal.h"
#include "gimppaintinfo.h"
#include "gimppickable.h"
#include "gimpprojection.h"
#include "gimpstrokedesc.h"
#include "gimp-intl.h"
@ -1549,7 +1548,9 @@ gimp_channel_new_from_component (GimpImage *gimage,
g_return_val_if_fail (pixel != -1, NULL);
projection = gimp_projection_get_tiles (gimage->projection);
gimp_pickable_flush (GIMP_PICKABLE (gimage->projection));
projection = gimp_pickable_get_tiles (GIMP_PICKABLE (gimage->projection));
width = tile_manager_width (projection);
height = tile_manager_height (projection);

View File

@ -232,6 +232,7 @@ gimp_drawable_pickable_iface_init (GimpPickableInterface *iface)
{
iface->get_image = gimp_item_get_image;
iface->get_image_type = gimp_drawable_type;
iface->get_bytes = gimp_drawable_bytes;
iface->get_tiles = gimp_drawable_data;
iface->get_color_at = gimp_drawable_get_color_at;
}

View File

@ -127,6 +127,8 @@ gimp_image_contiguous_region_by_seed (GimpImage *gimage,
else
pickable = GIMP_PICKABLE (drawable);
gimp_pickable_flush (pickable);
src_type = gimp_pickable_get_image_type (pickable);
has_alpha = GIMP_IMAGE_TYPE_HAS_ALPHA (src_type);
bytes = GIMP_IMAGE_TYPE_BYTES (src_type);
@ -230,6 +232,8 @@ gimp_image_contiguous_region_by_color (GimpImage *gimage,
else
pickable = GIMP_PICKABLE (drawable);
gimp_pickable_flush (pickable);
cont.type = gimp_pickable_get_image_type (pickable);
cont.has_alpha = GIMP_IMAGE_TYPE_HAS_ALPHA (cont.type);

View File

@ -320,6 +320,8 @@ gimp_image_crop_auto_shrink (GimpImage *gimage,
pickable = GIMP_PICKABLE (gimage->projection);
}
gimp_pickable_flush (pickable);
type = gimp_pickable_get_image_type (pickable);
bytes = GIMP_IMAGE_TYPE_BYTES (type);
has_alpha = GIMP_IMAGE_TYPE_HAS_ALPHA (type);

View File

@ -22,10 +22,10 @@
#include "core-types.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimpimage-pick-color.h"
#include "core/gimppickable.h"
#include "gimpdrawable.h"
#include "gimpimage.h"
#include "gimpimage-pick-color.h"
#include "gimppickable.h"
gboolean
@ -72,6 +72,11 @@ gimp_image_pick_color (GimpImage *gimage,
pickable = GIMP_PICKABLE (drawable);
}
/* Do *not* call gimp_pickable_flush() here because it's too expensive
* to call it unconditionally each time e.g. the cursor view is updated.
* Instead, call gimp_pickable_flush() in the callers if needed.
*/
if (sample_type)
*sample_type = gimp_pickable_get_image_type (pickable);

View File

@ -67,6 +67,7 @@ static void gimp_image_map_finalize (GObject *object);
static GimpImage * gimp_image_map_get_image (GimpPickable *pickable);
static GimpImageType gimp_image_map_get_image_type (GimpPickable *pickable);
static gint gimp_image_map_get_bytes (GimpPickable *pickable);
static TileManager * gimp_image_map_get_tiles (GimpPickable *pickable);
static guchar * gimp_image_map_get_color_at (GimpPickable *pickable,
gint x,
@ -119,6 +120,7 @@ gimp_image_map_pickable_iface_init (GimpPickableInterface *iface)
{
iface->get_image = gimp_image_map_get_image;
iface->get_image_type = gimp_image_map_get_image_type;
iface->get_bytes = gimp_image_map_get_bytes;
iface->get_tiles = gimp_image_map_get_tiles;
iface->get_color_at = gimp_image_map_get_color_at;
}
@ -153,6 +155,14 @@ gimp_image_map_get_image_type (GimpPickable *pickable)
return gimp_pickable_get_image_type (GIMP_PICKABLE (image_map->drawable));
}
static gint
gimp_image_map_get_bytes (GimpPickable *pickable)
{
GimpImageMap *image_map = GIMP_IMAGE_MAP (pickable);
return gimp_pickable_get_bytes (GIMP_PICKABLE (image_map->drawable));
}
static TileManager *
gimp_image_map_get_tiles (GimpPickable *pickable)
{

View File

@ -48,7 +48,7 @@
#include "gimpgradient.h"
#include "gimpimage.h"
#include "gimppalette.h"
#include "gimpprojection.h"
#include "gimppickable.h"
#include "gimp-intl.h"
@ -330,16 +330,21 @@ gimp_palette_import_from_image (GimpImage *gimage,
gint n_colors,
gint threshold)
{
GHashTable *colors;
GimpPickable *pickable;
GHashTable *colors;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);
g_return_val_if_fail (palette_name != NULL, NULL);
g_return_val_if_fail (n_colors > 1, NULL);
g_return_val_if_fail (threshold > 0, NULL);
pickable = GIMP_PICKABLE (gimage->projection);
gimp_pickable_flush (pickable);
colors = gimp_palette_import_extract (gimage,
gimp_projection_get_tiles (gimage->projection),
gimp_projection_get_image_type (gimage->projection),
gimp_pickable_get_tiles (pickable),
gimp_pickable_get_image_type (pickable),
0, 0, gimage->width, gimage->height,
n_colors, threshold);

View File

@ -56,6 +56,19 @@ gimp_pickable_interface_get_type (void)
return pickable_iface_type;
}
void
gimp_pickable_flush (GimpPickable *pickable)
{
GimpPickableInterface *pickable_iface;
g_return_if_fail (GIMP_IS_PICKABLE (pickable));
pickable_iface = GIMP_PICKABLE_GET_INTERFACE (pickable);
if (pickable_iface->flush)
return pickable_iface->flush (pickable);
}
GimpImage *
gimp_pickable_get_image (GimpPickable *pickable)
{
@ -86,6 +99,21 @@ gimp_pickable_get_image_type (GimpPickable *pickable)
return -1;
}
gint
gimp_pickable_get_bytes (GimpPickable *pickable)
{
GimpPickableInterface *pickable_iface;
g_return_val_if_fail (GIMP_IS_PICKABLE (pickable), 0);
pickable_iface = GIMP_PICKABLE_GET_INTERFACE (pickable);
if (pickable_iface->get_bytes)
return pickable_iface->get_bytes (pickable);
return 0;
}
TileManager *
gimp_pickable_get_tiles (GimpPickable *pickable)
{

View File

@ -36,8 +36,10 @@ struct _GimpPickableInterface
GTypeInterface base_iface;
/* virtual functions */
void (* flush) (GimpPickable *pickable);
GimpImage * (* get_image) (GimpPickable *pickable);
GimpImageType (* get_image_type) (GimpPickable *pickable);
gint (* get_bytes) (GimpPickable *pickable);
TileManager * (* get_tiles) (GimpPickable *pickable);
guchar * (* get_color_at) (GimpPickable *pickable,
gint x,
@ -50,8 +52,10 @@ struct _GimpPickableInterface
GType gimp_pickable_interface_get_type (void) G_GNUC_CONST;
void gimp_pickable_flush (GimpPickable *pickable);
GimpImage * gimp_pickable_get_image (GimpPickable *pickable);
GimpImageType gimp_pickable_get_image_type (GimpPickable *pickable);
gint gimp_pickable_get_bytes (GimpPickable *pickable);
TileManager * gimp_pickable_get_tiles (GimpPickable *pickable);
guchar * gimp_pickable_get_color_at (GimpPickable *pickable,
gint x,

View File

@ -50,6 +50,7 @@ static void gimp_projection_finalize (GObject *object)
static gint64 gimp_projection_get_memsize (GimpObject *object,
gint64 *gui_size);
static void gimp_projection_pickable_flush (GimpPickable *pickable);
static guchar * gimp_projection_get_color_at (GimpPickable *pickable,
gint x,
gint y);
@ -150,8 +151,10 @@ gimp_projection_init (GimpProjection *proj)
static void
gimp_projection_pickable_iface_init (GimpPickableInterface *iface)
{
iface->flush = gimp_projection_pickable_flush;
iface->get_image = gimp_projection_get_image;
iface->get_image_type = gimp_projection_get_image_type;
iface->get_bytes = gimp_projection_get_bytes;
iface->get_tiles = gimp_projection_get_tiles;
iface->get_color_at = gimp_projection_get_color_at;
iface->get_opacity_at = gimp_projection_get_opacity_at;
@ -197,6 +200,15 @@ gimp_projection_get_memsize (GimpObject *object,
gui_size);
}
static void
gimp_projection_pickable_flush (GimpPickable *pickable)
{
GimpProjection *proj = GIMP_PROJECTION (pickable);
gimp_projection_finish_draw (proj);
gimp_projection_flush_now (proj);
}
static guchar *
gimp_projection_get_color_at (GimpPickable *pickable,
gint x,
@ -330,6 +342,10 @@ gimp_projection_finish_draw (GimpProjection *proj)
if (proj->idle_render.idle_id)
{
#if 0
g_printerr ("%s: flushing idle render queue\n", G_STRFUNC);
#endif
g_source_remove (proj->idle_render.idle_id);
proj->idle_render.idle_id = 0;

View File

@ -36,7 +36,6 @@
#include "core/gimpimage.h"
#include "core/gimppattern.h"
#include "core/gimppickable.h"
#include "core/gimpprojection.h"
#include "gimpclone.h"
#include "gimpcloneoptions.h"
@ -268,6 +267,8 @@ gimp_clone_motion (GimpPaintCore *paint_core,
offset_x += off_x;
offset_y += off_y;
}
gimp_pickable_flush (src_pickable);
}
area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options);

View File

@ -36,7 +36,6 @@
#include "core/gimpimage.h"
#include "core/gimppattern.h"
#include "core/gimppickable.h"
#include "core/gimpprojection.h"
#include "gimpclone.h"
#include "gimpcloneoptions.h"
@ -268,6 +267,8 @@ gimp_clone_motion (GimpPaintCore *paint_core,
offset_x += off_x;
offset_y += off_y;
}
gimp_pickable_flush (src_pickable);
}
area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options);

View File

@ -48,6 +48,7 @@
#include "core/gimplayer.h"
#include "core/gimplayermask.h"
#include "core/gimplist.h"
#include "core/gimppickable.h"
#include "core/gimpunit.h"
#include "gimp-intl.h"
#include "vectors/gimpvectors.h"
@ -1642,15 +1643,22 @@ image_pick_color_invoker (Gimp *gimp,
success = FALSE;
if (success)
success = gimp_image_pick_color (gimage,
drawable,
(gint) x, (gint) y,
sample_merged,
sample_average,
average_radius,
NULL,
&color,
NULL);
{
if (sample_merged)
gimp_pickable_flush (GIMP_PICKABLE (gimage->projection));
else
gimp_pickable_flush (GIMP_PICKABLE (drawable));
success = gimp_image_pick_color (gimage,
drawable,
(gint) x, (gint) y,
sample_merged,
sample_average,
average_radius,
NULL,
&color,
NULL);
}
}
return_args = procedural_db_return_args (&image_pick_color_proc, success);
@ -1714,7 +1722,7 @@ static ProcRecord image_pick_color_proc =
"gimp-image-pick-color",
"gimp-image-pick-color",
"Determine the color at the given drawable coordinates",
"This tool determines the color at the specified coordinates. The returned color is an RGB triplet even for grayscale and indexed drawables. If the coordinates lie outside of the extents of the specified drawable, then an error is returned. If the drawable has an alpha channel, the algorithm examines the alpha value of the drawable at the coordinates. If the alpha value is completely transparent (0), then an error is returned. If the sample_merged parameter is non-zero, the data of the composite image will be used instead of that for the specified drawable. This is equivalent to sampling for colors after merging all visible layers. In the case of a merged sampling, the supplied drawable is ignored except for finding the image it belongs to.",
"This tool determines the color at the specified coordinates. The returned color is an RGB triplet even for grayscale and indexed drawables. If the coordinates lie outside of the extents of the specified drawable, then an error is returned. If the drawable has an alpha channel, the algorithm examines the alpha value of the drawable at the coordinates. If the alpha value is completely transparent (0), then an error is returned. If the sample_merged parameter is non-zero, the data of the composite image will be used instead of that for the specified drawable. This is equivalent to sampling for colors after merging all visible layers. In the case of a merged sampling, the supplied drawable is ignored.",
"Spencer Kimball & Peter Mattis",
"Spencer Kimball & Peter Mattis",
"1995-1996",

View File

@ -169,6 +169,8 @@ gimp_by_color_select_tool_button_release (GimpTool *tool,
else
pickable = GIMP_PICKABLE (drawable);
gimp_pickable_flush (pickable);
col = gimp_pickable_get_color_at (pickable,
by_color_sel->x,
by_color_sel->y);

View File

@ -67,7 +67,6 @@
#include "core/gimpchannel-select.h"
#include "core/gimpimage.h"
#include "core/gimppickable.h"
#include "core/gimpprojection.h"
#include "core/gimpscanconvert.h"
#include "core/gimptoolinfo.h"
@ -1675,19 +1674,20 @@ gradmap_tile_validate (TileManager *tm,
{
static gboolean first_gradient = TRUE;
gint x, y;
gint dw, dh;
gint sw, sh;
gint i, j;
gint b;
gfloat gradient;
guint8 *gradmap;
guint8 *tiledata;
guint8 *datah, *datav;
gint8 hmax, vmax;
Tile *srctile;
PixelRegion srcPR, destPR;
GimpImage *gimage;
gint x, y;
gint dw, dh;
gint sw, sh;
gint i, j;
gint b;
gfloat gradient;
guint8 *gradmap;
guint8 *tiledata;
guint8 *datah, *datav;
gint8 hmax, vmax;
GimpPickable *pickable;
Tile *srctile;
PixelRegion srcPR, destPR;
GimpImage *gimage;
gimage = (GimpImage *) tile_manager_get_user_data (tm);
@ -1708,8 +1708,12 @@ gradmap_tile_validate (TileManager *tm,
dw = tile_ewidth (tile);
dh = tile_eheight (tile);
pickable = GIMP_PICKABLE (gimage->projection);
gimp_pickable_flush (pickable);
/* get corresponding tile in the gimage */
srctile = tile_manager_get_tile (gimp_projection_get_tiles (gimage->projection),
srctile = tile_manager_get_tile (gimp_pickable_get_tiles (pickable),
x, y, TRUE, FALSE);
if (!srctile)
return;
@ -1718,8 +1722,8 @@ gradmap_tile_validate (TileManager *tm,
sh = tile_eheight (srctile);
pixel_region_init_data (&srcPR, tile_data_pointer (srctile, 0, 0),
gimp_projection_get_bytes (gimage->projection),
gimp_projection_get_bytes (gimage->projection) *
gimp_pickable_get_bytes (pickable),
gimp_pickable_get_bytes (pickable) *
MIN (dw, sw),
0, 0, MIN (dw, sw), MIN (dh, sh));

View File

@ -804,8 +804,7 @@ gimp_image_floating_sel_attached_to (gint32 image_ID)
* parameter is non-zero, the data of the composite image will be used
* instead of that for the specified drawable. This is equivalent to
* sampling for colors after merging all visible layers. In the case of
* a merged sampling, the supplied drawable is ignored except for
* finding the image it belongs to.
* a merged sampling, the supplied drawable is ignored.
*
* Returns: TRUE on success.
*/

View File

@ -555,8 +555,7 @@ then an error is returned. If the sample_merged parameter is non-zero,
the data of the composite image will be used instead of that for the
specified drawable. This is equivalent to sampling for colors after
merging all visible layers. In the case of a merged sampling, the
supplied drawable is ignored except for finding the image it belongs
to.
supplied drawable is ignored.
HELP
&std_pdb_misc;
@ -586,7 +585,7 @@ HELP
);
%invoke = (
headers => [ qw("core/gimpimage-pick-color.h") ],
headers => [ qw("core/gimpimage-pick-color.h" "core/gimppickable.h") ],
code => <<'CODE'
{
if (!sample_merged)
@ -594,15 +593,22 @@ HELP
success = FALSE;
if (success)
success = gimp_image_pick_color (gimage,
drawable,
(gint) x, (gint) y,
sample_merged,
sample_average,
average_radius,
NULL,
&color,
NULL);
{
if (sample_merged)
gimp_pickable_flush (GIMP_PICKABLE (gimage->projection));
else
gimp_pickable_flush (GIMP_PICKABLE (drawable));
success = gimp_image_pick_color (gimage,
drawable,
(gint) x, (gint) y,
sample_merged,
sample_average,
average_radius,
NULL,
&color,
NULL);
}
}
CODE
);