app: fix layer bounding box for different mask modes

In gimp_layer_get_bounding_box(), return the mask bounding box when
show-mask is active, and otherwise delegate the actual layer
bounding box calculation to a new GimpLayer::get_bounding_box()
function, and intersect its result with the mask bounding box, if
necessary.  The default GimpLayer::get_bounding_box()
implementation simply chains up to
GimpDrawable::get_bounding_box(), but GimpGroupLayer will override
this function in the following commits.

(cherry picked from commit 7f53cf9c55)
This commit is contained in:
Ell
2020-02-21 22:11:12 +02:00
parent 603d0a6274
commit 983698ecc1
2 changed files with 91 additions and 72 deletions

View File

@ -263,6 +263,8 @@ static void gimp_layer_real_convert_type (GimpLayer *layer,
GeglDitherMethod mask_dither_type,
gboolean push_undo,
GimpProgress *progress);
static GeglRectangle
gimp_layer_real_get_bounding_box (GimpLayer *layer);
static void gimp_layer_real_get_effective_mode (GimpLayer *layer,
GimpLayerMode *mode,
GimpLayerColorSpace *blend_space,
@ -484,6 +486,7 @@ gimp_layer_class_init (GimpLayerClass *klass)
klass->rotate = gimp_layer_real_rotate;
klass->transform = gimp_layer_real_transform;
klass->convert_type = gimp_layer_real_convert_type;
klass->get_bounding_box = gimp_layer_real_get_bounding_box;
klass->get_effective_mode = gimp_layer_real_get_effective_mode;
klass->get_excludes_backdrop = gimp_layer_real_get_excludes_backdrop;
@ -1513,22 +1516,28 @@ gimp_layer_set_buffer (GimpDrawable *drawable,
static GeglRectangle
gimp_layer_get_bounding_box (GimpDrawable *drawable)
{
GimpLayer *layer = GIMP_LAYER (drawable);
GimpLayerMask *mask = gimp_layer_get_mask (layer);
GimpLayer *layer = GIMP_LAYER (drawable);
GimpLayerMask *mask = gimp_layer_get_mask (layer);
GeglRectangle bounding_box;
bounding_box = GIMP_DRAWABLE_CLASS (parent_class)->get_bounding_box (
drawable);
if (mask && gimp_layer_get_apply_mask (layer))
if (mask && gimp_layer_get_show_mask (layer))
{
GeglRectangle mask_bounding_box;
bounding_box = gimp_drawable_get_bounding_box (GIMP_DRAWABLE (mask));
}
else
{
bounding_box = GIMP_LAYER_GET_CLASS (layer)->get_bounding_box (layer);
mask_bounding_box = gimp_drawable_get_bounding_box (
GIMP_DRAWABLE (mask));
if (mask && gimp_layer_get_apply_mask (layer))
{
GeglRectangle mask_bounding_box;
gegl_rectangle_intersect (&bounding_box,
&bounding_box, &mask_bounding_box);
mask_bounding_box = gimp_drawable_get_bounding_box (
GIMP_DRAWABLE (mask));
gegl_rectangle_intersect (&bounding_box,
&bounding_box, &mask_bounding_box);
}
}
return bounding_box;
@ -1767,6 +1776,13 @@ gimp_layer_real_convert_type (GimpLayer *layer,
g_object_unref (dest_buffer);
}
static GeglRectangle
gimp_layer_real_get_bounding_box (GimpLayer *layer)
{
return GIMP_DRAWABLE_CLASS (parent_class)->get_bounding_box (
GIMP_DRAWABLE (layer));
}
static void
gimp_layer_real_get_effective_mode (GimpLayer *layer,
GimpLayerMode *mode,
@ -2373,6 +2389,8 @@ gimp_layer_set_show_mask (GimpLayer *layer,
gimp_layer_update_mode_node (layer);
}
gimp_drawable_update_bounding_box (GIMP_DRAWABLE (layer));
gimp_layer_update_effective_mode (layer);
gimp_layer_update_excludes_backdrop (layer);

View File

@ -73,69 +73,70 @@ struct _GimpLayerClass
GimpDrawableClass parent_class;
/* signals */
void (* opacity_changed) (GimpLayer *layer);
void (* mode_changed) (GimpLayer *layer);
void (* blend_space_changed) (GimpLayer *layer);
void (* composite_space_changed) (GimpLayer *layer);
void (* composite_mode_changed) (GimpLayer *layer);
void (* effective_mode_changed) (GimpLayer *layer);
void (* excludes_backdrop_changed) (GimpLayer *layer);
void (* lock_alpha_changed) (GimpLayer *layer);
void (* mask_changed) (GimpLayer *layer);
void (* apply_mask_changed) (GimpLayer *layer);
void (* edit_mask_changed) (GimpLayer *layer);
void (* show_mask_changed) (GimpLayer *layer);
void (* opacity_changed) (GimpLayer *layer);
void (* mode_changed) (GimpLayer *layer);
void (* blend_space_changed) (GimpLayer *layer);
void (* composite_space_changed) (GimpLayer *layer);
void (* composite_mode_changed) (GimpLayer *layer);
void (* effective_mode_changed) (GimpLayer *layer);
void (* excludes_backdrop_changed) (GimpLayer *layer);
void (* lock_alpha_changed) (GimpLayer *layer);
void (* mask_changed) (GimpLayer *layer);
void (* apply_mask_changed) (GimpLayer *layer);
void (* edit_mask_changed) (GimpLayer *layer);
void (* show_mask_changed) (GimpLayer *layer);
/* virtual functions */
void (* translate) (GimpLayer *layer,
gint offset_x,
gint offset_y);
void (* scale) (GimpLayer *layer,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y,
GimpInterpolationType interpolation_type,
GimpProgress *progress);
void (* resize) (GimpLayer *layer,
GimpContext *context,
GimpFillType fill_type,
gint new_width,
gint new_height,
gint offset_x,
gint offset_y);
void (* flip) (GimpLayer *layer,
GimpContext *context,
GimpOrientationType flip_type,
gdouble axis,
gboolean clip_result);
void (* rotate) (GimpLayer *layer,
GimpContext *context,
GimpRotationType rotate_type,
gdouble center_x,
gdouble center_y,
gboolean clip_result);
void (* transform) (GimpLayer *layer,
GimpContext *context,
const GimpMatrix3 *matrix,
GimpTransformDirection direction,
GimpInterpolationType interpolation_type,
GimpTransformResize clip_result,
GimpProgress *progress);
void (* convert_type) (GimpLayer *layer,
GimpImage *dest_image,
const Babl *new_format,
GimpColorProfile *dest_profile,
GeglDitherMethod layer_dither_type,
GeglDitherMethod mask_dither_type,
gboolean push_undo,
GimpProgress *progress);
void (* get_effective_mode) (GimpLayer *layer,
GimpLayerMode *mode,
GimpLayerColorSpace *blend_space,
GimpLayerColorSpace *composite_space,
GimpLayerCompositeMode *composite_mode);
gboolean (* get_excludes_backdrop) (GimpLayer *layer);
void (* translate) (GimpLayer *layer,
gint offset_x,
gint offset_y);
void (* scale) (GimpLayer *layer,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y,
GimpInterpolationType interpolation_type,
GimpProgress *progress);
void (* resize) (GimpLayer *layer,
GimpContext *context,
GimpFillType fill_type,
gint new_width,
gint new_height,
gint offset_x,
gint offset_y);
void (* flip) (GimpLayer *layer,
GimpContext *context,
GimpOrientationType flip_type,
gdouble axis,
gboolean clip_result);
void (* rotate) (GimpLayer *layer,
GimpContext *context,
GimpRotationType rotate_type,
gdouble center_x,
gdouble center_y,
gboolean clip_result);
void (* transform) (GimpLayer *layer,
GimpContext *context,
const GimpMatrix3 *matrix,
GimpTransformDirection direction,
GimpInterpolationType interpolation_type,
GimpTransformResize clip_result,
GimpProgress *progress);
void (* convert_type) (GimpLayer *layer,
GimpImage *dest_image,
const Babl *new_format,
GimpColorProfile *dest_profile,
GeglDitherMethod layer_dither_type,
GeglDitherMethod mask_dither_type,
gboolean push_undo,
GimpProgress *progress);
GeglRectangle (* get_bounding_box) (GimpLayer *layer);
void (* get_effective_mode) (GimpLayer *layer,
GimpLayerMode *mode,
GimpLayerColorSpace *blend_space,
GimpLayerColorSpace *composite_space,
GimpLayerCompositeMode *composite_mode);
gboolean (* get_excludes_backdrop) (GimpLayer *layer);
};