On Thu, Jun 30, 2016 at 09:43:49PM +0800, Fengguang Wu <[email protected]>
wrote:
> On Thu, Jun 30, 2016 at 02:34:41PM +0300, Emanuele Giaquinta wrote:
> > On Thu, Jun 23, 2016 at 08:28:46PM +0800, Fengguang Wu wrote:
> > > When the color cube slot is found to be already occupied by a similar
> > > 24-bit color, search through the -1, 0, +1 R/G/B indices trying to find
> > > an empty slot, or the oldest used one (which hopefully is no longer in
> > > active use).
> > >
> > > This effectively reduces random collisions, hence make it pretty hard to
> > > hit a vim GUI color scheme that cannot be correctly showed in urxvt.
> >
> > Applied without hashing and with some cleanups. Thanks again.
>
> Thank you! I tried run it with the debug patch and it looks alright.
After playing around with it some more (and coming to the same
conclusion), I think going through all 26 neighbouring colours creates
colours that are too far off.
I have tuned it a bit, and got satisfactory results with the below code
(also in CVS) - this only visits the 6 nearest colours (+-1 in each
component), which is a compromise between being too far off and having some
replacement candidates.
As a side effect, it allows some code minor simplification, allows us to
visit the blue colours first, and of course can be much faster because it
only looks at 7 instead of 27 colours, not that any of it matters.
What do you think of this approach?
unsigned int
rxvt_term::map_rgb24_color (unsigned int r, unsigned int g, unsigned int b)
{
r &= 0xff;
g &= 0xff;
b &= 0xff;
unsigned int color = (r << 16) | (g << 8) | b;
unsigned int idx_r = r / (0xff / (Red_levels - 1));
unsigned int idx_g = g / (0xff / (Green_levels - 1));
unsigned int idx_b = b / (0xff / (Blue_levels - 1));
unsigned int idx = colorcube_index (idx_r, idx_g, idx_b);
if (rgb24_color[idx] == color)
return idx + minTermCOLOR24;
/* we allow one of the 6 directly neighbouring colours */
/* to replace the current color, if they not used recently */
static const signed char dxyz[][3] = {
0, 0, 0,
0, 0, -1,
0, 0, +1,
0, -1, 0,
0, +1, 0,
-1, 0, 0,
+1, 0, 0,
};
for (int n = 0; n < ecb_array_length (dxyz); ++n)
{
int i = idx_r + dxyz[n][0];
int j = idx_r + dxyz[n][1];
int k = idx_r + dxyz[n][2];
if (!IN_RANGE_EXC (i, 0, Red_levels))
continue;
if (!IN_RANGE_EXC (j, 0, Green_levels))
continue;
if (!IN_RANGE_EXC (k, 0, Blue_levels))
continue;
unsigned int index = colorcube_index (i, j, k);
// minor issue: could update index 0 few more times
if ((rgb24_seqno[index] | rgb24_color[index]) == 0)
{
idx = index;
goto update;
}
if (rgb24_color[index] == color)
return index + minTermCOLOR24;
// like (rgb24_seqno[idx] > rgb24_seqno[index])
// but also handles wrap around values good enough
if ((uint16_t)(rgb24_seqno[idx] - rgb24_seqno[index]) < 0x7fff)
idx = index;
}
--
The choice of a Deliantra, the free code+content MORPG
-----==- _GNU_ http://www.deliantra.net
----==-- _ generation
---==---(_)__ __ ____ __ Marc Lehmann
--==---/ / _ \/ // /\ \/ / [email protected]
-=====/_/_//_/\_,_/ /_/\_\
_______________________________________________
rxvt-unicode mailing list
[email protected]
http://lists.schmorp.de/mailman/listinfo/rxvt-unicode