Commit 51b1e61d authored by Sven Neumann's avatar Sven Neumann

Fixed a bug I introduced with the new mem_size_unit for the tile_cache_size.

Applied a patch from Jay Cox. Reimplements selection_grow, selection_shrink
and selection_border using new algorithms => faster and nicer results.


--Sven
parent ef05e30e
Wed Jun 17 17:47:30 MEST 1998 Sven Neumann <sven@gimp.org>
* app/preferences_dialog.c: fixed a bug I introduced with the
new mem_size_unit for the tile_cache_size
Wed Jun 17 16:38:40 MEST 1998 Sven Neumann <sven@gimp.org>
* app/channel.c
* app/paint_funcs.c
* app/paint_funcs.h: applied a patch from Jay Cox.
Reimplements selection_grow, selection_shrink, and selection_border
using new algorithms.
Wed Jun 17 12:07:44 MEST 1998 Sven Neumann <sven@gimp.org>
* app/gimprc.c: default "save_window_positions_on_exit" to FALSE
......
......@@ -1224,80 +1224,120 @@ channel_border (Channel *mask, int radius)
{
PixelRegion bPR;
int x1, y1, x2, y2;
BoundSeg * bs;
unsigned char bg = 0;
int num_segs;
if (radius < 0)
return;
if (! channel_bounds (mask, &x1, &y1, &x2, &y2))
return;
if (x1 - radius < 0)
x1 = 0;
else
x1 -= radius;
if (x2 + radius > GIMP_DRAWABLE(mask)->width)
x2 = GIMP_DRAWABLE(mask)->width;
else
x2 += radius;
if (y1 - radius < 0)
y1 = 0;
else
y1 -= radius;
if (y2 + radius > GIMP_DRAWABLE(mask)->height)
y2 = GIMP_DRAWABLE(mask)->height;
else
y2 += radius;
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
bs = find_mask_boundary (&bPR, &num_segs, WithinBounds, x1, y1, x2, y2);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1,
(x2-x1), (y2-y1), TRUE);
/* clear the channel */
if (mask->bounds_known && !mask->empty)
{
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, mask->x1, mask->y1,
(mask->x2 - mask->x1), (mask->y2 - mask->y1), TRUE);
color_region (&bPR, &bg);
}
else
{
/* clear the mask */
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&bPR, &bg);
}
/* calculate a border of specified radius based on the boundary segments */
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
border_region (&bPR, bs, num_segs, radius);
g_free (bs);
border_region(&bPR, radius);
mask->bounds_known = FALSE;
}
void
channel_grow (Channel *mask, int steps)
channel_grow (Channel *mask, int radius)
{
PixelRegion bPR;
int x1, y1, x2, y2;
if (radius < 0)
{
channel_shrink(mask, -radius);
return;
}
if (! channel_bounds (mask, &x1, &y1, &x2, &y2))
return;
if (channel_is_empty (mask))
return;
if (x1 - radius > 0)
x1 = x1 - radius;
else
x1 = 0;
if (y1 - radius > 0)
y1 = y1 - radius;
else
y1 = 0;
if (x2 + radius< GIMP_DRAWABLE(mask)->width)
x2 = x2 + radius;
else
x2 = GIMP_DRAWABLE(mask)->width;
if (y2 + radius< GIMP_DRAWABLE(mask)->height)
y2 = y2 + radius;
else
y2 = GIMP_DRAWABLE(mask)->height;
/* push the current channel onto the undo stack */
channel_push_undo (mask);
/* need full extents for grow */
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
while (steps--)
thin_region (&bPR, GROW_REGION);
/* need full extents for grow, not! */
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1),
(y2 - y1), TRUE);
fatten_region(&bPR, radius);
mask->bounds_known = FALSE;
}
void
channel_shrink (Channel *mask, int steps)
channel_shrink (Channel *mask, int radius)
{
PixelRegion bPR;
int x1, y1, x2, y2;
if (radius < 0)
{
channel_shrink(mask, -radius);
return;
}
if (! channel_bounds (mask, &x1, &y1, &x2, &y2))
return;
if (channel_is_empty (mask))
return;
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
if (x1 > 0)
x1--;
if (y1 > 0)
y1--;
if (x2 < GIMP_DRAWABLE(mask)->width)
x2++;
if (y2 < GIMP_DRAWABLE(mask)->height)
y2++;
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1),
(y2 - y1), TRUE);
while (steps--)
thin_region (&bPR, SHRINK_REGION);
thin_region (&bPR, radius);
mask->bounds_known = FALSE;
}
......
......@@ -1224,80 +1224,120 @@ channel_border (Channel *mask, int radius)
{
PixelRegion bPR;
int x1, y1, x2, y2;
BoundSeg * bs;
unsigned char bg = 0;
int num_segs;
if (radius < 0)
return;
if (! channel_bounds (mask, &x1, &y1, &x2, &y2))
return;
if (x1 - radius < 0)
x1 = 0;
else
x1 -= radius;
if (x2 + radius > GIMP_DRAWABLE(mask)->width)
x2 = GIMP_DRAWABLE(mask)->width;
else
x2 += radius;
if (y1 - radius < 0)
y1 = 0;
else
y1 -= radius;
if (y2 + radius > GIMP_DRAWABLE(mask)->height)
y2 = GIMP_DRAWABLE(mask)->height;
else
y2 += radius;
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
bs = find_mask_boundary (&bPR, &num_segs, WithinBounds, x1, y1, x2, y2);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1,
(x2-x1), (y2-y1), TRUE);
/* clear the channel */
if (mask->bounds_known && !mask->empty)
{
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, mask->x1, mask->y1,
(mask->x2 - mask->x1), (mask->y2 - mask->y1), TRUE);
color_region (&bPR, &bg);
}
else
{
/* clear the mask */
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&bPR, &bg);
}
/* calculate a border of specified radius based on the boundary segments */
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
border_region (&bPR, bs, num_segs, radius);
g_free (bs);
border_region(&bPR, radius);
mask->bounds_known = FALSE;
}
void
channel_grow (Channel *mask, int steps)
channel_grow (Channel *mask, int radius)
{
PixelRegion bPR;
int x1, y1, x2, y2;
if (radius < 0)
{
channel_shrink(mask, -radius);
return;
}
if (! channel_bounds (mask, &x1, &y1, &x2, &y2))
return;
if (channel_is_empty (mask))
return;
if (x1 - radius > 0)
x1 = x1 - radius;
else
x1 = 0;
if (y1 - radius > 0)
y1 = y1 - radius;
else
y1 = 0;
if (x2 + radius< GIMP_DRAWABLE(mask)->width)
x2 = x2 + radius;
else
x2 = GIMP_DRAWABLE(mask)->width;
if (y2 + radius< GIMP_DRAWABLE(mask)->height)
y2 = y2 + radius;
else
y2 = GIMP_DRAWABLE(mask)->height;
/* push the current channel onto the undo stack */
channel_push_undo (mask);
/* need full extents for grow */
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
while (steps--)
thin_region (&bPR, GROW_REGION);
/* need full extents for grow, not! */
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1),
(y2 - y1), TRUE);
fatten_region(&bPR, radius);
mask->bounds_known = FALSE;
}
void
channel_shrink (Channel *mask, int steps)
channel_shrink (Channel *mask, int radius)
{
PixelRegion bPR;
int x1, y1, x2, y2;
if (radius < 0)
{
channel_shrink(mask, -radius);
return;
}
if (! channel_bounds (mask, &x1, &y1, &x2, &y2))
return;
if (channel_is_empty (mask))
return;
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
if (x1 > 0)
x1--;
if (y1 > 0)
y1--;
if (x2 < GIMP_DRAWABLE(mask)->width)
x2++;
if (y2 < GIMP_DRAWABLE(mask)->height)
y2++;
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1),
(y2 - y1), TRUE);
while (steps--)
thin_region (&bPR, SHRINK_REGION);
thin_region (&bPR, radius);
mask->bounds_known = FALSE;
}
......
......@@ -1224,80 +1224,120 @@ channel_border (Channel *mask, int radius)
{
PixelRegion bPR;
int x1, y1, x2, y2;
BoundSeg * bs;
unsigned char bg = 0;
int num_segs;
if (radius < 0)
return;
if (! channel_bounds (mask, &x1, &y1, &x2, &y2))
return;
if (x1 - radius < 0)
x1 = 0;
else
x1 -= radius;
if (x2 + radius > GIMP_DRAWABLE(mask)->width)
x2 = GIMP_DRAWABLE(mask)->width;
else
x2 += radius;
if (y1 - radius < 0)
y1 = 0;
else
y1 -= radius;
if (y2 + radius > GIMP_DRAWABLE(mask)->height)
y2 = GIMP_DRAWABLE(mask)->height;
else
y2 += radius;
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
bs = find_mask_boundary (&bPR, &num_segs, WithinBounds, x1, y1, x2, y2);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1,
(x2-x1), (y2-y1), TRUE);
/* clear the channel */
if (mask->bounds_known && !mask->empty)
{
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, mask->x1, mask->y1,
(mask->x2 - mask->x1), (mask->y2 - mask->y1), TRUE);
color_region (&bPR, &bg);
}
else
{
/* clear the mask */
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&bPR, &bg);
}
/* calculate a border of specified radius based on the boundary segments */
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
border_region (&bPR, bs, num_segs, radius);
g_free (bs);
border_region(&bPR, radius);
mask->bounds_known = FALSE;
}
void
channel_grow (Channel *mask, int steps)
channel_grow (Channel *mask, int radius)
{
PixelRegion bPR;
int x1, y1, x2, y2;
if (radius < 0)
{
channel_shrink(mask, -radius);
return;
}
if (! channel_bounds (mask, &x1, &y1, &x2, &y2))
return;
if (channel_is_empty (mask))
return;
if (x1 - radius > 0)
x1 = x1 - radius;
else
x1 = 0;
if (y1 - radius > 0)
y1 = y1 - radius;
else
y1 = 0;
if (x2 + radius< GIMP_DRAWABLE(mask)->width)
x2 = x2 + radius;
else
x2 = GIMP_DRAWABLE(mask)->width;
if (y2 + radius< GIMP_DRAWABLE(mask)->height)
y2 = y2 + radius;
else
y2 = GIMP_DRAWABLE(mask)->height;
/* push the current channel onto the undo stack */
channel_push_undo (mask);
/* need full extents for grow */
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
while (steps--)
thin_region (&bPR, GROW_REGION);
/* need full extents for grow, not! */
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1),
(y2 - y1), TRUE);
fatten_region(&bPR, radius);
mask->bounds_known = FALSE;
}
void
channel_shrink (Channel *mask, int steps)
channel_shrink (Channel *mask, int radius)
{
PixelRegion bPR;
int x1, y1, x2, y2;
if (radius < 0)
{
channel_shrink(mask, -radius);
return;
}
if (! channel_bounds (mask, &x1, &y1, &x2, &y2))
return;
if (channel_is_empty (mask))
return;
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
if (x1 > 0)
x1--;
if (y1 > 0)
y1--;
if (x2 < GIMP_DRAWABLE(mask)->width)
x2++;
if (y2 < GIMP_DRAWABLE(mask)->height)
y2++;
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1),
(y2 - y1), TRUE);
while (steps--)
thin_region (&bPR, SHRINK_REGION);
thin_region (&bPR, radius);
mask->bounds_known = FALSE;
}
......
......@@ -111,7 +111,8 @@ static int edit_install_cmap;
static int edit_cycled_marching_ants;
static GtkWidget *tile_cache_size_spinbutton = NULL;
static int mem_size_unit = 1;
static int divided_tile_cache_size;
static int mem_size_unit;
/* Some information regarding preferences, compiled by Raph Levien 11/3/97.
......@@ -191,6 +192,7 @@ static void
file_prefs_ok_callback (GtkWidget *widget,
GtkWidget *dlg)
{
edit_tile_cache_size = mem_size_unit * divided_tile_cache_size;
if (levels_of_undo < 0)
{
......@@ -304,10 +306,10 @@ file_prefs_save_callback (GtkWidget *widget,
stingy_memory_use = edit_stingy_memory_use;
restart_notification = TRUE;
}
if ((edit_tile_cache_size * mem_size_unit) != tile_cache_size)
if (edit_tile_cache_size != tile_cache_size)
{
update = g_list_append (update, "tile-cache-size");
tile_cache_size = edit_tile_cache_size * mem_size_unit;
tile_cache_size = edit_tile_cache_size;
restart_notification = TRUE;
}
if (edit_install_cmap != old_install_cmap)
......@@ -501,17 +503,15 @@ file_prefs_mem_size_unit_callback (GtkWidget *widget,
gpointer data)
{
int new_unit;
int new_size;
new_unit = (int*)data;
if (new_unit != mem_size_unit)
{
new_size = edit_tile_cache_size * mem_size_unit / new_unit;
edit_tile_cache_size = new_size;
divided_tile_cache_size = divided_tile_cache_size * mem_size_unit / new_unit;
mem_size_unit = new_unit;
gtk_spin_button_set_value (GTK_SPIN_BUTTON (tile_cache_size_spinbutton), (float)edit_tile_cache_size);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (tile_cache_size_spinbutton), (float)divided_tile_cache_size);
}
}
......@@ -520,7 +520,7 @@ file_prefs_text_callback (GtkWidget *widget,
gpointer data)
{
int *val;
val = data;
*val = atoi (gtk_entry_get_text (GTK_ENTRY (widget)));
}
......@@ -566,7 +566,6 @@ file_pref_cmd_callback (GtkWidget *widget,
GtkWidget *table;
GtkAdjustment *adj;
GSList *group;
char buffer[32];
char *transparencies[] =
{
"Light Checks",
......@@ -650,8 +649,7 @@ file_pref_cmd_callback (GtkWidget *widget,
edit_plug_in_path = file_prefs_strdup (plug_in_path);
edit_gradient_path = file_prefs_strdup (gradient_path);
edit_stingy_memory_use = stingy_memory_use;
edit_tile_cache_size = tile_cache_size; /* take care! edit_tile_cache_size
will be divided by mem_size_unit */
edit_tile_cache_size = tile_cache_size;
edit_install_cmap = install_cmap;
edit_cycled_marching_ants = cycled_marching_ants;
}
......@@ -687,7 +685,7 @@ file_pref_cmd_callback (GtkWidget *widget,
if (edit_tile_cache_size % mem_size_units[i].unit == 0)
mem_size_unit = mem_size_units[i].unit;
}
edit_tile_cache_size = edit_tile_cache_size / mem_size_unit;
divided_tile_cache_size = edit_tile_cache_size / mem_size_unit;
prefs_dlg = gtk_dialog_new ();
gtk_window_set_wmclass (GTK_WINDOW (prefs_dlg), "preferences", "Gimp");
......@@ -1059,7 +1057,7 @@ file_pref_cmd_callback (GtkWidget *widget,
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
adj = (GtkAdjustment *) gtk_adjustment_new (edit_tile_cache_size, 0.0,
adj = (GtkAdjustment *) gtk_adjustment_new (divided_tile_cache_size, 0.0,
(4069.0 * 1024 * 1024), 1.0,
16.0, 0.0);
tile_cache_size_spinbutton = gtk_spin_button_new (adj, 1.0, 0.0);
......@@ -1071,7 +1069,7 @@ file_pref_cmd_callback (GtkWidget *widget,
gtk_box_pack_start (GTK_BOX (hbox), tile_cache_size_spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (tile_cache_size_spinbutton), "changed",
(GtkSignalFunc) file_prefs_spinbutton_callback,
&edit_tile_cache_size);
&divided_tile_cache_size);
gtk_widget_show (tile_cache_size_spinbutton);
menu = gtk_menu_new ();
......
......@@ -1224,80 +1224,120 @@ channel_border (Channel *mask, int radius)
{
PixelRegion bPR;
int x1, y1, x2, y2;
BoundSeg * bs;
unsigned char bg = 0;
int num_segs;
if (radius < 0)
return;
if (! channel_bounds (mask, &x1, &y1, &x2, &y2))
return;
if (x1 - radius < 0)
x1 = 0;
else
x1 -= radius;
if (x2 + radius > GIMP_DRAWABLE(mask)->width)
x2 = GIMP_DRAWABLE(mask)->width;
else
x2 += radius;
if (y1 - radius < 0)
y1 = 0;
else
y1 -= radius;
if (y2 + radius > GIMP_DRAWABLE(mask)->height)
y2 = GIMP_DRAWABLE(mask)->height;
else
y2 += radius;
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
bs = find_mask_boundary (&bPR, &num_segs, WithinBounds, x1, y1, x2, y2);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1,
(x2-x1), (y2-y1), TRUE);
/* clear the channel */
if (mask->bounds_known && !mask->empty)
{
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, mask->x1, mask->y1,
(mask->x2 - mask->x1), (mask->y2 - mask->y1), TRUE);
color_region (&bPR, &bg);
}
else
{
/* clear the mask */
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&bPR, &bg);
}
/* calculate a border of specified radius based on the boundary segments */
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
border_region (&bPR, bs, num_segs, radius);
g_free (bs);
border_region(&bPR, radius);
mask->bounds_known = FALSE;
}
void
channel_grow (Channel *mask, int steps)
channel_grow (Channel *mask, int radius)
{
PixelRegion bPR;
int x1, y1, x2, y2;
if (radius < 0)
{
channel_shrink(mask, -radius);
return;
}
if (! channel_bounds (mask, &x1, &y1, &x2, &y2))
return;
if (channel_is_empty (mask))
return;
if (x1 - radius > 0)
x1 = x1 - radius;
else
x1 = 0;
if (y1 - radius > 0)
y1 = y1 - radius;
else
y1 = 0;
if (x2 + radius< GIMP_DRAWABLE(mask)->width)
x2 = x2 + radius;
else
x2 = GIMP_DRAWABLE(mask)->width;
if (y2 + radius< GIMP_DRAWABLE(mask)->height)
y2 = y2 + radius;
else
y2 = GIMP_DRAWABLE(mask)->height;
/* push the current channel onto the undo stack */
channel_push_undo (mask);
/* need full extents for grow */
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
while (steps--)
thin_region (&bPR, GROW_REGION);
/* need full extents for grow, not! */
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1),
(y2 - y1), TRUE);
fatten_region(&bPR, radius);
mask->bounds_known = FALSE;
}
void
channel_shrink (Channel *mask, int steps)
channel_shrink (Channel *mask, int radius)
{
PixelRegion bPR;
int x1, y1, x2, y2;
if (radius < 0)
{
channel_shrink(mask, -radius);
return;
}
if (! channel_bounds (mask, &x1, &y1, &x2, &y2))
return;