gimplayermask.c 9.08 KB
Newer Older
1
/* GIMP - The GNU Image Manipulation Program
2 3
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
4
 * This program is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7 8 9 10 11 12 13 14
 * (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
15
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 17 18 19 20 21 22
 */

#include "config.h"

#include <stdlib.h>
#include <string.h>

23
#include <gdk-pixbuf/gdk-pixbuf.h>
24
#include <gegl.h>
25 26 27

#include "libgimpmath/gimpmath.h"

28
#include "core-types.h"
29

30 31
#include "gegl/gimp-babl.h"

32
#include "gimperror.h"
33
#include "gimpimage.h"
34
#include "gimpimage-undo-push.h"
35
#include "gimplayer.h"
36
#include "gimplayermask.h"
37

38
#include "gimp-intl.h"
39 40


41 42 43
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);
44 45 46 47 48 49 50 51 52 53 54
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_convert_type       (GimpDrawable      *drawable,
                                                           GimpImage         *dest_image,
                                                           const Babl        *new_format,
55
                                                           GimpColorProfile  *dest_profile,
56 57
                                                           GeglDitherMethod   layer_dither_type,
                                                           GeglDitherMethod   mask_dither_type,
58 59
                                                           gboolean           push_undo,
                                                           GimpProgress      *progress);
60

61

62
G_DEFINE_TYPE (GimpLayerMask, gimp_layer_mask, GIMP_TYPE_CHANNEL)
63

64
#define parent_class gimp_layer_mask_parent_class
65

66 67 68 69

static void
gimp_layer_mask_class_init (GimpLayerMaskClass *klass)
{
70 71
  GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
  GimpItemClass     *item_class     = GIMP_ITEM_CLASS (klass);
72
  GimpDrawableClass *drawable_class = GIMP_DRAWABLE_CLASS (klass);
73

74
  viewable_class->default_icon_name = "gimp-layer-mask";
75

76 77 78 79 80 81 82 83
  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");
84

85
  drawable_class->convert_type   = gimp_layer_mask_convert_type;
86 87 88 89 90
}

static void
gimp_layer_mask_init (GimpLayerMask *layer_mask)
{
91
  layer_mask->layer = NULL;
92 93
}

94
static gboolean
95
gimp_layer_mask_is_content_locked (GimpItem *item)
96 97 98 99 100 101 102 103 104
{
  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;
}
105 106

static gboolean
107
gimp_layer_mask_is_position_locked (GimpItem *item)
108 109 110 111 112 113 114 115 116
{
  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;
}
117

118
static gboolean
119
gimp_layer_mask_is_attached (GimpItem *item)
120 121 122 123
{
  GimpLayerMask *mask  = GIMP_LAYER_MASK (item);
  GimpLayer     *layer = gimp_layer_mask_get_layer (mask);

124 125 126
  return (GIMP_IS_IMAGE (gimp_item_get_image (item)) &&
          GIMP_IS_LAYER (layer)                      &&
          gimp_layer_get_mask (layer) == mask        &&
127 128 129
          gimp_item_is_attached (GIMP_ITEM (layer)));
}

130 131
static GimpItemTree *
gimp_layer_mask_get_tree (GimpItem *item)
132 133 134 135
{
  return NULL;
}

136 137
static GimpItem *
gimp_layer_mask_duplicate (GimpItem *item,
138
                           GType     new_type)
139
{
140
  GimpItem *new_item;
141 142 143

  g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_DRAWABLE), NULL);

144
  new_item = GIMP_ITEM_CLASS (parent_class)->duplicate (item, new_type);
145

146
  return new_item;
147 148
}

149
static gboolean
150 151 152 153
gimp_layer_mask_rename (GimpItem     *item,
                        const gchar  *new_name,
                        const gchar  *undo_desc,
                        GError      **error)
154 155 156
{
  /* reject renaming, layer masks are always named "<layer name> mask"  */

157
  g_set_error (error, GIMP_ERROR, GIMP_FAILED,
158
               _("Cannot rename layer masks."));
159

160 161 162
  return FALSE;
}

163 164 165 166
static void
gimp_layer_mask_convert_type (GimpDrawable      *drawable,
                              GimpImage         *dest_image,
                              const Babl        *new_format,
167
                              GimpColorProfile  *dest_profile,
168 169
                              GeglDitherMethod   layer_dither_type,
                              GeglDitherMethod   mask_dither_type,
170 171
                              gboolean           push_undo,
                              GimpProgress      *progress)
172
{
173 174
  new_format =
    gimp_babl_mask_format (gimp_babl_format_get_precision (new_format));
175 176 177

  GIMP_DRAWABLE_CLASS (parent_class)->convert_type (drawable, dest_image,
                                                    new_format,
178
                                                    dest_profile,
179 180
                                                    layer_dither_type,
                                                    mask_dither_type,
181 182
                                                    push_undo,
                                                    progress);
183 184
}

185
GimpLayerMask *
186
gimp_layer_mask_new (GimpImage     *image,
187 188 189 190
                     gint           width,
                     gint           height,
                     const gchar   *name,
                     const GimpRGB *color)
191 192 193
{
  GimpLayerMask *layer_mask;

194 195 196 197
  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);
198

199 200 201 202 203
  layer_mask =
    GIMP_LAYER_MASK (gimp_drawable_new (GIMP_TYPE_LAYER_MASK,
                                        image, name,
                                        0, 0, width, height,
                                        gimp_image_get_mask_format (image)));
204 205

  /*  set the layer_mask color and opacity  */
206 207
  gimp_channel_set_color (GIMP_CHANNEL (layer_mask), color, FALSE);
  gimp_channel_set_show_masked (GIMP_CHANNEL (layer_mask), TRUE);
208 209

  /*  selection mask variables  */
210 211
  GIMP_CHANNEL (layer_mask)->x2 = width;
  GIMP_CHANNEL (layer_mask)->y2 = height;
212 213 214 215

  return layer_mask;
}

216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
GimpLayerMask *
gimp_layer_mask_new_from_buffer (GeglBuffer    *buffer,
                                 GimpImage     *image,
                                 const gchar   *name,
                                 const GimpRGB *color)
{
  GimpLayerMask *layer_mask;
  GeglBuffer    *dest;

  g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);
  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);

  layer_mask = gimp_layer_mask_new (image,
                                    gegl_buffer_get_width  (buffer),
                                    gegl_buffer_get_height (buffer),
                                    name, color);

  dest = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer_mask));
234
  gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE, dest, NULL);
235 236 237 238

  return layer_mask;
}

239
void
240
gimp_layer_mask_set_layer (GimpLayerMask *layer_mask,
241
                           GimpLayer     *layer)
242
{
243
  g_return_if_fail (GIMP_IS_LAYER_MASK (layer_mask));
244
  g_return_if_fail (layer == NULL || GIMP_IS_LAYER (layer));
245 246

  layer_mask->layer = layer;
247 248 249

  if (layer)
    {
250
      gchar *mask_name;
251 252
      gint   offset_x;
      gint   offset_y;
253

254 255
      gimp_item_get_offset (GIMP_ITEM (layer), &offset_x, &offset_y);
      gimp_item_set_offset (GIMP_ITEM (layer_mask), offset_x, offset_y);
256

257
      mask_name = g_strdup_printf (_("%s mask"), gimp_object_get_name (layer));
258 259

      gimp_object_take_name (GIMP_OBJECT (layer_mask), mask_name);
260
    }
261 262 263
}

GimpLayer *
264
gimp_layer_mask_get_layer (GimpLayerMask *layer_mask)
265
{
266 267 268
  g_return_val_if_fail (GIMP_IS_LAYER_MASK (layer_mask), NULL);

  return layer_mask->layer;
269
}