From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Newsgroups: gmane.emacs.bugs Subject: bug#41544: 26.3; Possible incorrect results from color-distance Date: Mon, 8 Jun 2020 15:11:36 +0200 Message-ID: <1B0F31C8-1E11-4527-A053-DD2DE8235F58@acm.org> References: <5C4A633D-8222-4439-BE37-9B8674F1DA6D@acm.org> <87r1v2aat3.fsf@tromey.com> <9902865C-01B4-4E50-A433-DBC8B8311234@acm.org> <83tuzueogo.fsf@gnu.org> <6272275C-560C-4437-90F1-2A8294D27019@acm.org> <83o8q2elja.fsf@gnu.org> <83mu5mel4o.fsf@gnu.org> <77F1DDD3-A69F-40ED-902D-74986D5E6596@acm.org> <83y2p5cumz.fsf@gnu.org> <83blm0cjlz.fsf@gnu.org> <83367ccf8w.fsf@gnu.org> <624D7FB8-A836-4A7E-8895-47E867214504@acm.org> <83o8pyc4bq.fsf@gnu.org> <55D73CA5-1EFB-4B0A-8F8B-FDA1D39F51BF@acm.org> <835zc5bsut.fsf@gnu.org> <3BBCFDD4-C14D-4628-91CB-2A0456A96FC7@acm.org> <838sh0abzz.fsf@gnu.org> <83r1us8kw6.fsf@gnu.org> <020DE875-14A8-457A-9AE4-AA0925DB8997@acm.org> <83img48ffx.fsf@gnu.org> <83bllw82xt.fsf@gnu.org> Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.14\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_187E4226-740F-462B-93E6-2EE96E09EA79" Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="10197"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 41544@debbugs.gnu.org To: Eli Zaretskii , Simen =?UTF-8?Q?Heggest=C3=B8yl?= Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon Jun 08 15:12:11 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jiHZS-0002bJ-PY for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 08 Jun 2020 15:12:10 +0200 Original-Received: from localhost ([::1]:38990 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jiHZR-0002Qr-8t for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 08 Jun 2020 09:12:09 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:45878) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jiHZK-0002Qk-Af for bug-gnu-emacs@gnu.org; Mon, 08 Jun 2020 09:12:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:44624) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jiHZK-0002E1-1W for bug-gnu-emacs@gnu.org; Mon, 08 Jun 2020 09:12:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1jiHZJ-0001n3-Tt for bug-gnu-emacs@gnu.org; Mon, 08 Jun 2020 09:12:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 08 Jun 2020 13:12:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 41544 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 41544-submit@debbugs.gnu.org id=B41544.15916219056859 (code B ref 41544); Mon, 08 Jun 2020 13:12:01 +0000 Original-Received: (at 41544) by debbugs.gnu.org; 8 Jun 2020 13:11:45 +0000 Original-Received: from localhost ([127.0.0.1]:56170 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jiHZ3-0001mZ-28 for submit@debbugs.gnu.org; Mon, 08 Jun 2020 09:11:45 -0400 Original-Received: from mail234c50.megamailservers.eu ([91.136.10.244]:55206 helo=mail37c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jiHYz-0001mO-RB for 41544@debbugs.gnu.org; Mon, 08 Jun 2020 09:11:43 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1591621899; bh=NmwJ2Yo5SFpBkFUY1Do1nCgzhmUpM/Zg4YqT/itn+Xc=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=ooLhaEKsyIg6eZssOKUdKTNgvelBaTTlEJN8SMOTAQ/34bTqXtTYIVNJs9weTxD1Y DJRuLTGl0dtYWiFE0HgVRXkmH5V8Tt08I5LogN9Gbgi7TnlDlAkVwSGUESUeleKHJy AEny1vNqvmiI+JOjZeI2/o+3/iC/qYftL8fvvIIU= Feedback-ID: mattiase@acm.or Original-Received: from stanniol.lan (c-4e4ae655.032-75-73746f71.bbcust.telenor.se [85.230.74.78]) (authenticated bits=0) by mail37c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 058DBbqV011349; Mon, 8 Jun 2020 13:11:38 +0000 In-Reply-To: <83bllw82xt.fsf@gnu.org> X-Mailer: Apple Mail (2.3445.104.14) X-CTCH-RefID: str=0001.0A782F22.5EDE388A.008B:SCFSTAT68638221, ss=1, re=-4.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: -4.000 X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=bJNo382Z c=1 sm=1 tr=0 a=klNLuyVZdLUgl+K5Uafb2A==:117 a=klNLuyVZdLUgl+K5Uafb2A==:17 a=M51BFTxLslgA:10 a=mDV3o1hIAAAA:8 a=U-l7S3SeeBOyqu16-AIA:9 a=QEXdDO2ut3YA:10 a=LUiTdrM7ar1z_bhPKtoA:9 a=B2y7HmGcmWMA:10 a=_FVE-zBwftR9WsbkzFJk:22 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:181730 Archived-At: --Apple-Mail=_187E4226-740F-462B-93E6-2EE96E09EA79 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 6 juni 2020 kl. 20.27 skrev Eli Zaretskii : > What practical problem is being solved here? The current predicates for determining whether a colour is light or dark = are just bad. We can and should do better, and that's what this is all = about. Let's consider the three saturated colours #ff0000 (red), #00ff00 = (green) and #0000ff (blue). Black text looks terrible on blue, as does = white on green; black on red isn't good either. This comes as no = surprise: the human eye is more sensitive to brightness levels of green = than blue, with red somewhere in-between. (These three colours just serve as illustrative examples; large chunks = of the RGB space will share the same properties.) How do the existing predicates do? Let's call them MAX, AVG and DIST. MAX: dark iff max(r,g,b) < 0.5 This classifies saturated red and blue as light, which is clearly = terrible. AVG: dark iff (r+g+b) / 3 < 0.6 This classifies saturated green as dark, which is also wrong. DIST: dark iff (color-distance c "black") =E2=89=A4 292485 This one also thinks saturated green is dark. While the approach here = looks reasonable at first blush, it's really not: color-distance uses a = simplified expression for how dissimilar two colours are, but doesn't do = a very good job at determining brightness. For instance, its heavy blue = weight makes no sense when used in this way: (color-distance "#ff0000" "black") =3D> 162308 (color-distance "#00ff00" "black") =3D> 260100 (color-distance "#0000ff" "black") =3D> 194820 This means that we cannot fix DIST by tweaking its cut-off value; it's = fundamentally unfit for this purpose. For a proper solution, we have theory to guide us: determine the = perceived brightness of a colour, and classify everything below a = cut-off value as dark, others as light. The patch uses a standard = expression for relative luminance: Y =3D 0.2126R + 0.7152G + 0.0722B, = where R, G and B are linear colour components. We assume a gamma of 2.2; = it is nearly identical to the sRGB gamma curve and the results are = almost the same. With a cut-off of 0.6, this predicate turns out to be quite good: much = better than MAX, AVG or DIST at any rate. While not perfect, it's good = enough in the sense that for colours where it seems to make the wrong = decision, it's a fairly close call, and the colour is quite readable = with both black and write as contrast. I have tested it on several platforms and monitors, including 80x25 VGA = hardware text mode, and have yet to find a case where it fails, which = definitely cannot be said about the old predicates. We can still tweak it: mainly the cut-off value (which is just = experimentally determined) but also the coefficients and the gamma = correction. Although technically valid, they aren't holy. > This code's algorithm and rationale should be explained in the > comments before we can discuss whether it's an improvement and why. Thanks, I have improved this in the new patch. This patch should also use the right coefficients (see above); I think I = got them wrong the first time. --Apple-Mail=_187E4226-740F-462B-93E6-2EE96E09EA79 Content-Disposition: attachment; filename=0001-Improved-light-dark-colour-predicate-bug-41544.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="0001-Improved-light-dark-colour-predicate-bug-41544.patch" Content-Transfer-Encoding: quoted-printable =46rom=2000c9176cc26853e1314f95bfb540753273740807=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20= =0ADate:=20Sun,=2031=20May=202020=2021:12:46=20+0200=0A= Subject:=20[PATCH]=20Improved=20light/dark=20colour=20predicate=20= (bug#41544)=0A=0AAdd=20a=20single=20predicate,=20color-dark-p,=20for=20= deciding=20whether=20a=20colour=0Ais=20more=20readable=20against=20black=20= or=20white.=20=20Previously=20this=20was=20done=20in=0Adifferent=20ways=20= in=20several=20places,=20and=20with=20worse=20results.=0A=0AThe=20new=20= predicate=20compares=20the=20relative=20luminance=20of=20the=20colour=20= to=0Aan=20experimentally=20determined=20cut-off=20value,=20and=20it=20= seems=20to=20get=20it=0Aright=20in=20almost=20all=20cases,=20with=20no=20= value=20leading=20to=20outright=20bad=0Aresults.=0A=0A*=20= lisp/facemenu.el=20(list-colors-print):=20Use=20= readable-foreground-color.=0A(color-dark-p):=20New=20function.=0A*=20= lisp/term/pc-win.el:=20Update=20comment.=0A*=20lisp/term/rxvt.el=20= (rxvt-set-background-mode):=0A*=20lisp/term/w32console.el=20= (terminal-init-w32console):=0A*=20lisp/term/xterm.el=20= (xterm-maybe-set-dark-background-mode):=0A*=20lisp/faces.el=20= (readable-foreground-color):=0A*=20lisp/frame.el=20= (frame-set-background-mode):=20Use=20color-dark-p.=0A*=20= lisp/textmodes/css-mode.el=20(css--contrasty-color):=20Remove.=0A= (css--fontify-region):=20Use=20color-dark-p.=0A---=0A=20lisp/facemenu.el=20= =20=20=20=20=20=20=20=20=20=20|=2011=20+++++------=0A=20lisp/faces.el=20=20= =20=20=20=20=20=20=20=20=20=20=20=20|=2029=20= ++++++++++++++++++++---------=0A=20lisp/frame.el=20=20=20=20=20=20=20=20=20= =20=20=20=20=20|=2016=20+++++++++-------=0A=20lisp/term/pc-win.el=20=20=20= =20=20=20=20=20|=20=208=20+++-----=0A=20lisp/term/rxvt.el=20=20=20=20=20=20= =20=20=20=20|=2012=20+++++-------=0A=20lisp/term/w32console.el=20=20=20=20= |=20=206=20+++---=0A=20lisp/term/xterm.el=20=20=20=20=20=20=20=20=20|=20=20= 5=20++---=0A=20lisp/textmodes/css-mode.el=20|=2014=20++------------=0A=20= 8=20files=20changed,=2049=20insertions(+),=2052=20deletions(-)=0A=0Adiff=20= --git=20a/lisp/facemenu.el=20b/lisp/facemenu.el=0Aindex=20= b10d874b21..419b76101b=20100644=0A---=20a/lisp/facemenu.el=0A+++=20= b/lisp/facemenu.el=0A@@=20-621,12=20+621,11=20@@=20list-colors-print=0A=20= =09=09=09=09=09=09=20(downcase=20b))))))=0A=20=09(setq=20color=20(list=20= color)))=0A=20=20=20=20=20=20=20(let*=20((opoint=20(point))=0A-=09=20=20=20= =20=20(color-values=20(color-values=20(car=20color)))=0A-=09=20=20=20=20=20= (light-p=20(>=3D=20(apply=20'max=20color-values)=0A-=09=09=09=20=20(*=20= (car=20(color-values=20"white"))=20.5))))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20(fg=20(readable-foreground-color=20(car=20color))))=0A=20=09= (insert=20(car=20color))=0A=20=09(indent-to=2022)=0A-=09= (put-text-property=20opoint=20(point)=20'face=20`(:background=20,(car=20= color)))=0A+=09(put-text-property=20opoint=20(point)=20'face=20= `(:background=20,(car=20color)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20:foreground=20,fg))=0A=20=09= (put-text-property=0A=20=09=20(prog1=20(point)=0A=20=09=20=20=20(insert=20= "=20")=0A@@=20-639,7=20+638,7=20@@=20list-colors-print=0A=20=09(insert=20= (propertize=0A=20=09=09=20(apply=20'format=20"#%02x%02x%02x"=0A=20=09=09=09= (mapcar=20(lambda=20(c)=20(ash=20c=20-8))=0A-=09=09=09=09color-values))=0A= +=09=09=09=09(color-values=20(car=20color))))=0A=20=09=09=20'mouse-face=20= 'highlight=0A=20=09=09=20'help-echo=0A=20=09=09=20(let=20((hsv=20(apply=20= 'color-rgb-to-hsv=0A@@=20-651,7=20+650,7=20@@=20list-colors-print=0A=20=09= =20=20=20opoint=20(point)=0A=20=09=20=20=20'follow-link=20t=0A=20=09=20=20= =20'mouse-face=20(list=20:background=20(car=20color)=0A-=09=09=09=20=20=20= =20=20:foreground=20(if=20light-p=20"black"=20"white"))=0A+=09=09=09=20=20= =20=20=20:foreground=20fg)=0A=20=09=20=20=20'color-name=20(car=20color)=0A= =20=09=20=20=20'action=20callback-fn)))=0A=20=20=20=20=20=20=20(insert=20= "\n"))=0Adiff=20--git=20a/lisp/faces.el=20b/lisp/faces.el=0Aindex=20= f4a9dedd79..d68eb82de6=20100644=0A---=20a/lisp/faces.el=0A+++=20= b/lisp/faces.el=0A@@=20-1786,15=20+1786,26=20@@=20= defined-colors-with-face-attributes=0A=20=0A=20(defun=20= readable-foreground-color=20(color)=0A=20=20=20"Return=20a=20readable=20= foreground=20color=20for=20background=20COLOR."=0A-=20=20(let*=20((rgb=20= =20=20(color-values=20color))=0A-=09=20(max=20=20=20(apply=20#'max=20= rgb))=0A-=09=20(black=20(car=20(color-values=20"black")))=0A-=09=20= (white=20(car=20(color-values=20"white"))))=0A-=20=20=20=20;;=20Select=20= black=20or=20white=20depending=20on=20which=20one=20is=20less=20similar=20= to=0A-=20=20=20=20;;=20the=20brightest=20component.=0A-=20=20=20=20(if=20= (>=20(abs=20(-=20max=20black))=20(abs=20(-=20max=20white)))=0A-=09= "black"=0A-=20=20=20=20=20=20"white")))=0A+=20=20(if=20(color-dark-p=20= (color-name-to-rgb=20color))=20"white"=20"black"))=0A+=0A+(defun=20= color-dark-p=20(rgb)=0A+=20=20"Whether=20RGB=20is=20more=20readable=20= against=20white=20than=20black.=0A+RGB=20is=20a=203-element=20list=20(R=20= G=20B),=20each=20component=20in=20the=20range=20[0,1]."=0A+=20=20(unless=20= (<=3D=200=20(apply=20#'min=20rgb)=20(apply=20#'max=20rgb)=201)=0A+=20=20=20= =20(error=20"RGB=20components=20%S=20not=20in=20[0,1]"=20rgb))=0A+=20=20= (let*=20((sr=20(nth=200=20rgb))=0A+=20=20=20=20=20=20=20=20=20(sg=20(nth=20= 1=20rgb))=0A+=20=20=20=20=20=20=20=20=20(sb=20(nth=202=20rgb))=0A+=20=20=20= =20=20=20=20=20=20;;=20Gamma-correct=20the=20RGB=20components=20to=20= linear=20values.=0A+=20=20=20=20=20=20=20=20=20;;=20Use=20the=20power=20= 2.2=20as=20an=20approximation=20to=20sRGB=20gamma;=0A+=20=20=20=20=20=20=20= =20=20;;=20it=20should=20be=20good=20enough=20for=20the=20purpose=20of=20= this=20function.=0A+=20=20=20=20=20=20=20=20=20(r=20(expt=20sr=202.2))=0A= +=20=20=20=20=20=20=20=20=20(g=20(expt=20sg=202.2))=0A+=20=20=20=20=20=20= =20=20=20(b=20(expt=20sb=202.2))=0A+=20=20=20=20=20=20=20=20=20;;=20= Compute=20the=20relative=20luminance.=0A+=20=20=20=20=20=20=20=20=20(y=20= (+=20(*=20r=200.2126)=20(*=20g=200.7152)=20(*=20b=200.0722))))=0A+=20=20=20= =20;;=20Compare=20it=20to=20a=20cut-off=20value=20determined=20= experimentally;=20see=20bug#41544.=0A+=20=20=20=20(<=20y=20= (eval-when-compile=20(expt=200.6=202.2)))))=0A=20=0A=20(declare-function=20= xw-color-defined-p=20"xfns.c"=20(color=20&optional=20frame))=0A=20=0A= diff=20--git=20a/lisp/frame.el=20b/lisp/frame.el=0Aindex=20= 6c2f774709..b46ba3686f=20100644=0A---=20a/lisp/frame.el=0A+++=20= b/lisp/frame.el=0A@@=20-1156,6=20+1156,12=20@@=20frame-background-mode=0A= =20=0A=20(defvar=20inhibit-frame-set-background-mode=20nil)=0A=20=0A= +(defun=20frame--color-name-to-rgb=20(color=20frame)=0A+=20=20"Convert=20= the=20COLOR=20string=20to=20a=20list=20of=20normalised=20RGB=20= components.=0A+Like=20`color-name-to-rgb',=20but=20works=20even=20when=20= the=20display=20has=20not=20yet=0A+been=20initialised."=0A+=20=20(mapcar=20= (lambda=20(x)=20(/=20x=2065535.0))=20(color-values=20color=20frame)))=0A= +=0A=20(defun=20frame-set-background-mode=20(frame=20&optional=20= keep-face-specs)=0A=20=20=20"Set=20up=20display-dependent=20faces=20on=20= FRAME.=0A=20Display-dependent=20faces=20are=20those=20which=20have=20= different=20definitions=0A@@=20-1181,13=20+1187,9=20@@=20= frame-set-background-mode=0A=20=09=09=20=20=20non-default-bg-mode)=0A=20=09= =09=20=20((not=20(color-values=20bg-color=20frame))=0A=20=09=09=20=20=20= default-bg-mode)=0A-=09=09=20=20((>=3D=20(apply=20'+=20(color-values=20= bg-color=20frame))=0A-=09=09=20=20=20=20=20=20=20;;=20Just=20looking=20= at=20the=20screen,=20colors=20whose=0A-=09=09=20=20=20=20=20=20=20;;=20= values=20add=20up=20to=20.6=20of=20the=20white=20total=0A-=09=09=20=20=20= =20=20=20=20;;=20still=20look=20dark=20to=20me.=0A-=09=09=20=20=20=20=20=20= =20(*=20(apply=20'+=20(color-values=20"white"=20frame))=20.6))=0A-=09=09=20= =20=20'light)=0A-=09=09=20=20(t=20'dark)))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20((color-dark-p=20(frame--color-name-to-rgb=20= bg-color=20frame))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20'dark)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(t=20= 'light)))=0A=20=09=20=20=20(display-type=0A=20=09=20=20=20=20(cond=20= ((null=20(window-system=20frame))=0A=20=09=09=20=20=20(if=20= (tty-display-color-p=20frame)=20'color=20'mono))=0Adiff=20--git=20= a/lisp/term/pc-win.el=20b/lisp/term/pc-win.el=0Aindex=20= 76a48a86c7..16eb660f00=20100644=0A---=20a/lisp/term/pc-win.el=0A+++=20= b/lisp/term/pc-win.el=0A@@=20-54,11=20+54,9=20@@=0A=20;;=20= DJGPP-compiled=20Emacs=20on=20the=20same=20PC.=20=20The=20names=20of=20X=20= colors=20used=20to=0A=20;;=20define=20the=20pixel=20values=20are=20shown=20= as=20comments=20to=20each=20color=20below.=0A=20;;;=0A-;;=20If=20you=20= want=20to=20change=20the=20RGB=20values,=20keep=20in=20mind=20that=20= various=20pieces=0A-;;=20of=20Emacs=20think=20that=20a=20color=20whose=20= RGB=20values=20add=20up=20to=20less=20than=200.6=20of=0A-;;=20the=20= values=20for=20WHITE=20(i.e.=20less=20than=20117963)=20are=20``dark'',=20= otherwise=20the=0A-;;=20color=20is=20``light'';=20see=20= `frame-set-background-mode'=20in=20lisp/faces.el=20for=0A-;;=20an=20= example.=0A+;;=20If=20you=20want=20to=20change=20the=20RGB=20values,=20= consider=20the=20heuristics=20in=0A+;;=20`color-dark-p'=20which=20is=20= used=20to=20select=20a=20suitably=20contrasting=0A+;;=20foreground=20or=20= background=20colour.=0A=20(defvar=20msdos-color-values=0A=20=20=20= '(("black"=20=20=20=20=20=20=20=20=20=200=20=20=20=20=200=20=20=20=20=20= 0=20=20=20=20=200)=0A=20=20=20=20=20("blue"=20=20=20=20=20=20=20=20=20=20= =201=20=20=20=20=200=20=20=20=20=200=2052480)=20;=20MediumBlue=0Adiff=20= --git=20a/lisp/term/rxvt.el=20b/lisp/term/rxvt.el=0Aindex=20= 31e3d6ede4..5dc754c8e0=20100644=0A---=20a/lisp/term/rxvt.el=0A+++=20= b/lisp/term/rxvt.el=0A@@=20-206,13=20+206,11=20@@=20= rxvt-set-background-mode=0A=20=20=20=20=20=20=20;;=20The=20next=20line=20= assumes=20that=20rxvt-standard-colors=20are=20ordered=0A=20=20=20=20=20=20= =20;;=20by=20the=20color=20index=20in=20the=20ascending=20order!=0A=20=20= =20=20=20=20=20(setq=20rgb=20(car=20(cddr=20(nth=20bg=20= rxvt-standard-colors))))=0A-=20=20=20=20=20=20;;=20See=20the=20= commentary=20in=20frame-set-background-mode=20about=20the=0A-=20=20=20=20= =20=20;;=20computation=20below.=0A-=20=20=20=20=20=20(if=20(<=20(apply=20= '+=20rgb)=0A-=09=20=20=20=20=20;;=20The=20following=20line=20assumes=20= that=20white=20is=20the=2015th=0A-=09=20=20=20=20=20;;=20color=20in=20= rxvt-standard-colors.=0A-=09=20=20=20=20=20(*=20(apply=20'+=20(car=20= (cddr=20(nth=2015=20rxvt-standard-colors))))=200.6))=0A-=09=20=20= (set-terminal-parameter=20nil=20'background-mode=20'dark)))))=0A+=20=20=20= =20=20=20;;=20The=20following=20line=20assumes=20that=20white=20is=20the=20= 15th=0A+=20=20=20=20=20=20;;=20color=20in=20rxvt-standard-colors.=0A+=20=20= =20=20=20=20(let=20((comp-max=20(float=20(caddr=20(nth=2015=20= rxvt-standard-colors)))))=0A+=20=20=20=20=20=20=20=20(when=20= (color-dark-p=20(mapcar=20(lambda=20(c)=20(/=20c=20comp-max))=20rgb))=0A= +=09=20=20(set-terminal-parameter=20nil=20'background-mode=20'dark))))))=0A= =20=0A=20(provide=20'term/rxvt)=0A=20=0Adiff=20--git=20= a/lisp/term/w32console.el=20b/lisp/term/w32console.el=0Aindex=20= 36e9d896c7..0e9d7c8b5c=20100644=0A---=20a/lisp/term/w32console.el=0A+++=20= b/lisp/term/w32console.el=0A@@=20-86,9=20+86,9=20@@=20= terminal-init-w32console=0A=20=20=20=20=20(setq=20r=20(nth=202=20descr)=0A= =20=09=20=20g=20(nth=203=20descr)=0A=20=09=20=20b=20(nth=204=20descr))=0A= -=20=20=20=20(if=20(<=20(+=20r=20g=20b)=20(*=20.6=20(+=2065535=2065535=20= 65535)))=0A-=09(setq=20bg-mode=20'dark)=0A-=20=20=20=20=20=20(setq=20= bg-mode=20'light))=0A+=20=20=20=20(setq=20bg-mode=20(if=20(color-dark-p=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (list=20(/=20r=2065535.0)=20(/=20g=2065535.0)=20(/=20b=2065535.0)))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'dark=20= 'light))=0A=20=20=20=20=20(set-terminal-parameter=20nil=20= 'background-mode=20bg-mode))=0A=20=20=20(tty-set-up-initial-frame-faces)=0A= =20=20=20(run-hooks=20'terminal-init-w32-hook))=0Adiff=20--git=20= a/lisp/term/xterm.el=20b/lisp/term/xterm.el=0Aindex=20= 1a727e3933..bf9bcae526=20100644=0A---=20a/lisp/term/xterm.el=0A+++=20= b/lisp/term/xterm.el=0A@@=20-1120,9=20+1120,8=20@@=20= xterm-register-default-colors=0A=20=20=20=20=20(clear-face-cache)))=0A=20= =0A=20(defun=20xterm-maybe-set-dark-background-mode=20(redc=20greenc=20= bluec)=0A-=20=20;;=20Use=20the=20heuristic=20in=20= `frame-set-background-mode'=20to=20decide=20if=20a=0A-=20=20;;=20frame=20= is=20dark.=0A-=20=20(when=20(<=20(+=20redc=20greenc=20bluec)=20(*=20.6=20= (+=2065535=2065535=2065535)))=0A+=20=20(when=20(color-dark-p=20(mapcar=20= (lambda=20(c)=20(/=20c=2065535.0))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20redc=20= greenc=20bluec)))=0A=20=20=20=20=20(set-terminal-parameter=20nil=20= 'background-mode=20'dark)=0A=20=20=20=20=20t))=0A=20=0Adiff=20--git=20= a/lisp/textmodes/css-mode.el=20b/lisp/textmodes/css-mode.el=0Aindex=20= 0035c5e7b0..2cd99787e8=20100644=0A---=20a/lisp/textmodes/css-mode.el=0A= +++=20b/lisp/textmodes/css-mode.el=0A@@=20-1149,17=20+1149,6=20@@=20= css--compute-color=0A=20=20=20=20;;=20Evaluate=20to=20the=20color=20if=20= the=20name=20is=20found.=0A=20=20=20=20((css--named-color=20start-point=20= match))))=0A=20=0A-(defun=20css--contrasty-color=20(name)=0A-=20=20= "Return=20a=20color=20that=20contrasts=20with=20NAME.=0A-NAME=20is=20of=20= any=20form=20accepted=20by=20`color-distance'.=0A-The=20returned=20color=20= will=20be=20usable=20by=20Emacs=20and=20will=20contrast=0A-with=20NAME;=20= in=20particular=20so=20that=20if=20NAME=20is=20used=20as=20a=20= background=0A-color,=20the=20returned=20color=20can=20be=20used=20as=20= the=20foreground=20and=20still=0A-be=20readable."=0A-=20=20;;=20See=20= bug#25525=20for=20a=20discussion=20of=20this.=0A-=20=20(if=20(>=20= (color-distance=20name=20"black")=20292485)=0A-=20=20=20=20=20=20"black"=20= "white"))=0A-=0A=20(defcustom=20css-fontify-colors=20t=0A=20=20=20= "Whether=20CSS=20colors=20should=20be=20fontified=20using=20the=20color=20= as=20the=20background.=0A=20When=20non-`nil',=20a=20text=20representing=20= CSS=20color=20will=20be=20fontified=0A@@=20-1199,7=20+1188,8=20@@=20= css--fontify-region=0A=20=09=09=20=20=20=20(add-text-properties=0A=20=09=09= =20=20=20=20=20start=20(point)=0A=20=09=09=20=20=20=20=20(list=20'face=20= (list=20:background=20color=0A-=09=09=09=09=20=20=20=20=20=20=20= :foreground=20(css--contrasty-color=20color)=0A+=09=09=09=09=20=20=20=20=20= =20=20:foreground=20(readable-foreground-color=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20color)=0A=20=09=09= =09=09=20=20=20=20=20=20=20:box=20'(:line-width=20-1))))))))))))=0A=20=20= =20=20=20extended-region))=0A=20=0A--=20=0A2.21.1=20(Apple=20Git-122.3)=0A= =0A= --Apple-Mail=_187E4226-740F-462B-93E6-2EE96E09EA79--