Commit 323ed50c authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

More transform stuff virtualization:

2003-05-07  Michael Natterer  <mitch@gimp.org>

	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.
parent 2a17435e
2003-05-07 Michael Natterer <mitch@gimp.org>
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 <mitch@gimp.org>
Started to abstract item transformation so we can easily
......@@ -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))
floating_sel_relax (layer, TRUE);
{
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_LAYER_RESIZE,
_("Resize Layer"));
floating_sel_relax (layer, TRUE);
}
gimp_layer_resize (layer,
options->resize->width,
options->resize->height,
options->resize->offset_x,
options->resize->offset_y);
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_rigor (layer, TRUE);
{
floating_sel_rigor (layer, TRUE);
gimp_image_undo_group_end (gimage);
gimp_image_undo_group_end (gimage);
}
gimp_image_flush (gimage);
}
......
......@@ -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 */
......
......@@ -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 */
......
......@@ -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 */
......
......@@ -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 */
......
......@@ -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,
......
......@@ -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);
}
......
......@@ -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 */
......
......@@ -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;