Implemented #7100 (initialize layer mask with a copy of the image)

2002-02-20  Michael Natterer  <mitch@gimp.org>

	Implemented #7100 (initialize layer mask with a copy of the image)

	* app/core/core-types.h: added ADD_COPY_MASK and ADD_INV_COPY_MASK
	enum values.

	* app/pdb/layer_cmds.c
	* libgimp/gimpenums.h
	* plug-ins/script-fu/script-fu-constants.c
	* tools/pdbgen/enums.pl: regenerated.

	* app/core/gimplayer.c (gimp_layer_create_mask): implement
	the new layer mask add modes.

	* app/gui/layers-commands.c (layers_add_mask_query): added radio
	buttons for the new modes.

	* app/paint-funcs/paint-funcs.c (flatten_region): this function
	was never needed so nobody noticed that it never worked. Fixed now.

	* app/undo.c
	* app/core/gimplayermask.h
	* app/core/gimpimage.c: the "mode" field of LayerMaskUndo is
	obsolete since some earlier 1.3 layer mask change. Removed it.
	(Makes mask undos work again)
This commit is contained in:
Michael Natterer 2002-02-20 16:15:53 +00:00 committed by Michael Natterer
parent a49635e235
commit bc7c7f3216
13 changed files with 229 additions and 107 deletions

View File

@ -1,3 +1,30 @@
2002-02-20 Michael Natterer <mitch@gimp.org>
Implemented #7100 (initialize layer mask with a copy of the image)
* app/core/core-types.h: added ADD_COPY_MASK and ADD_INV_COPY_MASK
enum values.
* app/pdb/layer_cmds.c
* libgimp/gimpenums.h
* plug-ins/script-fu/script-fu-constants.c
* tools/pdbgen/enums.pl: regenerated.
* app/core/gimplayer.c (gimp_layer_create_mask): implement
the new layer mask add modes.
* app/gui/layers-commands.c (layers_add_mask_query): added radio
buttons for the new modes.
* app/paint-funcs/paint-funcs.c (flatten_region): this function
was never needed so nobody noticed that it never worked. Fixed now.
* app/undo.c
* app/core/gimplayermask.h
* app/core/gimpimage.c: the "mode" field of LayerMaskUndo is
obsolete since some earlier 1.3 layer mask change. Removed it.
(Makes mask undos work again)
2002-02-20 Michael Natterer <mitch@gimp.org>
Implemented #10125 ("quick" colour picker does not honour

View File

@ -922,40 +922,54 @@ layers_add_mask_query (GimpLayer *layer)
{
options->add_mask_type = ADD_SELECTION_MASK;
frame = gimp_radio_group_new2 (TRUE, _("Initialize Layer Mask to:"),
G_CALLBACK (gimp_radio_button_update),
&options->add_mask_type,
GINT_TO_POINTER (options->add_mask_type),
frame =
gimp_radio_group_new2 (TRUE, _("Initialize Layer Mask to:"),
G_CALLBACK (gimp_radio_button_update),
&options->add_mask_type,
GINT_TO_POINTER (options->add_mask_type),
_("Selection"),
GINT_TO_POINTER (ADD_SELECTION_MASK), NULL,
_("Inverse Selection"),
GINT_TO_POINTER (ADD_INV_SELECTION_MASK), NULL,
_("White (Full Opacity)"),
GINT_TO_POINTER (ADD_WHITE_MASK), NULL,
_("Black (Full Transparency)"),
GINT_TO_POINTER (ADD_BLACK_MASK), NULL,
_("Layer's Alpha Channel"),
GINT_TO_POINTER (ADD_ALPHA_MASK), NULL,
_("Selection"),
GINT_TO_POINTER (ADD_SELECTION_MASK), NULL,
_("Inverse Selection"),
GINT_TO_POINTER (ADD_INV_SELECTION_MASK), NULL,
NULL);
_("Grayscale Copy of Layer"),
GINT_TO_POINTER (ADD_COPY_MASK), NULL,
_("Inverse Grayscale Copy of Layer"),
GINT_TO_POINTER (ADD_INV_COPY_MASK), NULL,
_("White (Full Opacity)"),
GINT_TO_POINTER (ADD_WHITE_MASK), NULL,
_("Black (Full Transparency)"),
GINT_TO_POINTER (ADD_BLACK_MASK), NULL,
_("Layer's Alpha Channel"),
GINT_TO_POINTER (ADD_ALPHA_MASK), NULL,
NULL);
}
else
{
frame = gimp_radio_group_new2 (TRUE, _("Initialize Layer Mask to:"),
G_CALLBACK (gimp_radio_button_update),
&options->add_mask_type,
GINT_TO_POINTER (options->add_mask_type),
frame =
gimp_radio_group_new2 (TRUE, _("Initialize Layer Mask to:"),
G_CALLBACK (gimp_radio_button_update),
&options->add_mask_type,
GINT_TO_POINTER (options->add_mask_type),
_("White (Full Opacity)"),
GINT_TO_POINTER (ADD_WHITE_MASK), NULL,
_("Black (Full Transparency)"),
GINT_TO_POINTER (ADD_BLACK_MASK), NULL,
_("Layer's Alpha Channel"),
GINT_TO_POINTER (ADD_ALPHA_MASK), NULL,
_("Grayscale Copy of Layer"),
GINT_TO_POINTER (ADD_COPY_MASK), NULL,
_("Inverse Grayscale Copy of Layer"),
GINT_TO_POINTER (ADD_INV_COPY_MASK), NULL,
NULL);
_("White (Full Opacity)"),
GINT_TO_POINTER (ADD_WHITE_MASK), NULL,
_("Black (Full Transparency)"),
GINT_TO_POINTER (ADD_BLACK_MASK), NULL,
_("Layer's Alpha Channel"),
GINT_TO_POINTER (ADD_ALPHA_MASK), NULL,
NULL);
}
gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (options->query_box)->vbox),
frame);

View File

@ -40,7 +40,9 @@ typedef enum /*< chop=ADD_ >*/
ADD_BLACK_MASK,
ADD_ALPHA_MASK,
ADD_SELECTION_MASK,
ADD_INV_SELECTION_MASK
ADD_INV_SELECTION_MASK,
ADD_COPY_MASK,
ADD_INV_COPY_MASK
} AddMaskType;
typedef enum

View File

@ -1718,7 +1718,7 @@ undo_pop_layer_mask (GimpImage *gimage,
if ((state == UNDO && type == LAYER_MASK_ADD_UNDO) ||
(state == REDO && type == LAYER_MASK_REMOVE_UNDO))
{
gimp_layer_apply_mask (lmu->layer, lmu->mode, FALSE);
gimp_layer_apply_mask (lmu->layer, DISCARD, FALSE);
}
/* restore layer */
else

View File

@ -606,83 +606,135 @@ GimpLayerMask *
gimp_layer_create_mask (const GimpLayer *layer,
AddMaskType add_mask_type)
{
PixelRegion maskPR;
PixelRegion layerPR;
PixelRegion srcPR;
PixelRegion destPR;
GimpLayerMask *mask;
GimpImage *gimage;
GimpDrawable *selection;
gchar *mask_name;
GimpRGB black = { 0.0, 0.0, 0.0, 1.0 };
guchar white_mask = OPAQUE_OPACITY;
guchar black_mask = TRANSPARENT_OPACITY;
gimage = GIMP_DRAWABLE (layer)->gimage;
selection = GIMP_DRAWABLE(gimage->selection_mask);
gimage = gimp_drawable_gimage (GIMP_DRAWABLE (layer));
mask_name = g_strdup_printf (_("%s mask"),
gimp_object_get_name (GIMP_OBJECT (layer)));
/* Create the layer mask */
mask = gimp_layer_mask_new (GIMP_DRAWABLE (layer)->gimage,
GIMP_DRAWABLE (layer)->width,
GIMP_DRAWABLE (layer)->height,
mask_name, &black);
g_free (mask_name);
GIMP_DRAWABLE (mask)->offset_x = GIMP_DRAWABLE (layer)->offset_x;
GIMP_DRAWABLE (mask)->offset_y = GIMP_DRAWABLE (layer)->offset_y;
pixel_region_init (&maskPR, GIMP_DRAWABLE (mask)->tiles,
pixel_region_init (&destPR, GIMP_DRAWABLE (mask)->tiles,
0, 0,
GIMP_DRAWABLE (mask)->width, GIMP_DRAWABLE (mask)->height,
GIMP_DRAWABLE (mask)->width,
GIMP_DRAWABLE (mask)->height,
TRUE);
switch (add_mask_type)
{
case ADD_WHITE_MASK:
color_region (&maskPR, &white_mask);
{
guchar white_mask = OPAQUE_OPACITY;
color_region (&destPR, &white_mask);
}
break;
case ADD_BLACK_MASK:
color_region (&maskPR, &black_mask);
{
guchar black_mask = TRANSPARENT_OPACITY;
color_region (&destPR, &black_mask);
}
break;
case ADD_ALPHA_MASK:
/* Extract the layer's alpha channel */
if (gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
{
pixel_region_init (&layerPR, GIMP_DRAWABLE (layer)->tiles,
pixel_region_init (&srcPR, GIMP_DRAWABLE (layer)->tiles,
0, 0,
GIMP_DRAWABLE (layer)->width,
GIMP_DRAWABLE (layer)->height,
FALSE);
extract_alpha_region (&layerPR, NULL, &maskPR);
extract_alpha_region (&srcPR, NULL, &destPR);
}
break;
case ADD_SELECTION_MASK:
pixel_region_init (&layerPR, GIMP_DRAWABLE (selection)->tiles,
GIMP_DRAWABLE (layer)->offset_x,
GIMP_DRAWABLE (layer)->offset_y,
GIMP_DRAWABLE (layer)->width,
GIMP_DRAWABLE (layer)->height,
FALSE);
copy_region (&layerPR, &maskPR);
break;
case ADD_SELECTION_MASK:
case ADD_INV_SELECTION_MASK:
{
GimpDrawable *selection;
case ADD_INV_SELECTION_MASK:
pixel_region_init (&layerPR, GIMP_DRAWABLE (selection)->tiles,
GIMP_DRAWABLE (layer)->offset_x,
GIMP_DRAWABLE (layer)->offset_y,
GIMP_DRAWABLE (layer)->width,
GIMP_DRAWABLE (layer)->height,
FALSE);
copy_region (&layerPR, &maskPR);
selection = GIMP_DRAWABLE (gimage->selection_mask);
gimp_drawable_invert (GIMP_DRAWABLE (mask));
break;
pixel_region_init (&srcPR, GIMP_DRAWABLE (selection)->tiles,
GIMP_DRAWABLE (layer)->offset_x,
GIMP_DRAWABLE (layer)->offset_y,
GIMP_DRAWABLE (layer)->width,
GIMP_DRAWABLE (layer)->height,
FALSE);
copy_region (&srcPR, &destPR);
}
break;
case ADD_COPY_MASK:
case ADD_INV_COPY_MASK:
{
TileManager *copy_tiles;
GimpImageType layer_type;
GimpImageType copy_type;
guchar black_uchar[] = { 0, 0, 0, 0 };
layer_type = GIMP_DRAWABLE (layer)->type;
copy_type = (GIMP_IMAGE_TYPE_HAS_ALPHA (layer_type) ?
GIMP_GRAYA_IMAGE : GIMP_GRAY_IMAGE);
copy_tiles = tile_manager_new (GIMP_DRAWABLE (layer)->width,
GIMP_DRAWABLE (layer)->height,
GIMP_IMAGE_TYPE_BYTES (copy_type));
gimp_drawable_convert_grayscale (GIMP_DRAWABLE (layer),
copy_tiles,
GIMP_IMAGE_TYPE_BASE_TYPE (layer_type));
pixel_region_init (&srcPR, copy_tiles,
0, 0,
GIMP_DRAWABLE (layer)->width,
GIMP_DRAWABLE (layer)->height,
FALSE);
if (gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
{
flatten_region (&srcPR, &destPR, black_uchar);
}
else
{
copy_region (&srcPR, &destPR);
}
tile_manager_destroy (copy_tiles);
}
}
g_free (mask_name);
switch (add_mask_type)
{
case ADD_WHITE_MASK:
case ADD_BLACK_MASK:
case ADD_ALPHA_MASK:
case ADD_SELECTION_MASK:
case ADD_COPY_MASK:
break;
case ADD_INV_SELECTION_MASK:
case ADD_INV_COPY_MASK:
gimp_drawable_invert (GIMP_DRAWABLE (mask));
break;
}
return mask;
}
@ -723,7 +775,6 @@ gimp_layer_apply_mask (GimpLayer *layer,
lmu = g_new (LayerMaskUndo, 1);
lmu->layer = layer;
lmu->mask = layer->mask;
lmu->mode = mode;
}
/* check if applying the mask changes the projection */

View File

@ -60,7 +60,6 @@ struct _LayerMaskUndo
{
GimpLayer *layer; /* the layer */
GimpLayerMask *mask; /* the layer mask */
gint mode; /* the application mode */
};

View File

@ -922,40 +922,54 @@ layers_add_mask_query (GimpLayer *layer)
{
options->add_mask_type = ADD_SELECTION_MASK;
frame = gimp_radio_group_new2 (TRUE, _("Initialize Layer Mask to:"),
G_CALLBACK (gimp_radio_button_update),
&options->add_mask_type,
GINT_TO_POINTER (options->add_mask_type),
frame =
gimp_radio_group_new2 (TRUE, _("Initialize Layer Mask to:"),
G_CALLBACK (gimp_radio_button_update),
&options->add_mask_type,
GINT_TO_POINTER (options->add_mask_type),
_("Selection"),
GINT_TO_POINTER (ADD_SELECTION_MASK), NULL,
_("Inverse Selection"),
GINT_TO_POINTER (ADD_INV_SELECTION_MASK), NULL,
_("White (Full Opacity)"),
GINT_TO_POINTER (ADD_WHITE_MASK), NULL,
_("Black (Full Transparency)"),
GINT_TO_POINTER (ADD_BLACK_MASK), NULL,
_("Layer's Alpha Channel"),
GINT_TO_POINTER (ADD_ALPHA_MASK), NULL,
_("Selection"),
GINT_TO_POINTER (ADD_SELECTION_MASK), NULL,
_("Inverse Selection"),
GINT_TO_POINTER (ADD_INV_SELECTION_MASK), NULL,
NULL);
_("Grayscale Copy of Layer"),
GINT_TO_POINTER (ADD_COPY_MASK), NULL,
_("Inverse Grayscale Copy of Layer"),
GINT_TO_POINTER (ADD_INV_COPY_MASK), NULL,
_("White (Full Opacity)"),
GINT_TO_POINTER (ADD_WHITE_MASK), NULL,
_("Black (Full Transparency)"),
GINT_TO_POINTER (ADD_BLACK_MASK), NULL,
_("Layer's Alpha Channel"),
GINT_TO_POINTER (ADD_ALPHA_MASK), NULL,
NULL);
}
else
{
frame = gimp_radio_group_new2 (TRUE, _("Initialize Layer Mask to:"),
G_CALLBACK (gimp_radio_button_update),
&options->add_mask_type,
GINT_TO_POINTER (options->add_mask_type),
frame =
gimp_radio_group_new2 (TRUE, _("Initialize Layer Mask to:"),
G_CALLBACK (gimp_radio_button_update),
&options->add_mask_type,
GINT_TO_POINTER (options->add_mask_type),
_("White (Full Opacity)"),
GINT_TO_POINTER (ADD_WHITE_MASK), NULL,
_("Black (Full Transparency)"),
GINT_TO_POINTER (ADD_BLACK_MASK), NULL,
_("Layer's Alpha Channel"),
GINT_TO_POINTER (ADD_ALPHA_MASK), NULL,
_("Grayscale Copy of Layer"),
GINT_TO_POINTER (ADD_COPY_MASK), NULL,
_("Inverse Grayscale Copy of Layer"),
GINT_TO_POINTER (ADD_INV_COPY_MASK), NULL,
NULL);
_("White (Full Opacity)"),
GINT_TO_POINTER (ADD_WHITE_MASK), NULL,
_("Black (Full Transparency)"),
GINT_TO_POINTER (ADD_BLACK_MASK), NULL,
_("Layer's Alpha Channel"),
GINT_TO_POINTER (ADD_ALPHA_MASK), NULL,
NULL);
}
gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (options->query_box)->vbox),
frame);

View File

@ -2209,16 +2209,22 @@ flatten_region (PixelRegion *src,
{
gint h;
guchar *s, *d;
void *pr;
s = src->data;
d = dest->data;
h = src->h;
while (h --)
for (pr = pixel_regions_register (2, src, dest);
pr != NULL;
pr = pixel_regions_process (pr))
{
flatten_pixels (s, d, bg, src->w, src->bytes);
s += src->rowstride;
d += dest->rowstride;
s = src->data;
d = dest->data;
h = src->h;
while (h --)
{
flatten_pixels (s, d, bg, src->w, src->bytes);
s += src->rowstride;
d += dest->rowstride;
}
}
}

View File

@ -313,7 +313,7 @@ layer_create_mask_invoker (Gimp *gimp,
success = FALSE;
mask_type = args[1].value.pdb_int;
if (mask_type < ADD_WHITE_MASK || mask_type > ADD_INV_SELECTION_MASK)
if (mask_type < ADD_WHITE_MASK || mask_type > ADD_INV_COPY_MASK)
success = FALSE;
if (success)
@ -337,7 +337,7 @@ static ProcArg layer_create_mask_inargs[] =
{
GIMP_PDB_INT32,
"mask_type",
"The type of mask: { WHITE_MASK (0), BLACK_MASK (1), ALPHA_MASK (2), SELECTION_MASK (3), INV_SELECTION_MASK (4) }"
"The type of mask: { WHITE_MASK (0), BLACK_MASK (1), ALPHA_MASK (2), SELECTION_MASK (3), INV_SELECTION_MASK (4), COPY_MASK (5), INV_COPY_MASK (6) }"
}
};

View File

@ -1718,7 +1718,7 @@ undo_pop_layer_mask (GimpImage *gimage,
if ((state == UNDO && type == LAYER_MASK_ADD_UNDO) ||
(state == REDO && type == LAYER_MASK_REMOVE_UNDO))
{
gimp_layer_apply_mask (lmu->layer, lmu->mode, FALSE);
gimp_layer_apply_mask (lmu->layer, DISCARD, FALSE);
}
/* restore layer */
else

View File

@ -30,7 +30,9 @@ typedef enum
GIMP_BLACK_MASK,
GIMP_ALPHA_MASK,
GIMP_SELECTION_MASK,
GIMP_INV_SELECTION_MASK
GIMP_INV_SELECTION_MASK,
GIMP_COPY_MASK,
GIMP_INV_COPY_MASK
} GimpAddMaskType;
typedef enum

View File

@ -28,6 +28,8 @@ init_generated_constants (void)
setvar (cintern ("ALPHA-MASK"), flocons (2), NIL);
setvar (cintern ("SELECTION-MASK"), flocons (3), NIL);
setvar (cintern ("INV-SELECTION-MASK"), flocons (4), NIL);
setvar (cintern ("COPY-MASK"), flocons (5), NIL);
setvar (cintern ("INV-COPY-MASK"), flocons (6), NIL);
setvar (cintern ("HARD"), flocons (0), NIL);
setvar (cintern ("SOFT"), flocons (1), NIL);

View File

@ -165,17 +165,22 @@ package Gimp::CodeGen::enums;
{ contig => 1,
header => 'core/core-types.h',
symbols => [ qw(ADD_WHITE_MASK ADD_BLACK_MASK ADD_ALPHA_MASK
ADD_SELECTION_MASK ADD_INV_SELECTION_MASK) ],
ADD_SELECTION_MASK ADD_INV_SELECTION_MASK
ADD_COPY_MASK ADD_INV_COPY_MASK) ],
mapping => { ADD_WHITE_MASK => '0',
ADD_BLACK_MASK => '1',
ADD_ALPHA_MASK => '2',
ADD_SELECTION_MASK => '3',
ADD_INV_SELECTION_MASK => '4' },
ADD_INV_SELECTION_MASK => '4',
ADD_COPY_MASK => '5',
ADD_INV_COPY_MASK => '6' },
nicks => { ADD_WHITE_MASK => 'WHITE_MASK',
ADD_BLACK_MASK => 'BLACK_MASK',
ADD_ALPHA_MASK => 'ALPHA_MASK',
ADD_SELECTION_MASK => 'SELECTION_MASK',
ADD_INV_SELECTION_MASK => 'INV_SELECTION_MASK' }
ADD_INV_SELECTION_MASK => 'INV_SELECTION_MASK',
ADD_COPY_MASK => 'COPY_MASK',
ADD_INV_COPY_MASK => 'INV_COPY_MASK' }
},
MaskApplyMode =>
{ contig => 1,