[gimp] app: make rulers rotation aware



commit 5bdb20c8397e8422b307e7bf7b80c94f8405017f
Author: Ell <ell_se yahoo com>
Date:   Tue Jul 19 15:47:59 2016 +0000

    app: make rulers rotation aware
    
    Place the rulers' origin at the top-left corner of the canvas
    (screen space) bounding box, and set their scale to the image-
    space scale along the screen-space horizontal/vertical directions
    (in other words, measuring a distance using the rulers should
    give the same results as the measure tool; note that rotation
    comes into play here only when the horizontal and vertical
    image or screen resolutions are different, since otherwise the
    scale is direction invariant.)
    
    Make scrollbar step match ruler step under the new behavior.

 app/display/gimpdisplayshell-rulers.c     |   62 +++++++++++++++++++---------
 app/display/gimpdisplayshell-scale.c      |   35 ++++++++++++++++
 app/display/gimpdisplayshell-scale.h      |    3 +
 app/display/gimpdisplayshell-scrollbars.c |   12 ++++--
 4 files changed, 88 insertions(+), 24 deletions(-)
---
diff --git a/app/display/gimpdisplayshell-rulers.c b/app/display/gimpdisplayshell-rulers.c
index bebf46f..610a2ae 100644
--- a/app/display/gimpdisplayshell-rulers.c
+++ b/app/display/gimpdisplayshell-rulers.c
@@ -17,10 +17,13 @@
 
 #include "config.h"
 
+#include <math.h>
+
 #include <gegl.h>
 #include <gtk/gtk.h>
 
 #include "libgimpbase/gimpbase.h"
+#include "libgimpmath/gimpmath.h"
 #include "libgimpwidgets/gimpwidgets.h"
 
 #include "display-types.h"
@@ -30,6 +33,7 @@
 #include "gimpdisplay.h"
 #include "gimpdisplayshell.h"
 #include "gimpdisplayshell-rulers.h"
+#include "gimpdisplayshell-scale.h"
 
 
 /**
@@ -43,6 +47,10 @@ gimp_display_shell_rulers_update (GimpDisplayShell *shell)
   GimpImage *image;
   gint       image_width;
   gint       image_height;
+  gdouble    offset_x     = 0.0;
+  gdouble    offset_y     = 0.0;
+  gdouble    scale_x      = 1.0;
+  gdouble    scale_y      = 1.0;
   gdouble    resolution_x = 1.0;
   gdouble    resolution_y = 1.0;
   gdouble    horizontal_lower;
@@ -59,10 +67,37 @@ gimp_display_shell_rulers_update (GimpDisplayShell *shell)
 
   if (image)
     {
-      image_width  = gimp_image_get_width  (image);
-      image_height = gimp_image_get_height (image);
+      gint    image_x, image_y;
+      gdouble res_x, res_y;
+      gdouble cos_a, sin_a;
+
+      gimp_display_shell_scale_get_image_bounds (shell,
+                                                 &image_x, &image_y,
+                                                 &image_width, &image_height);
+
+      gimp_display_shell_get_rotated_scale (shell, &scale_x, &scale_y);
+
+      image_width  /= scale_x;
+      image_height /= scale_y;
 
-      gimp_image_get_resolution (image, &resolution_x, &resolution_y);
+      offset_x = shell->offset_x - image_x;
+      offset_y = shell->offset_y - image_y;
+
+      gimp_image_get_resolution (image, &res_x, &res_y);
+
+      cos_a = cos (G_PI * shell->rotate_angle / 180.0);
+      sin_a = sin (G_PI * shell->rotate_angle / 180.0);
+
+      if (shell->dot_for_dot)
+        {
+          resolution_x = 1.0 / sqrt (SQR (cos_a / res_x) + SQR (sin_a / res_y));
+          resolution_y = 1.0 / sqrt (SQR (cos_a / res_y) + SQR (sin_a / res_x));
+        }
+      else
+        {
+          resolution_x = sqrt (SQR (res_x * cos_a) + SQR (res_y * sin_a));
+          resolution_y = sqrt (SQR (res_y * cos_a) + SQR (res_x * sin_a));
+        }
     }
   else
     {
@@ -70,7 +105,6 @@ gimp_display_shell_rulers_update (GimpDisplayShell *shell)
       image_height = shell->disp_height;
     }
 
-
   /* Initialize values */
 
   horizontal_lower = 0;
@@ -78,8 +112,7 @@ gimp_display_shell_rulers_update (GimpDisplayShell *shell)
 
   if (image)
     {
-      horizontal_upper    = gimp_pixels_to_units (FUNSCALEX (shell,
-                                                             shell->disp_width),
+      horizontal_upper    = gimp_pixels_to_units (shell->disp_width / scale_x,
                                                   shell->unit,
                                                   resolution_x);
       horizontal_max_size = gimp_pixels_to_units (MAX (image_width,
@@ -87,8 +120,7 @@ gimp_display_shell_rulers_update (GimpDisplayShell *shell)
                                                   shell->unit,
                                                   resolution_x);
 
-      vertical_upper      = gimp_pixels_to_units (FUNSCALEY (shell,
-                                                             shell->disp_height),
+      vertical_upper      = gimp_pixels_to_units (shell->disp_height / scale_y,
                                                   shell->unit,
                                                   resolution_y);
       vertical_max_size   = gimp_pixels_to_units (MAX (image_width,
@@ -110,18 +142,8 @@ gimp_display_shell_rulers_update (GimpDisplayShell *shell)
 
   if (image)
     {
-      gdouble offset_x;
-      gdouble offset_y;
-
-      offset_x = gimp_pixels_to_units (FUNSCALEX (shell,
-                                                  (gdouble) shell->offset_x),
-                                       shell->unit,
-                                       resolution_x);
-
-      offset_y = gimp_pixels_to_units (FUNSCALEX (shell,
-                                                  (gdouble) shell->offset_y),
-                                       shell->unit,
-                                       resolution_y);
+      offset_x *= horizontal_upper / shell->disp_width;
+      offset_y *= vertical_upper   / shell->disp_height;
 
       horizontal_lower += offset_x;
       horizontal_upper += offset_x;
diff --git a/app/display/gimpdisplayshell-scale.c b/app/display/gimpdisplayshell-scale.c
index 3ca4ce1..afdfb7d 100644
--- a/app/display/gimpdisplayshell-scale.c
+++ b/app/display/gimpdisplayshell-scale.c
@@ -765,6 +765,41 @@ gimp_display_shell_set_initial_scale (GimpDisplayShell *shell,
 }
 
 /**
+ * gimp_display_shell_get_rotated_scale:
+ * @shell:   the #GimpDisplayShell
+ * @scale_x: horizontal scale output
+ * @scale_y: vertical scale output
+ *
+ * Returns the screen space horizontal and vertical scaling
+ * factors, taking rotation into account.
+ **/
+void
+gimp_display_shell_get_rotated_scale (GimpDisplayShell *shell,
+                                      gdouble          *scale_x,
+                                      gdouble          *scale_y)
+{
+  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+
+  if (shell->rotate_angle == 0.0)
+    {
+      if (scale_x) *scale_x = shell->scale_x;
+      if (scale_y) *scale_y = shell->scale_y;
+    }
+  else
+    {
+      gdouble a     = G_PI * shell->rotate_angle / 180.0;
+      gdouble cos_a = cos (a);
+      gdouble sin_a = sin (a);
+
+      if (scale_x) *scale_x = 1.0 / sqrt (SQR (cos_a / shell->scale_x) +
+                                          SQR (sin_a / shell->scale_y));
+
+      if (scale_y) *scale_y = 1.0 / sqrt (SQR (cos_a / shell->scale_y) +
+                                          SQR (sin_a / shell->scale_x));
+    }
+}
+
+/**
  * gimp_display_shell_push_zoom_focus_pointer_pos:
  * @shell:
  * @x:
diff --git a/app/display/gimpdisplayshell-scale.h b/app/display/gimpdisplayshell-scale.h
index 4e55f26..836fbac 100644
--- a/app/display/gimpdisplayshell-scale.h
+++ b/app/display/gimpdisplayshell-scale.h
@@ -70,6 +70,9 @@ void     gimp_display_shell_set_initial_scale        (GimpDisplayShell *shell,
                                                       gint             *display_width,
                                                       gint             *display_height);
 
+void     gimp_display_shell_get_rotated_scale        (GimpDisplayShell *shell,
+                                                      gdouble          *scale_x,
+                                                      gdouble          *scale_y);
 
 /*  debug API for testing  */
 
diff --git a/app/display/gimpdisplayshell-scrollbars.c b/app/display/gimpdisplayshell-scrollbars.c
index 34c461b..67e9147 100644
--- a/app/display/gimpdisplayshell-scrollbars.c
+++ b/app/display/gimpdisplayshell-scrollbars.c
@@ -95,6 +95,7 @@ gimp_display_shell_scrollbars_setup_horizontal (GimpDisplayShell *shell,
   gint    bounds_width;
   gdouble lower;
   gdouble upper;
+  gdouble scale_x;
 
   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
 
@@ -114,11 +115,12 @@ gimp_display_shell_scrollbars_setup_horizontal (GimpDisplayShell *shell,
   lower = MIN (value, bounds_x);
   upper = MAX (value + shell->disp_width, bounds_x + bounds_width);
 
+  gimp_display_shell_get_rotated_scale (shell, &scale_x, NULL);
+
   g_object_set (shell->hsbdata,
                 "lower",          lower,
                 "upper",          upper,
-                "step-increment", (gdouble) MAX (shell->scale_x,
-                                                 MINIMUM_STEP_AMOUNT),
+                "step-increment", (gdouble) MAX (scale_x, MINIMUM_STEP_AMOUNT),
                 NULL);
 }
 
@@ -137,6 +139,7 @@ gimp_display_shell_scrollbars_setup_vertical (GimpDisplayShell *shell,
   gint    bounds_height;
   gdouble lower;
   gdouble upper;
+  gdouble scale_y;
 
   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
 
@@ -156,11 +159,12 @@ gimp_display_shell_scrollbars_setup_vertical (GimpDisplayShell *shell,
   lower = MIN (value, bounds_y);
   upper = MAX (value + shell->disp_height, bounds_y + bounds_height);
 
+  gimp_display_shell_get_rotated_scale (shell, NULL, &scale_y);
+
   g_object_set (shell->vsbdata,
                 "lower",          lower,
                 "upper",          upper,
-                "step-increment", (gdouble) MAX (shell->scale_y,
-                                                 MINIMUM_STEP_AMOUNT),
+                "step-increment", (gdouble) MAX (scale_y, MINIMUM_STEP_AMOUNT),
                 NULL);
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]