1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
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 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18 #include "config.h"
19
20 #include <cairo.h>
21 #include <gegl.h>
22 #include <gdk-pixbuf/gdk-pixbuf.h>
23
24 #include "libgimpbase/gimpbase.h"
25 #include "libgimpcolor/gimpcolor.h"
26
27 #include "core-types.h"
28
29 #include "gimp.h"
30 #include "gimp-edit.h"
31 #include "gimpbuffer.h"
32 #include "gimpcontext.h"
33 #include "gimpgrouplayer.h"
34 #include "gimpimage.h"
35 #include "gimpimage-duplicate.h"
36 #include "gimpimage-new.h"
37 #include "gimpimage-undo.h"
38 #include "gimplayer-floating-selection.h"
39 #include "gimplayer-new.h"
40 #include "gimplist.h"
41 #include "gimppickable.h"
42 #include "gimpselection.h"
43
44 #include "gimp-intl.h"
45
46
47 /* local function protypes */
48
49 static GimpBuffer * gimp_edit_extract (GimpImage *image,
50 GimpPickable *pickable,
51 GimpContext *context,
52 gboolean cut_pixels,
53 GError **error);
54
55
56 /* public functions */
57
58 GimpObject *
gimp_edit_cut(GimpImage * image,GimpDrawable * drawable,GimpContext * context,GError ** error)59 gimp_edit_cut (GimpImage *image,
60 GimpDrawable *drawable,
61 GimpContext *context,
62 GError **error)
63 {
64 g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
65 g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
66 g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
67 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
68 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
69
70 if (GIMP_IS_LAYER (drawable) &&
71 gimp_channel_is_empty (gimp_image_get_mask (image)))
72 {
73 GimpImage *clip_image;
74 gint off_x, off_y;
75
76 gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
77
78 clip_image = gimp_image_new_from_drawable (image->gimp, drawable);
79 g_object_set_data (G_OBJECT (clip_image), "offset-x",
80 GINT_TO_POINTER (off_x));
81 g_object_set_data (G_OBJECT (clip_image), "offset-y",
82 GINT_TO_POINTER (off_y));
83 gimp_container_remove (image->gimp->images, GIMP_OBJECT (clip_image));
84 gimp_set_clipboard_image (image->gimp, clip_image);
85 g_object_unref (clip_image);
86
87 gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_CUT,
88 C_("undo-type", "Cut Layer"));
89
90 gimp_image_remove_layer (image, GIMP_LAYER (drawable),
91 TRUE, NULL);
92
93 gimp_image_undo_group_end (image);
94
95 return GIMP_OBJECT (gimp_get_clipboard_image (image->gimp));
96 }
97 else
98 {
99 GimpBuffer *buffer;
100
101 buffer = gimp_edit_extract (image, GIMP_PICKABLE (drawable),
102 context, TRUE, error);
103
104 if (buffer)
105 {
106 gimp_set_clipboard_buffer (image->gimp, buffer);
107 g_object_unref (buffer);
108
109 return GIMP_OBJECT (gimp_get_clipboard_buffer (image->gimp));
110 }
111 }
112
113 return NULL;
114 }
115
116 GimpObject *
gimp_edit_copy(GimpImage * image,GimpDrawable * drawable,GimpContext * context,GError ** error)117 gimp_edit_copy (GimpImage *image,
118 GimpDrawable *drawable,
119 GimpContext *context,
120 GError **error)
121 {
122 g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
123 g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
124 g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
125 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
126 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
127
128 if (GIMP_IS_LAYER (drawable) &&
129 gimp_channel_is_empty (gimp_image_get_mask (image)))
130 {
131 GimpImage *clip_image;
132 gint off_x, off_y;
133
134 gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
135
136 clip_image = gimp_image_new_from_drawable (image->gimp, drawable);
137 g_object_set_data (G_OBJECT (clip_image), "offset-x",
138 GINT_TO_POINTER (off_x));
139 g_object_set_data (G_OBJECT (clip_image), "offset-y",
140 GINT_TO_POINTER (off_y));
141 gimp_container_remove (image->gimp->images, GIMP_OBJECT (clip_image));
142 gimp_set_clipboard_image (image->gimp, clip_image);
143 g_object_unref (clip_image);
144
145 return GIMP_OBJECT (gimp_get_clipboard_image (image->gimp));
146 }
147 else
148 {
149 GimpBuffer *buffer;
150
151 buffer = gimp_edit_extract (image, GIMP_PICKABLE (drawable),
152 context, FALSE, error);
153
154 if (buffer)
155 {
156 gimp_set_clipboard_buffer (image->gimp, buffer);
157 g_object_unref (buffer);
158
159 return GIMP_OBJECT (gimp_get_clipboard_buffer (image->gimp));
160 }
161 }
162
163 return NULL;
164 }
165
166 GimpBuffer *
gimp_edit_copy_visible(GimpImage * image,GimpContext * context,GError ** error)167 gimp_edit_copy_visible (GimpImage *image,
168 GimpContext *context,
169 GError **error)
170 {
171 GimpBuffer *buffer;
172
173 g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
174 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
175 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
176
177 buffer = gimp_edit_extract (image, GIMP_PICKABLE (image),
178 context, FALSE, error);
179
180 if (buffer)
181 {
182 gimp_set_clipboard_buffer (image->gimp, buffer);
183 g_object_unref (buffer);
184
185 return gimp_get_clipboard_buffer (image->gimp);
186 }
187
188 return NULL;
189 }
190
191 static gboolean
gimp_edit_paste_is_in_place(GimpPasteType paste_type)192 gimp_edit_paste_is_in_place (GimpPasteType paste_type)
193 {
194 switch (paste_type)
195 {
196 case GIMP_PASTE_TYPE_FLOATING:
197 case GIMP_PASTE_TYPE_FLOATING_INTO:
198 case GIMP_PASTE_TYPE_NEW_LAYER:
199 return FALSE;
200
201 case GIMP_PASTE_TYPE_FLOATING_IN_PLACE:
202 case GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE:
203 case GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE:
204 return TRUE;
205 }
206
207 g_return_val_if_reached (FALSE);
208 }
209
210 static gboolean
gimp_edit_paste_is_floating(GimpPasteType paste_type)211 gimp_edit_paste_is_floating (GimpPasteType paste_type)
212 {
213 switch (paste_type)
214 {
215 case GIMP_PASTE_TYPE_FLOATING:
216 case GIMP_PASTE_TYPE_FLOATING_INTO:
217 case GIMP_PASTE_TYPE_FLOATING_IN_PLACE:
218 case GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE:
219 return TRUE;
220
221 case GIMP_PASTE_TYPE_NEW_LAYER:
222 case GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE:
223 return FALSE;
224 }
225
226 g_return_val_if_reached (FALSE);
227 }
228
229 static GimpLayer *
gimp_edit_paste_get_layer(GimpImage * image,GimpDrawable * drawable,GimpObject * paste,GimpPasteType * paste_type)230 gimp_edit_paste_get_layer (GimpImage *image,
231 GimpDrawable *drawable,
232 GimpObject *paste,
233 GimpPasteType *paste_type)
234 {
235 GimpLayer *layer = NULL;
236 const Babl *floating_format;
237
238 /* change paste type to NEW_LAYER for cases where we can't attach a
239 * floating selection
240 */
241 if (! drawable ||
242 gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) ||
243 gimp_item_is_content_locked (GIMP_ITEM (drawable)))
244 {
245 if (gimp_edit_paste_is_in_place (*paste_type))
246 *paste_type = GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE;
247 else
248 *paste_type = GIMP_PASTE_TYPE_NEW_LAYER;
249 }
250
251 /* floating pastes always have the pasted-to drawable's format with
252 * alpha; if drawable == NULL, user is pasting into an empty image
253 */
254 if (drawable && gimp_edit_paste_is_floating (*paste_type))
255 floating_format = gimp_drawable_get_format_with_alpha (drawable);
256 else
257 floating_format = gimp_image_get_layer_format (image, TRUE);
258
259 if (GIMP_IS_IMAGE (paste))
260 {
261 GType layer_type;
262
263 layer = gimp_image_get_layer_iter (GIMP_IMAGE (paste))->data;
264
265 switch (*paste_type)
266 {
267 case GIMP_PASTE_TYPE_FLOATING:
268 case GIMP_PASTE_TYPE_FLOATING_IN_PLACE:
269 case GIMP_PASTE_TYPE_FLOATING_INTO:
270 case GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE:
271 /* when pasting as floating make sure gimp_item_convert()
272 * will turn group layers into normal layers, otherwise use
273 * the same layer type so e.g. text information gets
274 * preserved. See issue #2667.
275 */
276 if (GIMP_IS_GROUP_LAYER (layer))
277 layer_type = GIMP_TYPE_LAYER;
278 else
279 layer_type = G_TYPE_FROM_INSTANCE (layer);
280 break;
281
282 case GIMP_PASTE_TYPE_NEW_LAYER:
283 case GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE:
284 layer_type = G_TYPE_FROM_INSTANCE (layer);
285 break;
286
287 default:
288 g_return_val_if_reached (NULL);
289 }
290
291 layer = GIMP_LAYER (gimp_item_convert (GIMP_ITEM (layer),
292 image, layer_type));
293
294 switch (*paste_type)
295 {
296 case GIMP_PASTE_TYPE_FLOATING:
297 case GIMP_PASTE_TYPE_FLOATING_IN_PLACE:
298 case GIMP_PASTE_TYPE_FLOATING_INTO:
299 case GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE:
300 /* when pasting as floating selection, get rid of the layer mask,
301 * and make sure the layer has the right format
302 */
303 if (gimp_layer_get_mask (layer))
304 gimp_layer_apply_mask (layer, GIMP_MASK_DISCARD, FALSE);
305
306 if (gimp_drawable_get_format (GIMP_DRAWABLE (layer)) !=
307 floating_format)
308 {
309 gimp_drawable_convert_type (GIMP_DRAWABLE (layer), image,
310 gimp_drawable_get_base_type (drawable),
311 gimp_drawable_get_precision (drawable),
312 TRUE,
313 NULL,
314 GEGL_DITHER_NONE, GEGL_DITHER_NONE,
315 FALSE, NULL);
316 }
317 break;
318
319 default:
320 break;
321 }
322 }
323 else if (GIMP_IS_BUFFER (paste))
324 {
325 layer = gimp_layer_new_from_buffer (GIMP_BUFFER (paste), image,
326 floating_format,
327 _("Pasted Layer"),
328 GIMP_OPACITY_OPAQUE,
329 gimp_image_get_default_new_layer_mode (image));
330 }
331
332 return layer;
333 }
334
335 static void
gimp_edit_paste_get_viewport_offset(GimpImage * image,GimpDrawable * drawable,GimpObject * paste,gint viewport_x,gint viewport_y,gint viewport_width,gint viewport_height,gint * offset_x,gint * offset_y)336 gimp_edit_paste_get_viewport_offset (GimpImage *image,
337 GimpDrawable *drawable,
338 GimpObject *paste,
339 gint viewport_x,
340 gint viewport_y,
341 gint viewport_width,
342 gint viewport_height,
343 gint *offset_x,
344 gint *offset_y)
345 {
346 gint image_width;
347 gint image_height;
348 gint width;
349 gint height;
350 gboolean clamp_to_image = TRUE;
351
352 g_return_if_fail (GIMP_IS_IMAGE (image));
353 g_return_if_fail (drawable == NULL || GIMP_IS_DRAWABLE (drawable));
354 g_return_if_fail (drawable == NULL ||
355 gimp_item_is_attached (GIMP_ITEM (drawable)));
356 g_return_if_fail (GIMP_IS_VIEWABLE (paste));
357 g_return_if_fail (offset_x != NULL);
358 g_return_if_fail (offset_y != NULL);
359
360 image_width = gimp_image_get_width (image);
361 image_height = gimp_image_get_height (image);
362
363 gimp_viewable_get_size (GIMP_VIEWABLE (paste), &width, &height);
364
365 if (viewport_width == image_width &&
366 viewport_height == image_height)
367 {
368 /* if the whole image is visible, act as if there was no viewport */
369
370 viewport_x = 0;
371 viewport_y = 0;
372 viewport_width = 0;
373 viewport_height = 0;
374 }
375
376 if (drawable)
377 {
378 /* if pasting to a drawable */
379
380 GimpContainer *children;
381 gint off_x, off_y;
382 gint target_x, target_y;
383 gint target_width, target_height;
384 gint paste_x, paste_y;
385 gint paste_width, paste_height;
386 gboolean have_mask;
387
388 have_mask = ! gimp_channel_is_empty (gimp_image_get_mask (image));
389
390 gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
391
392 children = gimp_viewable_get_children (GIMP_VIEWABLE (drawable));
393
394 if (children && gimp_container_get_n_children (children) == 0)
395 {
396 /* treat empty layer groups as image-sized, use the selection
397 * as target
398 */
399 gimp_item_bounds (GIMP_ITEM (gimp_image_get_mask (image)),
400 &target_x, &target_y,
401 &target_width, &target_height);
402 }
403 else
404 {
405 gimp_item_mask_intersect (GIMP_ITEM (drawable),
406 &target_x, &target_y,
407 &target_width, &target_height);
408 }
409
410 if (! have_mask && /* if we have no mask */
411 viewport_width > 0 && /* and we have a viewport */
412 viewport_height > 0 &&
413 (width < target_width || /* and the paste is smaller than the target */
414 height < target_height) &&
415
416 /* and the viewport intersects with the target */
417 gimp_rectangle_intersect (viewport_x, viewport_y,
418 viewport_width, viewport_height,
419 off_x, off_y, /* target_x,y are 0 */
420 target_width, target_height,
421 &paste_x, &paste_y,
422 &paste_width, &paste_height))
423 {
424 /* center on the viewport */
425
426 *offset_x = paste_x + (paste_width - width) / 2;
427 *offset_y = paste_y + (paste_height- height) / 2;
428 }
429 else
430 {
431 /* otherwise center on the target */
432
433 *offset_x = off_x + target_x + (target_width - width) / 2;
434 *offset_y = off_y + target_y + (target_height - height) / 2;
435
436 /* and keep it that way */
437 clamp_to_image = FALSE;
438 }
439 }
440 else if (viewport_width > 0 && /* if we have a viewport */
441 viewport_height > 0 &&
442 (width < image_width || /* and the paste is */
443 height < image_height)) /* smaller than the image */
444 {
445 /* center on the viewport */
446
447 *offset_x = viewport_x + (viewport_width - width) / 2;
448 *offset_y = viewport_y + (viewport_height - height) / 2;
449 }
450 else
451 {
452 /* otherwise center on the image */
453
454 *offset_x = (image_width - width) / 2;
455 *offset_y = (image_height - height) / 2;
456
457 /* and keep it that way */
458 clamp_to_image = FALSE;
459 }
460
461 if (clamp_to_image)
462 {
463 /* Ensure that the pasted layer is always within the image, if it
464 * fits and aligned at top left if it doesn't. (See bug #142944).
465 */
466 *offset_x = MIN (*offset_x, image_width - width);
467 *offset_y = MIN (*offset_y, image_height - height);
468 *offset_x = MAX (*offset_x, 0);
469 *offset_y = MAX (*offset_y, 0);
470 }
471 }
472
473 static void
gimp_edit_paste_get_paste_offset(GimpImage * image,GimpDrawable * drawable,GimpObject * paste,gint * offset_x,gint * offset_y)474 gimp_edit_paste_get_paste_offset (GimpImage *image,
475 GimpDrawable *drawable,
476 GimpObject *paste,
477 gint *offset_x,
478 gint *offset_y)
479 {
480 g_return_if_fail (GIMP_IS_IMAGE (image));
481 g_return_if_fail (drawable == NULL || GIMP_IS_DRAWABLE (drawable));
482 g_return_if_fail (drawable == NULL ||
483 gimp_item_is_attached (GIMP_ITEM (drawable)));
484 g_return_if_fail (GIMP_IS_VIEWABLE (paste));
485 g_return_if_fail (offset_x != NULL);
486 g_return_if_fail (offset_y != NULL);
487
488 if (GIMP_IS_IMAGE (paste))
489 {
490 *offset_x = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (paste),
491 "offset-x"));
492 *offset_y = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (paste),
493 "offset-y"));
494 }
495 else if (GIMP_IS_BUFFER (paste))
496 {
497 GimpBuffer *buffer = GIMP_BUFFER (paste);
498
499 *offset_x = buffer->offset_x;
500 *offset_y = buffer->offset_y;
501 }
502 }
503
504 static GimpLayer *
gimp_edit_paste_paste(GimpImage * image,GimpDrawable * drawable,GimpLayer * layer,GimpPasteType paste_type,gint offset_x,gint offset_y)505 gimp_edit_paste_paste (GimpImage *image,
506 GimpDrawable *drawable,
507 GimpLayer *layer,
508 GimpPasteType paste_type,
509 gint offset_x,
510 gint offset_y)
511 {
512 gimp_item_translate (GIMP_ITEM (layer), offset_x, offset_y, FALSE);
513
514 gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
515 C_("undo-type", "Paste"));
516
517 switch (paste_type)
518 {
519 case GIMP_PASTE_TYPE_FLOATING:
520 case GIMP_PASTE_TYPE_FLOATING_IN_PLACE:
521 /* if there is a selection mask clear it - this might not
522 * always be desired, but in general, it seems like the correct
523 * behavior
524 */
525 if (! gimp_channel_is_empty (gimp_image_get_mask (image)))
526 gimp_channel_clear (gimp_image_get_mask (image), NULL, TRUE);
527
528 /* fall thru */
529
530 case GIMP_PASTE_TYPE_FLOATING_INTO:
531 case GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE:
532 floating_sel_attach (layer, drawable);
533 break;
534
535 case GIMP_PASTE_TYPE_NEW_LAYER:
536 case GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE:
537 {
538 GimpLayer *parent = NULL;
539 gint position = 0;
540
541 /* always add on top of a passed layer, where we would attach
542 * a floating selection
543 */
544 if (GIMP_IS_LAYER (drawable))
545 {
546 parent = gimp_layer_get_parent (GIMP_LAYER (drawable));
547 position = gimp_item_get_index (GIMP_ITEM (drawable));
548 }
549
550 gimp_image_add_layer (image, layer, parent, position, TRUE);
551 }
552 break;
553 }
554
555 gimp_image_undo_group_end (image);
556
557 return layer;
558 }
559
560 GimpLayer *
gimp_edit_paste(GimpImage * image,GimpDrawable * drawable,GimpObject * paste,GimpPasteType paste_type,gint viewport_x,gint viewport_y,gint viewport_width,gint viewport_height)561 gimp_edit_paste (GimpImage *image,
562 GimpDrawable *drawable,
563 GimpObject *paste,
564 GimpPasteType paste_type,
565 gint viewport_x,
566 gint viewport_y,
567 gint viewport_width,
568 gint viewport_height)
569 {
570 GimpLayer *layer;
571 gint offset_x = 0;
572 gint offset_y = 0;
573
574 g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
575 g_return_val_if_fail (drawable == NULL || GIMP_IS_DRAWABLE (drawable), NULL);
576 g_return_val_if_fail (drawable == NULL ||
577 gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
578 g_return_val_if_fail (GIMP_IS_IMAGE (paste) || GIMP_IS_BUFFER (paste), NULL);
579
580 layer = gimp_edit_paste_get_layer (image, drawable, paste, &paste_type);
581
582 if (! layer)
583 return NULL;
584
585 if (gimp_edit_paste_is_in_place (paste_type))
586 {
587 gimp_edit_paste_get_paste_offset (image, drawable, paste,
588 &offset_x,
589 &offset_y);
590 }
591 else
592 {
593 gimp_edit_paste_get_viewport_offset (image, drawable, GIMP_OBJECT (layer),
594 viewport_x,
595 viewport_y,
596 viewport_width,
597 viewport_height,
598 &offset_x,
599 &offset_y);
600 }
601
602 return gimp_edit_paste_paste (image, drawable, layer, paste_type,
603 offset_x, offset_y);
604 }
605
606 GimpImage *
gimp_edit_paste_as_new_image(Gimp * gimp,GimpObject * paste)607 gimp_edit_paste_as_new_image (Gimp *gimp,
608 GimpObject *paste)
609 {
610 GimpImage *image = NULL;
611
612 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
613 g_return_val_if_fail (GIMP_IS_IMAGE (paste) || GIMP_IS_BUFFER (paste), NULL);
614
615 if (GIMP_IS_IMAGE (paste))
616 {
617 image = gimp_image_duplicate (GIMP_IMAGE (paste));
618 }
619 else if (GIMP_IS_BUFFER (paste))
620 {
621 image = gimp_image_new_from_buffer (gimp, GIMP_BUFFER (paste));
622 }
623
624 return image;
625 }
626
627 const gchar *
gimp_edit_named_cut(GimpImage * image,const gchar * name,GimpDrawable * drawable,GimpContext * context,GError ** error)628 gimp_edit_named_cut (GimpImage *image,
629 const gchar *name,
630 GimpDrawable *drawable,
631 GimpContext *context,
632 GError **error)
633 {
634 GimpBuffer *buffer;
635
636 g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
637 g_return_val_if_fail (name != NULL, NULL);
638 g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
639 g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
640 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
641 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
642
643 buffer = gimp_edit_extract (image, GIMP_PICKABLE (drawable),
644 context, TRUE, error);
645
646 if (buffer)
647 {
648 gimp_object_set_name (GIMP_OBJECT (buffer), name);
649 gimp_container_add (image->gimp->named_buffers, GIMP_OBJECT (buffer));
650 g_object_unref (buffer);
651
652 return gimp_object_get_name (buffer);
653 }
654
655 return NULL;
656 }
657
658 const gchar *
gimp_edit_named_copy(GimpImage * image,const gchar * name,GimpDrawable * drawable,GimpContext * context,GError ** error)659 gimp_edit_named_copy (GimpImage *image,
660 const gchar *name,
661 GimpDrawable *drawable,
662 GimpContext *context,
663 GError **error)
664 {
665 GimpBuffer *buffer;
666
667 g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
668 g_return_val_if_fail (name != NULL, NULL);
669 g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
670 g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
671 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
672 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
673
674 buffer = gimp_edit_extract (image, GIMP_PICKABLE (drawable),
675 context, FALSE, error);
676
677 if (buffer)
678 {
679 gimp_object_set_name (GIMP_OBJECT (buffer), name);
680 gimp_container_add (image->gimp->named_buffers, GIMP_OBJECT (buffer));
681 g_object_unref (buffer);
682
683 return gimp_object_get_name (buffer);
684 }
685
686 return NULL;
687 }
688
689 const gchar *
gimp_edit_named_copy_visible(GimpImage * image,const gchar * name,GimpContext * context,GError ** error)690 gimp_edit_named_copy_visible (GimpImage *image,
691 const gchar *name,
692 GimpContext *context,
693 GError **error)
694 {
695 GimpBuffer *buffer;
696
697 g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
698 g_return_val_if_fail (name != NULL, NULL);
699 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
700 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
701
702 buffer = gimp_edit_extract (image, GIMP_PICKABLE (image),
703 context, FALSE, error);
704
705 if (buffer)
706 {
707 gimp_object_set_name (GIMP_OBJECT (buffer), name);
708 gimp_container_add (image->gimp->named_buffers, GIMP_OBJECT (buffer));
709 g_object_unref (buffer);
710
711 return gimp_object_get_name (buffer);
712 }
713
714 return NULL;
715 }
716
717
718 /* private functions */
719
720 static GimpBuffer *
gimp_edit_extract(GimpImage * image,GimpPickable * pickable,GimpContext * context,gboolean cut_pixels,GError ** error)721 gimp_edit_extract (GimpImage *image,
722 GimpPickable *pickable,
723 GimpContext *context,
724 gboolean cut_pixels,
725 GError **error)
726 {
727 GeglBuffer *buffer;
728 gint offset_x;
729 gint offset_y;
730
731 if (cut_pixels)
732 gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_CUT,
733 C_("undo-type", "Cut"));
734
735 /* Cut/copy the mask portion from the image */
736 buffer = gimp_selection_extract (GIMP_SELECTION (gimp_image_get_mask (image)),
737 pickable, context,
738 cut_pixels, FALSE, FALSE,
739 &offset_x, &offset_y, error);
740
741 if (cut_pixels)
742 gimp_image_undo_group_end (image);
743
744 if (buffer)
745 {
746 GimpBuffer *gimp_buffer;
747 gdouble res_x;
748 gdouble res_y;
749
750 gimp_buffer = gimp_buffer_new (buffer, _("Global Buffer"),
751 offset_x, offset_y, FALSE);
752 g_object_unref (buffer);
753
754 gimp_image_get_resolution (image, &res_x, &res_y);
755 gimp_buffer_set_resolution (gimp_buffer, res_x, res_y);
756 gimp_buffer_set_unit (gimp_buffer, gimp_image_get_unit (image));
757
758 if (GIMP_IS_COLOR_MANAGED (pickable))
759 {
760 GimpColorProfile *profile =
761 gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (pickable));
762
763 if (profile)
764 gimp_buffer_set_color_profile (gimp_buffer, profile);
765 }
766
767 return gimp_buffer;
768 }
769
770 return NULL;
771 }
772