gimplayer.c 65.8 KB
Newer Older
1
/* GIMP - The GNU Image Manipulation Program
Elliot Lee's avatar
Elliot Lee committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15
 * 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 2 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, write to the Free Software
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Elliot Lee's avatar
Elliot Lee committed
17
 */
18

19 20
#include "config.h"

21
#include <stdlib.h>
22
#include <string.h>
23

24
#include <gegl.h>
25

26
#include "libgimpbase/gimpbase.h"
27 28
#include "libgimpmath/gimpmath.h"

Michael Natterer's avatar
Michael Natterer committed
29
#include "core-types.h"
30

Michael Natterer's avatar
Michael Natterer committed
31 32 33 34 35
#include "base/boundary.h"
#include "base/pixel-region.h"
#include "base/tile-manager.h"
#include "base/tile.h"

36 37
#include "paint-funcs/paint-funcs.h"

38 39
#include "gegl/gimp-gegl-utils.h"

40
#include "gimpcontext.h"
41
#include "gimpcontainer.h"
42
#include "gimpdrawable-convert.h"
43
#include "gimpdrawable-invert.h"
44
#include "gimpimage-undo-push.h"
45 46
#include "gimpimage-undo.h"
#include "gimpimage.h"
Michael Natterer's avatar
Michael Natterer committed
47
#include "gimplayer-floating-sel.h"
48
#include "gimplayer.h"
49
#include "gimplayermask.h"
50
#include "gimpmarshal.h"
51
#include "gimppickable.h"
52

53
#include "gimp-intl.h"
54 55


56 57
enum
{
58 59
  OPACITY_CHANGED,
  MODE_CHANGED,
60
  LOCK_ALPHA_CHANGED,
61 62 63 64
  MASK_CHANGED,
  LAST_SIGNAL
};

65 66 67 68 69 70 71 72
enum
{
  PROP_0,
  PROP_OPACITY,
  PROP_MODE,
  PROP_LOCK_ALPHA
};

73

74 75 76 77 78 79 80 81 82 83 84 85 86
#ifdef __GNUC__
#warning FIXME: gegl_node_add_child() needs to be public
#endif
GeglNode * gegl_node_add_child (GeglNode *self,
                                GeglNode *child);

#ifdef __GNUC__
#warning FIXME: gegl_node_remove_child() needs to be public
#endif
GeglNode * gegl_node_remove_child (GeglNode *self,
                                   GeglNode *child);


87
static void   gimp_layer_pickable_iface_init (GimpPickableInterface *iface);
88

89 90 91 92 93 94 95 96
static void       gimp_layer_set_property       (GObject            *object,
                                                 guint               property_id,
                                                 const GValue       *value,
                                                 GParamSpec         *pspec);
static void       gimp_layer_get_property       (GObject            *object,
                                                 guint               property_id,
                                                 GValue             *value,
                                                 GParamSpec         *pspec);
97
static void       gimp_layer_dispose            (GObject            *object);
98
static void       gimp_layer_finalize           (GObject            *object);
99

100
static void       gimp_layer_name_changed       (GimpObject         *object);
101 102
static gint64     gimp_layer_get_memsize        (GimpObject         *object,
                                                 gint64             *gui_size);
103

104
static void       gimp_layer_invalidate_preview (GimpViewable       *viewable);
105 106
static gchar    * gimp_layer_get_description    (GimpViewable       *viewable,
                                                 gchar             **tooltip);
107

108
static void       gimp_layer_removed            (GimpItem           *item);
109
static gboolean   gimp_layer_is_attached        (GimpItem           *item);
110
static GimpItem * gimp_layer_duplicate          (GimpItem           *item,
111
                                                 GType               new_type);
112 113
static void       gimp_layer_convert            (GimpItem           *item,
                                                 GimpImage          *dest_image);
114
static gboolean   gimp_layer_rename             (GimpItem           *item,
115
                                                 const gchar        *new_name,
116 117
                                                 const gchar        *undo_desc,
                                                 GError            **error);
118 119
static void       gimp_layer_translate          (GimpItem           *item,
                                                 gint                offset_x,
120 121
                                                 gint                offset_y,
                                                 gboolean            push_undo);
122 123 124 125 126
static void       gimp_layer_scale              (GimpItem           *item,
                                                 gint                new_width,
                                                 gint                new_height,
                                                 gint                new_offset_x,
                                                 gint                new_offset_y,
127
                                                 GimpInterpolationType  interp_type,
128
                                                 GimpProgress       *progress);
129
static void       gimp_layer_resize             (GimpItem           *item,
130
                                                 GimpContext        *context,
131 132 133 134
                                                 gint                new_width,
                                                 gint                new_height,
                                                 gint                offset_x,
                                                 gint                offset_y);
135
static void       gimp_layer_flip               (GimpItem           *item,
136
                                                 GimpContext        *context,
137
                                                 GimpOrientationType flip_type,
138 139
                                                 gdouble             axis,
                                                 gboolean            clip_result);
140
static void       gimp_layer_rotate             (GimpItem           *item,
141
                                                 GimpContext        *context,
142 143 144 145
                                                 GimpRotationType    rotate_type,
                                                 gdouble             center_x,
                                                 gdouble             center_y,
                                                 gboolean            clip_result);
146
static void       gimp_layer_transform          (GimpItem           *item,
147
                                                 GimpContext        *context,
148
                                                 const GimpMatrix3  *matrix,
149 150
                                                 GimpTransformDirection direction,
                                                 GimpInterpolationType  interpolation_type,
151
                                                 gint                recursion_level,
152
                                                 GimpTransformResize    clip_result,
153
                                                 GimpProgress       *progress);
154 155 156 157

static gint64  gimp_layer_estimate_memsize      (const GimpDrawable *drawable,
                                                 gint                width,
                                                 gint                height);
158 159 160
static void    gimp_layer_invalidate_boundary   (GimpDrawable       *drawable);
static void    gimp_layer_get_active_components (const GimpDrawable *drawable,
                                                 gboolean           *active);
161 162 163 164
static void    gimp_layer_set_tiles             (GimpDrawable       *drawable,
                                                 gboolean            push_undo,
                                                 const gchar        *undo_desc,
                                                 TileManager        *tiles,
165 166 167
                                                 GimpImageType       type,
                                                 gint                offset_x,
                                                 gint                offset_y);
168
static GeglNode * gimp_layer_get_node           (GimpItem           *item);
169

170 171 172
static gint    gimp_layer_get_opacity_at        (GimpPickable       *pickable,
                                                 gint                x,
                                                 gint                y);
173

174
static void       gimp_layer_transform_color    (GimpImage          *image,
175 176 177 178
                                                 PixelRegion        *srcPR,
                                                 GimpImageType       src_type,
                                                 PixelRegion        *destPR,
                                                 GimpImageType       dest_type);
179

180 181 182 183 184 185 186
static void       gimp_layer_layer_mask_update  (GimpDrawable       *layer_mask,
                                                 gint                x,
                                                 gint                y,
                                                 gint                width,
                                                 gint                height,
                                                 GimpLayer          *layer);

187

188 189
G_DEFINE_TYPE_WITH_CODE (GimpLayer, gimp_layer, GIMP_TYPE_DRAWABLE,
                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_PICKABLE,
190
                                                gimp_layer_pickable_iface_init))
191

192
#define parent_class gimp_layer_parent_class
193

194
static guint layer_signals[LAST_SIGNAL] = { 0 };
195

196 197

static void
198
gimp_layer_class_init (GimpLayerClass *klass)
199
{
200 201 202 203 204
  GObjectClass      *object_class      = G_OBJECT_CLASS (klass);
  GimpObjectClass   *gimp_object_class = GIMP_OBJECT_CLASS (klass);
  GimpViewableClass *viewable_class    = GIMP_VIEWABLE_CLASS (klass);
  GimpItemClass     *item_class        = GIMP_ITEM_CLASS (klass);
  GimpDrawableClass *drawable_class    = GIMP_DRAWABLE_CLASS (klass);
205

206
  layer_signals[OPACITY_CHANGED] =
207
    g_signal_new ("opacity-changed",
208 209 210 211 212 213
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GimpLayerClass, opacity_changed),
                  NULL, NULL,
                  gimp_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
214 215

  layer_signals[MODE_CHANGED] =
216
    g_signal_new ("mode-changed",
217 218 219 220 221 222
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GimpLayerClass, mode_changed),
                  NULL, NULL,
                  gimp_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
223

224 225
  layer_signals[LOCK_ALPHA_CHANGED] =
    g_signal_new ("lock-alpha-changed",
226 227 228 229 230 231
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GimpLayerClass, lock_alpha_changed),
                  NULL, NULL,
                  gimp_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
232

233
  layer_signals[MASK_CHANGED] =
234
    g_signal_new ("mask-changed",
235 236 237 238 239 240
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GimpLayerClass, mask_changed),
                  NULL, NULL,
                  gimp_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
241

242 243
  object_class->set_property          = gimp_layer_set_property;
  object_class->get_property          = gimp_layer_get_property;
244
  object_class->dispose               = gimp_layer_dispose;
245 246
  object_class->finalize              = gimp_layer_finalize;

247
  gimp_object_class->name_changed     = gimp_layer_name_changed;
248 249 250 251
  gimp_object_class->get_memsize      = gimp_layer_get_memsize;

  viewable_class->default_stock_id    = "gimp-layer";
  viewable_class->invalidate_preview  = gimp_layer_invalidate_preview;
252
  viewable_class->get_description     = gimp_layer_get_description;
253

254
  item_class->removed                 = gimp_layer_removed;
255
  item_class->is_attached             = gimp_layer_is_attached;
256
  item_class->duplicate               = gimp_layer_duplicate;
257
  item_class->convert                 = gimp_layer_convert;
258 259 260 261 262 263 264
  item_class->rename                  = gimp_layer_rename;
  item_class->translate               = gimp_layer_translate;
  item_class->scale                   = gimp_layer_scale;
  item_class->resize                  = gimp_layer_resize;
  item_class->flip                    = gimp_layer_flip;
  item_class->rotate                  = gimp_layer_rotate;
  item_class->transform               = gimp_layer_transform;
265
  item_class->get_node                = gimp_layer_get_node;
266 267
  item_class->default_name            = _("Layer");
  item_class->rename_desc             = _("Rename Layer");
268 269 270 271 272 273
  item_class->translate_desc          = _("Move Layer");
  item_class->scale_desc              = _("Scale Layer");
  item_class->resize_desc             = _("Resize Layer");
  item_class->flip_desc               = _("Flip Layer");
  item_class->rotate_desc             = _("Rotate Layer");
  item_class->transform_desc          = _("Transform Layer");
274

275
  drawable_class->estimate_memsize      = gimp_layer_estimate_memsize;
276 277
  drawable_class->invalidate_boundary   = gimp_layer_invalidate_boundary;
  drawable_class->get_active_components = gimp_layer_get_active_components;
278
  drawable_class->set_tiles             = gimp_layer_set_tiles;
279 280 281

  klass->opacity_changed              = NULL;
  klass->mode_changed                 = NULL;
282
  klass->lock_alpha_changed           = NULL;
283
  klass->mask_changed                 = NULL;
284 285 286 287 288 289

  g_object_class_install_property (object_class, PROP_OPACITY,
                                   g_param_spec_double ("opacity", NULL, NULL,
                                                        GIMP_OPACITY_TRANSPARENT,
                                                        GIMP_OPACITY_OPAQUE,
                                                        GIMP_OPACITY_OPAQUE,
290
                                                        GIMP_PARAM_READABLE));
291 292 293 294 295

  g_object_class_install_property (object_class, PROP_MODE,
                                   g_param_spec_enum ("mode", NULL, NULL,
                                                      GIMP_TYPE_LAYER_MODE_EFFECTS,
                                                      GIMP_NORMAL_MODE,
296
                                                      GIMP_PARAM_READABLE));
297 298 299 300 301

  g_object_class_install_property (object_class, PROP_LOCK_ALPHA,
                                   g_param_spec_boolean ("lock-alpha",
                                                         NULL, NULL,
                                                         FALSE,
302
                                                         GIMP_PARAM_READABLE));
303 304 305 306 307
}

static void
gimp_layer_init (GimpLayer *layer)
{
308 309 310
  layer->opacity    = GIMP_OPACITY_OPAQUE;
  layer->mode       = GIMP_NORMAL_MODE;
  layer->lock_alpha = FALSE;
311

312
  layer->mask       = NULL;
313

314 315 316 317 318 319 320
  /*  floating selection  */
  layer->fs.backing_store  = NULL;
  layer->fs.drawable       = NULL;
  layer->fs.initial        = TRUE;
  layer->fs.boundary_known = FALSE;
  layer->fs.segs           = NULL;
  layer->fs.num_segs       = 0;
321 322
}

323
static void
324
gimp_layer_pickable_iface_init (GimpPickableInterface *iface)
325
{
326
  iface->get_opacity_at = gimp_layer_get_opacity_at;
327 328
}

329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372
static void
gimp_layer_set_property (GObject      *object,
                         guint         property_id,
                         const GValue *value,
                         GParamSpec   *pspec)
{
  switch (property_id)
    {
    case PROP_OPACITY:
    case PROP_MODE:
    case PROP_LOCK_ALPHA:
      g_assert_not_reached ();
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

static void
gimp_layer_get_property (GObject    *object,
                         guint       property_id,
                         GValue     *value,
                         GParamSpec *pspec)
{
  GimpLayer *layer = GIMP_LAYER (object);

  switch (property_id)
    {
    case PROP_OPACITY:
      g_value_set_double (value, layer->opacity);
      break;
    case PROP_MODE:
      g_value_set_enum (value, layer->mode);
      break;
    case PROP_LOCK_ALPHA:
      g_value_set_boolean (value, layer->lock_alpha);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

373 374 375 376 377 378 379 380 381 382 383 384 385
static void
gimp_layer_dispose (GObject *object)
{
  GimpLayer *layer = GIMP_LAYER (object);

  if (layer->mask)
    g_signal_handlers_disconnect_by_func (layer->mask,
                                          gimp_layer_layer_mask_update,
                                          layer);

  G_OBJECT_CLASS (parent_class)->dispose (object);
}

386 387 388
static void
gimp_layer_finalize (GObject *object)
{
389
  GimpLayer *layer = GIMP_LAYER (object);
390 391 392

  if (layer->mask)
    {
393
      g_object_unref (layer->mask);
394 395 396
      layer->mask = NULL;
    }

397 398 399 400 401 402
  if (layer->fs.backing_store)
    {
      tile_manager_unref (layer->fs.backing_store);
      layer->fs.backing_store = NULL;
    }

403 404 405
  if (layer->fs.segs)
    {
      g_free (layer->fs.segs);
406 407
      layer->fs.segs     = NULL;
      layer->fs.num_segs = 0;
408 409 410 411 412
    }

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

413 414 415 416 417
static void
gimp_layer_name_changed (GimpObject *object)
{
  GimpLayer *layer = GIMP_LAYER (object);

418 419
  if (GIMP_OBJECT_CLASS (parent_class)->name_changed)
    GIMP_OBJECT_CLASS (parent_class)->name_changed (object);
420 421 422

  if (layer->mask)
    {
423 424
      gchar *mask_name = g_strdup_printf (_("%s mask"),
                                          gimp_object_get_name (object));
425

426
      gimp_object_take_name (GIMP_OBJECT (layer->mask), mask_name);
427 428 429
    }
}

430
static gint64
431
gimp_layer_get_memsize (GimpObject *object,
432
                        gint64     *gui_size)
433
{
434
  GimpLayer *layer   = GIMP_LAYER (object);
435
  gint64     memsize = 0;
436

437
  memsize += gimp_object_get_memsize (GIMP_OBJECT (layer->mask), gui_size);
438

439
  *gui_size += tile_manager_get_memsize (layer->fs.backing_store, FALSE);
440
  *gui_size += layer->fs.num_segs * sizeof (BoundSeg);
441

442 443
  return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
                                                                  gui_size);
444 445
}

Elliot Lee's avatar
Elliot Lee committed
446
static void
447
gimp_layer_invalidate_preview (GimpViewable *viewable)
448
{
449
  GimpLayer *layer = GIMP_LAYER (viewable);
450

451 452 453
  if (GIMP_VIEWABLE_CLASS (parent_class)->invalidate_preview)
    GIMP_VIEWABLE_CLASS (parent_class)->invalidate_preview (viewable);

454
  if (gimp_layer_is_floating_sel (layer))
455
    floating_sel_invalidate (layer);
456 457
}

458 459 460 461 462 463 464 465 466 467 468 469 470 471
static gchar *
gimp_layer_get_description (GimpViewable  *viewable,
                            gchar        **tooltip)
{
  if (gimp_layer_is_floating_sel (GIMP_LAYER (viewable)))
    {
      return g_strdup_printf (_("Floating Selection\n(%s)"),
                              gimp_object_get_name (GIMP_OBJECT (viewable)));
    }

  return GIMP_VIEWABLE_CLASS (parent_class)->get_description (viewable,
                                                              tooltip);
}

472 473 474 475
static void
gimp_layer_get_active_components (const GimpDrawable *drawable,
                                  gboolean           *active)
{
476 477
  GimpLayer *layer = GIMP_LAYER (drawable);
  GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
478 479
  gint       i;

480
  /*  first copy the image active channels  */
481
  for (i = 0; i < MAX_CHANNELS; i++)
482
    active[i] = image->active[i];
483

484
  if (gimp_drawable_has_alpha (drawable) && layer->lock_alpha)
485 486 487
    active[gimp_drawable_bytes (drawable) - 1] = FALSE;
}

488 489 490 491 492
static void
gimp_layer_set_tiles (GimpDrawable *drawable,
                      gboolean      push_undo,
                      const gchar  *undo_desc,
                      TileManager  *tiles,
493 494 495
                      GimpImageType type,
                      gint          offset_x,
                      gint          offset_y)
496
{
497 498
  GimpLayer *layer = GIMP_LAYER (drawable);

499 500 501
  if (gimp_layer_is_floating_sel (layer))
    floating_sel_relax (layer, FALSE);

502 503
  GIMP_DRAWABLE_CLASS (parent_class)->set_tiles (drawable,
                                                 push_undo, undo_desc,
504 505 506
                                                 tiles, type,
                                                 offset_x, offset_y);

507 508
  if (gimp_layer_is_floating_sel (layer))
    floating_sel_rigor (layer, FALSE);
509 510
}

511
static GeglNode *
512
gimp_layer_get_node (GimpItem *item)
513
{
514 515 516
  GimpDrawable *drawable = GIMP_DRAWABLE (item);
  GimpLayer    *layer    = GIMP_LAYER (item);
  GeglNode     *node;
517
  GeglNode     *offset_node;
518 519
  GeglNode     *source;
  GeglNode     *mode_node;
520

521
  node = GIMP_ITEM_CLASS (parent_class)->get_node (item);
522

523
  source = gimp_drawable_get_source_node (drawable);
524
  gegl_node_add_child (node, source);
525

526 527 528 529 530 531 532
  layer->opacity_node = gegl_node_new_child (node,
                                             "operation", "gegl:opacity",
                                             "value",     layer->opacity,
                                             NULL);
  gegl_node_connect_to (source,              "output",
                        layer->opacity_node, "input");

533 534 535 536 537 538
  if (layer->mask)
    {
      GeglNode *mask;

      mask = gimp_drawable_get_source_node (GIMP_DRAWABLE (layer->mask));

539 540
      gegl_node_connect_to (mask,                "output",
                            layer->opacity_node, "aux");
541 542
    }

543
  offset_node = gimp_item_get_offset_node (GIMP_ITEM (layer));
544

545
  gegl_node_connect_to (layer->opacity_node, "output",
546
                        offset_node,         "input");
547

548
  mode_node = gimp_drawable_get_mode_node (drawable);
549

550
  gegl_node_set (mode_node,
551
                 "operation",  "gimp:point-layer-mode",
552
                 "blend-mode", layer->mode,
553
                 NULL);
554

555 556
  gegl_node_connect_to (offset_node, "output",
                        mode_node,   "aux");
557

558
  return node;
559 560
}

561 562 563 564 565 566 567 568 569 570 571 572
static void
gimp_layer_removed (GimpItem *item)
{
  GimpLayer *layer = GIMP_LAYER (item);

  if (layer->mask)
    gimp_item_removed (GIMP_ITEM (layer->mask));

  if (GIMP_ITEM_CLASS (parent_class)->removed)
    GIMP_ITEM_CLASS (parent_class)->removed (item);
}

573 574 575
static gboolean
gimp_layer_is_attached (GimpItem *item)
{
576 577
  return (GIMP_IS_IMAGE (item->image) &&
          gimp_container_have (item->image->layers, GIMP_OBJECT (item)));
578 579
}

580 581
static GimpItem *
gimp_layer_duplicate (GimpItem *item,
582
                      GType     new_type)
583
{
584
  GimpItem *new_item;
585 586 587

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

588
  new_item = GIMP_ITEM_CLASS (parent_class)->duplicate (item, new_type);
589

590
  if (GIMP_IS_LAYER (new_item))
591
    {
592
      GimpLayer *layer     = GIMP_LAYER (item);
593 594
      GimpLayer *new_layer = GIMP_LAYER (new_item);

595 596 597 598 599 600
      gimp_layer_set_mode       (new_layer,
                                 gimp_layer_get_mode (layer), FALSE);
      gimp_layer_set_opacity    (new_layer,
                                 gimp_layer_get_opacity (layer), FALSE);
      gimp_layer_set_lock_alpha (new_layer,
                                 gimp_layer_get_lock_alpha (layer), FALSE);
601 602 603 604

      /*  duplicate the layer mask if necessary  */
      if (layer->mask)
        {
605 606 607 608
          GimpItem *mask;

          mask = gimp_item_duplicate (GIMP_ITEM (layer->mask),
                                      G_TYPE_FROM_INSTANCE (layer->mask));
609
          gimp_layer_add_mask (new_layer, GIMP_LAYER_MASK (mask), FALSE, NULL);
610
        }
611 612 613 614 615
    }

  return new_item;
}

616
static void
617 618
gimp_layer_convert (GimpItem  *item,
                    GimpImage *dest_image)
619
{
620 621 622
  GimpLayer         *layer    = GIMP_LAYER (item);
  GimpDrawable      *drawable = GIMP_DRAWABLE (item);
  GimpImageBaseType  old_base_type;
623 624
  GimpImageBaseType  new_base_type;

625
  old_base_type = GIMP_IMAGE_TYPE_BASE_TYPE (gimp_drawable_type (drawable));
626
  new_base_type = gimp_image_base_type (dest_image);
627

628
  if (old_base_type != new_base_type)
629 630 631 632 633 634
    {
      TileManager   *new_tiles;
      GimpImageType  new_type;

      new_type = GIMP_IMAGE_TYPE_FROM_BASE_TYPE (new_base_type);

635
      if (gimp_drawable_has_alpha (drawable))
636 637
        new_type = GIMP_IMAGE_TYPE_WITH_ALPHA (new_type);

638 639
      new_tiles = tile_manager_new (gimp_item_get_width  (item),
                                    gimp_item_get_height (item),
640 641 642 643 644
                                    GIMP_IMAGE_TYPE_BYTES (new_type));

      switch (new_base_type)
        {
        case GIMP_RGB:
645
          gimp_drawable_convert_rgb (drawable,
646
                                     new_tiles,
647
                                     old_base_type);
648 649 650
          break;

        case GIMP_GRAY:
651
          gimp_drawable_convert_grayscale (drawable,
652
                                           new_tiles,
653
                                           old_base_type);
654 655 656 657 658 659 660
          break;

        case GIMP_INDEXED:
          {
            PixelRegion layerPR;
            PixelRegion newPR;

661
            pixel_region_init (&layerPR, gimp_drawable_get_tiles (drawable),
662
                               0, 0,
663 664
                               gimp_item_get_width  (item),
                               gimp_item_get_height (item),
665 666 667
                               FALSE);
            pixel_region_init (&newPR, new_tiles,
                               0, 0,
668 669
                               gimp_item_get_width  (item),
                               gimp_item_get_height (item),
670 671
                               TRUE);

672
            gimp_layer_transform_color (dest_image,
673 674
                                        &layerPR, gimp_drawable_type (drawable),
                                        &newPR,   new_type);
675 676 677 678
          }
          break;
        }

679 680
      gimp_drawable_set_tiles (drawable, FALSE, NULL,
                               new_tiles, new_type);
681
      tile_manager_unref (new_tiles);
682 683
    }

684 685 686 687
  if (layer->mask)
    gimp_item_set_image (GIMP_ITEM (layer->mask), dest_image);

  GIMP_ITEM_CLASS (parent_class)->convert (item, dest_image);
688 689
}

690
static gboolean
691 692 693 694
gimp_layer_rename (GimpItem     *item,
                   const gchar  *new_name,
                   const gchar  *undo_desc,
                   GError      **error)
695
{
696
  GimpLayer *layer = GIMP_LAYER (item);
697
  GimpImage *image = gimp_item_get_image (item);
698 699
  gboolean   attached;
  gboolean   floating_sel;
700

701 702 703 704
  attached     = gimp_item_is_attached (item);
  floating_sel = gimp_layer_is_floating_sel (layer);

  if (floating_sel)
705
    {
706
      if (GIMP_IS_CHANNEL (layer->fs.drawable))
707 708 709 710 711 712
        {
          g_set_error (error, 0, 0,
                       _("Cannot create a new layer from the floating selection "
                         "because it belongs to a layer mask or channel."));
          return FALSE;
        }
713 714 715

      if (attached)
        {
716
          gimp_image_undo_group_start (image,
717 718
                                       GIMP_UNDO_GROUP_ITEM_PROPERTIES,
                                       undo_desc);
719

720
          floating_sel_to_layer (layer, NULL);
721
        }
722 723
    }

724
  GIMP_ITEM_CLASS (parent_class)->rename (item, new_name, undo_desc, error);
725

726
  if (attached && floating_sel)
727
    gimp_image_undo_group_end (image);
728 729

  return TRUE;
730 731
}

732 733
static void
gimp_layer_translate (GimpItem *item,
734 735
                      gint      offset_x,
                      gint      offset_y,
736
                      gboolean  push_undo)
737
{
738
  GimpLayer *layer = GIMP_LAYER (item);
739

740
  if (push_undo)
741
    gimp_image_undo_push_item_displace (gimp_item_get_image (item), NULL, item);
742

743
  /*  update the old region  */
744 745
  gimp_drawable_update (GIMP_DRAWABLE (layer),
                        0, 0,
746 747
                        gimp_item_get_width  (item),
                        gimp_item_get_height (item));
748 749

  /*  invalidate the selection boundary because of a layer modification  */
750
  gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
751

752 753 754
  if (gimp_layer_is_floating_sel (layer))
    floating_sel_relax (layer, FALSE);

755 756
  GIMP_ITEM_CLASS (parent_class)->translate (item, offset_x, offset_y,
                                             push_undo);
757

758 759 760
  if (gimp_layer_is_floating_sel (layer))
    floating_sel_rigor (layer, FALSE);

761
  /*  update the new region  */
762 763
  gimp_drawable_update (GIMP_DRAWABLE (layer),
                        0, 0,
764 765
                        gimp_item_get_width  (item),
                        gimp_item_get_height (item));
766

767
  if (layer->mask)
768 769 770 771 772 773 774 775
    {
      GIMP_ITEM (layer->mask)->offset_x = item->offset_x;
      GIMP_ITEM (layer->mask)->offset_y = item->offset_y;

      gimp_viewable_invalidate_preview (GIMP_VIEWABLE (layer->mask));
    }
}

776 777 778 779 780 781
static void
gimp_layer_scale (GimpItem              *item,
                  gint                   new_width,
                  gint                   new_height,
                  gint                   new_offset_x,
                  gint                   new_offset_y,
782
                  GimpInterpolationType  interpolation_type,
783
                  GimpProgress          *progress)
784
{
785
  GimpLayer *layer = GIMP_LAYER (item);
786 787 788

  GIMP_ITEM_CLASS (parent_class)->scale (item, new_width, new_height,
                                         new_offset_x, new_offset_y,
789
                                         interpolation_type, progress);
790 791

  if (layer->mask)
792 793 794
    gimp_item_scale (GIMP_ITEM (layer->mask),
                     new_width, new_height,
                     new_offset_x, new_offset_y,
795
                     interpolation_type, progress);
796 797
}

798
static void
799 800
gimp_layer_resize (GimpItem    *item,
                   GimpContext *context,
801 802 803 804
                   gint         new_width,
                   gint         new_height,
                   gint         offset_x,
                   gint         offset_y)
805
{
806
  GimpLayer *layer  = GIMP_LAYER (item);
807

808
  GIMP_ITEM_CLASS (parent_class)->resize (item, context, new_width, new_height,
809 810 811
                                          offset_x, offset_y);

  if (layer->mask)
812
    gimp_item_resize (GIMP_ITEM (layer->mask), context,
813
                      new_width, new_height, offset_x, offset_y);
814 815
}

816 817
static void
gimp_layer_flip (GimpItem            *item,
818
                 GimpContext         *context,
819
                 GimpOrientationType  flip_type,
820 821
                 gdouble              axis,
                 gboolean             clip_result)
822
{
823
  GimpLayer *layer = GIMP_LAYER (item);
824

825 826
  GIMP_ITEM_CLASS (parent_class)->flip (item, context, flip_type, axis,
                                        clip_result);
827 828

  if (layer->mask)