diff options
| author | Mattias EngdegÄrd | 2020-06-02 22:31:14 +0200 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2020-06-03 19:09:33 +0200 |
| commit | 7e8c1a671872ef8e45057f25912594cf548639ab (patch) | |
| tree | 26b930c5a722c0d07805f50fd9fc7a7cea51450a | |
| parent | 74966904b081a246a171bc7d2374f5d51712ed91 (diff) | |
| download | emacs-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.c | 24 | ||||
| -rw-r--r-- | test/src/xfaces-tests.el | 27 |
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, | |||
| 4374 | or lists of the form (RED GREEN BLUE), each in the range 0 to 65535 inclusive. | 4374 | or lists of the form (RED GREEN BLUE), each in the range 0 to 65535 inclusive. |
| 4375 | If FRAME is unspecified or nil, the current frame is used. | 4375 | If FRAME is unspecified or nil, the current frame is used. |
| 4376 | If METRIC is specified, it should be a function that accepts | 4376 | If METRIC is specified, it should be a function that accepts |
| 4377 | two lists of the form (RED GREEN BLUE) aforementioned. */) | 4377 | two lists of the form (RED GREEN BLUE) aforementioned. |
| 4378 | Despite the name, this is not a true distance metric as it does not satisfy | ||
| 4379 | the 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) | ||