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