emacs-diffs
[Top][All Lists]
Advanced

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

master 7e8c1a6: Make color-distance symmetric and more accurate


From: Mattias Engdegård
Subject: master 7e8c1a6: Make color-distance symmetric and more accurate
Date: Wed, 3 Jun 2020 15:31:35 -0400 (EDT)

branch: master
commit 7e8c1a671872ef8e45057f25912594cf548639ab
Author: Mattias Engdegård <mattiase@acm.org>
Commit: Mattias Engdegård <mattiase@acm.org>

    Make color-distance symmetric and more accurate
    
    * src/xfaces.c (color_distance): Don't throw away the low 8 bits of
    the colours, and make the function symmetric (bug41544)
    (Fcolor_distance): Add caution about this not being a true metric.
    * test/src/xfaces-tests.el: New file.
---
 src/xfaces.c             | 24 +++++++++++++-----------
 test/src/xfaces-tests.el | 27 +++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/src/xfaces.c b/src/xfaces.c
index 7d7aff9..cf15528 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -4356,15 +4356,15 @@ color_distance (Emacs_Color *x, Emacs_Color *y)
 
      See <https://www.compuphase.com/cmetric.htm> for more info.  */
 
-  long r = (x->red   - y->red)   >> 8;
-  long g = (x->green - y->green) >> 8;
-  long b = (x->blue  - y->blue)  >> 8;
-  long r_mean = (x->red + y->red) >> 9;
-
-  return
-    (((512 + r_mean) * r * r) >> 8)
-    + 4 * g * g
-    + (((767 - r_mean) * b * b) >> 8);
+  long long r = x->red   - y->red;
+  long long g = x->green - y->green;
+  long long b = x->blue  - y->blue;
+  long long r_mean = (x->red + y->red) >> 1;
+
+  return (((((2 * 65536 + r_mean) * r * r) >> 16)
+           + 4 * g * g
+           + (((2 * 65536 + 65535 - r_mean) * b * b) >> 16))
+          >> 16);
 }
 
 
@@ -4374,7 +4374,9 @@ COLOR1 and COLOR2 may be either strings containing the 
color name,
 or lists of the form (RED GREEN BLUE), each in the range 0 to 65535 inclusive.
 If FRAME is unspecified or nil, the current frame is used.
 If METRIC is specified, it should be a function that accepts
-two lists of the form (RED GREEN BLUE) aforementioned. */)
+two lists of the form (RED GREEN BLUE) aforementioned.
+Despite the name, this is not a true distance metric as it does not satisfy
+the triangle inequality.  */)
   (Lisp_Object color1, Lisp_Object color2, Lisp_Object frame,
    Lisp_Object metric)
 {
@@ -4931,7 +4933,7 @@ DEFUN ("face-attributes-as-vector", 
Fface_attributes_as_vector,
 
 /* If the distance (as returned by color_distance) between two colors is
    less than this, then they are considered the same, for determining
-   whether a color is supported or not.  The range of values is 0-65535.  */
+   whether a color is supported or not.  */
 
 #define TTY_SAME_COLOR_THRESHOLD  10000
 
diff --git a/test/src/xfaces-tests.el b/test/src/xfaces-tests.el
new file mode 100644
index 0000000..f08a87a
--- /dev/null
+++ b/test/src/xfaces-tests.el
@@ -0,0 +1,27 @@
+;;; xfaces-tests.el --- tests for xfaces.c           -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+(require 'ert)
+
+(ert-deftest xfaces-color-distance ()
+  ;; Check symmetry (bug#51455).
+  (should (equal (color-distance "#222222" "#ffffff")
+                 (color-distance "#ffffff" "#222222"))))
+
+(provide 'xfaces-tests)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]