[tools 1/3] winetest/build-patterns: Take the distance between key colors into account.

Francois Gouget fgouget at codeweavers.com
Tue Aug 31 08:39:59 CDT 2021


To get a uniform color gradient, fewer colors should be squeezed between
close key colors than between distant ones.

Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
There are two issues with the current pattern colors:
* We have lots of blue/green colors which are hard to distinguish.
* We have few colors in the yellow/red range despite those being easier 
  to distinguish.

This is in part because we don't take the space between key colors into 
account, but mainly because interpolating in the RGB colorspace does not 
yield good results.

So the goal of this patchset is to make it easier to distinguish the 
pattern colors by fixing these two issues.
---
 winetest/build-patterns | 35 ++++++++++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/winetest/build-patterns b/winetest/build-patterns
index 2ee5d5bdd..ff72516f6 100755
--- a/winetest/build-patterns
+++ b/winetest/build-patterns
@@ -872,6 +872,13 @@ sub blend($$$)
     return $r;
 }
 
+sub distance($$)
+{
+    my ($a, $b) = @_;
+    return sqrt(($b->[0] - $a->[0])**2 +
+                ($b->[1] - $a->[1])**2 +
+                ($b->[2] - $a->[2])**2);
+}
 
 # Use colors to differentiate the set values. Each unique value is assigned
 # a color (in HTML format) picked along a series of gradients passing by the
@@ -897,19 +904,33 @@ sub compute_set_colors($)
         # when many colors are needed.
         $keycolors[0] = [0, 179, 179] if ($count > 10);
 
+        # Compute the total length of the path traced by the key colors through
+        # the colorspace. This is necessary so the gradient remains uniform
+        # even if two key colors are close to each other. This does assume that
+        # the path does not zigzag too much: (0,0,0)->(255,0,0)->(1,0,0) cannot
+        # produce a meaningful gradient.
+        my @keypos = (0);
+        for (my $i = 1; $i < @keycolors; $i++)
+        {
+            my $d = distance($keycolors[$i - 1], $keycolors[$i]);
+            $keypos[$i] = $keypos[$i - 1] + $d;
+        }
+
         my $k = 0;
-        my ($start, $end) = (-1, 0);
         for (0..$count-1)
         {
-            while (!$end or $_ > $end)
+            # Compute the position of the current item on the path
+            my $pos = $_ / ($count - 1) * $keypos[-1];
+
+            # Figure out which segment of the path this corresponds to
+            while ($pos > $keypos[$k+1] and $k+1 < @keycolors-1)
             {
                 $k++;
-                $start = $end;
-                $end = ($count-1) * $k / (@keycolors-1);
             }
-            $set->{$values[$_]} = color2html(blend(($_-$start)/($end-$start),
-                                                   $keycolors[$k-1],
-                                                   $keycolors[$k]));
+
+            # And blend
+            my $Rgb = blend(($pos - $keypos[$k]) / ($keypos[$k+1] - $keypos[$k]), $keycolors[$k], $keycolors[$k+1]);
+            $set->{$values[$_]} = color2html($Rgb);
         }
     }
 }
-- 
2.30.2




More information about the wine-devel mailing list