From 323ed50c995be0d3dd9896595b0788b16eaee004 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Wed, 7 May 2003 13:01:17 +0000 Subject: [PATCH] More transform stuff virtualization: 2003-05-07 Michael Natterer More transform stuff virtualization: * app/core/gimpitem.[ch]: added new virtual function GimpItem::resize(). * app/core/gimpchannel.[ch] * app/core/gimplayer.[ch]: removed public resize functions and implement resize() instead. * app/core/gimpdrawable.c: implement resize() which contains the common parts of layer/channel resizing. * app/vectors/gimpvectors.c: added empty resize() implementation. * app/core/gimpimage-crop.c * app/core/gimpimage-resize.c * app/gui/layers-commands.c * tools/pdbgen/pdb/layer.pdb: changed accordingly. * app/pdb/layer_cmds.c: regenerated. --- ChangeLog | 23 +++++ app/actions/layers-commands.c | 32 +++--- app/core/gimpchannel-combine.c | 136 ++++++-------------------- app/core/gimpchannel-combine.h | 6 -- app/core/gimpchannel.c | 136 ++++++-------------------- app/core/gimpchannel.h | 6 -- app/core/gimpdrawable.c | 117 ++++++++++++++++++++++ app/core/gimpimage-crop.c | 13 +-- app/core/gimpimage-resize.c | 8 +- app/core/gimpitem.c | 23 ++++- app/core/gimpitem.h | 11 +++ app/core/gimplayer.c | 171 +++++++++------------------------ app/core/gimplayer.h | 6 +- app/gui/layers-commands.c | 32 +++--- app/pdb/layer_cmds.c | 2 +- tools/pdbgen/pdb/layer.pdb | 2 +- 16 files changed, 322 insertions(+), 402 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9be9512495..21db204f2d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2003-05-07 Michael Natterer + + More transform stuff virtualization: + + * app/core/gimpitem.[ch]: added new virtual function + GimpItem::resize(). + + * app/core/gimpchannel.[ch] + * app/core/gimplayer.[ch]: removed public resize functions + and implement resize() instead. + + * app/core/gimpdrawable.c: implement resize() which contains + the common parts of layer/channel resizing. + + * app/vectors/gimpvectors.c: added empty resize() implementation. + + * app/core/gimpimage-crop.c + * app/core/gimpimage-resize.c + * app/gui/layers-commands.c + * tools/pdbgen/pdb/layer.pdb: changed accordingly. + + * app/pdb/layer_cmds.c: regenerated. + 2003-05-07 Michael Natterer Started to abstract item transformation so we can easily diff --git a/app/actions/layers-commands.c b/app/actions/layers-commands.c index 519b75ef0b..7f0c7b83d5 100644 --- a/app/actions/layers-commands.c +++ b/app/actions/layers-commands.c @@ -312,7 +312,7 @@ layers_crop_cmd_callback (GtkWidget *widget, if (gimp_layer_is_floating_sel (active_layer)) floating_sel_relax (active_layer, TRUE); - gimp_layer_resize (active_layer, x2 - x1, y2 - y1, off_x, off_y); + gimp_item_resize (GIMP_ITEM (active_layer), x2 - x1, y2 - y1, off_x, off_y); if (gimp_layer_is_floating_sel (active_layer)) floating_sel_rigor (active_layer, TRUE); @@ -1029,22 +1029,26 @@ resize_layer_query_ok_callback (GtkWidget *widget, if (gimage) { - gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_LAYER_RESIZE, - _("Resize Layer")); + if (gimp_layer_is_floating_sel (layer)) + { + gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_LAYER_RESIZE, + _("Resize Layer")); + + floating_sel_relax (layer, TRUE); + } + + gimp_item_resize (GIMP_ITEM (layer), + options->resize->width, + options->resize->height, + options->resize->offset_x, + options->resize->offset_y); if (gimp_layer_is_floating_sel (layer)) - floating_sel_relax (layer, TRUE); + { + floating_sel_rigor (layer, TRUE); - gimp_layer_resize (layer, - options->resize->width, - options->resize->height, - options->resize->offset_x, - options->resize->offset_y); - - if (gimp_layer_is_floating_sel (layer)) - floating_sel_rigor (layer, TRUE); - - gimp_image_undo_group_end (gimage); + gimp_image_undo_group_end (gimage); + } gimp_image_flush (gimage); } diff --git a/app/core/gimpchannel-combine.c b/app/core/gimpchannel-combine.c index 28f26db154..67dcc7fd3a 100644 --- a/app/core/gimpchannel-combine.c +++ b/app/core/gimpchannel-combine.c @@ -64,6 +64,11 @@ static void gimp_channel_scale (GimpItem *item, gint new_offset_x, gint new_offset_y, GimpInterpolationType interp_type); +static void gimp_channel_resize (GimpItem *item, + gint new_width, + gint new_height, + gint offx, + gint offy); static void gimp_channel_push_undo (GimpChannel *mask, const gchar *undo_desc); @@ -125,6 +130,7 @@ gimp_channel_class_init (GimpChannelClass *klass) item_class->duplicate = gimp_channel_duplicate; item_class->scale = gimp_channel_scale; + item_class->resize = gimp_channel_resize; item_class->default_name = _("Channel"); item_class->rename_desc = _("Rename Channel"); } @@ -249,6 +255,28 @@ gimp_channel_scale (GimpItem *item, channel->bounds_known = FALSE; } +static void +gimp_channel_resize (GimpItem *item, + gint new_width, + gint new_height, + gint offset_x, + gint offset_y) +{ + GimpChannel *channel; + + channel = GIMP_CHANNEL (item); + + gimp_image_undo_push_channel_mod (gimp_item_get_image (item), + _("Resize Channel"), + channel); + + GIMP_ITEM_CLASS (parent_class)->resize (item, new_width, new_height, + offset_x, offset_y); + + /* bounds are now unknown */ + channel->bounds_known = FALSE; +} + static void gimp_channel_push_undo (GimpChannel *mask, const gchar *undo_desc) @@ -451,114 +479,6 @@ gimp_channel_set_show_masked (GimpChannel *channel, } } -void -gimp_channel_resize (GimpChannel *channel, - gint new_width, - gint new_height, - gint offx, - gint offy) -{ - PixelRegion srcPR, destPR; - TileManager *new_tiles; - guchar bg = 0; - gint clear; - gint w, h; - gint x1, y1, x2, y2; - - g_return_if_fail (GIMP_IS_CHANNEL (channel)); - - if (new_width == 0 || new_height == 0) - return; - - x1 = CLAMP (offx, 0, new_width); - y1 = CLAMP (offy, 0, new_height); - x2 = CLAMP ((offx + GIMP_DRAWABLE (channel)->width), 0, new_width); - y2 = CLAMP ((offy + GIMP_DRAWABLE (channel)->height), 0, new_height); - - w = x2 - x1; - h = y2 - y1; - - if (offx > 0) - { - x1 = 0; - x2 = offx; - } - else - { - x1 = -offx; - x2 = 0; - } - - if (offy > 0) - { - y1 = 0; - y2 = offy; - } - else - { - y1 = -offy; - y2 = 0; - } - - /* Update the old channel position */ - gimp_drawable_update (GIMP_DRAWABLE (channel), - 0, 0, - GIMP_DRAWABLE (channel)->width, - GIMP_DRAWABLE (channel)->height); - - /* Configure the pixel regions */ - pixel_region_init (&srcPR, GIMP_DRAWABLE (channel)->tiles, - x1, y1, w, h, FALSE); - - /* Determine whether the new channel needs to be initially cleared */ - if ((new_width > GIMP_DRAWABLE (channel)->width) || - (new_height > GIMP_DRAWABLE (channel)->height) || - (x2 || y2)) - clear = TRUE; - else - clear = FALSE; - - /* Allocate the new channel, configure dest region */ - new_tiles = tile_manager_new (new_width, new_height, 1); - - /* Set to black (empty--for selections) */ - if (clear) - { - pixel_region_init (&destPR, new_tiles, - 0, 0, - new_width, new_height, - TRUE); - - color_region (&destPR, &bg); - } - - /* copy from the old to the new */ - pixel_region_init (&destPR, new_tiles, x2, y2, w, h, TRUE); - if (w && h) - copy_region (&srcPR, &destPR); - - /* Push the channel on the undo stack */ - gimp_image_undo_push_channel_mod (gimp_item_get_image (GIMP_ITEM (channel)), - _("Resize Channel"), - channel); - - /* Configure the new channel */ - GIMP_DRAWABLE (channel)->tiles = new_tiles; - GIMP_DRAWABLE (channel)->width = new_width; - GIMP_DRAWABLE (channel)->height = new_height; - - /* bounds are now unknown */ - channel->bounds_known = FALSE; - - /* update the new channel area */ - gimp_drawable_update (GIMP_DRAWABLE (channel), - 0, 0, - GIMP_DRAWABLE (channel)->width, - GIMP_DRAWABLE (channel)->height); - - gimp_viewable_size_changed (GIMP_VIEWABLE (channel)); -} - /******************************/ /* selection mask functions */ diff --git a/app/core/gimpchannel-combine.h b/app/core/gimpchannel-combine.h index 317e47fa73..f8647201dc 100644 --- a/app/core/gimpchannel-combine.h +++ b/app/core/gimpchannel-combine.h @@ -92,12 +92,6 @@ gboolean gimp_channel_get_show_masked (GimpChannel *channel); void gimp_channel_set_show_masked (GimpChannel *channel, gboolean show_masked); -void gimp_channel_resize (GimpChannel *channel, - gint new_width, - gint new_height, - gint offx, - gint offy); - /* selection mask functions */ diff --git a/app/core/gimpchannel.c b/app/core/gimpchannel.c index 28f26db154..67dcc7fd3a 100644 --- a/app/core/gimpchannel.c +++ b/app/core/gimpchannel.c @@ -64,6 +64,11 @@ static void gimp_channel_scale (GimpItem *item, gint new_offset_x, gint new_offset_y, GimpInterpolationType interp_type); +static void gimp_channel_resize (GimpItem *item, + gint new_width, + gint new_height, + gint offx, + gint offy); static void gimp_channel_push_undo (GimpChannel *mask, const gchar *undo_desc); @@ -125,6 +130,7 @@ gimp_channel_class_init (GimpChannelClass *klass) item_class->duplicate = gimp_channel_duplicate; item_class->scale = gimp_channel_scale; + item_class->resize = gimp_channel_resize; item_class->default_name = _("Channel"); item_class->rename_desc = _("Rename Channel"); } @@ -249,6 +255,28 @@ gimp_channel_scale (GimpItem *item, channel->bounds_known = FALSE; } +static void +gimp_channel_resize (GimpItem *item, + gint new_width, + gint new_height, + gint offset_x, + gint offset_y) +{ + GimpChannel *channel; + + channel = GIMP_CHANNEL (item); + + gimp_image_undo_push_channel_mod (gimp_item_get_image (item), + _("Resize Channel"), + channel); + + GIMP_ITEM_CLASS (parent_class)->resize (item, new_width, new_height, + offset_x, offset_y); + + /* bounds are now unknown */ + channel->bounds_known = FALSE; +} + static void gimp_channel_push_undo (GimpChannel *mask, const gchar *undo_desc) @@ -451,114 +479,6 @@ gimp_channel_set_show_masked (GimpChannel *channel, } } -void -gimp_channel_resize (GimpChannel *channel, - gint new_width, - gint new_height, - gint offx, - gint offy) -{ - PixelRegion srcPR, destPR; - TileManager *new_tiles; - guchar bg = 0; - gint clear; - gint w, h; - gint x1, y1, x2, y2; - - g_return_if_fail (GIMP_IS_CHANNEL (channel)); - - if (new_width == 0 || new_height == 0) - return; - - x1 = CLAMP (offx, 0, new_width); - y1 = CLAMP (offy, 0, new_height); - x2 = CLAMP ((offx + GIMP_DRAWABLE (channel)->width), 0, new_width); - y2 = CLAMP ((offy + GIMP_DRAWABLE (channel)->height), 0, new_height); - - w = x2 - x1; - h = y2 - y1; - - if (offx > 0) - { - x1 = 0; - x2 = offx; - } - else - { - x1 = -offx; - x2 = 0; - } - - if (offy > 0) - { - y1 = 0; - y2 = offy; - } - else - { - y1 = -offy; - y2 = 0; - } - - /* Update the old channel position */ - gimp_drawable_update (GIMP_DRAWABLE (channel), - 0, 0, - GIMP_DRAWABLE (channel)->width, - GIMP_DRAWABLE (channel)->height); - - /* Configure the pixel regions */ - pixel_region_init (&srcPR, GIMP_DRAWABLE (channel)->tiles, - x1, y1, w, h, FALSE); - - /* Determine whether the new channel needs to be initially cleared */ - if ((new_width > GIMP_DRAWABLE (channel)->width) || - (new_height > GIMP_DRAWABLE (channel)->height) || - (x2 || y2)) - clear = TRUE; - else - clear = FALSE; - - /* Allocate the new channel, configure dest region */ - new_tiles = tile_manager_new (new_width, new_height, 1); - - /* Set to black (empty--for selections) */ - if (clear) - { - pixel_region_init (&destPR, new_tiles, - 0, 0, - new_width, new_height, - TRUE); - - color_region (&destPR, &bg); - } - - /* copy from the old to the new */ - pixel_region_init (&destPR, new_tiles, x2, y2, w, h, TRUE); - if (w && h) - copy_region (&srcPR, &destPR); - - /* Push the channel on the undo stack */ - gimp_image_undo_push_channel_mod (gimp_item_get_image (GIMP_ITEM (channel)), - _("Resize Channel"), - channel); - - /* Configure the new channel */ - GIMP_DRAWABLE (channel)->tiles = new_tiles; - GIMP_DRAWABLE (channel)->width = new_width; - GIMP_DRAWABLE (channel)->height = new_height; - - /* bounds are now unknown */ - channel->bounds_known = FALSE; - - /* update the new channel area */ - gimp_drawable_update (GIMP_DRAWABLE (channel), - 0, 0, - GIMP_DRAWABLE (channel)->width, - GIMP_DRAWABLE (channel)->height); - - gimp_viewable_size_changed (GIMP_VIEWABLE (channel)); -} - /******************************/ /* selection mask functions */ diff --git a/app/core/gimpchannel.h b/app/core/gimpchannel.h index 317e47fa73..f8647201dc 100644 --- a/app/core/gimpchannel.h +++ b/app/core/gimpchannel.h @@ -92,12 +92,6 @@ gboolean gimp_channel_get_show_masked (GimpChannel *channel); void gimp_channel_set_show_masked (GimpChannel *channel, gboolean show_masked); -void gimp_channel_resize (GimpChannel *channel, - gint new_width, - gint new_height, - gint offx, - gint offy); - /* selection mask functions */ diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c index 1b81e4d5c9..03fa32a09f 100644 --- a/app/core/gimpdrawable.c +++ b/app/core/gimpdrawable.c @@ -80,6 +80,11 @@ static void gimp_drawable_scale (GimpItem *item, gint new_offset_x, gint new_offset_y, GimpInterpolationType interp_type); +static void gimp_drawable_resize (GimpItem *item, + gint new_width, + gint new_height, + gint offset_x, + gint offset_y); /* private variables */ @@ -152,6 +157,7 @@ gimp_drawable_class_init (GimpDrawableClass *klass) item_class->duplicate = gimp_drawable_duplicate; item_class->scale = gimp_drawable_scale; + item_class->resize = gimp_drawable_resize; klass->visibility_changed = NULL; } @@ -345,6 +351,117 @@ gimp_drawable_scale (GimpItem *item, gimp_viewable_size_changed (GIMP_VIEWABLE (drawable)); } +static void +gimp_drawable_resize (GimpItem *item, + gint new_width, + gint new_height, + gint offset_x, + gint offset_y) +{ + GimpDrawable *drawable; + PixelRegion srcPR, destPR; + TileManager *new_tiles; + gint w, h; + gint x1, y1, x2, y2; + + drawable = GIMP_DRAWABLE (item); + + x1 = CLAMP (offset_x, 0, new_width); + y1 = CLAMP (offset_y, 0, new_height); + x2 = CLAMP (offset_x + drawable->width, 0, new_width); + y2 = CLAMP (offset_y + drawable->height, 0, new_height); + + w = x2 - x1; + h = y2 - y1; + + if (offset_x > 0) + { + x1 = 0; + x2 = offset_x; + } + else + { + x1 = -offset_x; + x2 = 0; + } + + if (offset_y > 0) + { + y1 = 0; + y2 = offset_y; + } + else + { + y1 = -offset_y; + y2 = 0; + } + + /* Update the old position */ + gimp_drawable_update (drawable, 0, 0, drawable->width, drawable->height); + + /* Configure the pixel regions */ + pixel_region_init (&srcPR, drawable->tiles, + x1, y1, + w, h, + FALSE); + + /* Allocate the new tile manager, configure dest region */ + new_tiles = tile_manager_new (new_width, new_height, + drawable->bytes); + + /* Determine whether the new tiles need to be initially cleared */ + if ((new_width > drawable->width) || + (new_height > drawable->height) || + (x2 || y2)) + { + pixel_region_init (&destPR, new_tiles, + 0, 0, + new_width, new_height, + TRUE); + + /* fill with the fill color */ + if (gimp_drawable_has_alpha (drawable) || + GIMP_IS_CHANNEL (drawable) /* EEK */) + { + /* Set to transparent and black */ + guchar bg[4] = { 0, 0, 0, 0 }; + + color_region (&destPR, bg); + } + else + { + guchar bg[3]; + + gimp_image_get_background (gimp_item_get_image (item), + drawable, bg); + color_region (&destPR, bg); + } + } + + /* copy from the old to the new */ + if (w && h) + { + pixel_region_init (&destPR, new_tiles, + x2, y2, + w, h, + TRUE); + + copy_region (&srcPR, &destPR); + } + + /* Configure the new drawable */ + drawable->tiles = new_tiles; + drawable->offset_x = x1 + drawable->offset_x - x2; + drawable->offset_y = y1 + drawable->offset_y - y2; + drawable->width = new_width; + drawable->height = new_height; + + /* update the new area */ + gimp_drawable_update (drawable, 0, 0, drawable->width, drawable->height); + + gimp_viewable_size_changed (GIMP_VIEWABLE (drawable)); +} + void gimp_drawable_configure (GimpDrawable *drawable, GimpImage *gimage, diff --git a/app/core/gimpimage-crop.c b/app/core/gimpimage-crop.c index f3774bf1dc..4d1f7ef44f 100644 --- a/app/core/gimpimage-crop.c +++ b/app/core/gimpimage-crop.c @@ -131,7 +131,7 @@ gimp_image_crop (GimpImage *gimage, if (gimp_layer_is_floating_sel (layer)) floating_sel_relax (layer, TRUE); - gimp_layer_resize (layer, width, height, off_x, off_y); + gimp_item_resize (GIMP_ITEM (layer), width, height, off_x, off_y); if (gimp_layer_is_floating_sel (layer)) floating_sel_rigor (layer, TRUE); @@ -163,11 +163,12 @@ gimp_image_crop (GimpImage *gimage, { channel = (GimpChannel *) list->data; - gimp_channel_resize (channel, width, height, -x1, -y1); + gimp_item_resize (GIMP_ITEM (channel), width, height, -x1, -y1); } /* Don't forget the selection mask! */ - gimp_channel_resize (gimage->selection_mask, width, height, -x1, -y1); + gimp_item_resize (GIMP_ITEM (gimage->selection_mask), + width, height, -x1, -y1); gimp_image_mask_invalidate (gimage); /* crop all layers */ @@ -199,9 +200,9 @@ gimp_image_crop (GimpImage *gimage, height = ly2 - ly1; if (width && height) - gimp_layer_resize (layer, width, height, - -(lx1 - off_x), - -(ly1 - off_y)); + gimp_item_resize (GIMP_ITEM (layer), width, height, + -(lx1 - off_x), + -(ly1 - off_y)); else gimp_image_remove_layer (gimage, layer); } diff --git a/app/core/gimpimage-resize.c b/app/core/gimpimage-resize.c index 9df423979d..7bd8e256fa 100644 --- a/app/core/gimpimage-resize.c +++ b/app/core/gimpimage-resize.c @@ -75,9 +75,9 @@ gimp_image_resize (GimpImage *gimage, list; list = g_list_next (list)) { - GimpChannel *channel = list->data; + GimpItem *item = list->data; - gimp_channel_resize (channel, new_width, new_height, offset_x, offset_y); + gimp_item_resize (item, new_width, new_height, offset_x, offset_y); } /* Reposition or remove any guides */ @@ -115,8 +115,8 @@ gimp_image_resize (GimpImage *gimage, } /* Don't forget the selection mask! */ - gimp_channel_resize (gimage->selection_mask, - new_width, new_height, offset_x, offset_y); + gimp_item_resize (GIMP_ITEM (gimage->selection_mask), + new_width, new_height, offset_x, offset_y); gimp_image_mask_invalidate (gimage); /* Reposition all layers */ diff --git a/app/core/gimpitem.c b/app/core/gimpitem.c index 4086a32dbc..6427b889b8 100644 --- a/app/core/gimpitem.c +++ b/app/core/gimpitem.c @@ -133,6 +133,8 @@ gimp_item_class_init (GimpItemClass *klass) klass->removed = NULL; klass->duplicate = gimp_item_real_duplicate; klass->rename = gimp_item_real_rename; + klass->scale = NULL; + klass->resize = NULL; } static void @@ -334,7 +336,7 @@ gimp_item_scale (GimpItem *item, g_return_if_fail (GIMP_IS_ITEM (item)); - if (new_width == 0 || new_height == 0) + if (new_width < 1 || new_height < 1) return; item_class = GIMP_ITEM_GET_CLASS (item); @@ -343,6 +345,25 @@ gimp_item_scale (GimpItem *item, interpolation_type); } +void +gimp_item_resize (GimpItem *item, + gint new_width, + gint new_height, + gint offset_x, + gint offset_y) +{ + GimpItemClass *item_class; + + g_return_if_fail (GIMP_IS_ITEM (item)); + + if (new_width < 1 || new_height < 1) + return; + + item_class = GIMP_ITEM_GET_CLASS (item); + + item_class->resize (item, new_width, new_height, offset_x, offset_y); +} + gint gimp_item_get_ID (GimpItem *item) { diff --git a/app/core/gimpitem.h b/app/core/gimpitem.h index 0670aa8631..f0e076480a 100644 --- a/app/core/gimpitem.h +++ b/app/core/gimpitem.h @@ -65,6 +65,11 @@ struct _GimpItemClass gint new_offset_x, gint new_offset_y, GimpInterpolationType interpolation_type); + void (* resize) (GimpItem *item, + gint new_width, + gint new_height, + gint offset_x, + gint offset_y); const gchar *default_name; const gchar *rename_desc; @@ -92,6 +97,12 @@ void gimp_item_scale (GimpItem *item, gint new_offset_x, gint new_offset_y, GimpInterpolationType interp_type); +void gimp_item_resize (GimpItem *item, + gint new_width, + gint new_height, + gint offset_x, + gint offset_y); +void gimp_item_resize_to_image (GimpItem *item); gint gimp_item_get_ID (GimpItem *item); GimpItem * gimp_item_get_by_ID (Gimp *gimp, diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c index 6720092ce0..5ae948c683 100644 --- a/app/core/gimplayer.c +++ b/app/core/gimplayer.c @@ -81,6 +81,11 @@ static void gimp_layer_scale (GimpItem *item, gint new_offset_x, gint new_offset_y, GimpInterpolationType interp_type); +static void gimp_layer_resize (GimpItem *item, + gint new_width, + gint new_height, + gint offset_x, + gint offset_y); static void gimp_layer_transform_color (GimpImage *gimage, PixelRegion *layerPR, @@ -192,6 +197,7 @@ gimp_layer_class_init (GimpLayerClass *klass) item_class->duplicate = gimp_layer_duplicate; item_class->rename = gimp_layer_rename; item_class->scale = gimp_layer_scale; + item_class->resize = gimp_layer_resize; item_class->default_name = _("Layer"); item_class->rename_desc = _("Rename Layer"); @@ -362,8 +368,7 @@ gimp_layer_scale (GimpItem *item, GimpLayer *layer; GimpImage *gimage; - layer = GIMP_LAYER (item); - + layer = GIMP_LAYER (item); gimage = gimp_item_get_image (item); if (layer->mask) @@ -391,6 +396,40 @@ gimp_layer_scale (GimpItem *item, gimp_layer_invalidate_boundary (layer); } +static void +gimp_layer_resize (GimpItem *item, + gint new_width, + gint new_height, + gint offset_x, + gint offset_y) +{ + GimpLayer *layer; + GimpImage *gimage; + + layer = GIMP_LAYER (item); + gimage = gimp_item_get_image (item); + + if (layer->mask) + gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_LAYER_RESIZE, + _("Resize Layer")); + + gimp_image_undo_push_layer_mod (gimage, _("Resize Layer"), layer); + + GIMP_ITEM_CLASS (parent_class)->resize (item, new_width, new_height, + offset_x, offset_y); + + if (layer->mask) + { + gimp_item_resize (GIMP_ITEM (layer->mask), + new_width, new_height, offset_x, offset_y); + + gimp_image_undo_group_end (gimage); + } + + /* Make sure we're not caching any old selection info */ + gimp_layer_invalidate_boundary (layer); +} + static void gimp_layer_transform_color (GimpImage *gimage, PixelRegion *layerPR, @@ -1180,131 +1219,6 @@ gimp_layer_scale_by_origin (GimpLayer *layer, interpolation_type); } -void -gimp_layer_resize (GimpLayer *layer, - gint new_width, - gint new_height, - gint offx, - gint offy) -{ - PixelRegion srcPR, destPR; - TileManager *new_tiles; - gint w, h; - gint x1, y1, x2, y2; - - g_return_if_fail (GIMP_IS_LAYER (layer)); - - if (new_width < 1 || new_height < 1) - return; - - x1 = CLAMP (offx, 0, new_width); - y1 = CLAMP (offy, 0, new_height); - x2 = CLAMP ((offx + GIMP_DRAWABLE(layer)->width), 0, new_width); - y2 = CLAMP ((offy + GIMP_DRAWABLE(layer)->height), 0, new_height); - w = x2 - x1; - h = y2 - y1; - - if (offx > 0) - { - x1 = 0; - x2 = offx; - } - else - { - x1 = -offx; - x2 = 0; - } - - if (offy > 0) - { - y1 = 0; - y2 = offy; - } - else - { - y1 = -offy; - y2 = 0; - } - - /* Update the old layer position */ - gimp_drawable_update (GIMP_DRAWABLE (layer), - 0, 0, - GIMP_DRAWABLE (layer)->width, - GIMP_DRAWABLE (layer)->height); - - /* Configure the pixel regions */ - pixel_region_init (&srcPR, GIMP_DRAWABLE (layer)->tiles, - x1, y1, - w, h, - FALSE); - - /* Allocate the new layer, configure dest region */ - new_tiles = tile_manager_new (new_width, new_height, - GIMP_DRAWABLE (layer)->bytes); - pixel_region_init (&destPR, new_tiles, - 0, 0, - new_width, new_height, - TRUE); - - /* fill with the fill color */ - if (gimp_drawable_has_alpha (GIMP_DRAWABLE (layer))) - { - /* Set to transparent and black */ - guchar bg[4] = {0, 0, 0, 0}; - - color_region (&destPR, bg); - } - else - { - guchar bg[3]; - - gimp_image_get_background (gimp_item_get_image (GIMP_ITEM (layer)), - GIMP_DRAWABLE (layer), bg); - color_region (&destPR, bg); - } - - pixel_region_init (&destPR, new_tiles, - x2, y2, - w, h, - TRUE); - - /* copy from the old to the new */ - if (w && h) - copy_region (&srcPR, &destPR); - - /* Push the layer on the undo stack */ - gimp_image_undo_push_layer_mod (gimp_item_get_image (GIMP_ITEM (layer)), - _("Resize Layer"), - layer); - - /* Configure the new layer */ - GIMP_DRAWABLE (layer)->tiles = new_tiles; - GIMP_DRAWABLE (layer)->offset_x = x1 + GIMP_DRAWABLE (layer)->offset_x - x2; - GIMP_DRAWABLE (layer)->offset_y = y1 + GIMP_DRAWABLE (layer)->offset_y - y2; - GIMP_DRAWABLE (layer)->width = new_width; - GIMP_DRAWABLE (layer)->height = new_height; - - /* If there is a layer mask, make sure it gets resized also */ - if (layer->mask) - { - GIMP_DRAWABLE (layer->mask)->offset_x = GIMP_DRAWABLE (layer)->offset_x; - GIMP_DRAWABLE (layer->mask)->offset_y = GIMP_DRAWABLE (layer)->offset_y; - gimp_channel_resize (GIMP_CHANNEL (layer->mask), - new_width, new_height, offx, offy); - } - - /* Make sure we're not caching any old selection info */ - gimp_layer_invalidate_boundary (layer); - - /* update the new layer area */ - gimp_drawable_update (GIMP_DRAWABLE (layer), - 0, 0, - GIMP_DRAWABLE (layer)->width, - GIMP_DRAWABLE (layer)->height); - - gimp_viewable_size_changed (GIMP_VIEWABLE (layer)); -} - void gimp_layer_resize_to_image (GimpLayer *layer) { @@ -1324,7 +1238,8 @@ gimp_layer_resize_to_image (GimpLayer *layer) floating_sel_relax (layer, TRUE); gimp_drawable_offsets (GIMP_DRAWABLE (layer), &offset_x, &offset_y); - gimp_layer_resize (layer, gimage->width, gimage->height, offset_x, offset_y); + gimp_item_resize (GIMP_ITEM (layer), gimage->width, gimage->height, + offset_x, offset_y); if (gimp_layer_is_floating_sel (layer)) floating_sel_rigor (layer, TRUE); diff --git a/app/core/gimplayer.h b/app/core/gimplayer.h index 5ee0fd8749..a0ef831d8f 100644 --- a/app/core/gimplayer.h +++ b/app/core/gimplayer.h @@ -116,11 +116,7 @@ void gimp_layer_scale_by_origin (GimpLayer *layer, gint new_height, GimpInterpolationType interpolation_type, gboolean local_origin); -void gimp_layer_resize (GimpLayer *layer, - gint new_width, - gint new_height, - gint offx, - gint offy); + void gimp_layer_resize_to_image (GimpLayer *layer); BoundSeg * gimp_layer_boundary (GimpLayer *layer, gint *num_segs); diff --git a/app/gui/layers-commands.c b/app/gui/layers-commands.c index 519b75ef0b..7f0c7b83d5 100644 --- a/app/gui/layers-commands.c +++ b/app/gui/layers-commands.c @@ -312,7 +312,7 @@ layers_crop_cmd_callback (GtkWidget *widget, if (gimp_layer_is_floating_sel (active_layer)) floating_sel_relax (active_layer, TRUE); - gimp_layer_resize (active_layer, x2 - x1, y2 - y1, off_x, off_y); + gimp_item_resize (GIMP_ITEM (active_layer), x2 - x1, y2 - y1, off_x, off_y); if (gimp_layer_is_floating_sel (active_layer)) floating_sel_rigor (active_layer, TRUE); @@ -1029,22 +1029,26 @@ resize_layer_query_ok_callback (GtkWidget *widget, if (gimage) { - gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_LAYER_RESIZE, - _("Resize Layer")); + if (gimp_layer_is_floating_sel (layer)) + { + gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_LAYER_RESIZE, + _("Resize Layer")); + + floating_sel_relax (layer, TRUE); + } + + gimp_item_resize (GIMP_ITEM (layer), + options->resize->width, + options->resize->height, + options->resize->offset_x, + options->resize->offset_y); if (gimp_layer_is_floating_sel (layer)) - floating_sel_relax (layer, TRUE); + { + floating_sel_rigor (layer, TRUE); - gimp_layer_resize (layer, - options->resize->width, - options->resize->height, - options->resize->offset_x, - options->resize->offset_y); - - if (gimp_layer_is_floating_sel (layer)) - floating_sel_rigor (layer, TRUE); - - gimp_image_undo_group_end (gimage); + gimp_image_undo_group_end (gimage); + } gimp_image_flush (gimage); } diff --git a/app/pdb/layer_cmds.c b/app/pdb/layer_cmds.c index 519b17c44d..93c13feaed 100644 --- a/app/pdb/layer_cmds.c +++ b/app/pdb/layer_cmds.c @@ -502,7 +502,7 @@ layer_resize_invoker (Gimp *gimp, if (floating_layer) floating_sel_relax (floating_layer, TRUE); - gimp_layer_resize (layer, new_width, new_height, offx, offy); + gimp_item_resize (GIMP_ITEM (layer), new_width, new_height, offx, offy); if (floating_layer) floating_sel_rigor (floating_layer, TRUE); diff --git a/tools/pdbgen/pdb/layer.pdb b/tools/pdbgen/pdb/layer.pdb index a462e6fbb4..9534d060ef 100644 --- a/tools/pdbgen/pdb/layer.pdb +++ b/tools/pdbgen/pdb/layer.pdb @@ -103,7 +103,7 @@ HELP "gimp_layer_scale_by_origin (layer, new_width, new_height, gimp->config->interpolation_type, $args);"); } else { &layer_change_invoke("LAYER_\U$op\E", 'Resize Layer', - "gimp_layer_$op (layer, new_width, new_height, $args);"); + "gimp_item_resize (GIMP_ITEM (layer), new_width, new_height, $args);"); } }