[gimp] app: add gimp_image_flip_full()
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add gimp_image_flip_full()
- Date: Sat, 10 Aug 2019 21:35:59 +0000 (UTC)
commit ae080f06f9934d83a4acb1ef83d126d805b4baad
Author: Ell <ell_se yahoo com>
Date: Sat Aug 10 22:48:49 2019 +0300
app: add gimp_image_flip_full()
... which takes the symmetry axis as a parameter, instead of hard-
coding the axis to the middle of the image, and which additionally
takes the clipping mode as a parameter, controlling whether to clip
or resize the canvas. Note that the actual canvas size never
changes, but it may be offset when flipped around an off-center
axis, without clipping.
Implement gimp_image_flip() in terms of gimp_image_flip_full().
app/core/gimpimage-flip.c | 245 +++++++++++++++++++++++++++++++++++-----------
app/core/gimpimage-flip.h | 14 ++-
2 files changed, 196 insertions(+), 63 deletions(-)
---
diff --git a/app/core/gimpimage-flip.c b/app/core/gimpimage-flip.c
index e999c3392e..5db05fe935 100644
--- a/app/core/gimpimage-flip.c
+++ b/app/core/gimpimage-flip.c
@@ -20,9 +20,12 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gegl.h>
+#include "libgimpmath/gimpmath.h"
+
#include "core-types.h"
#include "gimp.h"
+#include "gimpchannel.h"
#include "gimpcontainer.h"
#include "gimpcontext.h"
#include "gimpguide.h"
@@ -38,38 +41,185 @@
#include "gimpsamplepoint.h"
+/* local function prototypes */
+
+static void gimp_image_flip_guides (GimpImage *image,
+ GimpOrientationType flip_type,
+ gdouble axis);
+static void gimp_image_flip_sample_points (GimpImage *image,
+ GimpOrientationType flip_type,
+ gdouble axis);
+
+
+/* private functions */
+
+static void
+gimp_image_flip_guides (GimpImage *image,
+ GimpOrientationType flip_type,
+ gdouble axis)
+{
+ gint width = gimp_image_get_width (image);
+ gint height = gimp_image_get_height (image);
+ GList *iter;
+
+ for (iter = gimp_image_get_guides (image); iter;)
+ {
+ GimpGuide *guide = iter->data;
+ gint position = gimp_guide_get_position (guide);
+
+ iter = g_list_next (iter);
+
+ position = SIGNED_ROUND (2.0 * axis - position);
+
+ switch (gimp_guide_get_orientation (guide))
+ {
+ case GIMP_ORIENTATION_HORIZONTAL:
+ if (flip_type == GIMP_ORIENTATION_VERTICAL)
+ {
+ if (position >= 0 && position <= height)
+ gimp_image_move_guide (image, guide, position, TRUE);
+ else
+ gimp_image_remove_guide (image, guide, TRUE);
+ }
+ break;
+
+ case GIMP_ORIENTATION_VERTICAL:
+ if (flip_type == GIMP_ORIENTATION_HORIZONTAL)
+ {
+ if (position >= 0 && position <= width)
+ gimp_image_move_guide (image, guide, position, TRUE);
+ else
+ gimp_image_remove_guide (image, guide, TRUE);
+ }
+ break;
+
+ case GIMP_ORIENTATION_UNKNOWN:
+ g_return_if_reached ();
+ }
+ }
+}
+
+static void
+gimp_image_flip_sample_points (GimpImage *image,
+ GimpOrientationType flip_type,
+ gdouble axis)
+{
+ gint width = gimp_image_get_width (image);
+ gint height = gimp_image_get_height (image);
+ GList *iter;
+
+ for (iter = gimp_image_get_sample_points (image); iter;)
+ {
+ GimpSamplePoint *sample_point = iter->data;
+ gint x;
+ gint y;
+
+ iter = g_list_next (iter);
+
+ gimp_sample_point_get_position (sample_point, &x, &y);
+
+ switch (flip_type)
+ {
+ case GIMP_ORIENTATION_HORIZONTAL:
+ x = SIGNED_ROUND (2.0 * axis - x);
+ break;
+
+ case GIMP_ORIENTATION_VERTICAL:
+ y = SIGNED_ROUND (2.0 * axis - y);
+ break;
+
+ case GIMP_ORIENTATION_UNKNOWN:
+ g_return_if_reached ();
+ }
+
+ if (x >= 0 && x < width &&
+ y >= 0 && y < height)
+ {
+ gimp_image_move_sample_point (image, sample_point, x, y, TRUE);
+ }
+ else
+ {
+ gimp_image_remove_sample_point (image, sample_point, TRUE);
+ }
+ }
+}
+
+
+/* public functions */
+
void
gimp_image_flip (GimpImage *image,
GimpContext *context,
GimpOrientationType flip_type,
GimpProgress *progress)
{
- GimpObjectQueue *queue;
- GimpItem *item;
- GList *list;
- gdouble axis;
+ gdouble axis = 0.0;
g_return_if_fail (GIMP_IS_IMAGE (image));
g_return_if_fail (GIMP_IS_CONTEXT (context));
g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
- gimp_set_busy (image->gimp);
-
switch (flip_type)
{
case GIMP_ORIENTATION_HORIZONTAL:
- axis = (gdouble) gimp_image_get_width (image) / 2.0;
+ axis = gimp_image_get_width (image) / 2.0;
break;
case GIMP_ORIENTATION_VERTICAL:
- axis = (gdouble) gimp_image_get_height (image) / 2.0;
+ axis = gimp_image_get_height (image) / 2.0;
break;
- default:
- g_warning ("%s: unknown flip_type", G_STRFUNC);
- return;
+ case GIMP_ORIENTATION_UNKNOWN:
+ g_return_if_reached ();
}
+ gimp_image_flip_full (image, context, flip_type, axis,
+ GIMP_TRANSFORM_RESIZE_CLIP, progress);
+}
+
+void
+gimp_image_flip_full (GimpImage *image,
+ GimpContext *context,
+ GimpOrientationType flip_type,
+ gdouble axis,
+ gboolean clip_result,
+ GimpProgress *progress)
+{
+ GimpObjectQueue *queue;
+ GimpItem *item;
+ gint width;
+ gint height;
+ gint offset_x = 0;
+ gint offset_y = 0;
+
+ g_return_if_fail (GIMP_IS_IMAGE (image));
+ g_return_if_fail (GIMP_IS_CONTEXT (context));
+ g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
+
+ width = gimp_image_get_width (image);
+ height = gimp_image_get_height (image);
+
+ if (! clip_result)
+ {
+ switch (flip_type)
+ {
+ case GIMP_ORIENTATION_HORIZONTAL:
+ offset_x = SIGNED_ROUND (2.0 * axis - width);
+ axis = width / 2.0;
+ break;
+
+ case GIMP_ORIENTATION_VERTICAL:
+ offset_y = SIGNED_ROUND (2.0 * axis - height);
+ axis = height / 2.0;
+ break;
+
+ case GIMP_ORIENTATION_UNKNOWN:
+ g_return_if_reached ();
+ }
+ }
+
+ gimp_set_busy (image->gimp);
+
queue = gimp_object_queue_new (progress);
progress = GIMP_PROGRESS (queue);
@@ -83,67 +233,44 @@ gimp_image_flip (GimpImage *image,
/* Flip all layers, channels (including selection mask), and vectors */
while ((item = gimp_object_queue_pop (queue)))
{
- gimp_item_flip (item, context, flip_type, axis, FALSE);
+ gboolean clip = FALSE;
+
+ if (GIMP_IS_CHANNEL (item))
+ clip = clip_result;
+
+ gimp_item_flip (item, context, flip_type, axis, clip);
gimp_progress_set_value (progress, 1.0);
}
/* Flip all Guides */
- for (list = gimp_image_get_guides (image);
- list;
- list = g_list_next (list))
- {
- GimpGuide *guide = list->data;
- gint position = gimp_guide_get_position (guide);
-
- switch (gimp_guide_get_orientation (guide))
- {
- case GIMP_ORIENTATION_HORIZONTAL:
- if (flip_type == GIMP_ORIENTATION_VERTICAL)
- gimp_image_move_guide (image, guide,
- gimp_image_get_height (image) - position,
- TRUE);
- break;
-
- case GIMP_ORIENTATION_VERTICAL:
- if (flip_type == GIMP_ORIENTATION_HORIZONTAL)
- gimp_image_move_guide (image, guide,
- gimp_image_get_width (image) - position,
- TRUE);
- break;
-
- default:
- break;
- }
- }
+ gimp_image_flip_guides (image, flip_type, axis);
/* Flip all sample points */
- for (list = gimp_image_get_sample_points (image);
- list;
- list = g_list_next (list))
- {
- GimpSamplePoint *sample_point = list->data;
- gint x;
- gint y;
+ gimp_image_flip_sample_points (image, flip_type, axis);
- gimp_sample_point_get_position (sample_point, &x, &y);
-
- if (flip_type == GIMP_ORIENTATION_VERTICAL)
- gimp_image_move_sample_point (image, sample_point,
- x,
- gimp_image_get_height (image) - y,
- TRUE);
-
- if (flip_type == GIMP_ORIENTATION_HORIZONTAL)
- gimp_image_move_sample_point (image, sample_point,
- gimp_image_get_width (image) - x,
- y,
- TRUE);
+ if (offset_x || offset_y)
+ {
+ gimp_image_undo_push_image_size (image,
+ NULL,
+ offset_x,
+ offset_y,
+ width,
+ height);
}
gimp_image_undo_group_end (image);
g_object_unref (queue);
+ if (offset_x || offset_y)
+ {
+ gimp_image_size_changed_detailed (image,
+ -offset_x,
+ -offset_y,
+ width,
+ height);
+ }
+
gimp_unset_busy (image->gimp);
}
diff --git a/app/core/gimpimage-flip.h b/app/core/gimpimage-flip.h
index 0ab220f3d2..5fa6ce6046 100644
--- a/app/core/gimpimage-flip.h
+++ b/app/core/gimpimage-flip.h
@@ -19,10 +19,16 @@
#define __GIMP_IMAGE_FLIP_H__
-void gimp_image_flip (GimpImage *image,
- GimpContext *context,
- GimpOrientationType flip_type,
- GimpProgress *progress);
+void gimp_image_flip (GimpImage *image,
+ GimpContext *context,
+ GimpOrientationType flip_type,
+ GimpProgress *progress);
+void gimp_image_flip_full (GimpImage *image,
+ GimpContext *context,
+ GimpOrientationType flip_type,
+ gdouble axis,
+ gboolean clip_result,
+ GimpProgress *progress);
#endif /* __GIMP_IMAGE_FLIP_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]