summaryrefslogtreecommitdiffstats
path: root/app/core/gimplayermask.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:23:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:23:22 +0000
commite42129241681dde7adae7d20697e7b421682fbb4 (patch)
treeaf1fe815a5e639e68e59fabd8395ec69458b3e5e /app/core/gimplayermask.c
parentInitial commit. (diff)
downloadgimp-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.c297
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;
+}