mirror of https://github.com/GNOME/gimp.git
Issue #4634 - Pass-through groups bounding-box is not properly updated ...
... causing artifacts In GimpGroupLayer, override GimpLayer::get_bounding_box() to return the group's own calculated bounding box for pass-through groups, instead of using the group graph's bounding box, as calculated by the default implementation of GimpDrawable::get_bounding_box(). We don't currently update the group's bounding box in response to all the events that may affect the graph's bounding box, which can lead to artifacts, neither should we use the graph's bounding box anyway, since it includes the backdrop's bounding box, as the group's layers are composited against the background. Note that we still use the graph's bounding box for non-pass- through groups, since it takes attached filters into account, which are applicable for normal groups, but not pass-through groups. Additionally, don't restrict the group's bounding when it has a mask, since this is now handled by GimpLayer.
This commit is contained in:
parent
8c81c6e153
commit
aa9ae1c65c
|
@ -172,7 +172,8 @@ static void gimp_group_layer_opacity_changed (GimpLayer *layer);
|
|||
static void gimp_group_layer_effective_mode_changed (GimpLayer *layer);
|
||||
static void
|
||||
gimp_group_layer_excludes_backdrop_changed (GimpLayer *layer);
|
||||
static void gimp_group_layer_mask_changed (GimpLayer *layer);
|
||||
static GeglRectangle
|
||||
gimp_group_layer_get_bounding_box (GimpLayer *layer);
|
||||
static void gimp_group_layer_get_effective_mode (GimpLayer *layer,
|
||||
GimpLayerMode *mode,
|
||||
GimpLayerColorSpace *blend_space,
|
||||
|
@ -183,7 +184,7 @@ static gboolean
|
|||
|
||||
static const Babl * gimp_group_layer_get_format (GimpProjectable *projectable);
|
||||
static GeglRectangle
|
||||
gimp_group_layer_get_bounding_box (GimpProjectable *projectable);
|
||||
gimp_group_layer_projectable_get_bounding_box (GimpProjectable *projectable);
|
||||
static GeglNode * gimp_group_layer_get_graph (GimpProjectable *projectable);
|
||||
static void gimp_group_layer_begin_render (GimpProjectable *projectable);
|
||||
static void gimp_group_layer_end_render (GimpProjectable *projectable);
|
||||
|
@ -300,13 +301,13 @@ gimp_group_layer_class_init (GimpGroupLayerClass *klass)
|
|||
layer_class->opacity_changed = gimp_group_layer_opacity_changed;
|
||||
layer_class->effective_mode_changed = gimp_group_layer_effective_mode_changed;
|
||||
layer_class->excludes_backdrop_changed = gimp_group_layer_excludes_backdrop_changed;
|
||||
layer_class->mask_changed = gimp_group_layer_mask_changed;
|
||||
layer_class->translate = gimp_group_layer_translate;
|
||||
layer_class->scale = gimp_group_layer_scale;
|
||||
layer_class->flip = gimp_group_layer_flip;
|
||||
layer_class->rotate = gimp_group_layer_rotate;
|
||||
layer_class->transform = gimp_group_layer_transform;
|
||||
layer_class->convert_type = gimp_group_layer_convert_type;
|
||||
layer_class->get_bounding_box = gimp_group_layer_get_bounding_box;
|
||||
layer_class->get_effective_mode = gimp_group_layer_get_effective_mode;
|
||||
layer_class->get_excludes_backdrop = gimp_group_layer_get_excludes_backdrop;
|
||||
|
||||
|
@ -320,7 +321,7 @@ gimp_projectable_iface_init (GimpProjectableInterface *iface)
|
|||
iface->get_image = (GimpImage * (*) (GimpProjectable *)) gimp_item_get_image;
|
||||
iface->get_format = gimp_group_layer_get_format;
|
||||
iface->get_offset = (void (*) (GimpProjectable*, gint*, gint*)) gimp_item_get_offset;
|
||||
iface->get_bounding_box = gimp_group_layer_get_bounding_box;
|
||||
iface->get_bounding_box = gimp_group_layer_projectable_get_bounding_box;
|
||||
iface->get_graph = gimp_group_layer_get_graph;
|
||||
iface->begin_render = gimp_group_layer_begin_render;
|
||||
iface->end_render = gimp_group_layer_end_render;
|
||||
|
@ -1138,11 +1139,14 @@ gimp_group_layer_effective_mode_changed (GimpLayer *layer)
|
|||
GimpGroupLayerPrivate *private = GET_PRIVATE (layer);
|
||||
GimpLayerMode mode;
|
||||
gboolean pass_through;
|
||||
gboolean update_bounding_box = FALSE;
|
||||
|
||||
gimp_layer_get_effective_mode (layer, &mode, NULL, NULL, NULL);
|
||||
|
||||
pass_through = (mode == GIMP_LAYER_MODE_PASS_THROUGH);
|
||||
|
||||
if (pass_through != private->pass_through)
|
||||
{
|
||||
if (private->pass_through && ! pass_through)
|
||||
{
|
||||
/* when switching from pass-through mode to a non-pass-through mode,
|
||||
|
@ -1155,9 +1159,15 @@ gimp_group_layer_effective_mode_changed (GimpLayer *layer)
|
|||
|
||||
private->pass_through = pass_through;
|
||||
|
||||
update_bounding_box = TRUE;
|
||||
}
|
||||
|
||||
gimp_group_layer_update_source_node (group);
|
||||
gimp_group_layer_update_mode_node (group);
|
||||
|
||||
if (update_bounding_box)
|
||||
gimp_drawable_update_bounding_box (GIMP_DRAWABLE (group));
|
||||
|
||||
if (GIMP_LAYER_CLASS (parent_class)->effective_mode_changed)
|
||||
GIMP_LAYER_CLASS (parent_class)->effective_mode_changed (layer);
|
||||
}
|
||||
|
@ -1174,25 +1184,23 @@ gimp_group_layer_excludes_backdrop_changed (GimpLayer *layer)
|
|||
GIMP_LAYER_CLASS (parent_class)->excludes_backdrop_changed (layer);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_group_layer_mask_changed (GimpLayer *layer)
|
||||
static GeglRectangle
|
||||
gimp_group_layer_get_bounding_box (GimpLayer *layer)
|
||||
{
|
||||
GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
|
||||
GimpGroupLayerPrivate *private = GET_PRIVATE (layer);
|
||||
|
||||
g_warn_if_fail (GET_PRIVATE (layer)->suspend_mask == 0);
|
||||
|
||||
/* if we've already computed a bounding box, update it now, since the mask
|
||||
* limits the bounding box to the group's size. if we haven't computed a
|
||||
* bounding box yet we can skip this, and, in fact, we have to, or else the
|
||||
* mask will be improperly clipped when the group is duplicated, discarding
|
||||
* its data.
|
||||
/* for pass-through groups, use the group's calculated bounding box, instead
|
||||
* of the source-node's bounding box, since we don't update the bounding box
|
||||
* on all events that may affect the latter, and since it includes the
|
||||
* bounding box of the backdrop. this means we can't attach filters that may
|
||||
* affect the bounding box to a pass-through group (since their effect weon't
|
||||
* be reflected by the group's bounding box), but attaching filters to pass-
|
||||
* through groups makes little sense anyway.
|
||||
*/
|
||||
if (! gegl_rectangle_is_empty (&private->bounding_box))
|
||||
gimp_group_layer_update (group);
|
||||
|
||||
if (GIMP_LAYER_CLASS (parent_class)->mask_changed)
|
||||
GIMP_LAYER_CLASS (parent_class)->mask_changed (layer);
|
||||
if (private->pass_through)
|
||||
return private->bounding_box;
|
||||
else
|
||||
return GIMP_LAYER_CLASS (parent_class)->get_bounding_box (layer);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1367,7 +1375,7 @@ gimp_group_layer_get_format (GimpProjectable *projectable)
|
|||
}
|
||||
|
||||
static GeglRectangle
|
||||
gimp_group_layer_get_bounding_box (GimpProjectable *projectable)
|
||||
gimp_group_layer_projectable_get_bounding_box (GimpProjectable *projectable)
|
||||
{
|
||||
GimpGroupLayerPrivate *private = GET_PRIVATE (projectable);
|
||||
|
||||
|
@ -1981,9 +1989,6 @@ gimp_group_layer_update_size (GimpGroupLayer *group)
|
|||
}
|
||||
}
|
||||
|
||||
if (mask)
|
||||
bounding_box = bounds;
|
||||
|
||||
bounding_box.x -= bounds.x;
|
||||
bounding_box.y -= bounds.y;
|
||||
|
||||
|
|
Loading…
Reference in New Issue