[gimp] app: add gimp_drawable_filter_set_crop()
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add gimp_drawable_filter_set_crop()
- Date: Sun, 30 Dec 2018 10:14:21 +0000 (UTC)
commit 5c27d14fdfd151f26b8aab4ddd77e10376278c1e
Author: Ell <ell_se yahoo com>
Date: Sun Dec 30 04:46:10 2018 -0500
app: add gimp_drawable_filter_set_crop()
Add gimp_drawable_filter_set_crop(), which allows setting an output
crop rectangle for the filter; anything outside the rectangle
doesn't get filtered. The crop area is combined with the preview
area to determine the filtered area during preview, however, unlike
the preview area, the crop area remains in effect while committing
the filter.
Consequently, when merging a drawable filter, if the filter has a
crop, only process the cropped area.
app/core/gimpdrawable-filters.c | 164 +++++++++++++++++++++-------------------
app/core/gimpdrawablefilter.c | 156 ++++++++++++++++++++++++++------------
app/core/gimpdrawablefilter.h | 3 +
3 files changed, 196 insertions(+), 127 deletions(-)
---
diff --git a/app/core/gimpdrawable-filters.c b/app/core/gimpdrawable-filters.c
index 2dad613110..8c0421cf76 100644
--- a/app/core/gimpdrawable-filters.c
+++ b/app/core/gimpdrawable-filters.c
@@ -111,98 +111,104 @@ gimp_drawable_merge_filter (GimpDrawable *drawable,
const gchar *undo_desc,
gboolean cancellable)
{
- GeglRectangle rect;
- gboolean success = TRUE;
+ GimpImage *image;
+ GimpApplicator *applicator;
+ GeglBuffer *undo_buffer;
+ GeglRectangle undo_rect;
+ GeglBuffer *cache = NULL;
+ GeglRectangle *rects = NULL;
+ gint n_rects = 0;
+ GeglRectangle rect;
+ gboolean success = TRUE;
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE);
g_return_val_if_fail (GIMP_IS_FILTER (filter), FALSE);
g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
- if (gimp_item_mask_intersect (GIMP_ITEM (drawable),
- &rect.x, &rect.y,
- &rect.width, &rect.height))
+ image = gimp_item_get_image (GIMP_ITEM (drawable));
+ applicator = gimp_filter_get_applicator (filter);
+
+ if (! gimp_item_mask_intersect (GIMP_ITEM (drawable),
+ &rect.x, &rect.y,
+ &rect.width, &rect.height))
{
- GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
- GeglBuffer *undo_buffer;
- GeglRectangle undo_rect;
- GimpApplicator *applicator;
- GeglBuffer *cache = NULL;
- GeglRectangle *rects = NULL;
- gint n_rects = 0;
-
- gimp_gegl_rectangle_align_to_tile_grid (
- &undo_rect,
- &rect,
- gimp_drawable_get_buffer (drawable));
-
- undo_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
- undo_rect.width,
- undo_rect.height),
- gimp_drawable_get_format (drawable));
-
- gimp_gegl_buffer_copy (gimp_drawable_get_buffer (drawable),
- &undo_rect,
- GEGL_ABYSS_NONE,
- undo_buffer,
- GEGL_RECTANGLE (0, 0, 0, 0));
-
- applicator = gimp_filter_get_applicator (filter);
-
- if (applicator)
- {
- /* disable the output crop */
- gimp_applicator_set_crop (applicator, NULL);
-
- /* the cache and its valid rectangles are the region that
- * has already been processed by this applicator.
- */
- cache = gimp_applicator_get_cache_buffer (applicator,
- &rects, &n_rects);
- }
-
- gimp_projection_stop_rendering (gimp_image_get_projection (image));
-
- if (gimp_gegl_apply_cached_operation (gimp_drawable_get_buffer (drawable),
- progress, undo_desc,
- gimp_filter_get_node (filter),
- gimp_drawable_get_buffer (drawable),
- &rect, FALSE,
- cache, rects, n_rects,
- cancellable))
- {
- /* finished successfully */
-
- gimp_drawable_push_undo (drawable, undo_desc, undo_buffer,
- undo_rect.x, undo_rect.y,
- undo_rect.width, undo_rect.height);
- }
- else
- {
- /* canceled by the user */
-
- gimp_gegl_buffer_copy (undo_buffer,
- GEGL_RECTANGLE (0, 0,
+ return TRUE;
+ }
+
+ if (applicator)
+ {
+ const GeglRectangle *crop_rect;
+
+ crop_rect = gimp_applicator_get_crop (applicator);
+
+ if (crop_rect && ! gegl_rectangle_intersect (&rect, &rect, crop_rect))
+ return TRUE;
+
+ /* the cache and its valid rectangles are the region that
+ * has already been processed by this applicator.
+ */
+ cache = gimp_applicator_get_cache_buffer (applicator,
+ &rects, &n_rects);
+ }
+
+ gimp_gegl_rectangle_align_to_tile_grid (
+ &undo_rect,
+ &rect,
+ gimp_drawable_get_buffer (drawable));
+
+ undo_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
undo_rect.width,
undo_rect.height),
- GEGL_ABYSS_NONE,
- gimp_drawable_get_buffer (drawable),
- &undo_rect);
+ gimp_drawable_get_format (drawable));
+
+ gimp_gegl_buffer_copy (gimp_drawable_get_buffer (drawable),
+ &undo_rect,
+ GEGL_ABYSS_NONE,
+ undo_buffer,
+ GEGL_RECTANGLE (0, 0, 0, 0));
+
+ gimp_projection_stop_rendering (gimp_image_get_projection (image));
+
+ if (gimp_gegl_apply_cached_operation (gimp_drawable_get_buffer (drawable),
+ progress, undo_desc,
+ gimp_filter_get_node (filter),
+ gimp_drawable_get_buffer (drawable),
+ &rect, FALSE,
+ cache, rects, n_rects,
+ cancellable))
+ {
+ /* finished successfully */
+
+ gimp_drawable_push_undo (drawable, undo_desc, undo_buffer,
+ undo_rect.x, undo_rect.y,
+ undo_rect.width, undo_rect.height);
+ }
+ else
+ {
+ /* canceled by the user */
- success = FALSE;
- }
+ gimp_gegl_buffer_copy (undo_buffer,
+ GEGL_RECTANGLE (0, 0,
+ undo_rect.width,
+ undo_rect.height),
+ GEGL_ABYSS_NONE,
+ gimp_drawable_get_buffer (drawable),
+ &undo_rect);
- g_object_unref (undo_buffer);
+ success = FALSE;
+ }
- if (cache)
- {
- g_object_unref (cache);
- g_free (rects);
- }
+ g_object_unref (undo_buffer);
- gimp_drawable_update (drawable,
- rect.x, rect.y,
- rect.width, rect.height);
+ if (cache)
+ {
+ g_object_unref (cache);
+ g_free (rects);
}
+ gimp_drawable_update (drawable,
+ rect.x, rect.y,
+ rect.width, rect.height);
+
return success;
}
diff --git a/app/core/gimpdrawablefilter.c b/app/core/gimpdrawablefilter.c
index 02fefe0a11..5b27996b48 100644
--- a/app/core/gimpdrawablefilter.c
+++ b/app/core/gimpdrawablefilter.c
@@ -65,6 +65,8 @@ struct _GimpDrawableFilter
gboolean has_input;
GimpFilterRegion region;
+ gboolean crop_enabled;
+ GeglRectangle crop_rect;
gboolean preview_enabled;
GimpAlignmentType preview_alignment;
gdouble preview_position;
@@ -93,10 +95,13 @@ static void gimp_drawable_filter_dispose (GObject *ob
static void gimp_drawable_filter_finalize (GObject *object);
static void gimp_drawable_filter_sync_region (GimpDrawableFilter *filter);
-static void gimp_drawable_filter_sync_preview (GimpDrawableFilter *filter,
- gboolean old_enabled,
- GimpAlignmentType old_alignment,
- gdouble old_position);
+static void gimp_drawable_filter_sync_crop (GimpDrawableFilter *filter,
+ gboolean old_crop_enabled,
+ const GeglRectangle *old_crop_rect,
+ gboolean old_preview_enabled,
+ GimpAlignmentType old_preview_alignment,
+ gdouble old_preview_position,
+ gboolean update);
static void gimp_drawable_filter_sync_opacity (GimpDrawableFilter *filter);
static void gimp_drawable_filter_sync_mode (GimpDrawableFilter *filter);
static void gimp_drawable_filter_sync_affect (GimpDrawableFilter *filter);
@@ -292,6 +297,39 @@ gimp_drawable_filter_set_region (GimpDrawableFilter *filter,
}
}
+void
+gimp_drawable_filter_set_crop (GimpDrawableFilter *filter,
+ const GeglRectangle *rect,
+ gboolean update)
+{
+ g_return_if_fail (GIMP_IS_DRAWABLE_FILTER (filter));
+
+ if ((rect != NULL) != filter->crop_enabled ||
+ (rect && ! gegl_rectangle_equal (rect, &filter->crop_rect)))
+ {
+ gboolean old_enabled = filter->crop_enabled;
+ GeglRectangle old_rect = filter->crop_rect;
+
+ if (rect)
+ {
+ filter->crop_enabled = TRUE;
+ filter->crop_rect = *rect;
+ }
+ else
+ {
+ filter->crop_enabled = FALSE;
+ }
+
+ gimp_drawable_filter_sync_crop (filter,
+ old_enabled,
+ &old_rect,
+ filter->preview_enabled,
+ filter->preview_alignment,
+ filter->preview_position,
+ update);
+ }
+}
+
void
gimp_drawable_filter_set_preview (GimpDrawableFilter *filter,
gboolean enabled,
@@ -318,9 +356,13 @@ gimp_drawable_filter_set_preview (GimpDrawableFilter *filter,
filter->preview_alignment = alignment;
filter->preview_position = position;
- gimp_drawable_filter_sync_preview (filter,
- old_enabled,
- old_alignment, old_position);
+ gimp_drawable_filter_sync_crop (filter,
+ filter->crop_enabled,
+ &filter->crop_rect,
+ old_enabled,
+ old_alignment,
+ old_position,
+ TRUE);
}
}
@@ -427,6 +469,10 @@ gimp_drawable_filter_commit (GimpDrawableFilter *filter,
if (gimp_drawable_filter_is_filtering (filter))
{
+ gimp_drawable_filter_set_preview (filter, FALSE,
+ filter->preview_alignment,
+ filter->preview_position);
+
success = gimp_drawable_merge_filter (filter->drawable,
GIMP_FILTER (filter),
progress,
@@ -510,12 +556,14 @@ gimp_drawable_filter_sync_region (GimpDrawableFilter *filter)
}
}
-static void
-gimp_drawable_filter_get_preview_rect (GimpDrawableFilter *filter,
- gboolean enabled,
- GimpAlignmentType alignment,
- gdouble position,
- GeglRectangle *rect)
+static gboolean
+gimp_drawable_filter_get_crop_rect (GimpDrawableFilter *filter,
+ gboolean crop_enabled,
+ const GeglRectangle *crop_rect,
+ gboolean preview_enabled,
+ GimpAlignmentType preview_alignment,
+ gdouble preview_position,
+ GeglRectangle *rect)
{
gint width;
gint height;
@@ -528,62 +576,71 @@ gimp_drawable_filter_get_preview_rect (GimpDrawableFilter *filter,
width = rect->width;
height = rect->height;
- if (enabled)
+ if (preview_enabled)
{
- switch (alignment)
+ switch (preview_alignment)
{
case GIMP_ALIGN_LEFT:
- rect->width *= position;
+ rect->width *= preview_position;
break;
case GIMP_ALIGN_RIGHT:
- rect->width *= (1.0 - position);
+ rect->width *= (1.0 - preview_position);
rect->x = width - rect->width;
break;
case GIMP_ALIGN_TOP:
- rect->height *= position;
+ rect->height *= preview_position;
break;
case GIMP_ALIGN_BOTTOM:
- rect->height *= (1.0 - position);
+ rect->height *= (1.0 - preview_position);
rect->y = height - rect->height;
break;
default:
- g_return_if_reached ();
+ g_return_val_if_reached (FALSE);
}
}
+
+ if (crop_enabled)
+ gegl_rectangle_intersect (rect, rect, crop_rect);
+
+ return ! gegl_rectangle_equal_coords (rect, 0, 0, width, height);
}
static void
-gimp_drawable_filter_sync_preview (GimpDrawableFilter *filter,
- gboolean old_enabled,
- GimpAlignmentType old_alignment,
- gdouble old_position)
+gimp_drawable_filter_sync_crop (GimpDrawableFilter *filter,
+ gboolean old_crop_enabled,
+ const GeglRectangle *old_crop_rect,
+ gboolean old_preview_enabled,
+ GimpAlignmentType old_preview_alignment,
+ gdouble old_preview_position,
+ gboolean update)
{
GeglRectangle old_rect;
GeglRectangle new_rect;
-
- gimp_drawable_filter_get_preview_rect (filter,
- old_enabled,
- old_alignment,
- old_position,
- &old_rect);
-
- gimp_drawable_filter_get_preview_rect (filter,
- filter->preview_enabled,
- filter->preview_alignment,
- filter->preview_position,
- &new_rect);
-
- gimp_applicator_set_crop (filter->applicator,
- filter->preview_enabled ? &new_rect : NULL);
-
- if (old_rect.x != new_rect.x ||
- old_rect.y != new_rect.y ||
- old_rect.width != new_rect.width ||
- old_rect.height != new_rect.height)
+ gboolean enabled;
+
+ gimp_drawable_filter_get_crop_rect (filter,
+ old_crop_enabled,
+ old_crop_rect,
+ old_preview_enabled,
+ old_preview_alignment,
+ old_preview_position,
+ &old_rect);
+
+ enabled = gimp_drawable_filter_get_crop_rect (filter,
+ filter->crop_enabled,
+ &filter->crop_rect,
+ filter->preview_enabled,
+ filter->preview_alignment,
+ filter->preview_position,
+ &new_rect);
+
+ gimp_applicator_set_crop (filter->applicator, enabled ? &new_rect : NULL);
+
+ if (update && ! gegl_rectangle_equal (&old_rect, &new_rect))
{
cairo_region_t *region;
gint n_rects;
@@ -877,10 +934,13 @@ gimp_drawable_filter_add_filter (GimpDrawableFilter *filter)
gimp_drawable_filter_sync_mask (filter);
gimp_drawable_filter_sync_region (filter);
- gimp_drawable_filter_sync_preview (filter,
- filter->preview_enabled,
- filter->preview_alignment,
- filter->preview_position);
+ gimp_drawable_filter_sync_crop (filter,
+ filter->crop_enabled,
+ &filter->crop_rect,
+ filter->preview_enabled,
+ filter->preview_alignment,
+ filter->preview_position,
+ TRUE);
gimp_drawable_filter_sync_opacity (filter);
gimp_drawable_filter_sync_mode (filter);
gimp_drawable_filter_sync_affect (filter);
diff --git a/app/core/gimpdrawablefilter.h b/app/core/gimpdrawablefilter.h
index bb633322b4..cc3db76b43 100644
--- a/app/core/gimpdrawablefilter.h
+++ b/app/core/gimpdrawablefilter.h
@@ -57,6 +57,9 @@ GimpDrawableFilter *
void gimp_drawable_filter_set_region (GimpDrawableFilter *filter,
GimpFilterRegion region);
+void gimp_drawable_filter_set_crop (GimpDrawableFilter *filter,
+ const GeglRectangle *rect,
+ gboolean update);
void gimp_drawable_filter_set_preview (GimpDrawableFilter *filter,
gboolean enabled,
GimpAlignmentType alignment,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]