app: improve gimpchannel-{combine,select}
In gimpchannel-select, move some of the common functionality of the various gimp_channel_select_foo() functions to gimpchannel-combine. Furthermore, don't special-case CHANNEL_OP_INTERSECT, but rather pass it over to gimpchannel-combine, which is now prepared to handle it in all functions, as per the previous commits. In gimpchannel-combine, factor out the common functionality of the various gimp_channel_combine_foo() functions into a pair of gimp_channel_combine_{start,end}() functions, which are called before/after the actual gimp_gegl_mask_combine_foo() function, respectively. In particular, these functions deal with calculating the new channel bounds. Previously, the various gimp_gegl_mask_combine_foo() functions would implicitly invalidate the channel bounds (since commitd0ae244fe8
), rendering the bounds- recalculation code ineffective. This avoids manually recalculating the bounds in many cases, speeding up selection operations. (cherry picked from commit8e77347cac
)
This commit is contained in:
@ -28,11 +28,338 @@
|
||||
#include "core-types.h"
|
||||
|
||||
#include "gegl/gimp-gegl-mask-combine.h"
|
||||
#include "gegl/gimp-gegl-utils.h"
|
||||
|
||||
#include "gimpchannel.h"
|
||||
#include "gimpchannel-combine.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GeglRectangle rect;
|
||||
|
||||
gboolean bounds_known;
|
||||
gboolean empty;
|
||||
GeglRectangle bounds;
|
||||
} GimpChannelCombineData;
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static void gimp_channel_combine_clear (GimpChannel *mask,
|
||||
const GeglRectangle *rect);
|
||||
static void gimp_channel_combine_clear_complement (GimpChannel *mask,
|
||||
const GeglRectangle *rect);
|
||||
|
||||
static gboolean gimp_channel_combine_start (GimpChannel *mask,
|
||||
GimpChannelOps op,
|
||||
const GeglRectangle *rect,
|
||||
gboolean full_extent,
|
||||
gboolean full_value,
|
||||
GimpChannelCombineData *data);
|
||||
static void gimp_channel_combine_end (GimpChannel *mask,
|
||||
GimpChannelCombineData *data);
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
gimp_channel_combine_clear (GimpChannel *mask,
|
||||
const GeglRectangle *rect)
|
||||
{
|
||||
GeglBuffer *buffer;
|
||||
GeglRectangle area;
|
||||
GeglRectangle update_area;
|
||||
|
||||
if (mask->bounds_known && mask->empty)
|
||||
return;
|
||||
|
||||
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));
|
||||
|
||||
if (rect)
|
||||
{
|
||||
if (rect->width <= 0 || rect->height <= 0)
|
||||
return;
|
||||
|
||||
if (mask->bounds_known)
|
||||
{
|
||||
if (! gegl_rectangle_intersect (&area,
|
||||
GEGL_RECTANGLE (mask->x1,
|
||||
mask->y1,
|
||||
mask->x2 - mask->x1,
|
||||
mask->y2 - mask->y1),
|
||||
rect))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
area = *rect;
|
||||
}
|
||||
|
||||
update_area = area;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mask->bounds_known)
|
||||
{
|
||||
area.x = mask->x1;
|
||||
area.y = mask->y1;
|
||||
area.width = mask->x2 - mask->x1;
|
||||
area.height = mask->y2 - mask->y1;
|
||||
}
|
||||
else
|
||||
{
|
||||
area.x = 0;
|
||||
area.y = 0;
|
||||
area.width = gimp_item_get_width (GIMP_ITEM (mask));
|
||||
area.height = gimp_item_get_height (GIMP_ITEM (mask));
|
||||
}
|
||||
|
||||
update_area = area;
|
||||
|
||||
gimp_gegl_rectangle_align_to_tile_grid (&area, &area, buffer);
|
||||
}
|
||||
|
||||
gegl_buffer_clear (buffer, &area);
|
||||
|
||||
gimp_drawable_update (GIMP_DRAWABLE (mask),
|
||||
update_area.x, update_area.y,
|
||||
update_area.width, update_area.height);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_channel_combine_clear_complement (GimpChannel *mask,
|
||||
const GeglRectangle *rect)
|
||||
{
|
||||
gint width = gimp_item_get_width (GIMP_ITEM (mask));
|
||||
gint height = gimp_item_get_height (GIMP_ITEM (mask));
|
||||
|
||||
gimp_channel_combine_clear (
|
||||
mask,
|
||||
GEGL_RECTANGLE (0,
|
||||
0,
|
||||
width,
|
||||
rect->y));
|
||||
|
||||
gimp_channel_combine_clear (
|
||||
mask,
|
||||
GEGL_RECTANGLE (0,
|
||||
rect->y + rect->height,
|
||||
width,
|
||||
height - (rect->y + rect->height)));
|
||||
|
||||
gimp_channel_combine_clear (
|
||||
mask,
|
||||
GEGL_RECTANGLE (0,
|
||||
rect->y,
|
||||
rect->x,
|
||||
rect->height));
|
||||
|
||||
gimp_channel_combine_clear (
|
||||
mask,
|
||||
GEGL_RECTANGLE (rect->x + rect->width,
|
||||
rect->y,
|
||||
width - (rect->x + rect->width),
|
||||
rect->height));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_channel_combine_start (GimpChannel *mask,
|
||||
GimpChannelOps op,
|
||||
const GeglRectangle *rect,
|
||||
gboolean full_extent,
|
||||
gboolean full_value,
|
||||
GimpChannelCombineData *data)
|
||||
{
|
||||
GeglBuffer *buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));
|
||||
GeglRectangle extent;
|
||||
gboolean intersects;
|
||||
|
||||
extent.x = 0;
|
||||
extent.y = 0;
|
||||
extent.width = gimp_item_get_width (GIMP_ITEM (mask));
|
||||
extent.height = gimp_item_get_height (GIMP_ITEM (mask));
|
||||
|
||||
intersects = gegl_rectangle_intersect (&data->rect, rect, &extent);
|
||||
|
||||
data->bounds_known = mask->bounds_known;
|
||||
data->empty = mask->empty;
|
||||
|
||||
data->bounds.x = mask->x1;
|
||||
data->bounds.y = mask->y1;
|
||||
data->bounds.width = mask->x2 - mask->x1;
|
||||
data->bounds.height = mask->y2 - mask->y1;
|
||||
|
||||
gegl_buffer_freeze_changed (buffer);
|
||||
|
||||
/* Determine new boundary */
|
||||
switch (op)
|
||||
{
|
||||
case GIMP_CHANNEL_OP_REPLACE:
|
||||
gimp_channel_combine_clear (mask, NULL);
|
||||
|
||||
if (! intersects)
|
||||
{
|
||||
data->bounds_known = TRUE;
|
||||
data->empty = TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
data->bounds_known = FALSE;
|
||||
|
||||
if (full_extent)
|
||||
{
|
||||
data->bounds_known = TRUE;
|
||||
data->empty = FALSE;
|
||||
data->bounds = data->rect;
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMP_CHANNEL_OP_ADD:
|
||||
if (! intersects)
|
||||
return FALSE;
|
||||
|
||||
data->bounds_known = FALSE;
|
||||
|
||||
if (full_extent && (mask->bounds_known ||
|
||||
gegl_rectangle_equal (&data->rect, &extent)))
|
||||
{
|
||||
data->bounds_known = TRUE;
|
||||
data->empty = FALSE;
|
||||
|
||||
if (mask->bounds_known && ! mask->empty)
|
||||
{
|
||||
gegl_rectangle_bounding_box (&data->bounds,
|
||||
&data->bounds, &data->rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
data->bounds = data->rect;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMP_CHANNEL_OP_SUBTRACT:
|
||||
if (intersects && mask->bounds_known)
|
||||
{
|
||||
if (mask->empty)
|
||||
{
|
||||
intersects = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
intersects = gegl_rectangle_intersect (&data->rect,
|
||||
&data->rect,
|
||||
&data->bounds);
|
||||
}
|
||||
}
|
||||
|
||||
if (! intersects)
|
||||
return FALSE;
|
||||
|
||||
if (full_value &&
|
||||
gegl_rectangle_contains (&data->rect,
|
||||
mask->bounds_known ? &data->bounds :
|
||||
&extent))
|
||||
{
|
||||
gimp_channel_combine_clear (mask, NULL);
|
||||
|
||||
data->bounds_known = TRUE;
|
||||
data->empty = TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
data->bounds_known = FALSE;
|
||||
|
||||
gegl_buffer_set_abyss (buffer, &data->rect);
|
||||
break;
|
||||
|
||||
case GIMP_CHANNEL_OP_INTERSECT:
|
||||
if (intersects && mask->bounds_known)
|
||||
{
|
||||
if (mask->empty)
|
||||
{
|
||||
intersects = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
intersects = gegl_rectangle_intersect (&data->rect,
|
||||
&data->rect,
|
||||
&data->bounds);
|
||||
}
|
||||
}
|
||||
|
||||
if (! intersects)
|
||||
{
|
||||
gimp_channel_combine_clear (mask, NULL);
|
||||
|
||||
data->bounds_known = TRUE;
|
||||
data->empty = TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (full_value && mask->bounds_known &&
|
||||
gegl_rectangle_contains (&data->rect, &data->bounds))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
data->bounds_known = FALSE;
|
||||
|
||||
gimp_channel_combine_clear_complement (mask, &data->rect);
|
||||
|
||||
gegl_buffer_set_abyss (buffer, &data->rect);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_channel_combine_end (GimpChannel *mask,
|
||||
GimpChannelCombineData *data)
|
||||
{
|
||||
GeglBuffer *buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));
|
||||
|
||||
gegl_buffer_set_abyss (buffer, gegl_buffer_get_extent (buffer));
|
||||
|
||||
gegl_buffer_thaw_changed (buffer);
|
||||
|
||||
mask->bounds_known = data->bounds_known;
|
||||
|
||||
if (data->bounds_known)
|
||||
{
|
||||
mask->empty = data->empty;
|
||||
|
||||
if (data->empty)
|
||||
{
|
||||
mask->x1 = 0;
|
||||
mask->y1 = 0;
|
||||
mask->x2 = gimp_item_get_width (GIMP_ITEM (mask));
|
||||
mask->y2 = gimp_item_get_height (GIMP_ITEM (mask));
|
||||
}
|
||||
else
|
||||
{
|
||||
mask->x1 = data->bounds.x;
|
||||
mask->y1 = data->bounds.y;
|
||||
mask->x2 = data->bounds.x + data->bounds.width;
|
||||
mask->y2 = data->bounds.y + data->bounds.height;
|
||||
}
|
||||
}
|
||||
|
||||
gimp_drawable_update (GIMP_DRAWABLE (mask),
|
||||
data->rect.x, data->rect.y,
|
||||
data->rect.width, data->rect.height);
|
||||
}
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
void
|
||||
gimp_channel_combine_rect (GimpChannel *mask,
|
||||
GimpChannelOps op,
|
||||
@ -41,52 +368,19 @@ gimp_channel_combine_rect (GimpChannel *mask,
|
||||
gint w,
|
||||
gint h)
|
||||
{
|
||||
GeglBuffer *buffer;
|
||||
GimpChannelCombineData data;
|
||||
|
||||
g_return_if_fail (GIMP_IS_CHANNEL (mask));
|
||||
|
||||
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));
|
||||
|
||||
if (! gimp_gegl_mask_combine_rect (buffer, op, x, y, w, h))
|
||||
return;
|
||||
|
||||
gimp_rectangle_intersect (x, y, w, h,
|
||||
0, 0,
|
||||
gimp_item_get_width (GIMP_ITEM (mask)),
|
||||
gimp_item_get_height (GIMP_ITEM (mask)),
|
||||
&x, &y, &w, &h);
|
||||
|
||||
/* Determine new boundary */
|
||||
if (mask->bounds_known && (op == GIMP_CHANNEL_OP_ADD) && ! mask->empty)
|
||||
if (gimp_channel_combine_start (mask, op, GEGL_RECTANGLE (x, y, w, h),
|
||||
TRUE, TRUE, &data))
|
||||
{
|
||||
if (x < mask->x1)
|
||||
mask->x1 = x;
|
||||
if (y < mask->y1)
|
||||
mask->y1 = y;
|
||||
if ((x + w) > mask->x2)
|
||||
mask->x2 = (x + w);
|
||||
if ((y + h) > mask->y2)
|
||||
mask->y2 = (y + h);
|
||||
}
|
||||
else if (op == GIMP_CHANNEL_OP_REPLACE || mask->empty)
|
||||
{
|
||||
mask->empty = FALSE;
|
||||
mask->x1 = x;
|
||||
mask->y1 = y;
|
||||
mask->x2 = x + w;
|
||||
mask->y2 = y + h;
|
||||
}
|
||||
else
|
||||
{
|
||||
mask->bounds_known = FALSE;
|
||||
GeglBuffer *buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));
|
||||
|
||||
gimp_gegl_mask_combine_rect (buffer, op, x, y, w, h);
|
||||
}
|
||||
|
||||
mask->x1 = CLAMP (mask->x1, 0, gimp_item_get_width (GIMP_ITEM (mask)));
|
||||
mask->y1 = CLAMP (mask->y1, 0, gimp_item_get_height (GIMP_ITEM (mask)));
|
||||
mask->x2 = CLAMP (mask->x2, 0, gimp_item_get_width (GIMP_ITEM (mask)));
|
||||
mask->y2 = CLAMP (mask->y2, 0, gimp_item_get_height (GIMP_ITEM (mask)));
|
||||
|
||||
gimp_drawable_update (GIMP_DRAWABLE (mask), x, y, w, h);
|
||||
gimp_channel_combine_end (mask, &data);
|
||||
}
|
||||
|
||||
void
|
||||
@ -113,46 +407,20 @@ gimp_channel_combine_ellipse_rect (GimpChannel *mask,
|
||||
gdouble ry,
|
||||
gboolean antialias)
|
||||
{
|
||||
GeglBuffer *buffer;
|
||||
GimpChannelCombineData data;
|
||||
|
||||
g_return_if_fail (GIMP_IS_CHANNEL (mask));
|
||||
g_return_if_fail (op != GIMP_CHANNEL_OP_INTERSECT);
|
||||
|
||||
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));
|
||||
|
||||
if (! gimp_gegl_mask_combine_ellipse_rect (buffer, op, x, y, w, h,
|
||||
rx, ry, antialias))
|
||||
return;
|
||||
|
||||
gimp_rectangle_intersect (x, y, w, h,
|
||||
0, 0,
|
||||
gimp_item_get_width (GIMP_ITEM (mask)),
|
||||
gimp_item_get_height (GIMP_ITEM (mask)),
|
||||
&x, &y, &w, &h);
|
||||
|
||||
/* determine new boundary */
|
||||
if (mask->bounds_known && (op == GIMP_CHANNEL_OP_ADD) && ! mask->empty)
|
||||
if (gimp_channel_combine_start (mask, op, GEGL_RECTANGLE (x, y, w, h),
|
||||
TRUE, FALSE, &data))
|
||||
{
|
||||
if (x < mask->x1) mask->x1 = x;
|
||||
if (y < mask->y1) mask->y1 = y;
|
||||
GeglBuffer *buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));
|
||||
|
||||
if ((x + w) > mask->x2) mask->x2 = (x + w);
|
||||
if ((y + h) > mask->y2) mask->y2 = (y + h);
|
||||
}
|
||||
else if (op == GIMP_CHANNEL_OP_REPLACE || mask->empty)
|
||||
{
|
||||
mask->empty = FALSE;
|
||||
mask->x1 = x;
|
||||
mask->y1 = y;
|
||||
mask->x2 = x + w;
|
||||
mask->y2 = y + h;
|
||||
}
|
||||
else
|
||||
{
|
||||
mask->bounds_known = FALSE;
|
||||
gimp_gegl_mask_combine_ellipse_rect (buffer, op, x, y, w, h,
|
||||
rx, ry, antialias);
|
||||
}
|
||||
|
||||
gimp_drawable_update (GIMP_DRAWABLE (mask), x, y, w, h);
|
||||
gimp_channel_combine_end (mask, &data);
|
||||
}
|
||||
|
||||
void
|
||||
@ -180,27 +448,24 @@ gimp_channel_combine_buffer (GimpChannel *mask,
|
||||
gint off_x,
|
||||
gint off_y)
|
||||
{
|
||||
GeglBuffer *buffer;
|
||||
gint x, y, w, h;
|
||||
GimpChannelCombineData data;
|
||||
|
||||
g_return_if_fail (GIMP_IS_CHANNEL (mask));
|
||||
g_return_if_fail (GEGL_IS_BUFFER (add_on_buffer));
|
||||
|
||||
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));
|
||||
if (gimp_channel_combine_start (mask, op,
|
||||
GEGL_RECTANGLE (
|
||||
off_x,
|
||||
off_y,
|
||||
gegl_buffer_get_width (add_on_buffer),
|
||||
gegl_buffer_get_height (add_on_buffer)),
|
||||
FALSE, FALSE, &data))
|
||||
{
|
||||
GeglBuffer *buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));
|
||||
|
||||
if (! gimp_gegl_mask_combine_buffer (buffer, add_on_buffer,
|
||||
op, off_x, off_y))
|
||||
return;
|
||||
gimp_gegl_mask_combine_buffer (buffer, add_on_buffer, op,
|
||||
off_x, off_y);
|
||||
}
|
||||
|
||||
gimp_rectangle_intersect (off_x, off_y,
|
||||
gegl_buffer_get_width (add_on_buffer),
|
||||
gegl_buffer_get_height (add_on_buffer),
|
||||
0, 0,
|
||||
gimp_item_get_width (GIMP_ITEM (mask)),
|
||||
gimp_item_get_height (GIMP_ITEM (mask)),
|
||||
&x, &y, &w, &h);
|
||||
|
||||
mask->bounds_known = FALSE;
|
||||
|
||||
gimp_drawable_update (GIMP_DRAWABLE (mask), x, y, w, h);
|
||||
gimp_channel_combine_end (mask, &data);
|
||||
}
|
||||
|
@ -65,14 +65,10 @@ gimp_channel_select_rectangle (GimpChannel *channel,
|
||||
if (push_undo)
|
||||
gimp_channel_push_undo (channel, C_("undo-type", "Rectangle Select"));
|
||||
|
||||
/* if applicable, replace the current selection */
|
||||
if (op == GIMP_CHANNEL_OP_REPLACE)
|
||||
gimp_channel_clear (channel, NULL, FALSE);
|
||||
|
||||
/* if feathering for rect, make a new mask with the
|
||||
* rectangle and feather that with the old mask
|
||||
*/
|
||||
if (feather || op == GIMP_CHANNEL_OP_INTERSECT)
|
||||
if (feather)
|
||||
{
|
||||
GimpItem *item = GIMP_ITEM (channel);
|
||||
GeglBuffer *add_on;
|
||||
@ -82,12 +78,11 @@ gimp_channel_select_rectangle (GimpChannel *channel,
|
||||
gimp_item_get_height (item)),
|
||||
babl_format ("Y float"));
|
||||
|
||||
gimp_gegl_mask_combine_rect (add_on, GIMP_CHANNEL_OP_ADD, x, y, w, h);
|
||||
gimp_gegl_mask_combine_rect (add_on, GIMP_CHANNEL_OP_REPLACE, x, y, w, h);
|
||||
|
||||
if (feather)
|
||||
gimp_gegl_apply_feather (add_on, NULL, NULL, add_on, NULL,
|
||||
feather_radius_x,
|
||||
feather_radius_y);
|
||||
gimp_gegl_apply_feather (add_on, NULL, NULL, add_on, NULL,
|
||||
feather_radius_x,
|
||||
feather_radius_y);
|
||||
|
||||
gimp_channel_combine_buffer (channel, add_on, op, 0, 0);
|
||||
g_object_unref (add_on);
|
||||
@ -117,14 +112,10 @@ gimp_channel_select_ellipse (GimpChannel *channel,
|
||||
if (push_undo)
|
||||
gimp_channel_push_undo (channel, C_("undo-type", "Ellipse Select"));
|
||||
|
||||
/* if applicable, replace the current selection */
|
||||
if (op == GIMP_CHANNEL_OP_REPLACE)
|
||||
gimp_channel_clear (channel, NULL, FALSE);
|
||||
|
||||
/* if feathering for rect, make a new mask with the
|
||||
* rectangle and feather that with the old mask
|
||||
*/
|
||||
if (feather || op == GIMP_CHANNEL_OP_INTERSECT)
|
||||
if (feather)
|
||||
{
|
||||
GimpItem *item = GIMP_ITEM (channel);
|
||||
GeglBuffer *add_on;
|
||||
@ -134,13 +125,12 @@ gimp_channel_select_ellipse (GimpChannel *channel,
|
||||
gimp_item_get_height (item)),
|
||||
babl_format ("Y float"));
|
||||
|
||||
gimp_gegl_mask_combine_ellipse (add_on, GIMP_CHANNEL_OP_ADD,
|
||||
gimp_gegl_mask_combine_ellipse (add_on, GIMP_CHANNEL_OP_REPLACE,
|
||||
x, y, w, h, antialias);
|
||||
|
||||
if (feather)
|
||||
gimp_gegl_apply_feather (add_on, NULL, NULL, add_on, NULL,
|
||||
feather_radius_x,
|
||||
feather_radius_y);
|
||||
gimp_gegl_apply_feather (add_on, NULL, NULL, add_on, NULL,
|
||||
feather_radius_x,
|
||||
feather_radius_y);
|
||||
|
||||
gimp_channel_combine_buffer (channel, add_on, op, 0, 0);
|
||||
g_object_unref (add_on);
|
||||
@ -172,14 +162,10 @@ gimp_channel_select_round_rect (GimpChannel *channel,
|
||||
if (push_undo)
|
||||
gimp_channel_push_undo (channel, C_("undo-type", "Rounded Rectangle Select"));
|
||||
|
||||
/* if applicable, replace the current selection */
|
||||
if (op == GIMP_CHANNEL_OP_REPLACE)
|
||||
gimp_channel_clear (channel, NULL, FALSE);
|
||||
|
||||
/* if feathering for rect, make a new mask with the
|
||||
* rectangle and feather that with the old mask
|
||||
*/
|
||||
if (feather || op == GIMP_CHANNEL_OP_INTERSECT)
|
||||
if (feather)
|
||||
{
|
||||
GimpItem *item = GIMP_ITEM (channel);
|
||||
GeglBuffer *add_on;
|
||||
@ -189,15 +175,14 @@ gimp_channel_select_round_rect (GimpChannel *channel,
|
||||
gimp_item_get_height (item)),
|
||||
babl_format ("Y float"));
|
||||
|
||||
gimp_gegl_mask_combine_ellipse_rect (add_on, GIMP_CHANNEL_OP_ADD,
|
||||
gimp_gegl_mask_combine_ellipse_rect (add_on, GIMP_CHANNEL_OP_REPLACE,
|
||||
x, y, w, h,
|
||||
corner_radius_x, corner_radius_y,
|
||||
antialias);
|
||||
|
||||
if (feather)
|
||||
gimp_gegl_apply_feather (add_on, NULL, NULL, add_on, NULL,
|
||||
feather_radius_x,
|
||||
feather_radius_y);
|
||||
gimp_gegl_apply_feather (add_on, NULL, NULL, add_on, NULL,
|
||||
feather_radius_x,
|
||||
feather_radius_y);
|
||||
|
||||
gimp_channel_combine_buffer (channel, add_on, op, 0, 0);
|
||||
g_object_unref (add_on);
|
||||
@ -236,10 +221,6 @@ gimp_channel_select_scan_convert (GimpChannel *channel,
|
||||
if (push_undo)
|
||||
gimp_channel_push_undo (channel, undo_desc);
|
||||
|
||||
/* if applicable, replace the current selection */
|
||||
if (op == GIMP_CHANNEL_OP_REPLACE)
|
||||
gimp_channel_clear (channel, NULL, FALSE);
|
||||
|
||||
item = GIMP_ITEM (channel);
|
||||
|
||||
add_on = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
|
||||
@ -346,11 +327,7 @@ gimp_channel_select_buffer (GimpChannel *channel,
|
||||
|
||||
gimp_channel_push_undo (channel, undo_desc);
|
||||
|
||||
/* if applicable, replace the current selection */
|
||||
if (op == GIMP_CHANNEL_OP_REPLACE)
|
||||
gimp_channel_clear (channel, NULL, FALSE);
|
||||
|
||||
if (feather || op == GIMP_CHANNEL_OP_INTERSECT)
|
||||
if (feather)
|
||||
{
|
||||
GimpItem *item = GIMP_ITEM (channel);
|
||||
GeglBuffer *add_on2;
|
||||
@ -361,13 +338,12 @@ gimp_channel_select_buffer (GimpChannel *channel,
|
||||
babl_format ("Y float"));
|
||||
|
||||
gimp_gegl_mask_combine_buffer (add_on2, add_on,
|
||||
GIMP_CHANNEL_OP_ADD,
|
||||
GIMP_CHANNEL_OP_REPLACE,
|
||||
offset_x, offset_y);
|
||||
|
||||
if (feather)
|
||||
gimp_gegl_apply_feather (add_on2, NULL, NULL, add_on2, NULL,
|
||||
feather_radius_x,
|
||||
feather_radius_y);
|
||||
gimp_gegl_apply_feather (add_on2, NULL, NULL, add_on2, NULL,
|
||||
feather_radius_x,
|
||||
feather_radius_y);
|
||||
|
||||
gimp_channel_combine_buffer (channel, add_on2, op, 0, 0);
|
||||
g_object_unref (add_on2);
|
||||
|
Reference in New Issue
Block a user