gimplayer.c 53.8 KB
Newer Older
Elliot Lee's avatar
Elliot Lee committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/* The GIMP -- an 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 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 25
#include <glib-object.h>

26 27
#include "libgimpmath/gimpmath.h"

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

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

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

37
#include "gimp-utils.h"
38
#include "gimpcontext.h"
39
#include "gimpcontainer.h"
40
#include "gimpdrawable-convert.h"
41
#include "gimpdrawable-invert.h"
42
#include "gimpimage-undo-push.h"
43 44
#include "gimpimage-undo.h"
#include "gimpimage.h"
Michael Natterer's avatar
Michael Natterer committed
45
#include "gimplayer-floating-sel.h"
46
#include "gimplayer.h"
47
#include "gimplayermask.h"
48
#include "gimpmarshal.h"
49

50
#include "gimp-intl.h"
51 52


53 54
enum
{
55 56
  OPACITY_CHANGED,
  MODE_CHANGED,
57
  LOCK_ALPHA_CHANGED,
58 59 60 61 62
  MASK_CHANGED,
  LAST_SIGNAL
};


63 64
static void       gimp_layer_class_init         (GimpLayerClass     *klass);
static void       gimp_layer_init               (GimpLayer          *layer);
65

66
static void       gimp_layer_dispose            (GObject            *object);
67
static void       gimp_layer_finalize           (GObject            *object);
68

69
static void       gimp_layer_name_changed       (GimpObject         *object);
70 71
static gint64     gimp_layer_get_memsize        (GimpObject         *object,
                                                 gint64             *gui_size);
72

73
static void       gimp_layer_invalidate_preview (GimpViewable       *viewable);
74 75
static gchar    * gimp_layer_get_description    (GimpViewable       *viewable,
                                                 gchar             **tooltip);
76

77
static void       gimp_layer_removed            (GimpItem           *item);
78
static gboolean   gimp_layer_is_attached        (GimpItem           *item);
79 80 81
static GimpItem * gimp_layer_duplicate          (GimpItem           *item,
                                                 GType               new_type,
                                                 gboolean            add_alpha);
82 83
static void       gimp_layer_convert            (GimpItem           *item,
                                                 GimpImage          *dest_image);
84
static gboolean   gimp_layer_rename             (GimpItem           *item,
85 86
                                                 const gchar        *new_name,
                                                 const gchar        *undo_desc);
87 88
static void       gimp_layer_translate          (GimpItem           *item,
                                                 gint                offset_x,
89 90
                                                 gint                offset_y,
                                                 gboolean            push_undo);
91 92 93 94 95
static void       gimp_layer_scale              (GimpItem           *item,
                                                 gint                new_width,
                                                 gint                new_height,
                                                 gint                new_offset_x,
                                                 gint                new_offset_y,
96
                                                 GimpInterpolationType  interp_type,
97
                                                 GimpProgress       *progress);
98
static void       gimp_layer_resize             (GimpItem           *item,
99
                                                 GimpContext        *context,
100 101 102 103
                                                 gint                new_width,
                                                 gint                new_height,
                                                 gint                offset_x,
                                                 gint                offset_y);
104
static void       gimp_layer_flip               (GimpItem           *item,
105
                                                 GimpContext        *context,
106
                                                 GimpOrientationType flip_type,
107 108
                                                 gdouble             axis,
                                                 gboolean            clip_result);
109
static void       gimp_layer_rotate             (GimpItem           *item,
110
                                                 GimpContext        *context,
111 112 113 114
                                                 GimpRotationType    rotate_type,
                                                 gdouble             center_x,
                                                 gdouble             center_y,
                                                 gboolean            clip_result);
115
static void       gimp_layer_transform          (GimpItem           *item,
116
                                                 GimpContext        *context,
117
                                                 const GimpMatrix3  *matrix,
118 119
                                                 GimpTransformDirection direction,
                                                 GimpInterpolationType  interpolation_type,
120 121
                                                 gboolean            supersample,
                                                 gint                recursion_level,
122
                                                 gboolean            clip_result,
123
                                                 GimpProgress       *progress);
124 125 126
static void    gimp_layer_invalidate_boundary   (GimpDrawable       *drawable);
static void    gimp_layer_get_active_components (const GimpDrawable *drawable,
                                                 gboolean           *active);
127 128 129 130
static void    gimp_layer_set_tiles             (GimpDrawable       *drawable,
                                                 gboolean            push_undo,
                                                 const gchar        *undo_desc,
                                                 TileManager        *tiles,
131 132 133
                                                 GimpImageType       type,
                                                 gint                offset_x,
                                                 gint                offset_y);
134

135 136 137 138
static void       gimp_layer_transform_color    (GimpImage          *gimage,
                                                 PixelRegion        *layerPR,
                                                 PixelRegion        *bufPR,
                                                 GimpDrawable       *drawable,
139
                                                 GimpImageBaseType   src_type);
140

141 142 143 144 145 146 147
static void       gimp_layer_layer_mask_update  (GimpDrawable       *layer_mask,
                                                 gint                x,
                                                 gint                y,
                                                 gint                width,
                                                 gint                height,
                                                 GimpLayer          *layer);

148

149 150 151
static guint  layer_signals[LAST_SIGNAL] = { 0 };

static GimpDrawableClass *parent_class   = NULL;
152

153

154
GType
Manish Singh's avatar
Manish Singh committed
155
gimp_layer_get_type (void)
156
{
157
  static GType layer_type = 0;
158

159
  if (! layer_type)
160
    {
161
      static const GTypeInfo layer_info =
162
      {
163
        sizeof (GimpLayerClass),
164 165 166 167 168 169 170 171
        (GBaseInitFunc) NULL,
        (GBaseFinalizeFunc) NULL,
        (GClassInitFunc) gimp_layer_class_init,
        NULL,           /* class_finalize */
        NULL,           /* class_data     */
        sizeof (GimpLayer),
        0,              /* n_preallocs    */
        (GInstanceInitFunc) gimp_layer_init,
172 173
      };

174
      layer_type = g_type_register_static (GIMP_TYPE_DRAWABLE,
175 176
                                           "GimpLayer",
                                           &layer_info, 0);
177 178 179 180 181 182
    }

  return layer_type;
}

static void
183
gimp_layer_class_init (GimpLayerClass *klass)
184
{
185 186 187 188 189
  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);
190

191
  parent_class = g_type_class_peek_parent (klass);
192

193
  layer_signals[OPACITY_CHANGED] =
194
    g_signal_new ("opacity-changed",
195 196 197 198
		  G_TYPE_FROM_CLASS (klass),
		  G_SIGNAL_RUN_FIRST,
		  G_STRUCT_OFFSET (GimpLayerClass, opacity_changed),
		  NULL, NULL,
199
		  gimp_marshal_VOID__VOID,
200
		  G_TYPE_NONE, 0);
201 202

  layer_signals[MODE_CHANGED] =
203
    g_signal_new ("mode-changed",
204 205 206 207
		  G_TYPE_FROM_CLASS (klass),
		  G_SIGNAL_RUN_FIRST,
		  G_STRUCT_OFFSET (GimpLayerClass, mode_changed),
		  NULL, NULL,
208
		  gimp_marshal_VOID__VOID,
209
		  G_TYPE_NONE, 0);
210

211 212
  layer_signals[LOCK_ALPHA_CHANGED] =
    g_signal_new ("lock-alpha-changed",
213 214
		  G_TYPE_FROM_CLASS (klass),
		  G_SIGNAL_RUN_FIRST,
215
		  G_STRUCT_OFFSET (GimpLayerClass, lock_alpha_changed),
216
		  NULL, NULL,
217
		  gimp_marshal_VOID__VOID,
218
		  G_TYPE_NONE, 0);
219

220
  layer_signals[MASK_CHANGED] =
221
    g_signal_new ("mask-changed",
222 223 224 225
		  G_TYPE_FROM_CLASS (klass),
		  G_SIGNAL_RUN_FIRST,
		  G_STRUCT_OFFSET (GimpLayerClass, mask_changed),
		  NULL, NULL,
226
		  gimp_marshal_VOID__VOID,
227
		  G_TYPE_NONE, 0);
228

229
  object_class->dispose               = gimp_layer_dispose;
230 231
  object_class->finalize              = gimp_layer_finalize;

232
  gimp_object_class->name_changed     = gimp_layer_name_changed;
233 234 235 236
  gimp_object_class->get_memsize      = gimp_layer_get_memsize;

  viewable_class->default_stock_id    = "gimp-layer";
  viewable_class->invalidate_preview  = gimp_layer_invalidate_preview;
237
  viewable_class->get_description     = gimp_layer_get_description;
238

239
  item_class->removed                 = gimp_layer_removed;
240
  item_class->is_attached             = gimp_layer_is_attached;
241
  item_class->duplicate               = gimp_layer_duplicate;
242
  item_class->convert                 = gimp_layer_convert;
243 244 245 246 247 248 249 250 251
  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;
  item_class->default_name            = _("Layer");
  item_class->rename_desc             = _("Rename Layer");
252 253 254 255 256 257
  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");
258

259 260
  drawable_class->invalidate_boundary   = gimp_layer_invalidate_boundary;
  drawable_class->get_active_components = gimp_layer_get_active_components;
261
  drawable_class->set_tiles             = gimp_layer_set_tiles;
262 263 264

  klass->opacity_changed              = NULL;
  klass->mode_changed                 = NULL;
265
  klass->lock_alpha_changed           = NULL;
266
  klass->mask_changed                 = NULL;
267 268 269 270 271
}

static void
gimp_layer_init (GimpLayer *layer)
{
272 273 274
  layer->opacity    = GIMP_OPACITY_OPAQUE;
  layer->mode       = GIMP_NORMAL_MODE;
  layer->lock_alpha = FALSE;
275

276
  layer->mask       = NULL;
277

278 279 280 281 282 283 284
  /*  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;
285 286
}

287 288 289 290 291 292 293 294 295 296 297 298 299
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);
}

300 301 302
static void
gimp_layer_finalize (GObject *object)
{
303
  GimpLayer *layer = GIMP_LAYER (object);
304 305 306

  if (layer->mask)
    {
307
      g_object_unref (layer->mask);
308 309 310
      layer->mask = NULL;
    }

311 312 313 314 315 316
  if (layer->fs.backing_store)
    {
      tile_manager_unref (layer->fs.backing_store);
      layer->fs.backing_store = NULL;
    }

317 318 319
  if (layer->fs.segs)
    {
      g_free (layer->fs.segs);
320 321
      layer->fs.segs     = NULL;
      layer->fs.num_segs = 0;
322 323 324 325 326
    }

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

327 328 329 330 331
static void
gimp_layer_name_changed (GimpObject *object)
{
  GimpLayer *layer = GIMP_LAYER (object);

332 333
  if (GIMP_OBJECT_CLASS (parent_class)->name_changed)
    GIMP_OBJECT_CLASS (parent_class)->name_changed (object);
334 335 336 337 338 339 340 341 342 343 344

  if (layer->mask)
    {
      gchar *mask_name;

      mask_name = g_strdup_printf (_("%s mask"), gimp_object_get_name (object));
      gimp_object_set_name (GIMP_OBJECT (layer->mask), mask_name);
      g_free (mask_name);
    }
}

345
static gint64
346
gimp_layer_get_memsize (GimpObject *object,
347
                        gint64     *gui_size)
348
{
349
  GimpLayer *layer   = GIMP_LAYER (object);
350
  gint64     memsize = 0;
351 352

  if (layer->mask)
353
    memsize += gimp_object_get_memsize (GIMP_OBJECT (layer->mask), gui_size);
354 355

  if (layer->fs.backing_store)
356
    *gui_size += tile_manager_get_memsize (layer->fs.backing_store, FALSE);
357

358
  *gui_size += layer->fs.num_segs * sizeof (BoundSeg);
359

360 361
  return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
                                                                  gui_size);
362 363
}

Elliot Lee's avatar
Elliot Lee committed
364
static void
365
gimp_layer_invalidate_preview (GimpViewable *viewable)
366
{
367
  GimpLayer *layer = GIMP_LAYER (viewable);
368

369 370 371
  if (GIMP_VIEWABLE_CLASS (parent_class)->invalidate_preview)
    GIMP_VIEWABLE_CLASS (parent_class)->invalidate_preview (viewable);

372
  if (gimp_layer_is_floating_sel (layer))
373
    floating_sel_invalidate (layer);
374 375
}

376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
static gchar *
gimp_layer_get_description (GimpViewable  *viewable,
                            gchar        **tooltip)
{
  if (gimp_layer_is_floating_sel (GIMP_LAYER (viewable)))
    {
      if (tooltip)
        *tooltip = NULL;

      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);
}

393 394 395 396 397
static void
gimp_layer_get_active_components (const GimpDrawable *drawable,
                                  gboolean           *active)
{
  GimpLayer *layer  = GIMP_LAYER (drawable);
398
  GimpImage *gimage = gimp_item_get_image (GIMP_ITEM (drawable));
399 400 401 402 403 404
  gint       i;

  /*  first copy the gimage active channels  */
  for (i = 0; i < MAX_CHANNELS; i++)
    active[i] = gimage->active[i];

405
  if (gimp_drawable_has_alpha (drawable) && layer->lock_alpha)
406 407 408
    active[gimp_drawable_bytes (drawable) - 1] = FALSE;
}

409 410 411 412 413
static void
gimp_layer_set_tiles (GimpDrawable *drawable,
                      gboolean      push_undo,
                      const gchar  *undo_desc,
                      TileManager  *tiles,
414 415 416
                      GimpImageType type,
                      gint          offset_x,
                      gint          offset_y)
417
{
418 419
  GimpLayer *layer = GIMP_LAYER (drawable);

420 421 422
  if (gimp_layer_is_floating_sel (layer))
    floating_sel_relax (layer, FALSE);

423 424
  GIMP_DRAWABLE_CLASS (parent_class)->set_tiles (drawable,
                                                 push_undo, undo_desc,
425 426 427
                                                 tiles, type,
                                                 offset_x, offset_y);

428 429
  if (gimp_layer_is_floating_sel (layer))
    floating_sel_rigor (layer, FALSE);
430 431
}

432 433 434 435 436 437 438 439 440 441 442 443
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);
}

444 445 446 447 448 449 450
static gboolean
gimp_layer_is_attached (GimpItem *item)
{
  return (GIMP_IS_IMAGE (item->gimage) &&
          gimp_container_have (item->gimage->layers, GIMP_OBJECT (item)));
}

451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
static GimpItem *
gimp_layer_duplicate (GimpItem *item,
                      GType     new_type,
                      gboolean  add_alpha)
{
  GimpLayer *layer;
  GimpItem  *new_item;
  GimpLayer *new_layer;

  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,
                                                        add_alpha);

  if (! GIMP_IS_LAYER (new_item))
    return new_item;

  layer     = GIMP_LAYER (item);
  new_layer = GIMP_LAYER (new_item);

471 472 473
  new_layer->mode       = layer->mode;
  new_layer->opacity    = layer->opacity;
  new_layer->lock_alpha = layer->lock_alpha;
474 475 476 477

  /*  duplicate the layer mask if necessary  */
  if (layer->mask)
    {
Sven Neumann's avatar
Sven Neumann committed
478 479 480 481
      GimpItem *dup = gimp_item_duplicate (GIMP_ITEM (layer->mask),
                                           G_TYPE_FROM_INSTANCE (layer->mask),
                                           FALSE);
      gimp_layer_add_mask (new_layer, GIMP_LAYER_MASK (dup), FALSE);
482 483 484 485 486
    }

  return new_item;
}

487
static void
488 489
gimp_layer_convert (GimpItem  *item,
                    GimpImage *dest_image)
490
{
491 492 493
  GimpLayer         *layer    = GIMP_LAYER (item);
  GimpDrawable      *drawable = GIMP_DRAWABLE (item);
  GimpImageBaseType  old_base_type;
494 495
  GimpImageBaseType  new_base_type;

496
  old_base_type = GIMP_IMAGE_TYPE_BASE_TYPE (gimp_drawable_type (drawable));
497
  new_base_type = gimp_image_base_type (dest_image);
498

499
  if (old_base_type != new_base_type)
500 501 502 503 504 505
    {
      TileManager   *new_tiles;
      GimpImageType  new_type;

      new_type = GIMP_IMAGE_TYPE_FROM_BASE_TYPE (new_base_type);

506
      if (gimp_drawable_has_alpha (drawable))
507 508
        new_type = GIMP_IMAGE_TYPE_WITH_ALPHA (new_type);

509 510
      new_tiles = tile_manager_new (gimp_item_width (item),
                                    gimp_item_height (item),
511 512 513 514 515
                                    GIMP_IMAGE_TYPE_BYTES (new_type));

      switch (new_base_type)
        {
        case GIMP_RGB:
516
          gimp_drawable_convert_rgb (drawable,
517
                                     new_tiles,
518
                                     old_base_type);
519 520 521
          break;

        case GIMP_GRAY:
522
          gimp_drawable_convert_grayscale (drawable,
523
                                           new_tiles,
524
                                           old_base_type);
525 526 527 528 529 530 531
          break;

        case GIMP_INDEXED:
          {
            PixelRegion layerPR;
            PixelRegion newPR;

532
            pixel_region_init (&layerPR, drawable->tiles,
533
                               0, 0,
534 535
                               gimp_item_width (item),
                               gimp_item_height (item),
536 537 538
                               FALSE);
            pixel_region_init (&newPR, new_tiles,
                               0, 0,
539 540
                               gimp_item_width (item),
                               gimp_item_height (item),
541 542
                               TRUE);

543
            gimp_layer_transform_color (gimp_item_get_image (item),
544 545
                                        &newPR, &layerPR,
                                        NULL,
546
                                        old_base_type);
547 548 549 550
          }
          break;
        }

551
      gimp_drawable_set_tiles_full (drawable, FALSE, NULL,
552 553 554
                                    new_tiles, new_type,
                                    GIMP_ITEM (layer)->offset_x,
                                    GIMP_ITEM (layer)->offset_y);
555
      tile_manager_unref (new_tiles);
556 557
    }

558 559 560 561
  if (layer->mask)
    gimp_item_set_image (GIMP_ITEM (layer->mask), dest_image);

  GIMP_ITEM_CLASS (parent_class)->convert (item, dest_image);
562 563
}

564
static gboolean
565 566 567 568
gimp_layer_rename (GimpItem    *item,
                   const gchar *new_name,
                   const gchar *undo_desc)
{
569
  GimpLayer *layer = GIMP_LAYER (item);
570
  GimpImage *gimage;
571 572
  gboolean   attached;
  gboolean   floating_sel;
573 574 575

  gimage = gimp_item_get_image (item);

576 577 578 579
  attached     = gimp_item_is_attached (item);
  floating_sel = gimp_layer_is_floating_sel (layer);

  if (floating_sel)
580
    {
581 582 583 584 585 586 587 588
      if (GIMP_IS_CHANNEL (layer->fs.drawable))
        return FALSE;

      if (attached)
        {
          gimp_image_undo_group_start (gimage,
                                       GIMP_UNDO_GROUP_ITEM_PROPERTIES,
                                       undo_desc);
589

590 591
          floating_sel_to_layer (layer);
        }
592 593 594 595
    }

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

596
  if (attached && floating_sel)
597
    gimp_image_undo_group_end (gimage);
598 599

  return TRUE;
600 601
}

602 603
static void
gimp_layer_translate (GimpItem *item,
604 605 606
		      gint      offset_x,
		      gint      offset_y,
                      gboolean  push_undo)
607
{
608
  GimpLayer *layer = GIMP_LAYER (item);
609

610
  if (push_undo)
611
    gimp_image_undo_push_item_displace (gimp_item_get_image (item), NULL, item);
612

613 614 615 616
  /*  update the old region  */
  gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, item->width, item->height);

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

619 620 621
  if (gimp_layer_is_floating_sel (layer))
    floating_sel_relax (layer, FALSE);

622 623
  GIMP_ITEM_CLASS (parent_class)->translate (item, offset_x, offset_y,
                                             push_undo);
624

625 626 627
  if (gimp_layer_is_floating_sel (layer))
    floating_sel_rigor (layer, FALSE);

628 629 630
  /*  update the new region  */
  gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, item->width, item->height);

631
  if (layer->mask)
632 633 634 635 636 637 638 639
    {
      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));
    }
}

640 641 642 643 644 645
static void
gimp_layer_scale (GimpItem              *item,
                  gint                   new_width,
                  gint                   new_height,
                  gint                   new_offset_x,
                  gint                   new_offset_y,
646
                  GimpInterpolationType  interpolation_type,
647
                  GimpProgress          *progress)
648
{
649
  GimpLayer *layer = GIMP_LAYER (item);
650 651 652

  GIMP_ITEM_CLASS (parent_class)->scale (item, new_width, new_height,
                                         new_offset_x, new_offset_y,
653
                                         interpolation_type, progress);
654 655

  if (layer->mask)
656 657 658
    gimp_item_scale (GIMP_ITEM (layer->mask),
                     new_width, new_height,
                     new_offset_x, new_offset_y,
659
                     interpolation_type, progress);
660 661
}

662
static void
663 664 665 666 667 668
gimp_layer_resize (GimpItem    *item,
                   GimpContext *context,
		   gint         new_width,
		   gint         new_height,
		   gint         offset_x,
		   gint         offset_y)
669
{
670
  GimpLayer *layer  = GIMP_LAYER (item);
671

672
  GIMP_ITEM_CLASS (parent_class)->resize (item, context, new_width, new_height,
673 674 675
                                          offset_x, offset_y);

  if (layer->mask)
676
    gimp_item_resize (GIMP_ITEM (layer->mask), context,
677
                      new_width, new_height, offset_x, offset_y);
678 679
}

680 681
static void
gimp_layer_flip (GimpItem            *item,
682
                 GimpContext         *context,
683
                 GimpOrientationType  flip_type,
684 685
                 gdouble              axis,
                 gboolean             clip_result)
686
{
687
  GimpLayer *layer = GIMP_LAYER (item);
688

689 690
  GIMP_ITEM_CLASS (parent_class)->flip (item, context, flip_type, axis,
                                        clip_result);
691 692

  if (layer->mask)
693
    gimp_item_flip (GIMP_ITEM (layer->mask), context,
694
                    flip_type, axis, clip_result);
695 696
}

697 698
static void
gimp_layer_rotate (GimpItem         *item,
699
                   GimpContext      *context,
700 701 702 703 704
                   GimpRotationType  rotate_type,
                   gdouble           center_x,
                   gdouble           center_y,
                   gboolean          clip_result)
{
705
  GimpLayer *layer = GIMP_LAYER (item);
706

707
  GIMP_ITEM_CLASS (parent_class)->rotate (item, context,
708 709 710 711
                                          rotate_type, center_x, center_y,
                                          clip_result);

  if (layer->mask)
712
    gimp_item_rotate (GIMP_ITEM (layer->mask), context,
713 714 715
                      rotate_type, center_x, center_y, clip_result);
}

716 717
static void
gimp_layer_transform (GimpItem               *item,
718
                      GimpContext            *context,
719
                      const GimpMatrix3      *matrix,
720 721
                      GimpTransformDirection  direction,
                      GimpInterpolationType   interpolation_type,
722 723
                      gboolean                supersample,
                      gint                    recursion_level,
724
                      gboolean                clip_result,
725
                      GimpProgress           *progress)
726
{
727
  GimpLayer *layer = GIMP_LAYER (item);
728

729
  GIMP_ITEM_CLASS (parent_class)->transform (item, context, matrix, direction,
730 731
                                             interpolation_type,
                                             supersample, recursion_level,
732
                                             clip_result, progress);
733 734

  if (layer->mask)
735
    gimp_item_transform (GIMP_ITEM (layer->mask), context,
736
                         matrix, direction,
737 738
                         interpolation_type,
                         supersample, recursion_level,
739
                         clip_result, progress);
740 741 742 743 744
}

static void
gimp_layer_invalidate_boundary (GimpDrawable *drawable)
{
745
  GimpLayer   *layer = GIMP_LAYER (drawable);
746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769
  GimpImage   *gimage;
  GimpChannel *mask;

  if (! (gimage = gimp_item_get_image (GIMP_ITEM (layer))))
    return;

  /*  Turn the current selection off  */
  gimp_image_selection_control (gimage, GIMP_SELECTION_OFF);

  /*  clear the affected region surrounding the layer  */
  gimp_image_selection_control (gimage, GIMP_SELECTION_LAYER_OFF);

  /*  get the selection mask channel  */
  mask = gimp_image_get_mask (gimage);

  /*  Only bother with the bounds if there is a selection  */
  if (! gimp_channel_is_empty (mask))
    {
      mask->bounds_known   = FALSE;
      mask->boundary_known = FALSE;
    }

  if (gimp_layer_is_floating_sel (layer))
    floating_sel_invalidate (layer);
770 771
}

772
static void
773 774 775 776
gimp_layer_transform_color (GimpImage         *gimage,
			    PixelRegion       *layerPR,
			    PixelRegion       *bufPR,
			    GimpDrawable      *drawable,
777
			    GimpImageBaseType  src_type)
Elliot Lee's avatar
Elliot Lee committed
778
{
779
  gpointer  pr;
Elliot Lee's avatar
Elliot Lee committed
780

781 782
  for (pr = pixel_regions_register (2, layerPR, bufPR);
       pr != NULL;
783
       pr = pixel_regions_process (pr))
Elliot Lee's avatar
Elliot Lee committed
784
    {
Sven Neumann's avatar
Sven Neumann committed
785 786 787
      const guchar *src  = bufPR->data;
      guchar       *dest = layerPR->data;
      gint          h    = layerPR->h;
Elliot Lee's avatar
Elliot Lee committed
788 789 790

      while (h--)
	{
Sven Neumann's avatar
Sven Neumann committed
791 792 793 794
          const guchar *s = src;
          guchar       *d = dest;
          gint i;

Elliot Lee's avatar
Elliot Lee committed
795 796
	  for (i = 0; i < layerPR->w; i++)
	    {
Sven Neumann's avatar
Sven Neumann committed
797 798
	      gimp_image_transform_color (gimage, drawable, d, src_type, s);

Elliot Lee's avatar
Elliot Lee committed
799
	      /*  copy alpha channel  */
800
	      d[layerPR->bytes - 1] = s[bufPR->bytes - 1];
Sven Neumann's avatar
Sven Neumann committed
801 802 803

              s += bufPR->bytes;
              d += layerPR->bytes;
Elliot Lee's avatar
Elliot Lee committed
804 805
	    }

806 807
	  src  += bufPR->rowstride;
	  dest += layerPR->rowstride;
Elliot Lee's avatar
Elliot Lee committed
808 809 810 811
	}
    }
}

812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830
static void
gimp_layer_layer_mask_update (GimpDrawable *drawable,
                              gint          x,
                              gint          y,
                              gint          width,
                              gint          height,
                              GimpLayer    *layer)
{
  GimpLayerMask *layer_mask = GIMP_LAYER_MASK (drawable);

  if (layer_mask->apply_mask || layer_mask->show_mask)
    {
      gimp_drawable_update (GIMP_DRAWABLE (layer),
                            x, y, width, height);
    }
}


/*  public functions  */
Elliot Lee's avatar
Elliot Lee committed
831

832
GimpLayer *
833 834 835 836 837
gimp_layer_new (GimpImage            *gimage,
		gint                  width,
		gint                  height,
		GimpImageType         type,
		const gchar          *name,
838
		gdouble               opacity,
839
		GimpLayerModeEffects  mode)
Elliot Lee's avatar
Elliot Lee committed
840
{
841
  GimpLayer *layer;
Elliot Lee's avatar
Elliot Lee committed
842

843 844 845
  g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);
  g_return_val_if_fail (width > 0, NULL);
  g_return_val_if_fail (height > 0, NULL);
Elliot Lee's avatar
Elliot Lee committed
846

Michael Natterer's avatar
Michael Natterer committed
847
  layer = g_object_new (GIMP_TYPE_LAYER, NULL);
Elliot Lee's avatar
Elliot Lee committed
848

849
  gimp_drawable_configure (GIMP_DRAWABLE (layer),
850
			   gimage,
851
                           0, 0, width, height,
Michael Natterer's avatar