From 01a37dfe1888f1ac6da7ab12c6e4d59ce104d12c Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 14 Feb 2003 08:01:44 +0000 Subject: [PATCH] allocate colors in pseudocolor from the map we allocate in the rendercontrol --- otk/pseudorendercontrol.cc | 43 ++++++++++++++++++++++++++++++++++++-- otk/pseudorendercontrol.hh | 1 + otk/rendercolor.cc | 12 ++++------- otk/rendercontrol.hh | 2 ++ otk/truerendercontrol.cc | 10 +++++++++ otk/truerendercontrol.hh | 2 ++ 6 files changed, 60 insertions(+), 10 deletions(-) diff --git a/otk/pseudorendercontrol.cc b/otk/pseudorendercontrol.cc index 89e95ab6..29636ee9 100644 --- a/otk/pseudorendercontrol.cc +++ b/otk/pseudorendercontrol.cc @@ -93,9 +93,8 @@ int tr, tg, tb; _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! } @@ -135,4 +134,44 @@ void PseudoRenderControl::reduceDepth(Surface &sf, XImage *im) const } +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! +} + } diff --git a/otk/pseudorendercontrol.hh b/otk/pseudorendercontrol.hh index a52e7cc3..402190c5 100644 --- a/otk/pseudorendercontrol.hh +++ b/otk/pseudorendercontrol.hh @@ -18,6 +18,7 @@ public: PseudoRenderControl(int screen); virtual ~PseudoRenderControl(); + virtual void allocateColor(XColor *color) const; }; } diff --git a/otk/rendercolor.cc b/otk/rendercolor.cc index 448b3e10..e5cbb7cb 100644 --- a/otk/rendercolor.cc +++ b/otk/rendercolor.cc @@ -5,6 +5,7 @@ #include "rendercolor.hh" #include "display.hh" #include "screeninfo.hh" +#include "rendercontrol.hh" #include @@ -64,14 +65,9 @@ void RenderColor::create() const 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; diff --git a/otk/rendercontrol.hh b/otk/rendercontrol.hh index 72ad176f..01642824 100644 --- a/otk/rendercontrol.hh +++ b/otk/rendercontrol.hh @@ -68,6 +68,8 @@ public: //! 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; }; } diff --git a/otk/truerendercontrol.cc b/otk/truerendercontrol.cc index 1d5b8dc4..2f1b710e 100644 --- a/otk/truerendercontrol.cc +++ b/otk/truerendercontrol.cc @@ -99,4 +99,14 @@ void TrueRenderControl::reduceDepth(Surface &sf, XImage *im) const } } +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; + } +} + } diff --git a/otk/truerendercontrol.hh b/otk/truerendercontrol.hh index 1bfe8415..36dbe244 100644 --- a/otk/truerendercontrol.hh +++ b/otk/truerendercontrol.hh @@ -26,6 +26,8 @@ private: public: TrueRenderControl(int screen); virtual ~TrueRenderControl(); + + virtual void allocateColor(XColor *color) const; }; } -- 2.45.2