Commit 1edd8235 authored by Sven Neumann's avatar Sven Neumann Committed by Sven Neumann
Browse files

do not set the layer mode of the bottom layer to NORMAL_MODE if it is

2000-12-03  Sven Neumann  <sven@gimp.org>

	* app/gimpimage.c: do not set the layer mode of the bottom layer to
	NORMAL_MODE if it is DISSOLVE_MODE since the latter does not work
	on the projection with the lower layer but on the layers alpha
	channel. Fixes bug #7829.
parent ab6f7291
2000-12-03 Sven Neumann <sven@gimp.org>
* app/gimpimage.c: do not set the layer mode of the bottom layer to
NORMAL_MODE if it is DISSOLVE_MODE since the latter does not work
on the projection with the lower layer but on the layers alpha
channel. Fixes bug #7829.
2000-12-03 Michael Natterer <mitch@gimp.org>
 
* app/layers_dialog.c: when applying or deleting the layer mask,
......
......@@ -54,6 +54,7 @@
/* Local function declarations */
static void gimp_image_destroy (GtkObject *object);
static void gimp_image_free_projection (GimpImage *);
static void gimp_image_allocate_shadow (GimpImage *, gint, gint, gint);
static void gimp_image_allocate_projection (GimpImage *);
......@@ -79,7 +80,7 @@ static void project_channel (GimpImage *, Channel *,
/*
* Global variables
*/
int valid_combinations[][MAX_CHANNELS + 1] =
gint valid_combinations[][MAX_CHANNELS + 1] =
{
/* RGB GIMAGE */
{ -1, -1, -1, COMBINE_INTEN_INTEN, COMBINE_INTEN_INTEN_A },
......@@ -114,16 +115,15 @@ enum {
LAST_SIGNAL
};
static void gimp_image_destroy (GtkObject *);
static guint gimp_image_signals[LAST_SIGNAL];
static guint gimp_image_signals[LAST_SIGNAL];
static GimpObjectClass *parent_class;
static void
gimp_image_class_init (GimpImageClass *klass)
{
GtkObjectClass *object_class;
GtkType type;
GtkType type;
object_class = GTK_OBJECT_CLASS(klass);
parent_class = gtk_type_class (gimp_object_get_type ());
......@@ -537,9 +537,10 @@ gimp_image_scale (GimpImage *gimage,
GSList *remove = NULL;
GList *glist;
Guide *guide;
gint old_width, old_height;
gdouble img_scale_w = 1.0;
gdouble img_scale_h = 1.0;
gint old_width;
gint old_height;
gdouble img_scale_w = 1.0;
gdouble img_scale_h = 1.0;
if ((new_width == 0) || (new_height == 0))
{
......@@ -710,12 +711,12 @@ gimp_image_apply_image (GimpImage *gimage,
gint x,
gint y)
{
Channel *mask;
gint x1, y1, x2, y2;
gint offset_x, offset_y;
PixelRegion src1PR, destPR, maskPR;
gint operation;
gint active [MAX_CHANNELS];
Channel *mask;
gint x1, y1, x2, y2;
gint offset_x, offset_y;
PixelRegion src1PR, destPR, maskPR;
gint operation;
gint active [MAX_CHANNELS];
/* get the selection mask if one exists */
mask = (gimage_mask_is_empty (gimage)) ? NULL : gimp_image_get_mask (gimage);
......@@ -779,7 +780,11 @@ gimp_image_apply_image (GimpImage *gimage,
mx = x1 + offset_x;
my = y1 + offset_y;
pixel_region_init (&maskPR, drawable_data (GIMP_DRAWABLE(mask)), mx, my, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&maskPR,
drawable_data (GIMP_DRAWABLE(mask)),
mx, my,
(x2 - x1), (y2 - y1),
FALSE);
combine_regions (&src1PR, src2PR, &destPR, &maskPR, NULL,
opacity, mode, active, operation);
}
......@@ -804,14 +809,14 @@ gimp_image_replace_image (GimpImage *gimage,
gint x,
gint y)
{
Channel *mask;
gint x1, y1, x2, y2;
gint offset_x, offset_y;
PixelRegion src1PR, destPR;
PixelRegion mask2PR, tempPR;
guchar *temp_data;
gint operation;
gint active [MAX_CHANNELS];
Channel *mask;
gint x1, y1, x2, y2;
gint offset_x, offset_y;
PixelRegion src1PR, destPR;
PixelRegion mask2PR, tempPR;
guchar *temp_data;
gint operation;
gint active [MAX_CHANNELS];
/* get the selection mask if one exists */
mask = (gimage_mask_is_empty (gimage)) ? NULL : gimp_image_get_mask (gimage);
......@@ -872,7 +877,11 @@ gimp_image_replace_image (GimpImage *gimage,
mx = x1 + offset_x;
my = y1 + offset_y;
pixel_region_init (&mask2PR, drawable_data (GIMP_DRAWABLE(mask)), mx, my, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&mask2PR,
drawable_data (GIMP_DRAWABLE(mask)),
mx, my,
(x2 - x1), (y2 - y1),
FALSE);
tempPR.bytes = 1;
tempPR.x = 0;
......@@ -943,7 +952,7 @@ gimp_image_get_color_at (GimpImage *gimage,
gint x,
gint y)
{
Tile *tile;
Tile *tile;
guchar *src;
guchar *dest;
......@@ -1154,12 +1163,13 @@ gchar **
gimp_image_parasite_list (GimpImage *gimage,
gint *count)
{
gchar **list, **cur;
gchar **list;
gchar **cur;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);
*count = parasite_list_length (gimage->parasites);
cur = list = (gchar **) g_malloc (sizeof (gchar *) * *count);
cur = list = g_new (gchar*, *count);
parasite_list_foreach (gimage->parasites, (GHFunc) list_func, &cur);
......@@ -1182,12 +1192,7 @@ gimp_image_parasite_attach (GimpImage *gimage,
save (since most save plug-ins attach an undoable comment parasite).
Now we simply attach the parasite without pushing an undo. That way it's
undoable but does not block the undo system. --Sven
else if (gimp_parasite_is_persistent (parasite) &&
!gimp_parasite_compare (parasite,
gimp_image_parasite_find (gimage,
gimp_parasite_name (parasite))))
undo_push_cantundo (gimage, _("attach parasite to image"));
*/
*/
parasite_list_add (gimage->parasites, parasite);
......@@ -1212,11 +1217,6 @@ gimp_image_parasite_detach (GimpImage *gimage,
if (gimp_parasite_is_undoable (p))
undo_push_image_parasite_remove (gimage, gimp_parasite_name (p));
/* see comment in function gimp_image_parasite_attach()
else if (gimp_parasite_is_persistent (p))
undo_push_cantundo (gimage, _("detach parasite from image"));
*/
parasite_list_remove (gimage->parasites, parasite);
}
......@@ -1239,21 +1239,18 @@ gboolean
gimp_image_set_tattoo_state (GimpImage *gimage,
Tattoo val)
{
Layer *layer;
GSList *layers;
gboolean retval = TRUE;
Channel *channel;
GSList *channels;
Tattoo maxval = 0;
Path *pptr = NULL;
Layer *layer;
GSList *layers;
gboolean retval = TRUE;
Channel *channel;
GSList *channels;
Tattoo maxval = 0;
Path *pptr = NULL;
PathList *plist;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
layers = gimage->layers;
channels = gimage->channels;
while (layers)
for (layers = gimage->layers; layers; layers = g_slist_next (layers))
{
Tattoo ltattoo;
layer = (Layer *) layers->data;
......@@ -1271,12 +1268,12 @@ gimp_image_set_tattoo_state (GimpImage *gimage,
{
retval = FALSE; /* Oopps duplicated tattoo in layer */
}
layers = g_slist_next (layers);
}
/* Now check that the paths channel tattoos don't overlap */
while (channels)
for (channels = gimage->channels;
channels;
channels = g_slist_next (channels))
{
Tattoo ctattoo;
channel = (Channel *) channels->data;
......@@ -1289,18 +1286,15 @@ gimp_image_set_tattoo_state (GimpImage *gimage,
{
retval = FALSE; /* Oopps duplicated tattoo in layer */
}
channels = g_slist_next (channels);
}
/* Find the max tatto value in the paths */
plist = gimage->paths;
if (plist && plist->bz_paths)
{
Tattoo ptattoo;
GSList *pl = plist->bz_paths;
Tattoo ptattoo;
while (pl)
{
......@@ -1317,7 +1311,6 @@ gimp_image_set_tattoo_state (GimpImage *gimage,
if (val < maxval)
retval = FALSE;
/* Must check the state is valid */
if (retval == TRUE)
gimage->tattoo_state = val;
......@@ -1447,14 +1440,13 @@ project_channel (GimpImage *gimage,
static void
gimp_image_free_layers (GimpImage *gimage)
{
GSList *list = gimage->layers;
GSList *list;
Layer *layer;
while (list)
for (list = gimage->layers; list; list = g_slist_next (list))
{
layer = (Layer *) list->data;
layer_delete (layer);
list = g_slist_next (list);
}
g_slist_free (gimage->layers);
g_slist_free (gimage->layer_stack);
......@@ -1464,14 +1456,13 @@ gimp_image_free_layers (GimpImage *gimage)
static void
gimp_image_free_channels (GimpImage *gimage)
{
GSList *list = gimage->channels;
GSList *list;
Channel *channel;
while (list)
for (list = gimage->channels; list; list = g_slist_next (list))
{
channel = (Channel *) list->data;
channel_delete (channel);
list = g_slist_next (list);
}
g_slist_free (gimage->channels);
}
......@@ -1484,23 +1475,19 @@ gimp_image_construct_layers (GimpImage *gimage,
gint w,
gint h)
{
Layer * layer;
gint x1, y1, x2, y2;
PixelRegion src1PR, src2PR, maskPR;
Layer *layer;
gint x1, y1, x2, y2;
PixelRegion src1PR, src2PR, maskPR;
PixelRegion * mask;
GSList *list = gimage->layers;
GSList *reverse_list = NULL;
gint off_x, off_y;
GSList *list;
GSList *reverse_list = NULL;
gint off_x;
gint off_y;
/* composite the floating selection if it exists */
if ((layer = gimp_image_floating_sel (gimage)))
floating_sel_composite (layer, x, y, w, h, FALSE);
if (!list)
{
/* g_warning("g_i_c_l on layerless image."); */
}
/* Note added by Raph Levien, 27 Jan 1998
This looks it was intended as an optimization, but it seems to
......@@ -1532,15 +1519,15 @@ gimp_image_construct_layers (GimpImage *gimage,
}
#endif
while (list)
for (list = gimage->layers; list; list = g_slist_next (list))
{
layer = (Layer *) list->data;
/* only add layers that are visible and not floating selections to the list */
if (!layer_is_floating_sel (layer) && drawable_visible (GIMP_DRAWABLE(layer)))
/* only add layers that are visible and not floating selections
to the list */
if (!layer_is_floating_sel (layer) &&
drawable_visible (GIMP_DRAWABLE(layer)))
reverse_list = g_slist_prepend (reverse_list, layer);
list = g_slist_next (list);
}
while (reverse_list)
......@@ -1554,12 +1541,15 @@ gimp_image_construct_layers (GimpImage *gimage,
y2 = CLAMP (off_y + drawable_height (GIMP_DRAWABLE(layer)), y, y + h);
/* configure the pixel regions */
pixel_region_init (&src1PR, gimp_image_projection (gimage), x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&src1PR, gimp_image_projection (gimage),
x1, y1, (x2 - x1), (y2 - y1),
TRUE);
/* If we're showing the layer mask instead of the layer... */
if (layer->mask && layer->show_mask)
{
pixel_region_init (&src2PR, drawable_data (GIMP_DRAWABLE(layer->mask)),
pixel_region_init (&src2PR,
drawable_data (GIMP_DRAWABLE(layer->mask)),
(x1 - off_x), (y1 - off_y),
(x2 - x1), (y2 - y1), FALSE);
......@@ -1568,13 +1558,15 @@ gimp_image_construct_layers (GimpImage *gimage,
/* Otherwise, normal */
else
{
pixel_region_init (&src2PR, drawable_data (GIMP_DRAWABLE(layer)),
pixel_region_init (&src2PR,
drawable_data (GIMP_DRAWABLE (layer)),
(x1 - off_x), (y1 - off_y),
(x2 - x1), (y2 - y1), FALSE);
if (layer->mask && layer->apply_mask)
{
pixel_region_init (&maskPR, drawable_data (GIMP_DRAWABLE(layer->mask)),
pixel_region_init (&maskPR,
drawable_data (GIMP_DRAWABLE (layer->mask)),
(x1 - off_x), (y1 - off_y),
(x2 - x1), (y2 - y1), FALSE);
mask = &maskPR;
......@@ -1591,16 +1583,20 @@ gimp_image_construct_layers (GimpImage *gimage,
/* no mask possible */
project_intensity (gimage, layer, &src2PR, &src1PR, mask);
break;
case RGBA_GIMAGE: case GRAYA_GIMAGE:
project_intensity_alpha (gimage, layer, &src2PR, &src1PR, mask);
break;
case INDEXED_GIMAGE:
/* no mask possible */
project_indexed (gimage, layer, &src2PR, &src1PR);
break;
case INDEXEDA_GIMAGE:
project_indexed_alpha (gimage, layer, &src2PR, &src1PR, mask);
break;
default:
break;
}
......@@ -1620,32 +1616,28 @@ gimp_image_construct_channels (GimpImage *gimage,
gint w,
gint h)
{
Channel * channel;
PixelRegion src1PR, src2PR;
GSList *list = gimage->channels;
GSList *reverse_list = NULL;
if (!list)
{
/* g_warning("g_i_c_c on channelless image."); */
}
Channel *channel;
PixelRegion src1PR, src2PR;
GSList *list;
GSList *reverse_list = NULL;
/* reverse the channel list */
while (list)
{
reverse_list = g_slist_prepend (reverse_list, list->data);
list = g_slist_next (list);
}
for (list = gimage->channels; list; list = g_slist_next (list))
reverse_list = g_slist_prepend (reverse_list, list->data);
while (reverse_list)
{
channel = (Channel *) reverse_list->data;
if (drawable_visible (GIMP_DRAWABLE(channel)))
if (drawable_visible (GIMP_DRAWABLE (channel)))
{
/* configure the pixel regions */
pixel_region_init (&src1PR, gimp_image_projection (gimage), x, y, w, h, TRUE);
pixel_region_init (&src2PR, drawable_data (GIMP_DRAWABLE(channel)), x, y, w, h, FALSE);
pixel_region_init (&src1PR, gimp_image_projection (gimage),
x, y, w, h,
TRUE);
pixel_region_init (&src2PR, drawable_data (GIMP_DRAWABLE(channel)),
x, y, w, h,
FALSE);
project_channel (gimage, channel, &src1PR, &src2PR);
......@@ -1665,22 +1657,24 @@ gimp_image_initialize_projection (GimpImage *gimage,
gint w,
gint h)
{
GSList *list;
Layer *layer;
gint coverage = 0;
PixelRegion PR;
guchar clear[4] = { 0, 0, 0, 0 };
GSList *list;
Layer *layer;
gint coverage = 0;
PixelRegion PR;
guchar clear[4] = { 0, 0, 0, 0 };
/* this function determines whether a visible layer
* provides complete coverage over the image. If not,
* the projection is initialized to transparent
*/
list = gimage->layers;
while (list)
for (list = gimage->layers; list; list = g_slist_next (list))
{
int off_x, off_y;
gint off_x, off_y;
layer = (Layer *) list->data;
drawable_offsets (GIMP_DRAWABLE(layer), &off_x, &off_y);
if (drawable_visible (GIMP_DRAWABLE(layer)) &&
! layer_has_alpha (layer) &&
(off_x <= x) &&
......@@ -1691,13 +1685,12 @@ gimp_image_initialize_projection (GimpImage *gimage,
coverage = 1;
break;
}
list = g_slist_next (list);
}
if (!coverage)
{
pixel_region_init (&PR, gimp_image_projection (gimage), x, y, w, h, TRUE);
pixel_region_init (&PR, gimp_image_projection (gimage),
x, y, w, h, TRUE);
color_region (&PR, clear);
}
}
......@@ -1707,8 +1700,8 @@ gimp_image_get_active_channels (GimpImage *gimage,
GimpDrawable *drawable,
gint *active)
{
Layer * layer;
gint i;
Layer *layer;
gint i;
/* first, blindly copy the gimage active channels */
for (i = 0; i < MAX_CHANNELS; i++)
......@@ -1744,7 +1737,8 @@ gimp_image_construct (GimpImage *gimage,
g_return_if_fail (GIMP_IS_IMAGE (gimage));
#if 0
gint xoff, yoff;
gint xoff;
gint yoff;
/* set the construct flag, used to determine if anything
* has been written to the gimage raw image yet.
......@@ -1762,26 +1756,27 @@ gimp_image_construct (GimpImage *gimage,
(!g_slist_next(gimage->layers)) && /* It's the only layer. */
(layer_has_alpha((Layer*)(gimage->layers->data))) && /* It's !flat. */
/* It's visible. */
(drawable_visible (GIMP_DRAWABLE((Layer*)(gimage->layers->data)))) &&
(drawable_width (GIMP_DRAWABLE((Layer*)(gimage->layers->data))) ==
(drawable_visible (GIMP_DRAWABLE ((Layer*)(gimage->layers->data)))) &&
(drawable_width (GIMP_DRAWABLE ((Layer*)(gimage->layers->data))) ==
gimage->width) &&
(drawable_height (GIMP_DRAWABLE((Layer*)(gimage->layers->data))) ==
(drawable_height (GIMP_DRAWABLE ((Layer*)(gimage->layers->data))) ==
gimage->height) && /* Covers all. */
/* Not indexed. */
(!drawable_indexed (GIMP_DRAWABLE((Layer*)(gimage->layers->data)))) &&
(!drawable_indexed (GIMP_DRAWABLE ((Layer*)(gimage->layers->data)))) &&
(((Layer*)(gimage->layers->data))->opacity == OPAQUE_OPACITY) /*opaq */
)
{
int xoff, yoff;
gint xoff;
gint yoff;
gimp_drawable_offsets (GIMP_DRAWABLE((Layer*)(gimage->layers->data)),
gimp_drawable_offsets (GIMP_DRAWABLE ((Layer*)(gimage->layers->data)),
&xoff, &yoff);
if ((xoff==0) && (yoff==0)) /* Starts at 0,0 */
{
PixelRegion srcPR, destPR;
void * pr;
gpointer pr;
g_warning("Can use cow-projection hack. Yay!");
......@@ -1803,6 +1798,7 @@ gimp_image_construct (GimpImage *gimage,
gimage->construct_flag = 1;
gimp_image_construct_channels (gimage, x, y, w, h);
return;
}
}
......@@ -1835,9 +1831,9 @@ gimp_image_invalidate_without_render (GimpImage *gimage,
gint x2,
gint y2)
{
Tile *tile;
Tile *tile;
TileManager *tm;
gint i, j;
gint i, j;
g_return_if_fail (GIMP_IS_IMAGE (gimage));
......@@ -1874,12 +1870,12 @@ gimp_image_invalidate (GimpImage *gimage,
gint x2,
gint y2)
{
Tile *tile;
Tile *tile;
TileManager *tm;
gint i, j;
gint startx, starty;
gint endx, endy;
gint tilex, tiley;
gint i, j;
gint startx, starty;
gint endx, endy;
gint tilex, tiley;
g_return_if_fail (GIMP_IS_IMAGE (gimage));
......@@ -1887,8 +1883,8 @@ gimp_image_invalidate (GimpImage *gimage,
startx = x;
starty = y;
endx = x + w;
endy = y + h;
endx = x + w;
endy = y + h;
/* invalidate all tiles which are located outside of the displayed area
* all tiles inside the displayed area are constructed.
......@@ -1898,9 +1894,6 @@ gimp_image_invalidate (GimpImage *gimage,
{
tile = tile_manager_get_tile (tm, j, i, FALSE, FALSE);
/* invalidate all lower level tiles */
/*tile_manager_invalidate_tiles (gimp_image_projection (gimage), tile);*/
/* check if the tile is outside the bounds */
if ((MIN ((j + tile_ewidth(tile)), x2) - MAX (j, x1)) <= 0)
{
......@@ -1939,7 +1932,10 @@ gimp_image_invalidate (GimpImage *gimage,
}
if ((endx - startx) > 0 && (endy - starty) > 0)
gimp_image_construct (gimage, startx, starty, (endx - startx), (endy - starty), TRUE);
gimp_image_construct (gimage,
startx, starty,
(endx - startx), (endy - starty),
TRUE);
}
void
......@@ -1947,8 +1943,8 @@ gimp_image_validate (TileManager *tm,
Tile *tile)
{
GimpImage *gimage;
gint x, y;
gint w, h;
gint x, y;
gint w, h;
gimp_add_busy_cursors_until_idle ();
......@@ -1967,21 +1963,19 @@ gint
gimp_image_get_layer_index (GimpImage *gimage,
Layer *layer_arg)
{
Layer *layer;
Layer *layer;
GSList *layers;
gint index = 0;