mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-07-04 09:53:25 +00:00
core: Use prior filter size for stack crops
Previously filters were cropped to the layer size in the "crop_before" node. This was fine when we had destructive-only filters, but now that we can multiple active layers, this causes new layers to crop the prior ones if they're larger than the layer (e.g. If gegl:drop-shadow goes out of the layer boundaries) This patch sets the crop_before to the current sizes, then searches the filter stack to see if there's a filter that needs a larger width or height (or if it needs a smaller x or y values), then sets the crop to that size. This crop update is also run when a filter is raised or lowered.
This commit is contained in:
parent
42f8a61923
commit
59b7b6a5fb
4 changed files with 110 additions and 20 deletions
|
@ -43,6 +43,7 @@
|
|||
#include "gimpchannel.h"
|
||||
#include "gimpdrawable-filters.h"
|
||||
#include "gimpdrawablefilter.h"
|
||||
#include "gimpfilterstack.h"
|
||||
#include "gimpimage.h"
|
||||
#include "gimplayer.h"
|
||||
#include "gimpprogress.h"
|
||||
|
@ -1021,14 +1022,28 @@ gimp_drawable_filter_sync_region (GimpDrawableFilter *filter)
|
|||
{
|
||||
if (filter->has_input)
|
||||
{
|
||||
GeglRectangle rect;
|
||||
GimpContainer *filters;
|
||||
|
||||
rect.x = filter->filter_area.x;
|
||||
rect.y = filter->filter_area.y;
|
||||
rect.width = filter->filter_area.width;
|
||||
rect.height = filter->filter_area.height;
|
||||
|
||||
filters = gimp_drawable_get_filters (filter->drawable);
|
||||
gimp_filter_stack_get_bounding_box (GIMP_FILTER_STACK (filters),
|
||||
&rect);
|
||||
|
||||
gegl_node_set (filter->translate,
|
||||
"x", (gdouble) -filter->filter_area.x,
|
||||
"y", (gdouble) -filter->filter_area.y,
|
||||
NULL);
|
||||
|
||||
gegl_node_set (filter->crop_before,
|
||||
"width", (gdouble) filter->filter_area.width,
|
||||
"height", (gdouble) filter->filter_area.height,
|
||||
"x", (gdouble) rect.x,
|
||||
"y", (gdouble) rect.y,
|
||||
"width", (gdouble) rect.width,
|
||||
"height", (gdouble) rect.height,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
@ -1061,14 +1076,23 @@ gimp_drawable_filter_sync_region (GimpDrawableFilter *filter)
|
|||
|
||||
if (filter->has_input)
|
||||
{
|
||||
GeglRectangle rect = { 0, 0, width, height };
|
||||
GimpContainer *filters;
|
||||
|
||||
filters = gimp_drawable_get_filters (filter->drawable);
|
||||
gimp_filter_stack_get_bounding_box (GIMP_FILTER_STACK (filters),
|
||||
&rect);
|
||||
|
||||
gegl_node_set (filter->translate,
|
||||
"x", (gdouble) 0.0,
|
||||
"y", (gdouble) 0.0,
|
||||
NULL);
|
||||
|
||||
gegl_node_set (filter->crop_before,
|
||||
"width", width,
|
||||
"height", height,
|
||||
"x", (gdouble) rect.x,
|
||||
"y", (gdouble) rect.y,
|
||||
"width", (gdouble) rect.width,
|
||||
"height", (gdouble) rect.height,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "core-types.h"
|
||||
|
||||
#include "gimpdrawablefilter.h"
|
||||
#include "gimpfilter.h"
|
||||
#include "gimpfilterstack.h"
|
||||
|
||||
|
@ -223,6 +224,39 @@ gimp_filter_stack_get_graph (GimpFilterStack *stack)
|
|||
return stack->graph;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_filter_stack_get_bounding_box (GimpFilterStack *stack,
|
||||
GeglRectangle *rect)
|
||||
{
|
||||
GList *list;
|
||||
GeglRectangle current_rect;
|
||||
|
||||
g_return_if_fail (GIMP_IS_FILTER_STACK (stack));
|
||||
|
||||
for (list = GIMP_LIST (stack)->queue->tail;
|
||||
list; list = g_list_previous (list))
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (list->data))
|
||||
{
|
||||
GimpFilter *filter = GIMP_FILTER (list->data);
|
||||
|
||||
current_rect = gegl_node_get_bounding_box (gimp_filter_get_node (filter));
|
||||
|
||||
if (rect->x > current_rect.x)
|
||||
rect->x = current_rect.x;
|
||||
|
||||
if (rect->y > current_rect.y)
|
||||
rect->y = current_rect.y;
|
||||
|
||||
if (rect->width < (current_rect.width - current_rect.x))
|
||||
rect->width = (current_rect.width - current_rect.x);
|
||||
|
||||
if (rect->height < (current_rect.height - current_rect.y))
|
||||
rect->height = (current_rect.height - current_rect.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
|
|
|
@ -46,10 +46,11 @@ struct _GimpFilterStackClass
|
|||
};
|
||||
|
||||
|
||||
GType gimp_filter_stack_get_type (void) G_GNUC_CONST;
|
||||
GimpContainer * gimp_filter_stack_new (GType filter_type);
|
||||
|
||||
GeglNode * gimp_filter_stack_get_graph (GimpFilterStack *stack);
|
||||
GType gimp_filter_stack_get_type (void) G_GNUC_CONST;
|
||||
GimpContainer * gimp_filter_stack_new (GType filter_type);
|
||||
|
||||
GeglNode * gimp_filter_stack_get_graph (GimpFilterStack *stack);
|
||||
void gimp_filter_stack_get_bounding_box (GimpFilterStack *stack,
|
||||
GeglRectangle *rect);
|
||||
|
||||
#endif /* __GIMP_FILTER_STACK_H__ */
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "core/gimpdrawable-filters.h"
|
||||
#include "core/gimpdrawablefilter.h"
|
||||
#include "core/gimpdrawablefilterundo.h"
|
||||
#include "core/gimpfilterstack.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpimage-undo.h"
|
||||
#include "core/gimpimage-undo-push.h"
|
||||
|
@ -2683,7 +2684,8 @@ static void
|
|||
gimp_item_tree_view_effects_raised_clicked (GtkWidget *widget,
|
||||
GimpItemTreeView *view)
|
||||
{
|
||||
GimpImage *image = view->priv->image;
|
||||
GimpImage *image = view->priv->image;
|
||||
GimpDrawable *drawable = NULL;
|
||||
|
||||
if (! view->priv->effects_filter ||
|
||||
! GIMP_IS_DRAWABLE_FILTER (view->priv->effects_filter))
|
||||
|
@ -2696,12 +2698,13 @@ gimp_item_tree_view_effects_raised_clicked (GtkWidget *widget,
|
|||
return;
|
||||
}
|
||||
|
||||
if (view->priv->effects_drawable)
|
||||
drawable = gimp_drawable_filter_get_drawable (view->priv->effects_filter);
|
||||
if (drawable)
|
||||
{
|
||||
GimpContainer *filters;
|
||||
gint index;
|
||||
|
||||
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (view->priv->effects_drawable));
|
||||
filters = gimp_drawable_get_filters (drawable);
|
||||
|
||||
index = gimp_container_get_child_index (filters,
|
||||
GIMP_OBJECT (view->priv->effects_filter));
|
||||
|
@ -2709,8 +2712,11 @@ gimp_item_tree_view_effects_raised_clicked (GtkWidget *widget,
|
|||
|
||||
if (index >= 0)
|
||||
{
|
||||
GimpChannel *mask = NULL;
|
||||
GeglRectangle rect;
|
||||
|
||||
gimp_image_undo_push_filter_reorder (image, _("Reorder filter"),
|
||||
view->priv->effects_drawable,
|
||||
drawable,
|
||||
view->priv->effects_filter);
|
||||
|
||||
gimp_container_reorder (filters, GIMP_OBJECT (view->priv->effects_filter),
|
||||
|
@ -2723,10 +2729,18 @@ gimp_item_tree_view_effects_raised_clicked (GtkWidget *widget,
|
|||
gtk_widget_set_sensitive (view->priv->effects_raise_button, FALSE);
|
||||
}
|
||||
|
||||
mask = gimp_drawable_filter_get_mask (view->priv->effects_filter);
|
||||
gimp_filter_stack_get_bounding_box (GIMP_FILTER_STACK (filters),
|
||||
&rect);
|
||||
|
||||
if (gimp_channel_is_empty (mask))
|
||||
gimp_drawable_filter_refresh_crop (view->priv->effects_filter,
|
||||
&rect);
|
||||
|
||||
/* Hack to make the effects visibly change */
|
||||
gimp_item_set_visible (GIMP_ITEM (view->priv->effects_drawable), FALSE, FALSE);
|
||||
gimp_item_set_visible (GIMP_ITEM (drawable), FALSE, FALSE);
|
||||
gimp_image_flush (image);
|
||||
gimp_item_set_visible (GIMP_ITEM (view->priv->effects_drawable), TRUE, FALSE);
|
||||
gimp_item_set_visible (GIMP_ITEM (drawable), TRUE, FALSE);
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
}
|
||||
|
@ -2736,7 +2750,8 @@ static void
|
|||
gimp_item_tree_view_effects_lowered_clicked (GtkWidget *widget,
|
||||
GimpItemTreeView *view)
|
||||
{
|
||||
GimpImage *image = view->priv->image;
|
||||
GimpImage *image = view->priv->image;
|
||||
GimpDrawable *drawable = NULL;
|
||||
|
||||
if (! view->priv->effects_filter ||
|
||||
! GIMP_IS_DRAWABLE_FILTER (view->priv->effects_filter))
|
||||
|
@ -2749,12 +2764,13 @@ gimp_item_tree_view_effects_lowered_clicked (GtkWidget *widget,
|
|||
return;
|
||||
}
|
||||
|
||||
if (view->priv->effects_drawable)
|
||||
drawable = gimp_drawable_filter_get_drawable (view->priv->effects_filter);
|
||||
if (drawable)
|
||||
{
|
||||
GimpContainer *filters;
|
||||
gint index;
|
||||
|
||||
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (view->priv->effects_drawable));
|
||||
filters = gimp_drawable_get_filters (drawable);
|
||||
|
||||
index = gimp_container_get_child_index (filters,
|
||||
GIMP_OBJECT (view->priv->effects_filter));
|
||||
|
@ -2762,8 +2778,12 @@ gimp_item_tree_view_effects_lowered_clicked (GtkWidget *widget,
|
|||
|
||||
if (index < gimp_container_get_n_children (filters))
|
||||
{
|
||||
GimpDrawableFilter *moved_filter = NULL;
|
||||
GimpChannel *mask = NULL;
|
||||
GeglRectangle rect;
|
||||
|
||||
gimp_image_undo_push_filter_reorder (image, _("Reorder filter"),
|
||||
view->priv->effects_drawable,
|
||||
drawable,
|
||||
view->priv->effects_filter);
|
||||
|
||||
gimp_container_reorder (filters, GIMP_OBJECT (view->priv->effects_filter),
|
||||
|
@ -2776,10 +2796,21 @@ gimp_item_tree_view_effects_lowered_clicked (GtkWidget *widget,
|
|||
gtk_widget_set_sensitive (view->priv->effects_lower_button, FALSE);
|
||||
}
|
||||
|
||||
moved_filter = (GimpDrawableFilter *)
|
||||
gimp_container_get_child_by_index (filters, index - 1);
|
||||
|
||||
mask = gimp_drawable_filter_get_mask (moved_filter);
|
||||
gimp_filter_stack_get_bounding_box (GIMP_FILTER_STACK (filters),
|
||||
&rect);
|
||||
|
||||
if (gimp_channel_is_empty (mask))
|
||||
gimp_drawable_filter_refresh_crop (moved_filter, &rect);
|
||||
|
||||
|
||||
/* Hack to make the effects visibly change */
|
||||
gimp_item_set_visible (GIMP_ITEM (view->priv->effects_drawable), FALSE, FALSE);
|
||||
gimp_item_set_visible (GIMP_ITEM (drawable), FALSE, FALSE);
|
||||
gimp_image_flush (image);
|
||||
gimp_item_set_visible (GIMP_ITEM (view->priv->effects_drawable), TRUE, FALSE);
|
||||
gimp_item_set_visible (GIMP_ITEM (drawable), TRUE, FALSE);
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue