--- rxvt-unicode/src/rxvttoolkit.C 2014/05/22 18:54:33 1.142 +++ rxvt-unicode/src/rxvttoolkit.C 2014/12/17 14:25:01 1.148 @@ -25,6 +25,8 @@ #include #include +#include + #include #include @@ -281,7 +283,7 @@ cmap = XCreateColormap (dpy, display->root, visual, AllocNone); } else - rxvt_warn ("cannot requested visual id 0x%02x, using default visual.\n", id); + rxvt_warn ("no visual found for requested id 0x%02x, using default visual.\n", id); } void @@ -492,15 +494,10 @@ #if XRENDER int major, minor; if (XRenderQueryVersion (dpy, &major, &minor)) - if (major > 0 || (major == 0 && minor >= 10)) + if (major > 0 || (major == 0 && minor >= 11)) { flags |= DISPLAY_HAS_RENDER; -#if 0 - if (major > 0 || (major == 0 && minor >= 11)) - flags |= DISPLAY_HAS_RENDER_MUL; -#endif - if (XFilters *filters = XRenderQueryFilters (dpy, root)) { for (int i = 0; i < filters->nfilter; i++) @@ -760,6 +757,13 @@ #if XFT XRenderPictFormat *format; + // not needed by XftColorAlloc, but by the other paths (ours + // and fallback), so just set all components here. + c.color.red = color.r; + c.color.green = color.g; + c.color.blue = color.b; + c.color.alpha = alpha; + // FUCKING Xft gets it wrong, of course, so work around it. // Transparency users should eat shit and die, and then // XRenderQueryPictIndexValues themselves plenty. @@ -767,10 +771,6 @@ && (format = XRenderFindVisualFormat (screen->dpy, screen->visual))) { // the fun lies in doing everything manually... - c.color.red = color.r; - c.color.green = color.g; - c.color.blue = color.b; - c.color.alpha = alpha; // Xft wants premultiplied alpha, but abuses the alpha channel // as blend factor, and doesn't allow us to set the alpha channel @@ -794,6 +794,7 @@ d.blue = color.b; d.alpha = alpha; + // XftColorAlloc always returns 100% transparent pixels(!) if (XftColorAllocValue (screen->dpy, screen->visual, screen->cmap, &d, &c)) return true; } @@ -814,7 +815,7 @@ return true; #endif - c.pixel = (color.r + color.g + color.b) > 128*3 + c.pixel = (color.r * 2 + color.g * 3 + color.b) >= 0x8000 * 6 ? WhitePixelOfScreen (DefaultScreenOfDisplay (screen->dpy)) : BlackPixelOfScreen (DefaultScreenOfDisplay (screen->dpy)); @@ -882,26 +883,35 @@ // many extra optimisations. XQueryColors (screen->dpy, screen->cmap, colors, cmap_size); - int diff = 0x7fffffffUL; - XColor *best = colors; - - for (int i = 0; i < cmap_size; i++) + while (cmap_size) { - int d = (squared_diff (color.r >> 2, colors [i].red >> 2)) - + (squared_diff (color.g >> 2, colors [i].green >> 2)) - + (squared_diff (color.b >> 2, colors [i].blue >> 2)); + int diff = 0x7fffffffL; + XColor *best = colors; - if (d < diff) + for (int i = 0; i < cmap_size; i++) { - diff = d; - best = colors + i; + // simple weighted rgb distance sucks, but keeps it simple + int d = abs (color.r - colors [i].red ) * 2 + + abs (color.g - colors [i].green) * 3 + + abs (color.b - colors [i].blue ); + + if (d < diff) + { + diff = d; + best = colors + i; + } } - } - //rxvt_warn ("could not allocate %04x %04x %04x, getting %04x %04x %04x instead (%d)\n", - // color.r, color.g, color.b, best->red, best->green, best->blue, diff); + //rxvt_warn ("could not allocate %04x %04x %04x, getting %04x %04x %04x instead (%d,%d)\n", + // color.r, color.g, color.b, best->red, best->green, best->blue, diff, best - colors); + + got = alloc (screen, rgba (best->red, best->green, best->blue)); - got = alloc (screen, rgba (best->red, best->green, best->blue)); + if (got) + break; + + *best = colors [--cmap_size]; + } delete [] colors; } @@ -914,6 +924,7 @@ rxvt_color::get (rgba &color) const { #if XFT + //TODO premultiplied alpha?? color.r = c.color.red; color.g = c.color.green; color.b = c.color.blue;