mirror of https://github.com/GNOME/gimp.git
app: fix layer filter copying.
Copying filters over from one image to a partial copy was broken on multiple level by doing it on an additional loop, and assuming that the originally selected layers and the newly created ones had the same structure: 1. First the actually copied layers may be more numerous. For instance, we'd also copy parent layers. Typically copying a layer under a layer group, both the layer and its parent layer group would be in the clip image. 2. Second, because this structure may change, the assumptions made so that filters were not copied to the right image. 3. And as a last consequence, sometimes we could have crashes, assuming the same structure and therefore directly dereferencing a NULL pointer. I had such a crash when copy-pasting a layer group, while also selecting its children layers (though this crash also got hidden by my previous commit, but just by chance). Instead just copy filters in the same time as layers are copied, so that we can easily associate the filter from the correct original layer we copied from.
This commit is contained in:
parent
408c22dd70
commit
690391b985
|
@ -33,8 +33,6 @@
|
|||
#include "core/gimpcontainer.h"
|
||||
#include "core/gimpdrawable.h"
|
||||
#include "core/gimpdrawable-edit.h"
|
||||
#include "core/gimpdrawable-filters.h"
|
||||
#include "core/gimpdrawablefilter.h"
|
||||
#include "core/gimpfilloptions.h"
|
||||
#include "core/gimplayer.h"
|
||||
#include "core/gimplayer-new.h"
|
||||
|
@ -722,55 +720,6 @@ edit_paste (GimpDisplay *display,
|
|||
{
|
||||
gimp_image_set_selected_layers (image, pasted_layers);
|
||||
|
||||
/* Copy over layer effects */
|
||||
if (GIMP_IS_IMAGE (paste))
|
||||
{
|
||||
GList *old_layers_list;
|
||||
GList *new_layers_list;
|
||||
|
||||
old_layers_list = gimp_image_get_layer_iter (GIMP_IMAGE (paste));
|
||||
for (new_layers_list = pasted_layers; new_layers_list;
|
||||
new_layers_list = g_list_next (new_layers_list))
|
||||
{
|
||||
GimpLayer *layer = old_layers_list->data;
|
||||
GimpLayer *new_layer = new_layers_list->data;
|
||||
|
||||
if (gimp_drawable_has_filters (GIMP_DRAWABLE (layer)))
|
||||
{
|
||||
GList *filter_list;
|
||||
GimpContainer *filters;
|
||||
|
||||
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (layer));
|
||||
|
||||
for (filter_list = GIMP_LIST (filters)->queue->tail;
|
||||
filter_list;
|
||||
filter_list = g_list_previous (filter_list))
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (filter_list->data))
|
||||
{
|
||||
GimpDrawableFilter *old_filter = filter_list->data;
|
||||
GimpDrawableFilter *filter;
|
||||
|
||||
filter =
|
||||
gimp_drawable_filter_duplicate (GIMP_DRAWABLE (new_layer),
|
||||
old_filter);
|
||||
|
||||
if (filter != NULL)
|
||||
{
|
||||
gimp_drawable_filter_apply (filter, NULL);
|
||||
gimp_drawable_filter_commit (filter, TRUE, NULL, FALSE);
|
||||
|
||||
gimp_drawable_filter_layer_mask_freeze (filter);
|
||||
g_object_unref (filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
old_layers_list = g_list_next (old_layers_list);
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free (pasted_layers);
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "gimpbuffer.h"
|
||||
#include "gimpcontext.h"
|
||||
#include "gimpdrawable-edit.h"
|
||||
#include "gimpdrawable-filters.h"
|
||||
#include "gimpdrawablefilter.h"
|
||||
#include "gimperror.h"
|
||||
#include "gimpgrouplayer.h"
|
||||
#include "gimpimage.h"
|
||||
|
@ -493,6 +495,36 @@ gimp_edit_paste_get_tagged_layers (GimpImage *image,
|
|||
{
|
||||
layer = GIMP_LAYER (gimp_item_convert (GIMP_ITEM (iter->data),
|
||||
image, layer_type));
|
||||
|
||||
if (gimp_drawable_has_filters (GIMP_DRAWABLE (iter->data)))
|
||||
{
|
||||
GList *filter_list;
|
||||
GimpContainer *filters;
|
||||
|
||||
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (iter->data));
|
||||
|
||||
for (filter_list = GIMP_LIST (filters)->queue->tail;
|
||||
filter_list;
|
||||
filter_list = g_list_previous (filter_list))
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (filter_list->data))
|
||||
{
|
||||
GimpDrawableFilter *old_filter = filter_list->data;
|
||||
GimpDrawableFilter *filter;
|
||||
|
||||
filter = gimp_drawable_filter_duplicate (GIMP_DRAWABLE (layer), old_filter);
|
||||
|
||||
if (filter != NULL)
|
||||
{
|
||||
gimp_drawable_filter_apply (filter, NULL);
|
||||
gimp_drawable_filter_commit (filter, TRUE, NULL, FALSE);
|
||||
|
||||
gimp_drawable_filter_layer_mask_freeze (filter);
|
||||
g_object_unref (filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
returned_layers = g_list_prepend (returned_layers, layer);
|
||||
|
||||
switch (paste_type)
|
||||
|
|
|
@ -388,6 +388,35 @@ gimp_image_new_copy_drawables (GimpImage *image,
|
|||
if (gimp_layer_can_lock_alpha (new_layer))
|
||||
gimp_layer_set_lock_alpha (new_layer, FALSE, FALSE);
|
||||
|
||||
if (gimp_drawable_has_filters (GIMP_DRAWABLE (iter->data)))
|
||||
{
|
||||
GList *filter_list;
|
||||
GimpContainer *filters;
|
||||
|
||||
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (iter->data));
|
||||
|
||||
for (filter_list = GIMP_LIST (filters)->queue->tail; filter_list;
|
||||
filter_list = g_list_previous (filter_list))
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (filter_list->data))
|
||||
{
|
||||
GimpDrawableFilter *old_filter = filter_list->data;
|
||||
GimpDrawableFilter *filter;
|
||||
|
||||
filter = gimp_drawable_filter_duplicate (GIMP_DRAWABLE (new_layer), old_filter);
|
||||
|
||||
if (filter != NULL)
|
||||
{
|
||||
gimp_drawable_filter_apply (filter, NULL);
|
||||
gimp_drawable_filter_commit (filter, TRUE, NULL, FALSE);
|
||||
|
||||
gimp_drawable_filter_layer_mask_freeze (filter);
|
||||
g_object_unref (filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gimp_image_add_layer (new_image, new_layer, new_parent, index++, TRUE);
|
||||
|
||||
/* If a group, loop through children. */
|
||||
|
@ -419,8 +448,6 @@ gimp_image_new_from_drawables (Gimp *gimp,
|
|||
gdouble xres;
|
||||
gdouble yres;
|
||||
GimpColorProfile *profile = NULL;
|
||||
GList *old_layers_list;
|
||||
GList *new_layers_list;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
|
||||
g_return_val_if_fail (drawables != NULL, NULL);
|
||||
|
@ -478,48 +505,6 @@ gimp_image_new_from_drawables (Gimp *gimp,
|
|||
|
||||
gimp_image_new_copy_drawables (image, drawables, new_image, tag_copies, NULL, NULL, NULL, NULL);
|
||||
|
||||
/* Copy any attached layer effects */
|
||||
old_layers_list = drawables;
|
||||
for (new_layers_list = gimp_image_get_layer_iter (new_image);
|
||||
new_layers_list; new_layers_list = g_list_next (new_layers_list))
|
||||
{
|
||||
GimpLayer *layer = old_layers_list->data;
|
||||
GimpLayer *new_layer = new_layers_list->data;
|
||||
|
||||
if (gimp_drawable_has_filters (GIMP_DRAWABLE (layer)))
|
||||
{
|
||||
GList *filter_list;
|
||||
GimpContainer *filters;
|
||||
|
||||
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (layer));
|
||||
|
||||
for (filter_list = GIMP_LIST (filters)->queue->tail; filter_list;
|
||||
filter_list = g_list_previous (filter_list))
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (filter_list->data))
|
||||
{
|
||||
GimpDrawableFilter *old_filter = filter_list->data;
|
||||
GimpDrawableFilter *filter;
|
||||
|
||||
filter =
|
||||
gimp_drawable_filter_duplicate (GIMP_DRAWABLE (new_layer),
|
||||
old_filter);
|
||||
|
||||
if (filter != NULL)
|
||||
{
|
||||
gimp_drawable_filter_apply (filter, NULL);
|
||||
gimp_drawable_filter_commit (filter, TRUE, NULL, FALSE);
|
||||
|
||||
gimp_drawable_filter_layer_mask_freeze (filter);
|
||||
g_object_unref (filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
old_layers_list = g_list_next (old_layers_list);
|
||||
}
|
||||
|
||||
gimp_image_undo_enable (new_image);
|
||||
|
||||
return new_image;
|
||||
|
|
Loading…
Reference in New Issue