[gimp/wip/gradient-edit: 19/35] app: avoid NaN when expanding a 0-length gradient segment



commit 3b6bcb068b970f313f8e57a161a8c8ccd3c75dee
Author: Ell <ell_se yahoo com>
Date:   Tue Aug 1 13:39:01 2017 -0400

    app: avoid NaN when expanding a 0-length gradient segment
    
    When using gimp_gradient_segment_range_compress() do expand a 0-
    length segment, redistribute the range's endpoints and midpoints
    uniformly, rather than using the regular code path, which would
    result in NaN values.

 app/core/gimpgradient.c |   47 ++++++++++++++++++++++++++++++++++-------------
 1 files changed, 34 insertions(+), 13 deletions(-)
---
diff --git a/app/core/gimpgradient.c b/app/core/gimpgradient.c
index 7bddff0..e2ac92a 100644
--- a/app/core/gimpgradient.c
+++ b/app/core/gimpgradient.c
@@ -1182,7 +1182,6 @@ gimp_gradient_segment_range_compress (GimpGradient        *gradient,
                                       gdouble              new_r)
 {
   gdouble              orig_l, orig_r;
-  gdouble              scale;
   GimpGradientSegment *seg, *aseg;
 
   g_return_if_fail (GIMP_IS_GRADIENT (gradient));
@@ -1196,24 +1195,46 @@ gimp_gradient_segment_range_compress (GimpGradient        *gradient,
   orig_l = range_l->left;
   orig_r = range_r->right;
 
-  scale = (new_r - new_l) / (orig_r - orig_l);
+  if (orig_r - orig_l > EPSILON)
+    {
+      gdouble scale;
 
-  seg = range_l;
+      scale = (new_r - new_l) / (orig_r - orig_l);
 
-  do
+      seg = range_l;
+
+      do
+        {
+          if (seg->prev)
+            seg->left  = new_l + (seg->left - orig_l) * scale;
+          seg->middle  = new_l + (seg->middle - orig_l) * scale;
+          if (seg->next)
+            seg->right = new_l + (seg->right - orig_l) * scale;
+
+          /* Next */
+
+          aseg = seg;
+          seg  = seg->next;
+        }
+      while (aseg != range_r);
+    }
+  else
     {
-      if (seg->prev)
-        seg->left   = new_l + (seg->left - orig_l) * scale;
-      seg->middle = new_l + (seg->middle - orig_l) * scale;
-      if (seg->next)
-        seg->right  = new_l + (seg->right - orig_l) * scale;
+      gint n;
+      gint i;
 
-      /* Next */
+      n = gimp_gradient_segment_range_get_n_segments (gradient,
+                                                      range_l, range_r);
 
-      aseg = seg;
-      seg  = seg->next;
+      for (i = 0, seg = range_l; i < n; i++, seg = seg->next)
+        {
+          if (seg->prev)
+            seg->left  = new_l + (new_r - new_l) * (i + 0.0) / n;
+          seg->middle  = new_l + (new_r - new_l) * (i + 0.5) / n;;
+          if (seg->next)
+            seg->right = new_l + (new_r - new_l) * (i + 1.0) / n;
+        }
     }
-  while (aseg != range_r);
 
   gimp_data_thaw (GIMP_DATA (gradient));
 }


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