allocate colors in pseudocolor from the map we allocate in the rendercontrol
Dana Jansens danakj@orodu.net
6 files changed,
59 insertions(+),
9 deletions(-)
M
otk/pseudorendercontrol.cc
→
otk/pseudorendercontrol.cc
@@ -93,9 +93,8 @@ _colors[i].blue = icolors[close].blue;
_colors[i].pixel = icolors[close].pixel; // try alloc this closest color, it had better succeed! - if (XAllocColor(**display, info->colormap(), &_colors[i])) { + if (XAllocColor(**display, info->colormap(), &_colors[i])) _colors[i].flags = DoRed|DoGreen|DoBlue; // mark as alloced - } else assert(false); // wtf has gone wrong, its already alloced for chissake! }@@ -133,6 +132,46 @@ data += im->width;
p += im->bytes_per_line; } +} + +void PseudoRenderControl::allocateColor(XColor *color) const +{ + const ScreenInfo *info = display->screenInfo(_screen); + int depth = info->depth(); + + // get the allocated values from the X server (only the first 256 XXX why!?) + XColor icolors[256]; + int incolors = (((1 << depth) > 256) ? 256 : (1 << depth)); + for (int i = 0; i < incolors; i++) + icolors[i].pixel = i; + XQueryColors(**display, info->colormap(), icolors, incolors); + + unsigned long closest = 0xffffffff, close = 0; + for (int ii = 0; ii < incolors; ii++) { + // find deviations + int r = (color->red - icolors[ii].red) & 0xff; + int g = (color->green - icolors[ii].green) & 0xff; + int b = (color->blue - icolors[ii].blue) & 0xff; + // find a weighted absolute deviation + unsigned long dev = (r * r) + (g * g) + (b * b); + + if (dev < closest) { + closest = dev; + close = ii; + } + } + + color->red = icolors[close].red; + color->green = icolors[close].green; + color->blue = icolors[close].blue; + color->pixel = icolors[close].pixel; + + // try alloc this closest color, it had better succeed! + if (XAllocColor(**display, info->colormap(), color)) { + color->flags = DoRed|DoGreen|DoBlue; // mark as alloced + } + else + assert(false); // wtf has gone wrong, its already alloced for chissake! } }
M
otk/pseudorendercontrol.hh
→
otk/pseudorendercontrol.hh
@@ -18,6 +18,7 @@ public:
PseudoRenderControl(int screen); virtual ~PseudoRenderControl(); + virtual void allocateColor(XColor *color) const; }; }
M
otk/rendercolor.cc
→
otk/rendercolor.cc
@@ -5,6 +5,7 @@
#include "rendercolor.hh" #include "display.hh" #include "screeninfo.hh" +#include "rendercontrol.hh" #include <cstdio>@@ -64,14 +65,9 @@ XColor xcol; // convert from 0-0xff to 0-0xffff
xcol.red = (_red << 8) | _red; xcol.green = (_green << 8) | _green; xcol.blue = (_blue << 8) | _blue; - xcol.pixel = 0; - if (!XAllocColor(**display, info->colormap(), &xcol)) { - fprintf(stderr, "RenderColor: color alloc error: rgb:%x/%x/%x\n", - _red, _green, _blue); - xcol.pixel = 0; - } else - _allocated = true; + display->renderControl(_screen)->allocateColor(&xcol); + _allocated = true; _pixel = xcol.pixel; gcv.foreground = _pixel;
M
otk/rendercontrol.hh
→
otk/rendercontrol.hh
@@ -68,6 +68,8 @@
//! Draws a PixmapMask with a specified color onto a Surface virtual void drawMask(Surface &sf, const RenderColor &color, const PixmapMask &mask) const; + + virtual void allocateColor(XColor *color) const = 0; }; }
M
otk/truerendercontrol.cc
→
otk/truerendercontrol.cc
@@ -99,4 +99,14 @@ printf("your bit depth is currently unhandled\n");
} } +void TrueRenderControl::allocateColor(XColor *color) const +{ + const ScreenInfo *info = display->screenInfo(_screen); + if (!XAllocColor(**display, info->colormap(), color)) { + fprintf(stderr, "TrueRenderControl: color alloc error: rgb:%x/%x/%x\n", + color->red & 0xff, color->green & 0xff, color->blue & 0xff); + color->pixel = 0; + } +} + }
M
otk/truerendercontrol.hh
→
otk/truerendercontrol.hh
@@ -26,6 +26,8 @@
public: TrueRenderControl(int screen); virtual ~TrueRenderControl(); + + virtual void allocateColor(XColor *color) const; }; }