mirror of https://github.com/GNOME/gimp.git
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:
parent
02d2a673c9
commit
0527989edf
22
ChangeLog
22
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue