Item conversion depends on the old *and* the new item type, so it can't

2004-12-23  Michael Natterer  <mitch@gimp.org>

	Item conversion depends on the old *and* the new item type, so
	it can't live in the old item's vtable only:

	* app/core/gimpitem.[ch]: split GimpItem::convert() into
	GimpItem::convert_from() (which is called on the old item and
	creates the new item) and GimpItem::convert_to() (which is called
	on the new item). This way functions from the old *and* new items'
	vtables are called and it's possible to convert between item types
	which live on different branches of the class hierarchy or to item
	types which live further down the class tree than the old item.

	(gimp_item_convert): call ::convert_to() on the new item created
	by ::convert_from().

	* app/vectors/gimpvectors.c: changed ::convert() implementation
	to ::convert_from().

	* app/core/gimplayer.c: changed ::convert() to ::convert_to().
	Fixes bug #161877.
This commit is contained in:
Michael Natterer 2004-12-23 11:53:14 +00:00 committed by Michael Natterer
parent 02d2a673c9
commit 0527989edf
5 changed files with 163 additions and 151 deletions

View File

@ -1,3 +1,25 @@
2004-12-23 Michael Natterer <mitch@gimp.org>
Item conversion depends on the old *and* the new item type, so
it can't live in the old item's vtable only:
* app/core/gimpitem.[ch]: split GimpItem::convert() into
GimpItem::convert_from() (which is called on the old item and
creates the new item) and GimpItem::convert_to() (which is called
on the new item). This way functions from the old *and* new items'
vtables are called and it's possible to convert between item types
which live on different branches of the class hierarchy or to item
types which live further down the class tree than the old item.
(gimp_item_convert): call ::convert_to() on the new item created
by ::convert_from().
* app/vectors/gimpvectors.c: changed ::convert() implementation
to ::convert_from().
* app/core/gimplayer.c: changed ::convert() to ::convert_to().
Fixes bug #161877.
2004-12-22 Sven Neumann <sven@gimp.org>
* plug-ins/script-fu/scripts/Makefile.am

View File

@ -55,41 +55,41 @@ enum
/* local function prototypes */
static void gimp_item_class_init (GimpItemClass *klass);
static void gimp_item_init (GimpItem *item);
static void gimp_item_class_init (GimpItemClass *klass);
static void gimp_item_init (GimpItem *item);
static void gimp_item_finalize (GObject *object);
static void gimp_item_finalize (GObject *object);
static gint64 gimp_item_get_memsize (GimpObject *object,
gint64 *gui_size);
static gint64 gimp_item_get_memsize (GimpObject *object,
gint64 *gui_size);
static GimpItem * gimp_item_real_duplicate (GimpItem *item,
GType new_type,
gboolean add_alpha);
static GimpItem * gimp_item_real_convert (GimpItem *item,
GimpImage *dest_image,
GType new_type,
gboolean add_alpha);
static gboolean gimp_item_real_rename (GimpItem *item,
const gchar *new_name,
const gchar *undo_desc);
static void gimp_item_real_translate (GimpItem *item,
gint offset_x,
gint offset_y,
gboolean push_undo);
static void gimp_item_real_scale (GimpItem *item,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y,
GimpInterpolationType interpolation,
GimpProgress *progress);
static void gimp_item_real_resize (GimpItem *item,
GimpContext *context,
gint new_width,
gint new_height,
gint offset_x,
gint offset_y);
static GimpItem * gimp_item_real_duplicate (GimpItem *item,
GType new_type,
gboolean add_alpha);
static GimpItem * gimp_item_real_convert_from (GimpItem *item,
GimpImage *dest_image,
GType new_type,
gboolean add_alpha);
static gboolean gimp_item_real_rename (GimpItem *item,
const gchar *new_name,
const gchar *undo_desc);
static void gimp_item_real_translate (GimpItem *item,
gint offset_x,
gint offset_y,
gboolean push_undo);
static void gimp_item_real_scale (GimpItem *item,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y,
GimpInterpolationType interpolation,
GimpProgress *progress);
static void gimp_item_real_resize (GimpItem *item,
GimpContext *context,
gint new_width,
gint new_height,
gint offset_x,
gint offset_y);
/* private variables */
@ -176,7 +176,8 @@ gimp_item_class_init (GimpItemClass *klass)
klass->is_attached = NULL;
klass->duplicate = gimp_item_real_duplicate;
klass->convert = gimp_item_real_convert;
klass->convert_from = gimp_item_real_convert_from;
klass->convert_to = NULL;
klass->rename = gimp_item_real_rename;
klass->translate = gimp_item_real_translate;
klass->scale = gimp_item_real_scale;
@ -306,10 +307,10 @@ gimp_item_real_duplicate (GimpItem *item,
}
static GimpItem *
gimp_item_real_convert (GimpItem *item,
GimpImage *dest_image,
GType new_type,
gboolean add_alpha)
gimp_item_real_convert_from (GimpItem *item,
GimpImage *dest_image,
GType new_type,
gboolean add_alpha)
{
return gimp_item_duplicate (item, new_type, add_alpha);
}
@ -535,11 +536,17 @@ gimp_item_convert (GimpItem *item,
g_return_val_if_fail (GIMP_IS_IMAGE (dest_image), NULL);
g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_ITEM), NULL);
new_item = GIMP_ITEM_GET_CLASS (item)->convert (item, dest_image,
new_type, add_alpha);
new_item = GIMP_ITEM_GET_CLASS (item)->convert_from (item, dest_image,
new_type, add_alpha);
if (dest_image != item->gimage)
gimp_item_set_image (new_item, dest_image);
if (new_item)
{
if (dest_image != item->gimage)
gimp_item_set_image (new_item, dest_image);
if (GIMP_ITEM_GET_CLASS (new_item)->convert_to)
GIMP_ITEM_GET_CLASS (new_item)->convert_to (new_item, item);
}
return new_item;
}

View File

@ -64,58 +64,60 @@ struct _GimpItemClass
void (* linked_changed) (GimpItem *item);
/* virtual functions */
gboolean (* is_attached) (GimpItem *item);
GimpItem * (* duplicate) (GimpItem *item,
GType new_type,
gboolean add_alpha);
GimpItem * (* convert) (GimpItem *item,
GimpImage *dest_image,
GType new_type,
gboolean add_alpha);
gboolean (* rename) (GimpItem *item,
const gchar *new_name,
const gchar *undo_desc);
void (* translate) (GimpItem *item,
gint offset_x,
gint offset_y,
gboolean push_undo);
void (* scale) (GimpItem *item,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y,
GimpInterpolationType interpolation_type,
GimpProgress *progress);
void (* resize) (GimpItem *item,
GimpContext *context,
gint new_width,
gint new_height,
gint offset_x,
gint offset_y);
void (* flip) (GimpItem *item,
GimpContext *context,
GimpOrientationType flip_type,
gdouble axis,
gboolean clip_result);
void (* rotate) (GimpItem *item,
GimpContext *context,
GimpRotationType rotate_type,
gdouble center_x,
gdouble center_y,
gboolean clip_result);
void (* transform) (GimpItem *item,
GimpContext *context,
const GimpMatrix3 *matrix,
GimpTransformDirection direction,
GimpInterpolationType interpolation_type,
gboolean supersample,
gint recursion_level,
gboolean clip_result,
GimpProgress *progress);
gboolean (* stroke) (GimpItem *item,
GimpDrawable *drawable,
GimpContext *context,
GimpStrokeDesc *stroke_desc);
gboolean (* is_attached) (GimpItem *item);
GimpItem * (* duplicate) (GimpItem *item,
GType new_type,
gboolean add_alpha);
GimpItem * (* convert_from) (GimpItem *item,
GimpImage *dest_image,
GType new_type,
gboolean add_alpha);
void (* convert_to) (GimpItem *item,
GimpItem *src_item);
gboolean (* rename) (GimpItem *item,
const gchar *new_name,
const gchar *undo_desc);
void (* translate) (GimpItem *item,
gint offset_x,
gint offset_y,
gboolean push_undo);
void (* scale) (GimpItem *item,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y,
GimpInterpolationType interpolation_type,
GimpProgress *progress);
void (* resize) (GimpItem *item,
GimpContext *context,
gint new_width,
gint new_height,
gint offset_x,
gint offset_y);
void (* flip) (GimpItem *item,
GimpContext *context,
GimpOrientationType flip_type,
gdouble axis,
gboolean clip_result);
void (* rotate) (GimpItem *item,
GimpContext *context,
GimpRotationType rotate_type,
gdouble center_x,
gdouble center_y,
gboolean clip_result);
void (* transform) (GimpItem *item,
GimpContext *context,
const GimpMatrix3 *matrix,
GimpTransformDirection direction,
GimpInterpolationType interpolation_type,
gboolean supersample,
gint recursion_level,
gboolean clip_result,
GimpProgress *progress);
gboolean (* stroke) (GimpItem *item,
GimpDrawable *drawable,
GimpContext *context,
GimpStrokeDesc *stroke_desc);
const gchar *default_name;
const gchar *rename_desc;

View File

@ -79,10 +79,8 @@ static gboolean gimp_layer_is_attached (GimpItem *item);
static GimpItem * gimp_layer_duplicate (GimpItem *item,
GType new_type,
gboolean add_alpha);
static GimpItem * gimp_layer_convert (GimpItem *item,
GimpImage *dest_image,
GType new_type,
gboolean add_alpha);
static void gimp_layer_convert_to (GimpItem *item,
GimpItem *src_item);
static gboolean gimp_layer_rename (GimpItem *item,
const gchar *new_name,
const gchar *undo_desc);
@ -241,7 +239,7 @@ gimp_layer_class_init (GimpLayerClass *klass)
item_class->removed = gimp_layer_removed;
item_class->is_attached = gimp_layer_is_attached;
item_class->duplicate = gimp_layer_duplicate;
item_class->convert = gimp_layer_convert;
item_class->convert_to = gimp_layer_convert_to;
item_class->rename = gimp_layer_rename;
item_class->translate = gimp_layer_translate;
item_class->scale = gimp_layer_scale;
@ -488,62 +486,47 @@ gimp_layer_duplicate (GimpItem *item,
return new_item;
}
static GimpItem *
gimp_layer_convert (GimpItem *item,
GimpImage *dest_image,
GType new_type,
gboolean add_alpha)
static void
gimp_layer_convert_to (GimpItem *item,
GimpItem *src_item)
{
GimpLayer *layer;
GimpDrawable *drawable;
GimpItem *new_item;
GimpLayer *new_layer;
GimpDrawable *new_drawable;
GimpImageBaseType src_base_type;
GimpLayer *layer = GIMP_LAYER (item);
GimpDrawable *drawable = GIMP_DRAWABLE (item);
GimpImageBaseType old_base_type;
GimpImageBaseType new_base_type;
g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_DRAWABLE), NULL);
if (GIMP_ITEM_CLASS (parent_class)->convert_to)
GIMP_ITEM_CLASS (parent_class)->convert_to (item, src_item);
new_item = GIMP_ITEM_CLASS (parent_class)->convert (item, dest_image,
new_type, add_alpha);
old_base_type = GIMP_IMAGE_TYPE_BASE_TYPE (gimp_drawable_type (drawable));
new_base_type = gimp_image_base_type (gimp_item_get_image (item));
if (! GIMP_IS_LAYER (new_item))
return new_item;
layer = GIMP_LAYER (item);
drawable = GIMP_DRAWABLE (item);
new_layer = GIMP_LAYER (new_item);
new_drawable = GIMP_DRAWABLE (new_item);
src_base_type = GIMP_IMAGE_TYPE_BASE_TYPE (gimp_drawable_type (drawable));
new_base_type = gimp_image_base_type (dest_image);
if (src_base_type != new_base_type)
if (old_base_type != new_base_type)
{
TileManager *new_tiles;
GimpImageType new_type;
new_type = GIMP_IMAGE_TYPE_FROM_BASE_TYPE (new_base_type);
if (gimp_drawable_has_alpha (new_drawable))
if (gimp_drawable_has_alpha (drawable))
new_type = GIMP_IMAGE_TYPE_WITH_ALPHA (new_type);
new_tiles = tile_manager_new (gimp_item_width (new_item),
gimp_item_height (new_item),
new_tiles = tile_manager_new (gimp_item_width (item),
gimp_item_height (item),
GIMP_IMAGE_TYPE_BYTES (new_type));
switch (new_base_type)
{
case GIMP_RGB:
gimp_drawable_convert_rgb (new_drawable,
gimp_drawable_convert_rgb (drawable,
new_tiles,
src_base_type);
old_base_type);
break;
case GIMP_GRAY:
gimp_drawable_convert_grayscale (new_drawable,
gimp_drawable_convert_grayscale (drawable,
new_tiles,
src_base_type);
old_base_type);
break;
case GIMP_INDEXED:
@ -551,36 +534,34 @@ gimp_layer_convert (GimpItem *item,
PixelRegion layerPR;
PixelRegion newPR;
pixel_region_init (&layerPR, new_drawable->tiles,
pixel_region_init (&layerPR, drawable->tiles,
0, 0,
gimp_item_width (new_item),
gimp_item_height (new_item),
gimp_item_width (item),
gimp_item_height (item),
FALSE);
pixel_region_init (&newPR, new_tiles,
0, 0,
gimp_item_width (new_item),
gimp_item_height (new_item),
gimp_item_width (item),
gimp_item_height (item),
TRUE);
gimp_layer_transform_color (dest_image,
gimp_layer_transform_color (gimp_item_get_image (item),
&newPR, &layerPR,
NULL,
src_base_type);
old_base_type);
}
break;
}
gimp_drawable_set_tiles_full (new_drawable, FALSE, NULL,
gimp_drawable_set_tiles_full (drawable, FALSE, NULL,
new_tiles, new_type,
GIMP_ITEM (layer)->offset_x,
GIMP_ITEM (layer)->offset_y);
tile_manager_unref (new_tiles);
}
if (new_layer->mask && dest_image != item->gimage)
gimp_item_set_image (GIMP_ITEM (new_layer->mask), dest_image);
return new_item;
if (layer->mask && item->gimage != src_item->gimage)
gimp_item_set_image (GIMP_ITEM (layer->mask), item->gimage);
}
static gboolean

View File

@ -69,7 +69,7 @@ static gboolean gimp_vectors_is_attached (GimpItem *item);
static GimpItem * gimp_vectors_duplicate (GimpItem *item,
GType new_type,
gboolean add_alpha);
static GimpItem * gimp_vectors_convert (GimpItem *item,
static GimpItem * gimp_vectors_convert_from (GimpItem *item,
GimpImage *dest_image,
GType new_type,
gboolean add_alpha);
@ -220,7 +220,7 @@ gimp_vectors_class_init (GimpVectorsClass *klass)
item_class->is_attached = gimp_vectors_is_attached;
item_class->duplicate = gimp_vectors_duplicate;
item_class->convert = gimp_vectors_convert;
item_class->convert_from = gimp_vectors_convert_from;
item_class->translate = gimp_vectors_translate;
item_class->scale = gimp_vectors_scale;
item_class->resize = gimp_vectors_resize;
@ -333,17 +333,17 @@ gimp_vectors_duplicate (GimpItem *item,
}
static GimpItem *
gimp_vectors_convert (GimpItem *item,
GimpImage *dest_image,
GType new_type,
gboolean add_alpha)
gimp_vectors_convert_from (GimpItem *item,
GimpImage *dest_image,
GType new_type,
gboolean add_alpha)
{
GimpItem *new_item;
g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_VECTORS), NULL);
new_item = GIMP_ITEM_CLASS (parent_class)->convert (item, dest_image,
new_type, add_alpha);
new_item = GIMP_ITEM_CLASS (parent_class)->convert_from (item, dest_image,
new_type, add_alpha);
if (! GIMP_IS_VECTORS (new_item))
return new_item;