[gimp] Bug 768726 - Canvas rotation, flipping applied in image space ...
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 768726 - Canvas rotation, flipping applied in image space ...
- Date: Thu, 21 Jul 2016 21:32:04 +0000 (UTC)
commit 3fbd47eb2ea4d34c31b2f8840eab1d7b7f4ea0b5
Author: Ell <ell_se yahoo com>
Date: Sat Jul 16 21:23:02 2016 +0000
Bug 768726 - Canvas rotation, flipping applied in image space ...
... not screen space
Flip and rotate the canvas around the center of the viewport,
instead of the center of the image. Scroll the display as
necessary to keep the center of the viewport fixed during
these operations. This applies to both the corresponding
menu items, and rotation using Shift+Space.
Likewise, flip the canvas across the designated axis in
screen space, instead of image space. Rotate the display as
necessary, such that the reflection appears to happen in
screen space, regardless of the current rotation angle of the
canvas.
app/display/gimpdisplayshell-rotate.c | 128 +++++++++++++++++++++++---------
1 files changed, 92 insertions(+), 36 deletions(-)
---
diff --git a/app/display/gimpdisplayshell-rotate.c b/app/display/gimpdisplayshell-rotate.c
index efc7f6f..be1a45e 100644
--- a/app/display/gimpdisplayshell-rotate.c
+++ b/app/display/gimpdisplayshell-rotate.c
@@ -17,6 +17,8 @@
#include "config.h"
+#include <math.h>
+
#include <gegl.h>
#include <gtk/gtk.h>
@@ -29,6 +31,18 @@
#include "gimpdisplayshell-expose.h"
#include "gimpdisplayshell-rotate.h"
#include "gimpdisplayshell-scale.h"
+#include "gimpdisplayshell-scroll.h"
+#include "gimpdisplayshell-transform.h"
+
+
+/* local function prototypes */
+
+static void gimp_display_shell_save_viewport_center (GimpDisplayShell *shell,
+ gdouble *x,
+ gdouble *y);
+static void gimp_display_shell_restore_viewport_center (GimpDisplayShell *shell,
+ gdouble x,
+ gdouble y);
/* public functions */
@@ -40,13 +54,35 @@ gimp_display_shell_flip (GimpDisplayShell *shell,
{
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+ flip_horizontally = flip_horizontally ? TRUE : FALSE;
+ flip_vertically = flip_vertically ? TRUE : FALSE;
+
if (flip_horizontally != shell->flip_horizontally ||
flip_vertically != shell->flip_vertically)
{
- shell->flip_horizontally = flip_horizontally ? TRUE : FALSE;
- shell->flip_vertically = flip_vertically ? TRUE : FALSE;
+ gdouble cx, cy;
+
+ /* Maintain the current center of the viewport. */
+ gimp_display_shell_save_viewport_center (shell, &cx, &cy);
+
+ /* Adjust the rotation angle so that the image gets reflected across the
+ * horizontal, and/or vertical, axes in screen space, regardless of the
+ * current rotation.
+ */
+ if (flip_horizontally == shell->flip_horizontally ||
+ flip_vertically == shell->flip_vertically)
+ {
+ if (shell->rotate_angle != 0.0)
+ shell->rotate_angle = 360.0 - shell->rotate_angle;
+ }
+
+ shell->flip_horizontally = flip_horizontally;
+ shell->flip_vertically = flip_vertically;
gimp_display_shell_rotated (shell);
+
+ gimp_display_shell_restore_viewport_center (shell, cx, cy);
+
gimp_display_shell_expose_full (shell);
}
}
@@ -64,19 +100,26 @@ void
gimp_display_shell_rotate_to (GimpDisplayShell *shell,
gdouble value)
{
+ gdouble cx, cy;
+
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
- while (value < 0.0)
- value += 360;
+ /* Maintain the current center of the viewport. */
+ gimp_display_shell_save_viewport_center (shell, &cx, &cy);
- while (value >= 360.0)
- value -= 360;
+ /* Make sure the angle is within the range [0, 360). */
+ value = fmod (value, 360.0);
+ if (value < 0.0)
+ value += 360.0;
shell->rotate_angle = value;
gimp_display_shell_scroll_clamp_and_update (shell);
gimp_display_shell_rotated (shell);
+
+ gimp_display_shell_restore_viewport_center (shell, cx, cy);
+
gimp_display_shell_expose_full (shell);
}
@@ -88,46 +131,32 @@ gimp_display_shell_rotate_drag (GimpDisplayShell *shell,
gdouble cur_y,
gboolean constrain)
{
- gint image_width, image_height;
- gdouble px, py;
- gdouble x1, y1, x2, y2;
- gdouble angle1, angle2, angle;
+ gdouble pivot_x, pivot_y;
+ gdouble src_x, src_y, src_angle;
+ gdouble dest_x, dest_y, dest_angle;
+ gdouble delta_angle;
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
- gimp_display_shell_scale_get_image_size (shell,
- &image_width, &image_height);
-
- px = -shell->offset_x + image_width / 2;
- py = -shell->offset_y + image_height / 2;
+ /* Rotate the image around the center of the viewport. */
+ pivot_x = shell->disp_width / 2.0;
+ pivot_y = shell->disp_height / 2.0;
- x1 = cur_x - px;
- x2 = last_x - px;
- y1 = py - cur_y;
- y2 = py - last_y;
+ src_x = last_x - pivot_x;
+ src_y = last_y - pivot_y;
+ src_angle = atan2 (src_y, src_x);
- /* find the first angle */
- angle1 = atan2 (y1, x1);
+ dest_x = cur_x - pivot_x;
+ dest_y = cur_y - pivot_y;
+ dest_angle = atan2 (dest_y, dest_x);
- /* find the angle */
- angle2 = atan2 (y2, x2);
+ delta_angle = dest_angle - src_angle;
- angle = angle2 - angle1;
-
- if (angle > G_PI || angle < -G_PI)
- angle = angle2 - ((angle1 < 0) ? 2.0 * G_PI + angle1 : angle1 - 2.0 * G_PI);
-
- shell->rotate_drag_angle += (angle * 180.0 / G_PI);
-
- if (shell->rotate_drag_angle < 0.0)
- shell->rotate_drag_angle += 360;
-
- if (shell->rotate_drag_angle >= 360.0)
- shell->rotate_drag_angle -= 360;
+ shell->rotate_drag_angle += 180.0 * delta_angle / G_PI;
gimp_display_shell_rotate_to (shell,
constrain ?
- (gint) shell->rotate_drag_angle / 15 * 15 :
+ RINT (shell->rotate_drag_angle / 15.0) * 15.0 :
shell->rotate_drag_angle);
}
@@ -179,3 +208,30 @@ gimp_display_shell_rotate_update_transform (GimpDisplayShell *shell)
shell->rotate_untransform = NULL;
}
}
+
+
+/* private functions */
+
+static void
+gimp_display_shell_save_viewport_center (GimpDisplayShell *shell,
+ gdouble *x,
+ gdouble *y)
+{
+ gimp_display_shell_unrotate_xy_f (shell,
+ shell->disp_width / 2,
+ shell->disp_height / 2,
+ x, y);
+}
+
+static void
+gimp_display_shell_restore_viewport_center (GimpDisplayShell *shell,
+ gdouble x,
+ gdouble y)
+{
+ gimp_display_shell_rotate_xy_f (shell, x, y, &x, &y);
+
+ x += shell->offset_x - shell->disp_width / 2;
+ y += shell->offset_y - shell->disp_height / 2;
+
+ gimp_display_shell_scroll_set_offset (shell, RINT (x), RINT (y));
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]