aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias EngdegÄrd2020-06-02 22:31:14 +0200
committerMattias EngdegÄrd2020-06-03 19:09:33 +0200
commit7e8c1a671872ef8e45057f25912594cf548639ab (patch)
tree26b930c5a722c0d07805f50fd9fc7a7cea51450a
parent74966904b081a246a171bc7d2374f5d51712ed91 (diff)
downloademacs-7e8c1a671872ef8e45057f25912594cf548639ab.tar.gz
emacs-7e8c1a671872ef8e45057f25912594cf548639ab.zip
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.
-rw-r--r--src/xfaces.c24
-rw-r--r--test/src/xfaces-tests.el27
2 files changed, 40 insertions, 11 deletions
diff --git a/src/xfaces.c b/src/xfaces.c
index 7d7aff95c11..cf155288bd1 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -4356,15 +4356,15 @@ color_distance (Emacs_Color *x, Emacs_Color *y)
4356 4356
4357 See <https://www.compuphase.com/cmetric.htm> for more info. */ 4357 See <https://www.compuphase.com/cmetric.htm> for more info. */
4358 4358
4359 long r = (x->red - y->red) >> 8; 4359 long long r = x->red - y->red;
4360 long g = (x->green - y->green) >> 8; 4360 long long g = x->green - y->green;
4361 long b = (x->blue - y->blue) >> 8; 4361 long long b = x->blue - y->blue;
4362 long r_mean = (x->red + y->red) >> 9; 4362 long long r_mean = (x->red + y->red) >> 1;
4363 4363
4364 return 4364 return (((((2 * 65536 + r_mean) * r * r) >> 16)
4365 (((512 + r_mean) * r * r) >> 8) 4365 + 4 * g * g
4366 + 4 * g * g 4366 + (((2 * 65536 + 65535 - r_mean) * b * b) >> 16))
4367 + (((767 - r_mean) * b * b) >> 8); 4367 >> 16);
4368} 4368}
4369 4369
4370 4370
@@ -4374,7 +4374,9 @@ COLOR1 and COLOR2 may be either strings containing the color name,
4374or lists of the form (RED GREEN BLUE), each in the range 0 to 65535 inclusive. 4374or lists of the form (RED GREEN BLUE), each in the range 0 to 65535 inclusive.
4375If FRAME is unspecified or nil, the current frame is used. 4375If FRAME is unspecified or nil, the current frame is used.
4376If METRIC is specified, it should be a function that accepts 4376If METRIC is specified, it should be a function that accepts
4377two lists of the form (RED GREEN BLUE) aforementioned. */) 4377two lists of the form (RED GREEN BLUE) aforementioned.
4378Despite the name, this is not a true distance metric as it does not satisfy
4379the triangle inequality. */)
4378 (Lisp_Object color1, Lisp_Object color2, Lisp_Object frame, 4380 (Lisp_Object color1, Lisp_Object color2, Lisp_Object frame,
4379 Lisp_Object metric) 4381 Lisp_Object metric)
4380{ 4382{
@@ -4931,7 +4933,7 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
4931 4933
4932/* If the distance (as returned by color_distance) between two colors is 4934/* If the distance (as returned by color_distance) between two colors is
4933 less than this, then they are considered the same, for determining 4935 less than this, then they are considered the same, for determining
4934 whether a color is supported or not. The range of values is 0-65535. */ 4936 whether a color is supported or not. */
4935 4937
4936#define TTY_SAME_COLOR_THRESHOLD 10000 4938#define TTY_SAME_COLOR_THRESHOLD 10000
4937 4939
diff --git a/test/src/xfaces-tests.el b/test/src/xfaces-tests.el
new file mode 100644
index 00000000000..f08a87a518a
--- /dev/null
+++ b/test/src/xfaces-tests.el
@@ -0,0 +1,27 @@
1;;; xfaces-tests.el --- tests for xfaces.c -*- lexical-binding: t -*-
2
3;; Copyright (C) 2020 Free Software Foundation, Inc.
4
5;; This file is part of GNU Emacs.
6
7;; GNU Emacs is free software: you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation, either version 3 of the License, or
10;; (at your option) any later version.
11
12;; GNU Emacs is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
19
20(require 'ert)
21
22(ert-deftest xfaces-color-distance ()
23 ;; Check symmetry (bug#51455).
24 (should (equal (color-distance "#222222" "#ffffff")
25 (color-distance "#ffffff" "#222222"))))
26
27(provide 'xfaces-tests)