[gimp] app: use absolute offset for filter-tool split-preview guide position



commit 214936e8c6d14e17249d06d1b02aaf53b18f73b2
Author: Ell <ell_se yahoo com>
Date:   Thu Jun 11 20:25:55 2020 +0300

    app: use absolute offset for filter-tool split-preview guide position
    
    In GimpDrawableFilter and GimpFilterTool, use an absolute offset
    for the split-preview guide position, instead of storing it as a
    fraction of the drawable's width/height.  The latter could
    introduce rounding error, which would result in wrong coordinates
    when converted back to an absolute offset.

 app/core/gimpdrawablefilter.c | 47 +++++++++++++--------
 app/core/gimpdrawablefilter.h |  2 +-
 app/tools/gimpfilteroptions.c | 14 +++----
 app/tools/gimpfilteroptions.h |  2 +-
 app/tools/gimpfiltertool.c    | 97 +++++++++++++++++++------------------------
 5 files changed, 82 insertions(+), 80 deletions(-)
---
diff --git a/app/core/gimpdrawablefilter.c b/app/core/gimpdrawablefilter.c
index 032b25d08f..8b0ab1ccff 100644
--- a/app/core/gimpdrawablefilter.c
+++ b/app/core/gimpdrawablefilter.c
@@ -71,7 +71,7 @@ struct _GimpDrawableFilter
   gboolean                preview_enabled;
   gboolean                preview_split_enabled;
   GimpAlignmentType       preview_split_alignment;
-  gdouble                 preview_split_position;
+  gint                    preview_split_position;
   gdouble                 opacity;
   GimpLayerMode           paint_mode;
   GimpLayerColorSpace     blend_space;
@@ -107,7 +107,7 @@ static void       gimp_drawable_filter_sync_crop             (GimpDrawableFilter
                                                               const GeglRectangle *old_crop_rect,
                                                               gboolean             old_preview_split_enabled,
                                                               GimpAlignmentType    
old_preview_split_alignment,
-                                                              gdouble              
old_preview_split_position,
+                                                              gint                 
old_preview_split_position,
                                                               gboolean             update);
 static void       gimp_drawable_filter_sync_opacity          (GimpDrawableFilter  *filter);
 static void       gimp_drawable_filter_sync_mode             (GimpDrawableFilter  *filter);
@@ -171,7 +171,7 @@ gimp_drawable_filter_init (GimpDrawableFilter *drawable_filter)
   drawable_filter->preview_enabled         = TRUE;
   drawable_filter->preview_split_enabled   = FALSE;
   drawable_filter->preview_split_alignment = GIMP_ALIGN_LEFT;
-  drawable_filter->preview_split_position  = 1.0;
+  drawable_filter->preview_split_position  = 0;
   drawable_filter->opacity                 = GIMP_OPACITY_OPAQUE;
   drawable_filter->paint_mode              = GIMP_LAYER_MODE_REPLACE;
   drawable_filter->blend_space             = GIMP_LAYER_COLOR_SPACE_AUTO;
@@ -387,15 +387,33 @@ void
 gimp_drawable_filter_set_preview_split (GimpDrawableFilter  *filter,
                                         gboolean             enabled,
                                         GimpAlignmentType    alignment,
-                                        gdouble              position)
+                                        gint                 position)
 {
+  GimpItem *item;
+
   g_return_if_fail (GIMP_IS_DRAWABLE_FILTER (filter));
   g_return_if_fail (alignment == GIMP_ALIGN_LEFT  ||
                     alignment == GIMP_ALIGN_RIGHT ||
                     alignment == GIMP_ALIGN_TOP   ||
                     alignment == GIMP_ALIGN_BOTTOM);
 
-  position = CLAMP (position, 0.0, 1.0);
+  item = GIMP_ITEM (filter->drawable);
+
+  switch (alignment)
+    {
+    case GIMP_ALIGN_LEFT:
+    case GIMP_ALIGN_RIGHT:
+      position = CLAMP (position, 0, gimp_item_get_width (item));
+      break;
+
+    case GIMP_ALIGN_TOP:
+    case GIMP_ALIGN_BOTTOM:
+      position = CLAMP (position, 0, gimp_item_get_height (item));
+      break;
+
+    default:
+      g_return_if_reached ();
+    }
 
   if (enabled   != filter->preview_split_enabled   ||
       alignment != filter->preview_split_alignment ||
@@ -403,7 +421,7 @@ gimp_drawable_filter_set_preview_split (GimpDrawableFilter  *filter,
     {
       gboolean          old_enabled   = filter->preview_split_enabled;
       GimpAlignmentType old_alignment = filter->preview_split_alignment;
-      gdouble           old_position  = filter->preview_split_position;
+      gint              old_position  = filter->preview_split_position;
 
       filter->preview_split_enabled   = enabled;
       filter->preview_split_alignment = alignment;
@@ -742,20 +760,15 @@ gimp_drawable_filter_get_crop_rect (GimpDrawableFilter  *filter,
                                     const GeglRectangle *crop_rect,
                                     gboolean             preview_split_enabled,
                                     GimpAlignmentType    preview_split_alignment,
-                                    gdouble              preview_split_position,
+                                    gint                 preview_split_position,
                                     GeglRectangle       *rect)
 {
   GeglRectangle bounds;
-  gint          width;
-  gint          height;
   gint          x1, x2;
   gint          y1, y2;
 
   bounds = gegl_rectangle_infinite_plane ();
 
-  width  = gimp_item_get_width  (GIMP_ITEM (filter->drawable));
-  height = gimp_item_get_height (GIMP_ITEM (filter->drawable));
-
   x1 = bounds.x;
   x2 = bounds.x + bounds.width;
 
@@ -767,19 +780,19 @@ gimp_drawable_filter_get_crop_rect (GimpDrawableFilter  *filter,
       switch (preview_split_alignment)
         {
         case GIMP_ALIGN_LEFT:
-          x2 = width * preview_split_position;
+          x2 = preview_split_position;
           break;
 
         case GIMP_ALIGN_RIGHT:
-          x1 = width * preview_split_position;
+          x1 = preview_split_position;
           break;
 
         case GIMP_ALIGN_TOP:
-          y2 = height * preview_split_position;
+          y2 = preview_split_position;
           break;
 
         case GIMP_ALIGN_BOTTOM:
-          y1 = height * preview_split_position;
+          y1 = preview_split_position;
           break;
 
         default:
@@ -801,7 +814,7 @@ gimp_drawable_filter_sync_crop (GimpDrawableFilter  *filter,
                                 const GeglRectangle *old_crop_rect,
                                 gboolean             old_preview_split_enabled,
                                 GimpAlignmentType    old_preview_split_alignment,
-                                gdouble              old_preview_split_position,
+                                gint                 old_preview_split_position,
                                 gboolean             update)
 {
   GeglRectangle old_rect;
diff --git a/app/core/gimpdrawablefilter.h b/app/core/gimpdrawablefilter.h
index 7e68cc9a2d..d45b680bd1 100644
--- a/app/core/gimpdrawablefilter.h
+++ b/app/core/gimpdrawablefilter.h
@@ -72,7 +72,7 @@ void       gimp_drawable_filter_set_preview_split
                                                (GimpDrawableFilter  *filter,
                                                 gboolean             enabled,
                                                 GimpAlignmentType    alignment,
-                                                gdouble              split_position);
+                                                gint                 split_position);
 void       gimp_drawable_filter_set_opacity    (GimpDrawableFilter  *filter,
                                                 gdouble              opacity);
 void       gimp_drawable_filter_set_mode       (GimpDrawableFilter  *filter,
diff --git a/app/tools/gimpfilteroptions.c b/app/tools/gimpfilteroptions.c
index c78d6d046d..2a8f5cd020 100644
--- a/app/tools/gimpfilteroptions.c
+++ b/app/tools/gimpfilteroptions.c
@@ -91,11 +91,11 @@ gimp_filter_options_class_init (GimpFilterOptionsClass *klass)
                                                       G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (object_class, PROP_PREVIEW_SPLIT_POSITION,
-                                   g_param_spec_double ("preview-split-position",
-                                                        NULL, NULL,
-                                                        0.0, 1.0, 0.5,
-                                                        GIMP_PARAM_READWRITE |
-                                                        G_PARAM_CONSTRUCT));
+                                   g_param_spec_int ("preview-split-position",
+                                                     NULL, NULL,
+                                                     G_MININT, G_MAXINT, 0,
+                                                     GIMP_PARAM_READWRITE |
+                                                     G_PARAM_CONSTRUCT));
 
   GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CONTROLLER,
                             "controller",
@@ -145,7 +145,7 @@ gimp_filter_options_set_property (GObject      *object,
       break;
 
     case PROP_PREVIEW_SPLIT_POSITION:
-      options->preview_split_position = g_value_get_double (value);
+      options->preview_split_position = g_value_get_int (value);
       break;
 
     case PROP_CONTROLLER:
@@ -189,7 +189,7 @@ gimp_filter_options_get_property (GObject    *object,
       break;
 
     case PROP_PREVIEW_SPLIT_POSITION:
-      g_value_set_double (value, options->preview_split_position);
+      g_value_set_int (value, options->preview_split_position);
       break;
 
     case PROP_CONTROLLER:
diff --git a/app/tools/gimpfilteroptions.h b/app/tools/gimpfilteroptions.h
index 04b18217f2..5ae9192ae1 100644
--- a/app/tools/gimpfilteroptions.h
+++ b/app/tools/gimpfilteroptions.h
@@ -39,7 +39,7 @@ struct _GimpFilterOptions
   gboolean           preview;
   gboolean           preview_split;
   GimpAlignmentType  preview_split_alignment;
-  gdouble            preview_split_position;
+  gint               preview_split_position;
   gboolean           controller;
 
   gboolean           blending_options_expanded;
diff --git a/app/tools/gimpfiltertool.c b/app/tools/gimpfiltertool.c
index db877673b1..9c7a7bfde5 100644
--- a/app/tools/gimpfiltertool.c
+++ b/app/tools/gimpfiltertool.c
@@ -722,40 +722,38 @@ gimp_filter_tool_options_notify (GimpTool         *tool,
           GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
           GimpItem         *item  = GIMP_ITEM (tool->drawables->data);
           gint              x, y, width, height;
+          gint              position;
 
           gimp_display_shell_untransform_viewport (shell, TRUE,
                                                    &x, &y, &width, &height);
 
-          if (gimp_rectangle_intersect (gimp_item_get_offset_x (item),
-                                        gimp_item_get_offset_y (item),
-                                        gimp_item_get_width  (item),
-                                        gimp_item_get_height (item),
-                                        x, y, width, height,
-                                        &x, &y, &width, &height))
+          if (! gimp_rectangle_intersect (gimp_item_get_offset_x (item),
+                                          gimp_item_get_offset_y (item),
+                                          gimp_item_get_width  (item),
+                                          gimp_item_get_height (item),
+                                          x, y, width, height,
+                                          &x, &y, &width, &height))
             {
-              gdouble position;
-
-              if (filter_options->preview_split_alignment == GIMP_ALIGN_LEFT ||
-                  filter_options->preview_split_alignment == GIMP_ALIGN_RIGHT)
-                {
-                  position = ((gdouble) ((x + width / 2) -
-                                         gimp_item_get_offset_x (item)) /
-                              (gdouble) gimp_item_get_width (item));
-
-
-                }
-              else
-                {
-                  position = ((gdouble) ((y + height / 2) -
-                                         gimp_item_get_offset_y (item)) /
-                              (gdouble) gimp_item_get_height (item));
-                }
-
-              g_object_set (
-                options,
-                "preview-split-position", CLAMP (position, 0.0, 1.0),
-                NULL);
+              x      = gimp_item_get_offset_x (item);
+              y      = gimp_item_get_offset_y (item);
+              width  = gimp_item_get_width    (item);
+              height = gimp_item_get_height   (item);
+            }
+
+          if (filter_options->preview_split_alignment == GIMP_ALIGN_LEFT ||
+              filter_options->preview_split_alignment == GIMP_ALIGN_RIGHT)
+            {
+              position = (x + width  / 2) - gimp_item_get_offset_x (item);
+            }
+          else
+            {
+              position = (y + height / 2) - gimp_item_get_offset_y (item);
             }
+
+          g_object_set (
+            options,
+            "preview-split-position", position,
+            NULL);
         }
 
       gimp_filter_tool_update_filter (filter_tool);
@@ -1365,18 +1363,14 @@ gimp_filter_tool_add_guide (GimpFilterTool *filter_tool)
       options->preview_split_alignment == GIMP_ALIGN_RIGHT)
     {
       orientation = GIMP_ORIENTATION_VERTICAL;
-
-      position = (gimp_item_get_offset_x (item) +
-                  gimp_item_get_width (item) *
-                  options->preview_split_position);
+      position    = gimp_item_get_offset_x (item) +
+                    options->preview_split_position;
     }
   else
     {
       orientation = GIMP_ORIENTATION_HORIZONTAL;
-
-      position = (gimp_item_get_offset_y (item) +
-                  gimp_item_get_height (item) *
-                  options->preview_split_position);
+      position    = gimp_item_get_offset_y (item) +
+                    options->preview_split_position;
     }
 
   filter_tool->preview_guide =
@@ -1428,18 +1422,14 @@ gimp_filter_tool_move_guide (GimpFilterTool *filter_tool)
       options->preview_split_alignment == GIMP_ALIGN_RIGHT)
     {
       orientation = GIMP_ORIENTATION_VERTICAL;
-
-      position = (gimp_item_get_offset_x (item) +
-                  gimp_item_get_width (item) *
-                  options->preview_split_position);
+      position    = gimp_item_get_offset_x (item) +
+                    options->preview_split_position;
     }
   else
     {
       orientation = GIMP_ORIENTATION_HORIZONTAL;
-
-      position = (gimp_item_get_offset_y (item) +
-                  gimp_item_get_height (item) *
-                  options->preview_split_position);
+      position    = gimp_item_get_offset_x (item) +
+                    options->preview_split_position;
     }
 
   if (orientation != gimp_guide_get_orientation (filter_tool->preview_guide) ||
@@ -1479,7 +1469,7 @@ gimp_filter_tool_guide_moved (GimpGuide        *guide,
   GimpTool          *tool    = GIMP_TOOL (filter_tool);
   GimpFilterOptions *options = GIMP_FILTER_TOOL_GET_OPTIONS (filter_tool);
   GimpItem          *item;
-  gdouble            position;
+  gint               position;
 
   g_return_if_fail (g_list_length (tool->drawables) == 1);
 
@@ -1488,19 +1478,19 @@ gimp_filter_tool_guide_moved (GimpGuide        *guide,
   if (options->preview_split_alignment == GIMP_ALIGN_LEFT ||
       options->preview_split_alignment == GIMP_ALIGN_RIGHT)
     {
-      position = ((gdouble) (gimp_guide_get_position (guide) -
-                             gimp_item_get_offset_x (item)) /
-                  (gdouble) gimp_item_get_width (item));
+      position = CLAMP (gimp_guide_get_position (guide) -
+                        gimp_item_get_offset_x (item),
+                        0, gimp_item_get_width (item));
     }
   else
     {
-      position = ((gdouble) (gimp_guide_get_position (guide) -
-                             gimp_item_get_offset_y (item)) /
-                  (gdouble) gimp_item_get_height (item));
+      position = CLAMP (gimp_guide_get_position (guide) -
+                        gimp_item_get_offset_y (item),
+                        0, gimp_item_get_height (item));
     }
 
   g_object_set (options,
-                "preview-split-position", CLAMP (position, 0.0, 1.0),
+                "preview-split-position", position,
                 NULL);
 }
 
@@ -1707,8 +1697,7 @@ gimp_filter_tool_get_operation (GimpFilterTool *filter_tool)
   g_free (operation_name);
 
   g_object_set (GIMP_FILTER_TOOL_GET_OPTIONS (filter_tool),
-                "preview-split",          FALSE,
-                "preview-split-position", 0.5,
+                "preview-split", FALSE,
                 NULL);
 
   g_signal_connect_object (filter_tool->config, "notify",


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