]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix bit rot in the color allocation code
authorPo Lu <luangruo@yahoo.com>
Fri, 4 Feb 2022 07:38:07 +0000 (15:38 +0800)
committerPo Lu <luangruo@yahoo.com>
Fri, 4 Feb 2022 07:38:07 +0000 (15:38 +0800)
* src/xterm.c (x_alloc_nearest_color_1): Reintroduce an older
version of the code that would try to allocate a "compromise
delta".

src/xterm.c

index 2e09c454b24d0304372aaa4c52eea6930ac6e16b..874baa20f8c7f460f79cea54f80b4f829ab5e82c 100644 (file)
@@ -3083,34 +3083,56 @@ x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color)
   if (rc == 0)
     {
       /* If we got to this point, the colormap is full, so we're going
-        to try to get the next closest color.  The algorithm used is
+        to try and get the next closest color.  The algorithm used is
         a least-squares matching, which is what X uses for closest
         color matching with StaticColor visuals.  */
-      int nearest, i;
-      int max_color_delta = 255;
-      int max_delta = 3 * max_color_delta;
-      int nearest_delta = max_delta + 1;
-      int ncells;
-      const XColor *cells = x_color_cells (dpy, &ncells);
-
-      for (nearest = i = 0; i < ncells; ++i)
-       {
-         int dred   = (color->red   >> 8) - (cells[i].red   >> 8);
-         int dgreen = (color->green >> 8) - (cells[i].green >> 8);
-         int dblue  = (color->blue  >> 8) - (cells[i].blue  >> 8);
-         int delta = dred * dred + dgreen * dgreen + dblue * dblue;
 
-         if (delta < nearest_delta)
+      const XColor *cells;
+      int no_cells;
+      int nearest;
+      long nearest_delta, trial_delta;
+      int x;
+      Status status;
+
+      cells = x_color_cells (dpy, &no_cells);
+
+      XQueryColors (dpy, cmap, cells, no_cells);
+      nearest = 0;
+      /* I'm assuming CSE so I'm not going to condense this. */
+      nearest_delta = ((((color->red >> 8) - (cells[0].red >> 8))
+                       * ((color->red >> 8) - (cells[0].red >> 8)))
+                      + (((color->green >> 8) - (cells[0].green >> 8))
+                         * ((color->green >> 8) - (cells[0].green >> 8)))
+                      + (((color->blue >> 8) - (cells[0].blue >> 8))
+                         * ((color->blue >> 8) - (cells[0].blue >> 8))));
+      for (x = 1; x < no_cells; x++)
+       {
+         trial_delta = ((((color->red >> 8) - (cells[x].red >> 8))
+                         * ((color->red >> 8) - (cells[x].red >> 8)))
+                        + (((color->green >> 8) - (cells[x].green >> 8))
+                           * ((color->green >> 8) - (cells[x].green >> 8)))
+                        + (((color->blue >> 8) - (cells[x].blue >> 8))
+                           * ((color->blue >> 8) - (cells[x].blue >> 8))));
+         if (trial_delta < nearest_delta)
            {
-             nearest = i;
-             nearest_delta = delta;
+             XColor temp;
+             temp.red = cells[x].red;
+             temp.green = cells[x].green;
+             temp.blue = cells[x].blue;
+             status = XAllocColor (dpy, cmap, &temp);
+             if (status)
+               {
+                 nearest = x;
+                 nearest_delta = trial_delta;
+               }
            }
        }
-
-      color->red   = cells[nearest].red;
+      color->red = cells[nearest].red;
       color->green = cells[nearest].green;
-      color->blue  = cells[nearest].blue;
-      rc = XAllocColor (dpy, cmap, color) != 0;
+      color->blue = cells[nearest].blue;
+      status = XAllocColor (dpy, cmap, color);
+
+      rc = status != 0;
     }
   else
     {