[bug] background variable is automatically set to the wrong value

1,354 views
Skip to first unread message

Matteo Cavalleri

unread,
Jan 7, 2014, 9:44:14 AM1/7/14
to vim...@googlegroups.com
some easy steps to reproduce the problem:

:set t_Co?
t_Co=256
:set background?
background=light
:set background=dark
:set background?
background=dark
:hi Normal ctermfg=grey ctermbg=234
:set background?
background=light
:hi Normal ctermfg=grey ctermbg=0
:set background?
background=dark

as you can see, the "hi" command changes background to light when ctermbg is set to 234, however, according to http://upload.wikimedia.org/wikipedia/commons/9/95/Xterm_color_chart.png color 234 is indeed a dark grey

Christian Brabandt

unread,
Jan 8, 2014, 2:11:34 PM1/8/14
to vim...@googlegroups.com
I see the problem:

7728 if (color >= 0)
7729 {
7730 if (termcap_active)
7731 term_bg_color(color);
7732 if (t_colors < 16)
7733 i = (color == 0 || color == 4);
7734 else
7735 i = (color < 7 || color == 8);
7736 /* Set the 'background' option if the value is
7737 * wrong. */
7738 if (i != (*p_bg == 'd'))
7739 set_option_value((char_u *)"bg", 0L,
7740 i ? (char_u *)"dark"
7741 : (char_u *)"light", 0);
7742 }

i.e. Vim always sets a light background for all colors except the first
7 and color 8 for which it will set a dark background. I don't think Vim
should try to determine what color is used and depending on it's value
try to set a sane 'bg' value for the other 256 colors (in a 256 color
terminal or the 88 rxvt color cube) so for now, I would propose to
adjust the logic only slightly to something like this:

diff --git a/src/syntax.c b/src/syntax.c
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -7731,6 +7731,14 @@
term_bg_color(color);
if (t_colors < 16)
i = (color == 0 || color == 4);
+ else if (t_colors == 256)
+ {
+ i = (color < 7 || color == 8 ||
+ (color > 231 && color < 244));
+ if (i > 16 && i < 232)
+ i = (*p_bg == 'd');
+ }
+

Which means only for the lower 12 (dark) gray colors (232 until 243) in
the 256 color cube set the 'bg' to dark, for all other (except the ones
mentioned above) leave the bg setting alone.

Best,
Christian
--
Die Radfahrer haben einen alten Wunsch der Menschheit verwirklicht:
Im Sitzen zu wandern.
-- Franz Molnar

Matteo Cavalleri

unread,
Jan 10, 2014, 3:31:36 AM1/10/14
to vim...@googlegroups.com
>
> i.e. Vim always sets a light background for all colors except the first
>
> 7 and color 8 for which it will set a dark background. I don't think Vim
>
> should try to determine what color is used and depending on it's value
>
> try to set a sane 'bg' value for the other 256 colors (in a 256 color
>
> terminal or the 88 rxvt color cube) so for now, I would propose to
>
> adjust the logic only slightly to something like this:
>
>

thanks :) hope it'll get included sooner or later.

Bram Moolenaar

unread,
Jan 10, 2014, 7:06:23 AM1/10/14
to Christian Brabandt, vim...@googlegroups.com
It's a start. However, if we change this we might as well do it
properly.

In my opinion we should take the color chart and compute the brightness
of each color. If it's above 50% 'background' should be set to light.

There at least is this image:
http://upload.wikimedia.org/wikipedia/en/thumb/1/15/Xterm_256color_chart.svg/2000px-Xterm_256color_chart.svg.png

A list of #RGB values could be used to compute the brightness.

--
I'm writing a book. I've got the page numbers done.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Matteo Cavalleri

unread,
Jan 10, 2014, 9:31:03 AM1/10/14
to vim...@googlegroups.com
ok, i took the rgb values from that image of the xterm colors (using the gist linked in the image itself) and wrote a little ruby script to print 1 or 0 depending on the brightness of the color.

according to the source snippet posted by Christian, it seems that when "i" is true then the background is set to dark, otherwise to "light", so my script prints 1 for dark colors and 0 for light ones. I don't work with c, so I'm not sure if an array of integers is really the best option for a quick look up depending on the color index, but anyway, modifying my script shouldn't be too difficult :p

I made this just for those 256 term colors, looking at that snippet of vim source. I've no idea what happens when the gui is in use...

BTW I've to say I'm totally ignorant about luma, luminance, gamma correction etc, so i basically took a formula from someone who seemed to know what he was talking about and used it...

here's the output and the script attached. I hope I made something useful :)

1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

color.rb

Bram Moolenaar

unread,
Jan 10, 2014, 11:12:03 AM1/10/14
to Matteo Cavalleri, vim...@googlegroups.com
To see if this is right we would need to make areas with the background
color, put some white and black text in it, and check which text is best
readable.

For the first 16 colors it's a bit different, but that doesn't mean it
is wrong (e.g. blue is considered light, but it's actually quite dark).


--
There are three kinds of persons: Those who can count and those who can't.

Matteo Cavalleri

unread,
Jan 10, 2014, 11:30:52 AM1/10/14
to vim...@googlegroups.com, Matteo Cavalleri
>
> To see if this is right we would need to make areas with the background
>
> color, put some white and black text in it, and check which text is best
>
> readable.
>

the formula I choosen should calculate the "perceptual" brightness, i.e. it should take into account human perception and also sRGB color space. As I said i'm no expert in this field, but after documenting a bit and doing a couple of tests I think it should give the expected result.

manual tests might be a good idea, but I think we might fall into personal opinions, with people wondering if the tests where made under daylight or in some dark room, with monitor correctly calibrated or with brightness and contrast settings completely blown up...

ok i'm exagerating a bit here, but I already wondered how really should be defined the point when a color is no longer "dark".

if someone wants to manually test the text/background combinations (and what about grey text instead of just black and white?) I suggest just to test some edge cases and then adjust that "above 50%" you suggested earlier. but maybe discussing the formula might be a better idea than doing the manual test.

for the first 16 colors, well, those might even be customized by the user to something completely different, but I've no idea if it is possible to read rgb values runtime on all shells / oses vim run on. but in the best case vim might calculate brigthness runtime for those 16 colors and lookup the pre-calculated, remaining ones.

Christian Brabandt

unread,
Jan 10, 2014, 3:19:48 PM1/10/14
to vim...@googlegroups.com
How about the attached patch? For colors > 15, it uses the rxvt color
cube for 88 color terminals and the xterm color cube for 256 color
terminals and computes the luminance. If the luminance is above a
certain treshhold, it uses a light background, else it uses a dark
background.

It uses the same logic, that I have been using for my Colorizer plugin
(https://github.com/chrisbra/color_highlight) for which I haven't seen
any complaints about the luminance yet (of course this doesn't mean this
is correct by all means).

Best,
Christian
--
set_bg.diff

Bram Moolenaar

unread,
Jan 10, 2014, 3:53:13 PM1/10/14
to Christian Brabandt, vim...@googlegroups.com
I suppose this would be OK. But I was thinking of a built-in table.
Avoids computing stuff at runtime, just lookup the flag.


--
The coffee just wasn't strong enough to defend itself -- Tom Waits

Bram Moolenaar

unread,
Jan 10, 2014, 3:53:13 PM1/10/14
to Matteo Cavalleri, vim...@googlegroups.com

Matteo Cavalleri wrote:

> > To see if this is right we would need to make areas with the background
> > color, put some white and black text in it, and check which text is best
> > readable.
>
> the formula I choosen should calculate the "perceptual" brightness,
> i.e. it should take into account human perception and also sRGB color
> space. As I said i'm no expert in this field, but after documenting a
> bit and doing a couple of tests I think it should give the expected
> result.

That's what I was thinking of, to check if the formula is more or less
OK.

> manual tests might be a good idea, but I think we might fall into
> personal opinions, with people wondering if the tests where made under
> daylight or in some dark room, with monitor correctly calibrated or
> with brightness and contrast settings completely blown up...

Yeah, I don't want to look at every possible color and manually choose
if it's light or dark. It's already difficult enough to make a table
for the values you found with the formula.

> ok i'm exagerating a bit here, but I already wondered how really
> should be defined the point when a color is no longer "dark".
>
> if someone wants to manually test the text/background combinations
> (and what about grey text instead of just black and white?) I suggest
> just to test some edge cases and then adjust that "above 50%" you
> suggested earlier. but maybe discussing the formula might be a better
> idea than doing the manual test.
>
> for the first 16 colors, well, those might even be customized by the
> user to something completely different, but I've no idea if it is
> possible to read rgb values runtime on all shells / oses vim run on.
> but in the best case vim might calculate brigthness runtime for those
> 16 colors and lookup the pre-calculated, remaining ones.

There are some border cases, such as 50% grey, #808080. Can be
considered light or dark. In these cases I would prefer to keep what we
had before, if there was a value before.

--
hundred-and-one symptoms of being an internet addict:
137. You decide to stay in college for an additional year or two,
just so you can have the free Internet access.
Reply all
Reply to author
Forward
0 new messages