diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:23:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:23:22 +0000 |
commit | e42129241681dde7adae7d20697e7b421682fbb4 (patch) | |
tree | af1fe815a5e639e68e59fabd8395ec69458b3e5e /app/core/gimplayermask.c | |
parent | Initial commit. (diff) | |
download | gimp-upstream/2.10.22.tar.xz gimp-upstream/2.10.22.zip |
Adding upstream version 2.10.22.upstream/2.10.22upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'app/core/gimplayermask.c')
-rw-r--r-- | app/core/gimplayermask.c | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/app/core/gimplayermask.c b/app/core/gimplayermask.c new file mode 100644 index 0000000..ec0dbfb --- /dev/null +++ b/app/core/gimplayermask.c @@ -0,0 +1,297 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <gegl.h> + +#include "core-types.h" + +#include "gegl/gimp-babl.h" + +#include "gimperror.h" +#include "gimpimage.h" +#include "gimplayer.h" +#include "gimplayermask.h" + +#include "gimp-intl.h" + + +static void gimp_layer_mask_preview_freeze (GimpViewable *viewable); +static void gimp_layer_mask_preview_thaw (GimpViewable *viewable); + +static gboolean gimp_layer_mask_is_attached (GimpItem *item); +static gboolean gimp_layer_mask_is_content_locked (GimpItem *item); +static gboolean gimp_layer_mask_is_position_locked (GimpItem *item); +static GimpItemTree * gimp_layer_mask_get_tree (GimpItem *item); +static GimpItem * gimp_layer_mask_duplicate (GimpItem *item, + GType new_type); +static gboolean gimp_layer_mask_rename (GimpItem *item, + const gchar *new_name, + const gchar *undo_desc, + GError **error); + +static void gimp_layer_mask_bounding_box_changed (GimpDrawable *drawable); +static void gimp_layer_mask_convert_type (GimpDrawable *drawable, + GimpImage *dest_image, + const Babl *new_format, + GimpColorProfile *dest_profile, + GeglDitherMethod layer_dither_type, + GeglDitherMethod mask_dither_type, + gboolean push_undo, + GimpProgress *progress); + + +G_DEFINE_TYPE (GimpLayerMask, gimp_layer_mask, GIMP_TYPE_CHANNEL) + +#define parent_class gimp_layer_mask_parent_class + + +static void +gimp_layer_mask_class_init (GimpLayerMaskClass *klass) +{ + GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass); + GimpItemClass *item_class = GIMP_ITEM_CLASS (klass); + GimpDrawableClass *drawable_class = GIMP_DRAWABLE_CLASS (klass); + + viewable_class->default_icon_name = "gimp-layer-mask"; + + viewable_class->preview_freeze = gimp_layer_mask_preview_freeze; + viewable_class->preview_thaw = gimp_layer_mask_preview_thaw; + + item_class->is_attached = gimp_layer_mask_is_attached; + item_class->is_content_locked = gimp_layer_mask_is_content_locked; + item_class->is_position_locked = gimp_layer_mask_is_position_locked; + item_class->get_tree = gimp_layer_mask_get_tree; + item_class->duplicate = gimp_layer_mask_duplicate; + item_class->rename = gimp_layer_mask_rename; + item_class->translate_desc = C_("undo-type", "Move Layer Mask"); + item_class->to_selection_desc = C_("undo-type", "Layer Mask to Selection"); + + drawable_class->bounding_box_changed = gimp_layer_mask_bounding_box_changed; + drawable_class->convert_type = gimp_layer_mask_convert_type; +} + +static void +gimp_layer_mask_init (GimpLayerMask *layer_mask) +{ + layer_mask->layer = NULL; +} + +static void +gimp_layer_mask_preview_freeze (GimpViewable *viewable) +{ + GimpLayerMask *mask = GIMP_LAYER_MASK (viewable); + GimpLayer *layer = gimp_layer_mask_get_layer (mask); + + if (layer) + { + GimpViewable *parent = gimp_viewable_get_parent (GIMP_VIEWABLE (layer)); + + if (! parent && gimp_item_is_attached (GIMP_ITEM (layer))) + parent = GIMP_VIEWABLE (gimp_item_get_image (GIMP_ITEM (layer))); + + if (parent) + gimp_viewable_preview_freeze (parent); + } +} + +static void +gimp_layer_mask_preview_thaw (GimpViewable *viewable) +{ + GimpLayerMask *mask = GIMP_LAYER_MASK (viewable); + GimpLayer *layer = gimp_layer_mask_get_layer (mask); + + if (layer) + { + GimpViewable *parent = gimp_viewable_get_parent (GIMP_VIEWABLE (layer)); + + if (! parent && gimp_item_is_attached (GIMP_ITEM (layer))) + parent = GIMP_VIEWABLE (gimp_item_get_image (GIMP_ITEM (layer))); + + if (parent) + gimp_viewable_preview_thaw (parent); + } +} + +static gboolean +gimp_layer_mask_is_content_locked (GimpItem *item) +{ + GimpLayerMask *mask = GIMP_LAYER_MASK (item); + GimpLayer *layer = gimp_layer_mask_get_layer (mask); + + if (layer) + return gimp_item_is_content_locked (GIMP_ITEM (layer)); + + return FALSE; +} + +static gboolean +gimp_layer_mask_is_position_locked (GimpItem *item) +{ + GimpLayerMask *mask = GIMP_LAYER_MASK (item); + GimpLayer *layer = gimp_layer_mask_get_layer (mask); + + if (layer) + return gimp_item_is_position_locked (GIMP_ITEM (layer)); + + return FALSE; +} + +static gboolean +gimp_layer_mask_is_attached (GimpItem *item) +{ + GimpLayerMask *mask = GIMP_LAYER_MASK (item); + GimpLayer *layer = gimp_layer_mask_get_layer (mask); + + return (GIMP_IS_IMAGE (gimp_item_get_image (item)) && + GIMP_IS_LAYER (layer) && + gimp_layer_get_mask (layer) == mask && + gimp_item_is_attached (GIMP_ITEM (layer))); +} + +static GimpItemTree * +gimp_layer_mask_get_tree (GimpItem *item) +{ + return NULL; +} + +static GimpItem * +gimp_layer_mask_duplicate (GimpItem *item, + GType new_type) +{ + GimpItem *new_item; + + g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_DRAWABLE), NULL); + + new_item = GIMP_ITEM_CLASS (parent_class)->duplicate (item, new_type); + + return new_item; +} + +static gboolean +gimp_layer_mask_rename (GimpItem *item, + const gchar *new_name, + const gchar *undo_desc, + GError **error) +{ + /* reject renaming, layer masks are always named "<layer name> mask" */ + + g_set_error (error, GIMP_ERROR, GIMP_FAILED, + _("Cannot rename layer masks.")); + + return FALSE; +} + +static void +gimp_layer_mask_bounding_box_changed (GimpDrawable *drawable) +{ + GimpLayerMask *mask = GIMP_LAYER_MASK (drawable); + GimpLayer *layer = gimp_layer_mask_get_layer (mask); + + if (GIMP_DRAWABLE_CLASS (parent_class)->bounding_box_changed) + GIMP_DRAWABLE_CLASS (parent_class)->bounding_box_changed (drawable); + + if (layer) + gimp_drawable_update_bounding_box (GIMP_DRAWABLE (layer)); +} + +static void +gimp_layer_mask_convert_type (GimpDrawable *drawable, + GimpImage *dest_image, + const Babl *new_format, + GimpColorProfile *dest_profile, + GeglDitherMethod layer_dither_type, + GeglDitherMethod mask_dither_type, + gboolean push_undo, + GimpProgress *progress) +{ + new_format = + gimp_babl_mask_format (gimp_babl_format_get_precision (new_format)); + + GIMP_DRAWABLE_CLASS (parent_class)->convert_type (drawable, dest_image, + new_format, + dest_profile, + layer_dither_type, + mask_dither_type, + push_undo, + progress); +} + +GimpLayerMask * +gimp_layer_mask_new (GimpImage *image, + gint width, + gint height, + const gchar *name, + const GimpRGB *color) +{ + GimpLayerMask *layer_mask; + + g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); + g_return_val_if_fail (color != NULL, NULL); + + layer_mask = + GIMP_LAYER_MASK (gimp_drawable_new (GIMP_TYPE_LAYER_MASK, + image, name, + 0, 0, width, height, + gimp_image_get_mask_format (image))); + + /* set the layer_mask color and opacity */ + gimp_channel_set_color (GIMP_CHANNEL (layer_mask), color, FALSE); + gimp_channel_set_show_masked (GIMP_CHANNEL (layer_mask), TRUE); + + /* selection mask variables */ + GIMP_CHANNEL (layer_mask)->x2 = width; + GIMP_CHANNEL (layer_mask)->y2 = height; + + return layer_mask; +} + +void +gimp_layer_mask_set_layer (GimpLayerMask *layer_mask, + GimpLayer *layer) +{ + g_return_if_fail (GIMP_IS_LAYER_MASK (layer_mask)); + g_return_if_fail (layer == NULL || GIMP_IS_LAYER (layer)); + + layer_mask->layer = layer; + + if (layer) + { + gchar *mask_name; + gint offset_x; + gint offset_y; + + gimp_item_get_offset (GIMP_ITEM (layer), &offset_x, &offset_y); + gimp_item_set_offset (GIMP_ITEM (layer_mask), offset_x, offset_y); + + mask_name = g_strdup_printf (_("%s mask"), gimp_object_get_name (layer)); + + gimp_object_take_name (GIMP_OBJECT (layer_mask), mask_name); + } +} + +GimpLayer * +gimp_layer_mask_get_layer (GimpLayerMask *layer_mask) +{ + g_return_val_if_fail (GIMP_IS_LAYER_MASK (layer_mask), NULL); + + return layer_mask->layer; +} |