gimpdrawable.c 61 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
 */
Sven Neumann's avatar
Sven Neumann committed
17

18 19
#include "config.h"

20
#include <cairo.h>
21
#include <gegl.h>
22
#include <gdk-pixbuf/gdk-pixbuf.h>
Sven Neumann's avatar
Sven Neumann committed
23

24
#include "libgimpbase/gimpbase.h"
25
#include "libgimpcolor/gimpcolor.h"
26
#include "libgimpmath/gimpmath.h"
27

28
#include "core-types.h"
29

30
#include "gegl/gimp-babl.h"
31
#include "gegl/gimp-gegl-apply-operation.h"
32
#include "gegl/gimp-gegl-loops.h"
33 34
#include "gegl/gimp-gegl-utils.h"

35
#include "gimp-memsize.h"
36
#include "gimp-utils.h"
37
#include "gimpchannel.h"
38
#include "gimpcontext.h"
39
#include "gimpdrawable-combine.h"
40
#include "gimpdrawable-fill.h"
41
#include "gimpdrawable-floating-selection.h"
42
#include "gimpdrawable-preview.h"
43
#include "gimpdrawable-private.h"
44
#include "gimpdrawable-shadow.h"
45
#include "gimpdrawable-transform.h"
46
#include "gimpfilterstack.h"
47
#include "gimpimage.h"
48
#include "gimpimage-colormap.h"
49
#include "gimpimage-undo-push.h"
50
#include "gimpmarshal.h"
51
#include "gimppickable.h"
52
#include "gimpprogress.h"
53

54 55
#include "gimp-log.h"

56
#include "gimp-intl.h"
57

58

59 60 61 62 63 64 65
#define PAINT_COPY_CHUNK_WIDTH    128
#define PAINT_COPY_CHUNK_HEIGHT   128

#define PAINT_UPDATE_CHUNK_WIDTH   32
#define PAINT_UPDATE_CHUNK_HEIGHT  32


66 67
enum
{
68
  UPDATE,
69
  ALPHA_CHANGED,
70 71 72
  LAST_SIGNAL
};

73 74
enum
{
75 76
  PROP_0,
  PROP_BUFFER
77 78
};

79

80 81
/*  local function prototypes  */

82 83
static void       gimp_color_managed_iface_init    (GimpColorManagedInterface *iface);
static void       gimp_pickable_iface_init         (GimpPickableInterface     *iface);
84

85
static void       gimp_drawable_dispose            (GObject           *object);
86
static void       gimp_drawable_finalize           (GObject           *object);
87 88 89 90 91 92 93 94
static void       gimp_drawable_set_property       (GObject           *object,
                                                    guint              property_id,
                                                    const GValue      *value,
                                                    GParamSpec        *pspec);
static void       gimp_drawable_get_property       (GObject           *object,
                                                    guint              property_id,
                                                    GValue            *value,
                                                    GParamSpec        *pspec);
95

96 97
static gint64     gimp_drawable_get_memsize        (GimpObject        *object,
                                                    gint64            *gui_size);
98

99 100 101
static gboolean   gimp_drawable_get_size           (GimpViewable      *viewable,
                                                    gint              *width,
                                                    gint              *height);
102

103 104
static GeglNode * gimp_drawable_get_node           (GimpFilter        *filter);

105
static void       gimp_drawable_removed            (GimpItem          *item);
106
static GimpItem * gimp_drawable_duplicate          (GimpItem          *item,
107
                                                    GType              new_type);
108 109 110 111 112
static void       gimp_drawable_scale              (GimpItem          *item,
                                                    gint               new_width,
                                                    gint               new_height,
                                                    gint               new_offset_x,
                                                    gint               new_offset_y,
113
                                                    GimpInterpolationType interp_type,
114
                                                    GimpProgress      *progress);
115
static void       gimp_drawable_resize             (GimpItem          *item,
116
                                                    GimpContext       *context,
117
                                                    GimpFillType       fill_type,
118 119 120 121
                                                    gint               new_width,
                                                    gint               new_height,
                                                    gint               offset_x,
                                                    gint               offset_y);
122
static void       gimp_drawable_flip               (GimpItem          *item,
123
                                                    GimpContext       *context,
124 125 126
                                                    GimpOrientationType  flip_type,
                                                    gdouble            axis,
                                                    gboolean           clip_result);
127
static void       gimp_drawable_rotate             (GimpItem          *item,
128
                                                    GimpContext       *context,
129 130 131 132
                                                    GimpRotationType   rotate_type,
                                                    gdouble            center_x,
                                                    gdouble            center_y,
                                                    gboolean           clip_result);
133
static void       gimp_drawable_transform          (GimpItem          *item,
134
                                                    GimpContext       *context,
135
                                                    const GimpMatrix3 *matrix,
136 137 138
                                                    GimpTransformDirection direction,
                                                    GimpInterpolationType interpolation_type,
                                                    GimpTransformResize clip_result,
139
                                                    GimpProgress      *progress);
140

141 142 143 144 145 146 147
static const guint8 *
                  gimp_drawable_get_icc_profile    (GimpColorManaged  *managed,
                                                    gsize             *len);
static GimpColorProfile *
                  gimp_drawable_get_color_profile  (GimpColorManaged  *managed);
static void       gimp_drawable_profile_changed    (GimpColorManaged  *managed);

148 149 150
static gboolean   gimp_drawable_get_pixel_at       (GimpPickable      *pickable,
                                                    gint               x,
                                                    gint               y,
151 152
                                                    const Babl        *format,
                                                    gpointer           pixel);
153 154 155 156 157
static void       gimp_drawable_get_pixel_average  (GimpPickable      *pickable,
                                                    const GeglRectangle *rect,
                                                    const Babl        *format,
                                                    gpointer           pixel);

158 159 160 161 162 163
static void       gimp_drawable_real_update        (GimpDrawable      *drawable,
                                                    gint               x,
                                                    gint               y,
                                                    gint               width,
                                                    gint               height);

164
static gint64  gimp_drawable_real_estimate_memsize (GimpDrawable      *drawable,
165
                                                    GimpComponentType  component_type,
166 167 168
                                                    gint               width,
                                                    gint               height);

169 170
static void       gimp_drawable_real_convert_type  (GimpDrawable      *drawable,
                                                    GimpImage         *dest_image,
171
                                                    const Babl        *new_format,
172
                                                    GimpColorProfile  *dest_profile,
173 174
                                                    GeglDitherMethod   layer_dither_type,
                                                    GeglDitherMethod   mask_dither_type,
175 176
                                                    gboolean           push_undo,
                                                    GimpProgress      *progress);
177

178
static GeglBuffer * gimp_drawable_real_get_buffer  (GimpDrawable      *drawable);
179
static void       gimp_drawable_real_set_buffer    (GimpDrawable      *drawable,
180 181
                                                    gboolean           push_undo,
                                                    const gchar       *undo_desc,
182
                                                    GeglBuffer        *buffer,
183 184
                                                    gint               offset_x,
                                                    gint               offset_y);
185

186 187
static void       gimp_drawable_real_push_undo     (GimpDrawable      *drawable,
                                                    const gchar       *undo_desc,
188
                                                    GeglBuffer        *buffer,
189 190 191 192
                                                    gint               x,
                                                    gint               y,
                                                    gint               width,
                                                    gint               height);
193
static void       gimp_drawable_real_swap_pixels   (GimpDrawable      *drawable,
194
                                                    GeglBuffer        *buffer,
195
                                                    gint               x,
196
                                                    gint               y);
197
static GeglNode * gimp_drawable_real_get_source_node (GimpDrawable    *drawable);
198

199

200
G_DEFINE_TYPE_WITH_CODE (GimpDrawable, gimp_drawable, GIMP_TYPE_ITEM,
201 202
                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_COLOR_MANAGED,
                                                gimp_color_managed_iface_init)
203
                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_PICKABLE,
204
                                                gimp_pickable_iface_init))
205

206
#define parent_class gimp_drawable_parent_class
207

208
static guint gimp_drawable_signals[LAST_SIGNAL] = { 0 };
209

210 211

static void
212
gimp_drawable_class_init (GimpDrawableClass *klass)
213
{
214 215 216
  GObjectClass      *object_class      = G_OBJECT_CLASS (klass);
  GimpObjectClass   *gimp_object_class = GIMP_OBJECT_CLASS (klass);
  GimpViewableClass *viewable_class    = GIMP_VIEWABLE_CLASS (klass);
217
  GimpFilterClass   *filter_class      = GIMP_FILTER_CLASS (klass);
218
  GimpItemClass     *item_class        = GIMP_ITEM_CLASS (klass);
219

220 221
  gimp_drawable_signals[UPDATE] =
    g_signal_new ("update",
222 223 224 225 226 227 228 229 230 231
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GimpDrawableClass, update),
                  NULL, NULL,
                  gimp_marshal_VOID__INT_INT_INT_INT,
                  G_TYPE_NONE, 4,
                  G_TYPE_INT,
                  G_TYPE_INT,
                  G_TYPE_INT,
                  G_TYPE_INT);
232

233
  gimp_drawable_signals[ALPHA_CHANGED] =
234
    g_signal_new ("alpha-changed",
235 236 237 238 239 240
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GimpDrawableClass, alpha_changed),
                  NULL, NULL,
                  gimp_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
241

242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
  object_class->dispose           = gimp_drawable_dispose;
  object_class->finalize          = gimp_drawable_finalize;
  object_class->set_property      = gimp_drawable_set_property;
  object_class->get_property      = gimp_drawable_get_property;

  gimp_object_class->get_memsize  = gimp_drawable_get_memsize;

  viewable_class->get_size        = gimp_drawable_get_size;
  viewable_class->get_new_preview = gimp_drawable_get_new_preview;
  viewable_class->get_new_pixbuf  = gimp_drawable_get_new_pixbuf;

  filter_class->get_node          = gimp_drawable_get_node;

  item_class->removed             = gimp_drawable_removed;
  item_class->duplicate           = gimp_drawable_duplicate;
  item_class->scale               = gimp_drawable_scale;
  item_class->resize              = gimp_drawable_resize;
  item_class->flip                = gimp_drawable_flip;
  item_class->rotate              = gimp_drawable_rotate;
  item_class->transform           = gimp_drawable_transform;

  klass->update                   = gimp_drawable_real_update;
  klass->alpha_changed            = NULL;
  klass->estimate_memsize         = gimp_drawable_real_estimate_memsize;
  klass->invalidate_boundary      = NULL;
  klass->get_active_components    = NULL;
  klass->get_active_mask          = NULL;
  klass->convert_type             = gimp_drawable_real_convert_type;
  klass->apply_buffer             = gimp_drawable_real_apply_buffer;
  klass->replace_buffer           = gimp_drawable_real_replace_buffer;
  klass->get_buffer               = gimp_drawable_real_get_buffer;
  klass->set_buffer               = gimp_drawable_real_set_buffer;
  klass->push_undo                = gimp_drawable_real_push_undo;
  klass->swap_pixels              = gimp_drawable_real_swap_pixels;
  klass->get_source_node          = gimp_drawable_real_get_source_node;
277

278 279
  g_object_class_override_property (object_class, PROP_BUFFER, "buffer");

280
  g_type_class_add_private (klass, sizeof (GimpDrawablePrivate));
281 282
}

283 284 285
static void
gimp_drawable_init (GimpDrawable *drawable)
{
286 287 288
  drawable->private = G_TYPE_INSTANCE_GET_PRIVATE (drawable,
                                                   GIMP_TYPE_DRAWABLE,
                                                   GimpDrawablePrivate);
289 290

  drawable->private->filter_stack = gimp_filter_stack_new (GIMP_TYPE_FILTER);
291 292
}

293 294
/* sorry for the evil casts */

295
static void
296 297 298 299 300 301 302 303 304
gimp_color_managed_iface_init (GimpColorManagedInterface *iface)
{
  iface->get_icc_profile   = gimp_drawable_get_icc_profile;
  iface->get_color_profile = gimp_drawable_get_color_profile;
  iface->profile_changed   = gimp_drawable_profile_changed;
}

static void
gimp_pickable_iface_init (GimpPickableInterface *iface)
305
{
306 307 308
  iface->get_image             = (GimpImage     * (*) (GimpPickable *pickable)) gimp_item_get_image;
  iface->get_format            = (const Babl    * (*) (GimpPickable *pickable)) gimp_drawable_get_format;
  iface->get_format_with_alpha = (const Babl    * (*) (GimpPickable *pickable)) gimp_drawable_get_format_with_alpha;
309
  iface->get_buffer            = (GeglBuffer    * (*) (GimpPickable *pickable)) gimp_drawable_get_buffer;
310
  iface->get_pixel_at          = gimp_drawable_get_pixel_at;
311
  iface->get_pixel_average     = gimp_drawable_get_pixel_average;
312 313
}

314
static void
315
gimp_drawable_dispose (GObject *object)
316
{
317
  GimpDrawable *drawable = GIMP_DRAWABLE (object);
318

319 320 321 322 323 324 325 326 327 328
  if (gimp_drawable_get_floating_sel (drawable))
    gimp_drawable_detach_floating_sel (drawable);

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

static void
gimp_drawable_finalize (GObject *object)
{
  GimpDrawable *drawable = GIMP_DRAWABLE (object);
329

330 331 332
  while (drawable->private->paint_count)
    gimp_drawable_end_paint (drawable);

333
  g_clear_object (&drawable->private->buffer);
334

335
  gimp_drawable_free_shadow_buffer (drawable);
336

337
  g_clear_object (&drawable->private->source_node);
338
  g_clear_object (&drawable->private->buffer_source_node);
339
  g_clear_object (&drawable->private->filter_stack);
340

341
  G_OBJECT_CLASS (parent_class)->finalize (object);
342 343
}

344 345 346 347 348 349 350 351
static void
gimp_drawable_set_property (GObject      *object,
                            guint         property_id,
                            const GValue *value,
                            GParamSpec   *pspec)
{
  switch (property_id)
    {
352
    case PROP_BUFFER:
353 354 355 356 357 358 359 360 361 362 363 364
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

static void
gimp_drawable_get_property (GObject    *object,
                            guint       property_id,
                            GValue     *value,
                            GParamSpec *pspec)
{
365 366
  GimpDrawable *drawable = GIMP_DRAWABLE (object);

367 368
  switch (property_id)
    {
369 370 371 372
    case PROP_BUFFER:
      g_value_set_object (value, drawable->private->buffer);
      break;

373 374 375 376 377 378
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

379
static gint64
380
gimp_drawable_get_memsize (GimpObject *object,
381
                           gint64     *gui_size)
382
{
383 384
  GimpDrawable *drawable = GIMP_DRAWABLE (object);
  gint64        memsize  = 0;
385

386
  memsize += gimp_gegl_buffer_get_memsize (gimp_drawable_get_buffer (drawable));
387
  memsize += gimp_gegl_buffer_get_memsize (drawable->private->shadow);
388

389 390
  return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
                                                                  gui_size);
391 392
}

393 394 395 396 397 398 399
static gboolean
gimp_drawable_get_size (GimpViewable *viewable,
                        gint         *width,
                        gint         *height)
{
  GimpItem *item = GIMP_ITEM (viewable);

400 401
  *width  = gimp_item_get_width  (item);
  *height = gimp_item_get_height (item);
402 403 404 405

  return TRUE;
}

406 407 408 409 410 411 412 413 414 415 416 417 418 419
static GeglNode *
gimp_drawable_get_node (GimpFilter *filter)
{
  GimpDrawable *drawable = GIMP_DRAWABLE (filter);
  GeglNode     *node;
  GeglNode     *input;
  GeglNode     *output;

  node = GIMP_FILTER_CLASS (parent_class)->get_node (filter);

  g_warn_if_fail (drawable->private->mode_node == NULL);

  drawable->private->mode_node =
    gegl_node_new_child (node,
420
                         "operation", "gimp:normal",
421 422 423 424 425
                         NULL);

  input  = gegl_node_get_input_proxy  (node, "input");
  output = gegl_node_get_output_proxy (node, "output");

426 427
  gegl_node_connect_to (input,                        "output",
                        drawable->private->mode_node, "input");
428 429
  gegl_node_connect_to (drawable->private->mode_node, "output",
                        output,                       "input");
430 431 432 433

  return node;
}

434 435 436 437 438
static void
gimp_drawable_removed (GimpItem *item)
{
  GimpDrawable *drawable = GIMP_DRAWABLE (item);

439
  gimp_drawable_free_shadow_buffer (drawable);
440 441 442 443 444

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

445 446
static GimpItem *
gimp_drawable_duplicate (GimpItem *item,
447
                         GType     new_type)
448
{
449
  GimpItem *new_item;
450 451 452

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

453
  new_item = GIMP_ITEM_CLASS (parent_class)->duplicate (item, new_type);
454

455 456 457 458
  if (GIMP_IS_DRAWABLE (new_item))
    {
      GimpDrawable  *drawable     = GIMP_DRAWABLE (item);
      GimpDrawable  *new_drawable = GIMP_DRAWABLE (new_item);
459
      GeglBuffer    *new_buffer;
460

461
      new_buffer = gegl_buffer_dup (gimp_drawable_get_buffer (drawable));
462

463 464
      gimp_drawable_set_buffer (new_drawable, FALSE, NULL, new_buffer);
      g_object_unref (new_buffer);
465
    }
466

467 468 469
  return new_item;
}

470 471 472 473 474 475
static void
gimp_drawable_scale (GimpItem              *item,
                     gint                   new_width,
                     gint                   new_height,
                     gint                   new_offset_x,
                     gint                   new_offset_y,
476
                     GimpInterpolationType  interpolation_type,
477
                     GimpProgress          *progress)
478
{
479
  GimpDrawable *drawable = GIMP_DRAWABLE (item);
480
  GeglBuffer   *new_buffer;
481

482 483 484
  new_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
                                                new_width, new_height),
                                gimp_drawable_get_format (drawable));
485

486 487 488 489 490 491 492 493
  gimp_gegl_apply_scale (gimp_drawable_get_buffer (drawable),
                         progress, C_("undo-type", "Scale"),
                         new_buffer,
                         interpolation_type,
                         ((gdouble) new_width /
                          gimp_item_get_width  (item)),
                         ((gdouble) new_height /
                          gimp_item_get_height (item)));
494

495
  gimp_drawable_set_buffer_full (drawable, gimp_item_is_attached (item), NULL,
496
                                 new_buffer,
497 498
                                 new_offset_x, new_offset_y);
  g_object_unref (new_buffer);
499 500
}

501
static void
502 503 504 505 506 507 508
gimp_drawable_resize (GimpItem     *item,
                      GimpContext  *context,
                      GimpFillType  fill_type,
                      gint          new_width,
                      gint          new_height,
                      gint          offset_x,
                      gint          offset_y)
509
{
510
  GimpDrawable *drawable = GIMP_DRAWABLE (item);
511
  GeglBuffer   *new_buffer;
512 513 514 515
  gint          new_offset_x;
  gint          new_offset_y;
  gint          copy_x, copy_y;
  gint          copy_width, copy_height;
516
  gboolean      intersect;
517

518
  /*  if the size doesn't change, this is a nop  */
519 520
  if (new_width  == gimp_item_get_width  (item) &&
      new_height == gimp_item_get_height (item) &&
521
      offset_x   == 0                           &&
522
      offset_y   == 0)
523 524
    return;

525 526
  new_offset_x = gimp_item_get_offset_x (item) - offset_x;
  new_offset_y = gimp_item_get_offset_y (item) - offset_y;
527

528 529 530 531 532 533 534 535 536 537 538 539
  intersect = gimp_rectangle_intersect (gimp_item_get_offset_x (item),
                                        gimp_item_get_offset_y (item),
                                        gimp_item_get_width (item),
                                        gimp_item_get_height (item),
                                        new_offset_x,
                                        new_offset_y,
                                        new_width,
                                        new_height,
                                        &copy_x,
                                        &copy_y,
                                        &copy_width,
                                        &copy_height);
540

541 542 543
  new_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
                                                new_width, new_height),
                                gimp_drawable_get_format (drawable));
544

545 546
  if (! intersect              ||
      copy_width  != new_width ||
547
      copy_height != new_height)
548
    {
549
      /*  Clear the new buffer if needed  */
550

551 552
      GimpRGB      color;
      GimpPattern *pattern;
553

554 555 556
      gimp_get_fill_params (context, fill_type, &color, &pattern, NULL);
      gimp_drawable_fill_buffer (drawable, new_buffer,
                                 &color, pattern, 0, 0);
557 558
    }

559
  if (intersect && copy_width && copy_height)
560
    {
561
      /*  Copy the pixels in the intersection  */
562 563 564 565 566 567 568 569 570
      gimp_gegl_buffer_copy (
        gimp_drawable_get_buffer (drawable),
        GEGL_RECTANGLE (copy_x - gimp_item_get_offset_x (item),
                        copy_y - gimp_item_get_offset_y (item),
                        copy_width,
                        copy_height), GEGL_ABYSS_NONE,
        new_buffer,
        GEGL_RECTANGLE (copy_x - new_offset_x,
                        copy_y - new_offset_y, 0, 0));
571 572
    }

573
  gimp_drawable_set_buffer_full (drawable, gimp_item_is_attached (item), NULL,
574
                                 new_buffer,
575 576
                                 new_offset_x, new_offset_y);
  g_object_unref (new_buffer);
577 578
}

579 580
static void
gimp_drawable_flip (GimpItem            *item,
581
                    GimpContext         *context,
582 583 584 585
                    GimpOrientationType  flip_type,
                    gdouble              axis,
                    gboolean             clip_result)
{
586 587 588 589 590
  GimpDrawable     *drawable = GIMP_DRAWABLE (item);
  GeglBuffer       *buffer;
  GimpColorProfile *buffer_profile;
  gint              off_x, off_y;
  gint              new_off_x, new_off_y;
591

592
  gimp_item_get_offset (item, &off_x, &off_y);
593

594 595 596 597 598
  buffer = gimp_drawable_transform_buffer_flip (drawable, context,
                                                gimp_drawable_get_buffer (drawable),
                                                off_x, off_y,
                                                flip_type, axis,
                                                clip_result,
599
                                                &buffer_profile,
600
                                                &new_off_x, &new_off_y);
601

602
  if (buffer)
603
    {
604
      gimp_drawable_transform_paste (drawable, buffer, buffer_profile,
605
                                     new_off_x, new_off_y, FALSE);
606
      g_object_unref (buffer);
607
    }
608 609
}

610 611
static void
gimp_drawable_rotate (GimpItem         *item,
612
                      GimpContext      *context,
613 614 615 616 617
                      GimpRotationType  rotate_type,
                      gdouble           center_x,
                      gdouble           center_y,
                      gboolean          clip_result)
{
618 619 620 621 622
  GimpDrawable     *drawable = GIMP_DRAWABLE (item);
  GeglBuffer       *buffer;
  GimpColorProfile *buffer_profile;
  gint              off_x, off_y;
  gint              new_off_x, new_off_y;
623

624
  gimp_item_get_offset (item, &off_x, &off_y);
625

626 627 628 629 630
  buffer = gimp_drawable_transform_buffer_rotate (drawable, context,
                                                  gimp_drawable_get_buffer (drawable),
                                                  off_x, off_y,
                                                  rotate_type, center_x, center_y,
                                                  clip_result,
631
                                                  &buffer_profile,
632
                                                  &new_off_x, &new_off_y);
633

634
  if (buffer)
635
    {
636
      gimp_drawable_transform_paste (drawable, buffer, buffer_profile,
637
                                     new_off_x, new_off_y, FALSE);
638
      g_object_unref (buffer);
639
    }
640 641
}

642 643
static void
gimp_drawable_transform (GimpItem               *item,
644
                         GimpContext            *context,
645
                         const GimpMatrix3      *matrix,
646 647
                         GimpTransformDirection  direction,
                         GimpInterpolationType   interpolation_type,
648
                         GimpTransformResize     clip_result,
649
                         GimpProgress           *progress)
650
{
651 652 653 654 655
  GimpDrawable     *drawable = GIMP_DRAWABLE (item);
  GeglBuffer       *buffer;
  GimpColorProfile *buffer_profile;
  gint              off_x, off_y;
  gint              new_off_x, new_off_y;
656

657
  gimp_item_get_offset (item, &off_x, &off_y);
658

659 660 661 662 663 664
  buffer = gimp_drawable_transform_buffer_affine (drawable, context,
                                                  gimp_drawable_get_buffer (drawable),
                                                  off_x, off_y,
                                                  matrix, direction,
                                                  interpolation_type,
                                                  clip_result,
665
                                                  &buffer_profile,
666 667 668 669
                                                  &new_off_x, &new_off_y,
                                                  progress);

  if (buffer)
670
    {
671
      gimp_drawable_transform_paste (drawable, buffer, buffer_profile,
672
                                     new_off_x, new_off_y, FALSE);
673
      g_object_unref (buffer);
674
    }
675 676
}

677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699
static const guint8 *
gimp_drawable_get_icc_profile (GimpColorManaged *managed,
                               gsize            *len)
{
  GimpColorProfile *profile = gimp_color_managed_get_color_profile (managed);

  return gimp_color_profile_get_icc_profile (profile, len);
}

static GimpColorProfile *
gimp_drawable_get_color_profile (GimpColorManaged *managed)
{
  const Babl *format = gimp_drawable_get_format (GIMP_DRAWABLE (managed));

  return gimp_babl_format_get_color_profile (format);
}

static void
gimp_drawable_profile_changed (GimpColorManaged *managed)
{
  gimp_viewable_invalidate_preview (GIMP_VIEWABLE (managed));
}

700 701 702 703
static gboolean
gimp_drawable_get_pixel_at (GimpPickable *pickable,
                            gint          x,
                            gint          y,
704 705
                            const Babl   *format,
                            gpointer      pixel)
706 707 708 709
{
  GimpDrawable *drawable = GIMP_DRAWABLE (pickable);

  /* do not make this a g_return_if_fail() */
710 711
  if (x < 0 || x >= gimp_item_get_width  (GIMP_ITEM (drawable)) ||
      y < 0 || y >= gimp_item_get_height (GIMP_ITEM (drawable)))
712 713
    return FALSE;

714
  gegl_buffer_sample (gimp_drawable_get_buffer (drawable),
715
                      x, y, NULL, pixel, format,
716
                      GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
717 718 719 720

  return TRUE;
}

721 722 723 724 725 726 727 728 729 730 731 732
static void
gimp_drawable_get_pixel_average (GimpPickable        *pickable,
                                 const GeglRectangle *rect,
                                 const Babl          *format,
                                 gpointer             pixel)
{
  GimpDrawable *drawable = GIMP_DRAWABLE (pickable);

  return gimp_gegl_average_color (gimp_drawable_get_buffer (drawable),
                                  rect, TRUE, GEGL_ABYSS_NONE, format, pixel);
}

733 734 735 736 737 738 739 740 741 742
static void
gimp_drawable_real_update (GimpDrawable *drawable,
                           gint          x,
                           gint          y,
                           gint          width,
                           gint          height)
{
  gimp_viewable_invalidate_preview (GIMP_VIEWABLE (drawable));
}

743
static gint64
744 745 746 747
gimp_drawable_real_estimate_memsize (GimpDrawable      *drawable,
                                     GimpComponentType  component_type,
                                     gint               width,
                                     gint               height)
748
{
749 750
  GimpImage  *image  = gimp_item_get_image (GIMP_ITEM (drawable));
  gboolean    linear = gimp_drawable_get_linear (drawable);
751 752
  const Babl *format;

753 754 755 756
  format = gimp_image_get_format (image,
                                  gimp_drawable_get_base_type (drawable),
                                  gimp_babl_precision (component_type, linear),
                                  gimp_drawable_has_alpha (drawable));
757 758

  return (gint64) babl_format_get_bytes_per_pixel (format) * width * height;
759 760
}

761
/* FIXME: this default impl is currently unused because no subclass
762
 * chains up. the goal is to handle the almost identical subclass code
763 764
 * here again.
 */
765 766 767
static void
gimp_drawable_real_convert_type (GimpDrawable      *drawable,
                                 GimpImage         *dest_image,
768
                                 const Babl        *new_format,
769
                                 GimpColorProfile  *dest_profile,
770 771
                                 GeglDitherMethod   layer_dither_type,
                                 GeglDitherMethod   mask_dither_type,
772 773
                                 gboolean           push_undo,
                                 GimpProgress      *progress)
774
{
775
  GeglBuffer *dest_buffer;
776

777
  dest_buffer =
778 779 780
    gegl_buffer_new (GEGL_RECTANGLE (0, 0,
                                     gimp_item_get_width  (GIMP_ITEM (drawable)),
                                     gimp_item_get_height (GIMP_ITEM (drawable))),
781
                     new_format);
782

783 784 785
  gimp_gegl_buffer_copy (
    gimp_drawable_get_buffer (drawable), NULL, GEGL_ABYSS_NONE,
    dest_buffer, NULL);
786 787 788

  gimp_drawable_set_buffer (drawable, push_undo, NULL, dest_buffer);
  g_object_unref (dest_buffer);
789 790
}

791 792
static GeglBuffer *
gimp_drawable_real_get_buffer (GimpDrawable *drawable)
793
{
794
  return drawable->private->buffer;
795 796
}

797
static void
798 799 800 801 802 803
gimp_drawable_real_set_buffer (GimpDrawable *drawable,
                               gboolean      push_undo,
                               const gchar  *undo_desc,
                               GeglBuffer   *buffer,
                               gint          offset_x,
                               gint          offset_y)
804
{
805 806
  GimpItem *item          = GIMP_ITEM (drawable);
  gint      old_has_alpha = -1;
807

808 809
  g_object_freeze_notify (G_OBJECT (drawable));

810 811
  gimp_drawable_invalidate_boundary (drawable);

812
  if (push_undo)
813 814
    gimp_image_undo_push_drawable_mod (gimp_item_get_image (item), undo_desc,
                                       drawable, FALSE);
815

816
  if (drawable->private->buffer)
817
    old_has_alpha = gimp_drawable_has_alpha (drawable);
818

819
  g_set_object (&drawable->private->buffer, buffer);
820

821 822 823 824 825
  if (drawable->private->buffer_source_node)
    gegl_node_set (drawable->private->buffer_source_node,
                   "buffer", gimp_drawable_get_buffer (drawable),
                   NULL);

826 827 828 829 830 831 832 833 834 835 836 837 838 839 840
  if (drawable->private->convert_format)
    {
      const Babl *format = gimp_drawable_get_format (drawable);

      if (babl_format_is_palette (format))
        gegl_node_set (drawable->private->convert_format,
                       "operation", "gegl:convert-format",
                       "format",    gimp_drawable_get_format (drawable),
                       NULL);
      else
        gegl_node_set (drawable->private->convert_format,
                       "operation", "gegl:nop",
                       NULL);
    }

841
  gimp_item_set_offset (item, offset_x, offset_y);
842 843 844
  gimp_item_set_size (item,
                      gegl_buffer_get_width  (buffer),
                      gegl_buffer_get_height (buffer));
845

846 847
  if (gimp_drawable_has_alpha (drawable) != old_has_alpha)
    gimp_drawable_alpha_changed (drawable);
848

849
  g_object_notify (G_OBJECT (drawable), "buffer");
850 851

  g_object_thaw_notify (G_OBJECT (drawable));
852 853
}

854 855 856
static void
gimp_drawable_real_push_undo (GimpDrawable *drawable,
                              const gchar  *undo_desc,
857
                              GeglBuffer   *buffer,
858 859 860 861 862
                              gint          x,
                              gint          y,
                              gint          width,
                              gint          height)
{
863
  if (! buffer)
864
    {
865 866
      buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height),
                                gimp_drawable_get_format (drawable));
867

868 869 870 871 872
      gimp_gegl_buffer_copy (
        gimp_drawable_get_buffer (drawable),
        GEGL_RECTANGLE (x, y, width, height), GEGL_ABYSS_NONE,
        buffer,
        GEGL_RECTANGLE (0, 0, 0, 0));
873 874 875 876
    }
  else
    {
      g_object_ref (buffer);
877 878 879 880
    }

  gimp_image_undo_push_drawable (gimp_item_get_image (GIMP_ITEM (drawable)),
                                 undo_desc, drawable,
881
                                 buffer, x, y);
882

883
  g_object_unref (buffer);
884 885
}

886
static void
887
gimp_drawable_real_swap_pixels (GimpDrawable *drawable,
888
                                GeglBuffer   *buffer,
889
                                gint          x,
890
                                gint          y)
891
{
892
  GeglBuffer *tmp;
893 894
  gint        width  = gegl_buffer_get_width (buffer);
  gint        height = gegl_buffer_get_height (buffer);
895

896
  tmp = gegl_buffer_dup (buffer);
897

898 899 900 901 902 903 904 905
  gimp_gegl_buffer_copy (gimp_drawable_get_buffer (drawable),
                         GEGL_RECTANGLE (x, y, width, height), GEGL_ABYSS_NONE,
                         buffer,
                         GEGL_RECTANGLE (0, 0, 0, 0));
  gimp_gegl_buffer_copy (tmp,
                         GEGL_RECTANGLE (0, 0, width, height), GEGL_ABYSS_NONE,
                         gimp_drawable_get_buffer (drawable),
                         GEGL_RECTANGLE (x, y, 0, 0));
906

907
  g_object_unref (tmp);
908 909 910 911

  gimp_drawable_update (drawable, x, y, width, height);
}

912 913 914 915 916 917 918
static GeglNode *
gimp_drawable_real_get_source_node (GimpDrawable *drawable)
{
  g_warn_if_fail (drawable->private->buffer_source_node == NULL);

  drawable->private->buffer_source_node =
    gegl_node_new_child (NULL,
919
                         "operation", "gimp:buffer-source-validate",
920 921 922 923 924 925
                         "buffer",    gimp_drawable_get_buffer (drawable),
                         NULL);

  return g_object_ref (drawable->private->buffer_source_node);
}

926 927 928

/*  public functions  */

929 930 931 932 933 934 935 936
GimpDrawable *
gimp_drawable_new (GType          type,
                   GimpImage     *image,
                   const gchar   *name,
                   gint           offset_x,
                   gint           offset_y,
                   gint           width,
                   gint           height,
937
                   const Babl    *format)
938 939
{
  GimpDrawable *drawable;
940
  GeglBuffer   *buffer;
941 942 943 944

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
  g_return_val_if_fail (g_type_is_a (type, GIMP_TYPE_DRAWABLE), NULL);
  g_return_val_if_fail (width > 0 && height > 0, NULL);
945
  g_return_val_if_fail (format != NULL, NULL);
946 947 948 949 950 951

  drawable = GIMP_DRAWABLE (gimp_item_new (type,
                                           image, name,
                                           offset_x, offset_y,
                                           width, height));

952 953 954 955
  buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height), format);

  gimp_drawable_set_buffer (drawable, FALSE, NULL, buffer);
  g_object_unref (buffer);
956 957 958 959

  return drawable;
}

960
gint64
961 962 963 964
gimp_drawable_estimate_memsize (GimpDrawable      *drawable,
                                GimpComponentType  component_type,
                                gint               width,
                                gint               height)
965 966 967 968
{
  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), 0);

  return GIMP_DRAWABLE_GET_CLASS (drawable)->estimate_memsize (drawable,
969
                                                               component_type,
970 971 972
                                                               width, height);
}

973 974
void
gimp_drawable_update (GimpDrawable *drawable,
975 976 977 978
                      gint          x,
                      gint          y,
                      gint          width,
                      gint          height)
979 980 981
{
  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));

982 983 984 985 986 987
  if (width == -1)
    width = gimp_item_get_width (GIMP_ITEM (drawable));

  if (height == -1)
    height = gimp_item_get_height (GIMP_ITEM (drawable));

988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040
  if (drawable->private->paint_count == 0)
    {
      g_signal_emit (drawable, gimp_drawable_signals[UPDATE], 0,
                     x, y, width, height);
    }
  else
    {
      GeglRectangle rect;

      rect.x      = floor ((gdouble) x            / PAINT_COPY_CHUNK_WIDTH)  * PAINT_COPY_CHUNK_WIDTH;
      rect.y      = floor ((gdouble) y            / PAINT_COPY_CHUNK_HEIGHT) * PAINT_COPY_CHUNK_HEIGHT;
      rect.width  = ceil  ((gdouble) (x + width)  / PAINT_COPY_CHUNK_WIDTH)  * PAINT_COPY_CHUNK_WIDTH  - rect.x;
      rect.height = ceil  ((gdouble) (y + height) / PAINT_COPY_CHUNK_HEIGHT) * PAINT_COPY_CHUNK_HEIGHT - rect.y;

      if (gegl_rectangle_intersect (
            &rect,
            &rect,
            GEGL_RECTANGLE (0, 0,
                            gimp_item_get_width  (GIMP_ITEM (drawable)),
                            gimp_item_get_height (GIMP_ITEM (drawable)))))
        {
          if (drawable->private->paint_copy_region)
            {
              cairo_region_union_rectangle (
                drawable->private->paint_copy_region,
                (const cairo_rectangle_int_t *) &rect);
            }
          else
            {
              drawable->private->paint_copy_region =
                cairo_region_create_rectangle (
                  (const cairo_rectangle_int_t *) &rect);
            }

            rect.x      = floor ((gdouble) x            / PAINT_UPDATE_CHUNK_WIDTH)  * PAINT_UPDATE_CHUNK_WIDTH;
            rect.y      = floor ((gdouble) y            / PAINT_UPDATE_CHUNK_HEIGHT) * PAINT_UPDATE_CHUNK_HEIGHT;
            rect.width  = ceil  ((gdouble) (x + width)  / PAINT_UPDATE_CHUNK_WIDTH)  * PAINT_UPDATE_CHUNK_WIDTH  - rect.x;
            rect.height = ceil  ((gdouble) (y + height) / PAINT_UPDATE_CHUNK_HEIGHT) * PAINT_UPDATE_CHUNK_HEIGHT - rect.y;

            if (drawable->private->paint_update_region)
              {
                cairo_region_union_rectangle (
                  drawable->private->paint_update_region,
                  (const cairo_rectangle_int_t *) &rect);
              }
            else
              {
                drawable->private->paint_update_region =
                  cairo_region_create_rectangle (
                    (const cairo_rectangle_int_t *) &rect);
              }
        }
    }
1041 1042
}

1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064
void
gimp_drawable_alpha_changed (GimpDrawable *drawable)
{
  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));

  g_signal_emit (drawable, gimp_drawable_signals[ALPHA_CHANGED], 0);
}

void
gimp_drawable_invalidate_boundary (GimpDrawable *drawable)
{
  GimpDrawableClass *drawable_class;

  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));

  drawable_class = GIMP_DRAWABLE_GET_CLASS (drawable);

  if (drawable_class->invalidate_boundary)
    drawable_class->invalidate_boundary (drawable);
}

void
1065 1066
gimp_drawable_get_active_components (GimpDrawable *drawable,
                                     gboolean     *active)
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
{
  GimpDrawableClass *drawable_class;

  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
  g_return_if_fail (active != NULL);

  drawable_class = GIMP_DRAWABLE_GET_CLASS (drawable);

  if (drawable_class->get_active_components)
    drawable_class->get_active_components (drawable, active);
}

1079
GimpComponentMask
1080
gimp_drawable_get_active_mask (GimpDrawable *drawable)
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093
{
  GimpDrawableClass *drawable_class;

  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), 0);

  drawable_class = GIMP_DRAWABLE_GET_CLASS (drawable);

  if (drawable_class->get_active_mask)
    return drawable_class->get_active_mask (drawable);

  return 0;
}

1094 1095 1096
void
gimp_drawable_convert_type (GimpDrawable      *drawable,
                            GimpImage         *dest_image,
1097
                            GimpImageBaseType  new_base_type,
1098
                            GimpPrecision      new_precision,
1099
                            gboolean           new_has_alpha,
1100
                            GimpColorProfile  *dest_profile,
1101 1102
                            GeglDitherMethod   layer_dither_type,
                            GeglDitherMethod   mask_dither_type,
1103 1104
                            gboolean           push_undo,
                            GimpProgress      *progress)
1105
{
1106
  const Babl *old_format;
1107
  const Babl *new_format;
1108 1109
  gint        old_bits;
  gint        new_bits;
1110

1111
  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
1112
  g_return_if_fail (GIMP_IS_IMAGE (dest_image));
1113
  g_return_if_fail (new_base_type != gimp_drawable_get_base_type (drawable) ||
1114
                    new_precision != gimp_drawable_get_precision (drawable) ||
1115
                    new_has_alpha != gimp_drawable_has_alpha (drawable)     ||
1116 1117
                    dest_profile);
  g_return_if_fail (dest_profile == NULL || GIMP_IS_COLOR_PROFILE (dest_profile));
1118
  g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
1119

1120 1121 1122
  if (! gimp_item_is_attached (GIMP_ITEM (drawable)))
    push_undo = FALSE;

1123
  old_format = gimp_drawable_get_format (drawable);
1124 1125 1126
  new_format = gimp_image_get_format (dest_image,
                                      new_base_type,
                                      new_precision,
1127
                                      new_has_alpha);
1128

1129 1130 1131 1132 1133 1134 1135 1136
  old_bits = (babl_format_get_bytes_per_pixel (old_format) * 8 /
              babl_format_get_n_components (old_format));
  new_bits = (babl_format_get_bytes_per_pixel (new_format) * 8 /
              babl_format_get_n_components (new_format));

  if (old_bits <= new_bits || new_bits > 16)
    {
      /*  don't dither if we are converting to a higher bit depth,
1137
       *  or to more than 16 bits (gegl:dither only does
1138 1139 1140 1141 1142 1143
       *  16 bits).
       */
      layer_dither_type = GEGL_DITHER_NONE;
      mask_dither_type  = GEGL_DITHER_NONE;
    }

1144
  GIMP_DRAWABLE_GET_CLASS (drawable)->convert_type (drawable, dest_image,
1145
                                                    new_format,
1146
                                                    dest_profile,
1147 1148
                                                    layer_dither_type,
                                                    mask_dither_type,
1149 1150 1151 1152 1153
                                                    push_undo,
                                                    progress);

  if (progress)
    gimp_progress_set_value (progress, 1.0);
1154 1155
}

1156
void
1157 1158 1159 1160 1161 1162 1163
gimp_drawable_apply_buffer (GimpDrawable           *drawable,
                            GeglBuffer             *buffer,
                            const GeglRectangle    *buffer_region,
                            gboolean                push_undo,
                            const gchar            *undo_desc,
                            gdouble                 opacity,
                            GimpLayerMode           mode,
1164 1165 1166
                            GimpLayerColorSpace     blend_space,
                            GimpLayerColorSpace     composite_space,
                            GimpLayerCompositeMode  composite_mode,
1167 1168 1169
                            GeglBuffer             *base_buffer,
                            gint                    base_x,
                            gint                    base_y)
1170 1171 1172 1173
{
  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
  g_return_if_fail (GEGL_IS_BUFFER (buffer));
1174
  g_return_if_fail (buffer_region != NULL);
1175
  g_return_if_fail (base_buffer == NULL || GEGL_IS_BUFFER (base_buffer));
1176

1177 1178
  GIMP_DRAWABLE_GET_CLASS (drawable)->apply_buffer (drawable, buffer,
                                                    buffer_region,
1179
                                                    push_undo, undo_desc,
1180 1181 1182 1183
                                                    opacity, mode,
                                                    blend_space,
                                                    composite_space,
                                                    composite_mode,
1184
                                                    base_buffer,
1185
                                                    base_x, base_y);
1186 1187 1188
}

void
1189 1190 1191 1192 1193 1194
gimp_drawable_replace_buffer (GimpDrawable        *drawable,
                              GeglBuffer          *buffer,
                              const GeglRectangle *buffer_region,
                              gboolean             push_undo,
                              const gchar         *undo_desc,
                              gdouble              opacity,
1195 1196
                              GeglBuffer          *mask,
                              const GeglRectangle *mask_region,
1197 1198
                              gint                 x,
                              gint                 y)
1199 1200
{
  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
1201
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
1202
  g_return_if_fail (GEGL_IS_BUFFER (buffer));
1203
  g_return_if_fail (GEGL_IS_BUFFER (mask));
1204

1205 1206
  GIMP_DRAWABLE_GET_CLASS (drawable)->replace_buffer (drawable, buffer,
                                                      buffer_region,
1207
                                                      push_undo, undo_desc,
1208 1209
                                                      opacity,
                                                      mask, mask_region,
1210 1211
                                                      x, y);
}
1212

1213
GeglBuffer *
1214
gimp_drawable_get_buffer (GimpDrawable *drawable)
1215 1216 1217
{
  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);

1218 1219 1220 1221
  if (drawable->private->paint_count == 0)
    return GIMP_DRAWABLE_GET_CLASS (drawable)->get_buffer (drawable);
  else
    return drawable->private->paint_buffer;
1222 1223
}

1224
void
1225 1226 1227 1228
gimp_drawable_set_buffer (GimpDrawable *drawable,
                          gboolean      push_undo,
                          const gchar  *undo_desc,
                          GeglBuffer   *buffer)
1229 1230 1231 1232
{
  gint offset_x, offset_y;

  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
1233
  g_return_if_fail (GEGL_IS_BUFFER (buffer));
1234

1235 1236 1237
  if (! gimp_item_is_attached (GIMP_ITEM (drawable)))
    push_undo = FALSE;

1238
  gimp_item_get_offset (GIMP_ITEM (drawable), &offset_x, &offset_y);
1239

1240 1241
  gimp_drawable_set_buffer_full (drawable, push_undo, undo_desc,