all repos — openbox @ f2e005f4d99c069431f27a102cef2ee26991ca97

openbox fork - make it a bit more like ryudo

remove the old blackbox bullshit
Dana Jansens danakj@orodu.net
commit

f2e005f4d99c069431f27a102cef2ee26991ca97

parent

104c1a164b1e4e881e141d14263895401779d453

11 files changed, 0 insertions(+), 3700 deletions(-)

jump to
D otk/color.cc

@@ -1,215 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif // HAVE_CONFIG_H - -extern "C" { -#include <stdio.h> -} - -#include <assert.h> - -#include "color.hh" -#include "display.hh" -#include "screeninfo.hh" - -namespace otk { - -Color::ColorCache Color::colorcache; -bool Color::cleancache = false; - -Color::Color(unsigned int _screen) - : allocated(false), r(-1), g(-1), b(-1), p(0), scrn(_screen) -{} - -Color::Color(int _r, int _g, int _b, unsigned int _screen) - : allocated(false), r(_r), g(_g), b(_b), p(0), scrn(_screen) -{} - - -Color::Color(const std::string &_name, unsigned int _screen) - : allocated(false), r(-1), g(-1), b(-1), p(0), scrn(_screen), - colorname(_name) { - parseColorName(); -} - - -Color::~Color(void) { - deallocate(); -} - - -void Color::setScreen(unsigned int _screen) { - if (_screen == screen()) { - // nothing to do - return; - } - - deallocate(); - - scrn = _screen; - - if (! colorname.empty()) { - parseColorName(); - } -} - - -unsigned long Color::pixel(void) const { - if (! allocated) { - // mutable - Color *that = (Color *) this; - that->allocate(); - } - - return p; -} - - -void Color::parseColorName(void) { - if (colorname.empty()) { - fprintf(stderr, "Color: empty colorname, cannot parse (using black)\n"); - setRGB(0, 0, 0); - } - - if (scrn == ~(0u)) - scrn = DefaultScreen(**display); - Colormap colormap = display->screenInfo(scrn)->colormap(); - - // get rgb values from colorname - XColor xcol; - xcol.red = 0; - xcol.green = 0; - xcol.blue = 0; - xcol.pixel = 0; - - if (! XParseColor(**display, colormap, - colorname.c_str(), &xcol)) { - fprintf(stderr, "Color::allocate: color parse error: \"%s\"\n", - colorname.c_str()); - setRGB(0, 0, 0); - return; - } - - setRGB(xcol.red >> 8, xcol.green >> 8, xcol.blue >> 8); -} - - -void Color::allocate(void) { - if (scrn == ~(0u)) scrn = DefaultScreen(**display); - Colormap colormap = display->screenInfo(scrn)->colormap(); - - if (! isValid()) { - if (colorname.empty()) { - fprintf(stderr, "Color: cannot allocate invalid color (using black)\n"); - setRGB(0, 0, 0); - } else { - parseColorName(); - } - } - - // see if we have allocated this color before - RGB rgb(scrn, r, g, b); - ColorCache::iterator it = colorcache.find(rgb); - if (it != colorcache.end()) { - // found - allocated = true; - p = (*it).second.p; - (*it).second.count++; - return; - } - - // allocate color from rgb values - XColor xcol; - xcol.red = r | r << 8; - xcol.green = g | g << 8; - xcol.blue = b | b << 8; - xcol.pixel = 0; - - if (! XAllocColor(**display, colormap, &xcol)) { - fprintf(stderr, "Color::allocate: color alloc error: rgb:%x/%x/%x\n", - r, g, b); - xcol.pixel = 0; - } - - p = xcol.pixel; - allocated = true; - - colorcache.insert(ColorCacheItem(rgb, PixelRef(p))); - - if (cleancache) - doCacheCleanup(); -} - - -void Color::deallocate(void) { - if (! allocated) - return; - - ColorCache::iterator it = colorcache.find(RGB(scrn, r, g, b)); - if (it != colorcache.end()) { - if ((*it).second.count >= 1) - (*it).second.count--; - } - - if (cleancache) - doCacheCleanup(); - - allocated = false; -} - - -Color &Color::operator=(const Color &c) { - deallocate(); - - setRGB(c.r, c.g, c.b); - colorname = c.colorname; - scrn = c.scrn; - return *this; -} - - -void Color::cleanupColorCache(void) { - cleancache = true; -} - - -void Color::doCacheCleanup(void) { - // ### TODO - support multiple displays! - ColorCache::iterator it = colorcache.begin(); - if (it == colorcache.end()) { - // nothing to do - return; - } - - unsigned long *pixels = new unsigned long[ colorcache.size() ]; - int i; - unsigned count; - - for (i = 0; i < ScreenCount(**display); i++) { - count = 0; - it = colorcache.begin(); - - while (it != colorcache.end()) { - if ((*it).second.count != 0 || (*it).first.screen != i) { - ++it; - continue; - } - - pixels[ count++ ] = (*it).second.p; - ColorCache::iterator it2 = it; - ++it; - colorcache.erase(it2); - } - - if (count > 0) - XFreeColors(**display, display->screenInfo(i)->colormap(), - pixels, count, 0); - } - - delete [] pixels; - cleancache = false; -} - -}
D otk/color.hh

@@ -1,102 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- -#ifndef __color_hh -#define __color_hh - -extern "C" { -#include <X11/Xlib.h> -} - -#include <map> -#include <string> - -namespace otk { - -class Color { -public: - Color(unsigned int _screen = ~(0u)); - Color(int _r, int _g, int _b, unsigned int _screen = ~(0u)); - Color(const std::string &_name, unsigned int _screen = ~(0u)); - ~Color(void); - - inline const std::string &name(void) const { return colorname; } - - inline int red(void) const { return r; } - inline int green(void) const { return g; } - inline int blue(void) const { return b; } - void setRGB(int _r, int _g, int _b) { - deallocate(); - r = _r; - g = _g; - b = _b; - } - - inline unsigned int screen(void) const { return scrn; } - void setScreen(unsigned int _screen = ~(0u)); - - inline bool isAllocated(void) const { return allocated; } - - inline bool isValid(void) const { return r != -1 && g != -1 && b != -1; } - - unsigned long pixel(void) const; - - // operators -#ifndef SWIG - Color &operator=(const Color &c); -#endif - inline bool operator==(const Color &c) const - { return (r == c.r && b == c.b && b == c.b); } - inline bool operator!=(const Color &c) const - { return (! operator==(c)); } - - static void cleanupColorCache(void); - -private: - void parseColorName(void); - void allocate(void); - void deallocate(void); - - bool allocated; - int r, g, b; - unsigned long p; - unsigned int scrn; - std::string colorname; - - // global color allocator/deallocator - struct RGB { - const int screen; - const int r, g, b; - - RGB(void) : screen(~(0u)), r(-1), g(-1), b(-1) { } - RGB(const int b, const int x, const int y, const int z) - : screen(b), r(x), g(y), b(z) {} - RGB(const RGB &x) - : screen(x.screen), r(x.r), g(x.g), b(x.b) {} - - inline bool operator==(const RGB &x) const { - return screen == x.screen && - r == x.r && g == x.g && b == x.b; - } - - inline bool operator<(const RGB &x) const { - unsigned long p1, p2; - p1 = (screen << 24 | r << 16 | g << 8 | b) & 0x00ffffff; - p2 = (x.screen << 24 | x.r << 16 | x.g << 8 | x.b) & 0x00ffffff; - return p1 < p2; - } - }; - struct PixelRef { - const unsigned long p; - unsigned int count; - inline PixelRef(void) : p(0), count(0) { } - inline PixelRef(const unsigned long x) : p(x), count(1) { } - }; - typedef std::map<RGB,PixelRef> ColorCache; - typedef ColorCache::value_type ColorCacheItem; - static ColorCache colorcache; - static bool cleancache; - static void doCacheCleanup(void); -}; - -} - -#endif // __color_hh
D otk/gccache.cc

@@ -1,191 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif // HAVE_CONFIG_H - -extern "C" { -#include <stdio.h> -} - -#include <algorithm> - -#include "gccache.hh" -#include "color.hh" -#include "assassin.hh" -#include "screeninfo.hh" - -namespace otk { - -GCCacheContext::~GCCacheContext(void) { - if (gc) - XFreeGC(**display, gc); -} - - -void GCCacheContext::set(const Color &_color, - const XFontStruct * const _font, - const int _function, const int _subwindow, - int _linewidth) { - XGCValues gcv; - pixel = gcv.foreground = _color.pixel(); - function = gcv.function = _function; - subwindow = gcv.subwindow_mode = _subwindow; - linewidth = gcv.line_width = _linewidth; - gcv.cap_style = CapProjecting; - - unsigned long mask = GCForeground | GCFunction | GCSubwindowMode | - GCLineWidth | GCCapStyle; - - if (_font) { - fontid = gcv.font = _font->fid; - mask |= GCFont; - } else { - fontid = 0; - } - - XChangeGC(**display, gc, mask, &gcv); -} - - -void GCCacheContext::set(const XFontStruct * const _font) { - if (! _font) { - fontid = 0; - return; - } - - XGCValues gcv; - fontid = gcv.font = _font->fid; - XChangeGC(**display, gc, GCFont, &gcv); -} - - -GCCache::GCCache(unsigned int screen_count) - : context_count(128u), cache_size(16u), cache_buckets(8u * screen_count), - cache_total_size(cache_size * cache_buckets) { - - contexts = new GCCacheContext*[context_count]; - unsigned int i; - for (i = 0; i < context_count; i++) { - contexts[i] = new GCCacheContext(); - } - - cache = new GCCacheItem*[cache_total_size]; - for (i = 0; i < cache_total_size; ++i) { - cache[i] = new GCCacheItem; - } -} - - -GCCache::~GCCache(void) { - std::for_each(contexts, contexts + context_count, PointerAssassin()); - std::for_each(cache, cache + cache_total_size, PointerAssassin()); - delete [] cache; - delete [] contexts; -} - - -GCCacheContext *GCCache::nextContext(unsigned int scr) { - Window hd = display->screenInfo(scr)->rootWindow(); - - GCCacheContext *c; - - for (unsigned int i = 0; i < context_count; ++i) { - c = contexts[i]; - - if (! c->gc) { - c->gc = XCreateGC(**display, hd, 0, 0); - c->used = false; - c->screen = scr; - } - if (! c->used && c->screen == scr) - return c; - } - - fprintf(stderr, "GCCache: context fault!\n"); - abort(); - return (GCCacheContext*) 0; // not reached -} - - -void GCCache::release(GCCacheContext *ctx) { - ctx->used = false; -} - - -GCCacheItem *GCCache::find(const Color &_color, - const XFontStruct * const _font, - int _function, int _subwindow, int _linewidth) { - const unsigned long pixel = _color.pixel(); - const unsigned int screen = _color.screen(); - const int key = _color.red() ^ _color.green() ^ _color.blue(); - int k = (key % cache_size) * cache_buckets; - unsigned int i = 0; // loop variable - GCCacheItem *c = cache[ k ], *prev = 0; - - /* - this will either loop cache_buckets times then return/abort or - it will stop matching - */ - while (c->ctx && - (c->ctx->pixel != pixel || c->ctx->function != _function || - c->ctx->subwindow != _subwindow || c->ctx->screen != screen || - c->ctx->linewidth != _linewidth)) { - if (i < (cache_buckets - 1)) { - prev = c; - c = cache[ ++k ]; - ++i; - continue; - } - if (c->count == 0 && c->ctx->screen == screen) { - // use this cache item - c->ctx->set(_color, _font, _function, _subwindow, _linewidth); - c->ctx->used = true; - c->count = 1; - c->hits = 1; - return c; - } - // cache fault! - fprintf(stderr, "GCCache: cache fault, count: %d, screen: %d, item screen: %d\n", c->count, screen, c->ctx->screen); - abort(); - } - - if (c->ctx) { - // reuse existing context - if (_font && _font->fid && _font->fid != c->ctx->fontid) - c->ctx->set(_font); - c->count++; - c->hits++; - if (prev && c->hits > prev->hits) { - cache[ k ] = prev; - cache[ k - 1 ] = c; - } - } else { - c->ctx = nextContext(screen); - c->ctx->set(_color, _font, _function, _subwindow, _linewidth); - c->ctx->used = true; - c->count = 1; - c->hits = 1; - } - - return c; -} - - -void GCCache::release(GCCacheItem *_item) { - _item->count--; -} - - -void GCCache::purge(void) { - for (unsigned int i = 0; i < cache_total_size; ++i) { - GCCacheItem *d = cache[ i ]; - - if (d->ctx && d->count == 0) { - release(d->ctx); - d->ctx = 0; - } - } -} - -}
D otk/gccache.hh

@@ -1,119 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- -#ifndef __gccache_hh -#define __gccache_hh - -extern "C" { -#include <X11/Xlib.h> -} - -#include "display.hh" -#include "color.hh" - -namespace otk { - -class GCCacheItem; - -class GCCacheContext { -public: - void set(const Color &_color, const XFontStruct * const _font, - const int _function, const int _subwindow, const int _linewidth); - void set(const XFontStruct * const _font); - - ~GCCacheContext(void); - -private: - GCCacheContext() - : gc(0), pixel(0ul), fontid(0ul), - function(0), subwindow(0), used(false), screen(~(0u)), linewidth(0) {} - - GC gc; - unsigned long pixel; - unsigned long fontid; - int function; - int subwindow; - bool used; - unsigned int screen; - int linewidth; - - GCCacheContext(const GCCacheContext &_nocopy); - GCCacheContext &operator=(const GCCacheContext &_nocopy); - - friend class GCCache; - friend class GCCacheItem; -}; - -class GCCacheItem { -public: - inline const GC &gc(void) const { return ctx->gc; } - -private: - GCCacheItem(void) : ctx(0), count(0), hits(0), fault(false) { } - - GCCacheContext *ctx; - unsigned int count; - unsigned int hits; - bool fault; - - GCCacheItem(const GCCacheItem &_nocopy); - GCCacheItem &operator=(const GCCacheItem &_nocopy); - - friend class GCCache; -}; - -class GCCache { -public: - GCCache(unsigned int screen_count); - ~GCCache(void); - - // cleans up the cache - void purge(void); - - GCCacheItem *find(const Color &_color, const XFontStruct * const _font = 0, - int _function = GXcopy, int _subwindow = ClipByChildren, - int _linewidth = 0); - void release(GCCacheItem *_item); - -private: - GCCacheContext *nextContext(unsigned int _screen); - void release(GCCacheContext *ctx); - - // this is closely modelled after the Qt GC cache, but with some of the - // complexity stripped out - const unsigned int context_count; - const unsigned int cache_size; - const unsigned int cache_buckets; - const unsigned int cache_total_size; - GCCacheContext **contexts; - GCCacheItem **cache; -}; - -class Pen { -public: - inline Pen(const Color &_color, const XFontStruct * const _font = 0, - int _linewidth = 0, int _function = GXcopy, - int _subwindow = ClipByChildren) - : color(_color), font(_font), linewidth(_linewidth), function(_function), - subwindow(_subwindow), cache(display->gcCache()), item(0) { } - - inline ~Pen(void) { if (item) cache->release(item); } - - inline const GC &gc(void) const { - if (! item) item = cache->find(color, font, function, subwindow, - linewidth); - return item->gc(); - } - -private: - const Color &color; - const XFontStruct *font; - int linewidth; - int function; - int subwindow; - - mutable GCCache *cache; - mutable GCCacheItem *item; -}; - -} - -#endif // __gccache_hh
D otk/image.cc

@@ -1,1674 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif // HAVE_CONFIG_H - -#ifdef HAVE_STDIO_H -# include <stdio.h> -#endif // HAVE_STDIO_H - -#include <algorithm> -using std::max; -using std::min; - -#include "display.hh" -#include "gccache.hh" -#include "image.hh" -#include "texture.hh" - -namespace otk { - -Image::Image(ImageControl *c, int w, int h) { - control = c; - - width = (w > 0) ? w : 1; - height = (h > 0) ? h : 1; - - red = new unsigned char[width * height]; - green = new unsigned char[width * height]; - blue = new unsigned char[width * height]; - - xtable = ytable = (unsigned int *) 0; - - cpc = control->getColorsPerChannel(); - cpccpc = cpc * cpc; - - control->getColorTables(&red_table, &green_table, &blue_table, - &red_offset, &green_offset, &blue_offset, - &red_bits, &green_bits, &blue_bits); - - if (control->getVisual()->c_class != TrueColor) - control->getXColorTable(&colors, &ncolors); -} - - -Image::~Image(void) { - delete [] red; - delete [] green; - delete [] blue; -} - - -Pixmap Image::render(const Texture &texture) { - if (texture.texture() & Texture::Parent_Relative) - return ParentRelative; - else if (texture.texture() & Texture::Solid) - return render_solid(texture); - else if (texture.texture() & Texture::Gradient) - return render_gradient(texture); - return None; -} - - -Pixmap Image::render_solid(const Texture &texture) { - Pixmap pixmap = XCreatePixmap(**display, control->getDrawable(), width, - height, control->getDepth()); - if (pixmap == None) { - fprintf(stderr, "Image::render_solid: error creating pixmap\n"); - return None; - } - - Pen pen(texture.color()); - Pen penlight(texture.lightColor()); - Pen penshadow(texture.shadowColor()); - - XFillRectangle(**display, pixmap, pen.gc(), 0, 0, width, height); - - if (texture.texture() & Texture::Interlaced) { - Pen peninterlace(texture.colorTo()); - for (unsigned int i = 0; i < height; i += 2) - XDrawLine(**display, pixmap, peninterlace.gc(), 0, i, width, i); - } - - int left = 0, top = 0, right = width - 1, bottom = height - 1; - - if (texture.texture() & Texture::Border) { - Pen penborder(texture.borderColor()); - XDrawRectangle(**display, pixmap, penborder.gc(), - left, top, right, bottom); - } - - if (texture.texture() & Texture::Bevel1) { - if (texture.texture() & Texture::Raised) { - XDrawLine(**display, pixmap, penshadow.gc(), - left, bottom, right, bottom); - XDrawLine(**display, pixmap, penshadow.gc(), - right, bottom, right, top); - - XDrawLine(**display, pixmap, penlight.gc(), - left, top, right, top); - XDrawLine(**display, pixmap, penlight.gc(), - left, bottom, left, top); - } else if (texture.texture() & Texture::Sunken) { - XDrawLine(**display, pixmap, penlight.gc(), - left, bottom, right, bottom); - XDrawLine(**display, pixmap, penlight.gc(), - right, bottom, right, top); - - XDrawLine(**display, pixmap, penshadow.gc(), - left, top, right, top); - XDrawLine(**display, pixmap, penshadow.gc(), - left, bottom, left, top); - } - } else if (texture.texture() & Texture::Bevel2) { - if (texture.texture() & Texture::Raised) { - XDrawLine(**display, pixmap, penshadow.gc(), - left + 1, bottom - 2, right - 2, bottom - 2); - XDrawLine(**display, pixmap, penshadow.gc(), - right - 2, bottom - 2, right - 2, top + 1); - - XDrawLine(**display, pixmap, penlight.gc(), - left + 1, top + 1, right - 2, top + 1); - XDrawLine(**display, pixmap, penlight.gc(), - left + 1, bottom - 2, left + 1, top + 1); - } else if (texture.texture() & Texture::Sunken) { - XDrawLine(**display, pixmap, penlight.gc(), - left + 1, bottom - 2, right - 2, bottom - 2); - XDrawLine(**display, pixmap, penlight.gc(), - right - 2, bottom - 2, right - 2, top + 1); - - XDrawLine(**display, pixmap, penshadow.gc(), - left + 1, top + 1, right - 2, top + 1); - XDrawLine(**display, pixmap, penshadow.gc(), - left + 1, bottom - 2, left + 1, top + 1); - } - } - - return pixmap; -} - - -Pixmap Image::render_gradient(const Texture &texture) { - bool inverted = False; - - interlaced = texture.texture() & Texture::Interlaced; - - if (texture.texture() & Texture::Sunken) { - from = texture.colorTo(); - to = texture.color(); - - if (! (texture.texture() & Texture::Invert)) inverted = True; - } else { - from = texture.color(); - to = texture.colorTo(); - - if (texture.texture() & Texture::Invert) inverted = True; - } - - control->getGradientBuffers(width, height, &xtable, &ytable); - - if (texture.texture() & Texture::Diagonal) dgradient(); - else if (texture.texture() & Texture::Elliptic) egradient(); - else if (texture.texture() & Texture::Horizontal) hgradient(); - else if (texture.texture() & Texture::Pyramid) pgradient(); - else if (texture.texture() & Texture::Rectangle) rgradient(); - else if (texture.texture() & Texture::Vertical) vgradient(); - else if (texture.texture() & Texture::CrossDiagonal) cdgradient(); - else if (texture.texture() & Texture::PipeCross) pcgradient(); - - if (texture.texture() & Texture::Bevel1) bevel1(); - else if (texture.texture() & Texture::Bevel2) bevel2(); - - if (texture.texture() & Texture::Border) border(texture); - - if (inverted) invert(); - - return renderPixmap(); - -} - - -static const unsigned char dither4[4][4] = { - {0, 4, 1, 5}, - {6, 2, 7, 3}, - {1, 5, 0, 4}, - {7, 3, 6, 2} -}; - - -/* - * Helper function for TrueColorDither and renderXImage - * - * This handles the proper setting of the image data based on the image depth - * and the machine's byte ordering - */ -static inline -void assignPixelData(unsigned int bit_depth, unsigned char **data, - unsigned long pixel) { - unsigned char *pixel_data = *data; - switch (bit_depth) { - case 8: // 8bpp - *pixel_data++ = pixel; - break; - - case 16: // 16bpp LSB - *pixel_data++ = pixel; - *pixel_data++ = pixel >> 8; - break; - - case 17: // 16bpp MSB - *pixel_data++ = pixel >> 8; - *pixel_data++ = pixel; - break; - - case 24: // 24bpp LSB - *pixel_data++ = pixel; - *pixel_data++ = pixel >> 8; - *pixel_data++ = pixel >> 16; - break; - - case 25: // 24bpp MSB - *pixel_data++ = pixel >> 16; - *pixel_data++ = pixel >> 8; - *pixel_data++ = pixel; - break; - - case 32: // 32bpp LSB - *pixel_data++ = pixel; - *pixel_data++ = pixel >> 8; - *pixel_data++ = pixel >> 16; - *pixel_data++ = pixel >> 24; - break; - - case 33: // 32bpp MSB - *pixel_data++ = pixel >> 24; - *pixel_data++ = pixel >> 16; - *pixel_data++ = pixel >> 8; - *pixel_data++ = pixel; - break; - } - *data = pixel_data; // assign back so we don't lose our place -} - - -// algorithm: ordered dithering... many many thanks to rasterman -// (raster@rasterman.com) for telling me about this... portions of this -// code is based off of his code in Imlib -void Image::TrueColorDither(unsigned int bit_depth, int bytes_per_line, - unsigned char *pixel_data) { - unsigned int x, y, dithx, dithy, r, g, b, er, eg, eb, offset; - unsigned char *ppixel_data = pixel_data; - unsigned long pixel; - - for (y = 0, offset = 0; y < height; y++) { - dithy = y & 0x3; - - for (x = 0; x < width; x++, offset++) { - dithx = x & 0x3; - r = red[offset]; - g = green[offset]; - b = blue[offset]; - - er = r & (red_bits - 1); - eg = g & (green_bits - 1); - eb = b & (blue_bits - 1); - - r = red_table[r]; - g = green_table[g]; - b = blue_table[b]; - - if ((dither4[dithy][dithx] < er) && (r < red_table[255])) r++; - if ((dither4[dithy][dithx] < eg) && (g < green_table[255])) g++; - if ((dither4[dithy][dithx] < eb) && (b < blue_table[255])) b++; - - pixel = (r << red_offset) | (g << green_offset) | (b << blue_offset); - assignPixelData(bit_depth, &pixel_data, pixel); - } - - pixel_data = (ppixel_data += bytes_per_line); - } -} - -#ifdef ORDEREDPSEUDO -const static unsigned char dither8[8][8] = { - { 0, 32, 8, 40, 2, 34, 10, 42}, - { 48, 16, 56, 24, 50, 18, 58, 26}, - { 12, 44, 4, 36, 14, 46, 6, 38}, - { 60, 28, 52, 20, 62, 30, 54, 22}, - { 3, 35, 11, 43, 1, 33, 9, 41}, - { 51, 19, 59, 27, 49, 17, 57, 25}, - { 15, 47, 7, 39, 13, 45, 5, 37}, - { 63, 31, 55, 23, 61, 29, 53, 21} -}; - -void Image::OrderedPseudoColorDither(int bytes_per_line, - unsigned char *pixel_data) { - unsigned int x, y, dithx, dithy, r, g, b, er, eg, eb, offset; - unsigned long pixel; - unsigned char *ppixel_data = pixel_data; - - for (y = 0, offset = 0; y < height; y++) { - dithy = y & 7; - - for (x = 0; x < width; x++, offset++) { - dithx = x & 7; - - r = red[offset]; - g = green[offset]; - b = blue[offset]; - - er = r & (red_bits - 1); - eg = g & (green_bits - 1); - eb = b & (blue_bits - 1); - - r = red_table[r]; - g = green_table[g]; - b = blue_table[b]; - - if ((dither8[dithy][dithx] < er) && (r < red_table[255])) r++; - if ((dither8[dithy][dithx] < eg) && (g < green_table[255])) g++; - if ((dither8[dithy][dithx] < eb) && (b < blue_table[255])) b++; - - pixel = (r * cpccpc) + (g * cpc) + b; - *(pixel_data++) = colors[pixel].pixel; - } - - pixel_data = (ppixel_data += bytes_per_line); - } -} -#endif - -void Image::PseudoColorDither(int bytes_per_line, unsigned char *pixel_data) { - short *terr, - *rerr = new short[width + 2], - *gerr = new short[width + 2], - *berr = new short[width + 2], - *nrerr = new short[width + 2], - *ngerr = new short[width + 2], - *nberr = new short[width + 2]; - - int rr, gg, bb, rer, ger, ber; - int dd = 255 / control->getColorsPerChannel(); - unsigned int x, y, r, g, b, offset; - unsigned long pixel; - unsigned char *ppixel_data = pixel_data; - - for (x = 0; x < width; x++) { - *(rerr + x) = *(red + x); - *(gerr + x) = *(green + x); - *(berr + x) = *(blue + x); - } - - *(rerr + x) = *(gerr + x) = *(berr + x) = 0; - - for (y = 0, offset = 0; y < height; y++) { - if (y < (height - 1)) { - int i = offset + width; - for (x = 0; x < width; x++, i++) { - *(nrerr + x) = *(red + i); - *(ngerr + x) = *(green + i); - *(nberr + x) = *(blue + i); - } - - *(nrerr + x) = *(red + (--i)); - *(ngerr + x) = *(green + i); - *(nberr + x) = *(blue + i); - } - - for (x = 0; x < width; x++) { - rr = rerr[x]; - gg = gerr[x]; - bb = berr[x]; - - if (rr > 255) rr = 255; else if (rr < 0) rr = 0; - if (gg > 255) gg = 255; else if (gg < 0) gg = 0; - if (bb > 255) bb = 255; else if (bb < 0) bb = 0; - - r = red_table[rr]; - g = green_table[gg]; - b = blue_table[bb]; - - rer = rerr[x] - r*dd; - ger = gerr[x] - g*dd; - ber = berr[x] - b*dd; - - pixel = (r * cpccpc) + (g * cpc) + b; - *pixel_data++ = colors[pixel].pixel; - - r = rer >> 1; - g = ger >> 1; - b = ber >> 1; - rerr[x+1] += r; - gerr[x+1] += g; - berr[x+1] += b; - nrerr[x] += r; - ngerr[x] += g; - nberr[x] += b; - } - - offset += width; - - pixel_data = (ppixel_data += bytes_per_line); - - terr = rerr; - rerr = nrerr; - nrerr = terr; - - terr = gerr; - gerr = ngerr; - ngerr = terr; - - terr = berr; - berr = nberr; - nberr = terr; - } - - delete [] rerr; - delete [] gerr; - delete [] berr; - delete [] nrerr; - delete [] ngerr; - delete [] nberr; -} - -XImage *Image::renderXImage(void) { - XImage *image = - XCreateImage(**display, control->getVisual(), control->getDepth(), - ZPixmap, 0, 0,width, height, 32, 0); - - if (! image) { - fprintf(stderr, "Image::renderXImage: error creating XImage\n"); - return (XImage *) 0; - } - - // insurance policy - image->data = (char *) 0; - - unsigned char *d = new unsigned char[image->bytes_per_line * (height + 1)]; - - unsigned int o = image->bits_per_pixel + - ((image->byte_order == MSBFirst) ? 1 : 0); - - bool unsupported = False; - - if (control->doDither() && width > 1 && height > 1) { - switch (control->getVisual()->c_class) { - case TrueColor: - TrueColorDither(o, image->bytes_per_line, d); - break; - - case StaticColor: - case PseudoColor: { -#ifdef ORDEREDPSEUDO - OrderedPseudoColorDither(image->bytes_per_line, d); -#else - PseudoColorDither(image->bytes_per_line, d); -#endif - break; - } - - default: - unsupported = True; - } - } else { - unsigned int x, y, r, g, b, offset; - unsigned char *pixel_data = d, *ppixel_data = d; - unsigned long pixel; - - switch (control->getVisual()->c_class) { - case StaticColor: - case PseudoColor: - for (y = 0, offset = 0; y < height; ++y) { - for (x = 0; x < width; ++x, ++offset) { - r = red_table[red[offset]]; - g = green_table[green[offset]]; - b = blue_table[blue[offset]]; - - pixel = (r * cpccpc) + (g * cpc) + b; - *pixel_data++ = colors[pixel].pixel; - } - - pixel_data = (ppixel_data += image->bytes_per_line); - } - - break; - - case TrueColor: - for (y = 0, offset = 0; y < height; y++) { - for (x = 0; x < width; x++, offset++) { - r = red_table[red[offset]]; - g = green_table[green[offset]]; - b = blue_table[blue[offset]]; - - pixel = (r << red_offset) | (g << green_offset) | (b << blue_offset); - assignPixelData(o, &pixel_data, pixel); - } - - pixel_data = (ppixel_data += image->bytes_per_line); - } - - break; - - case StaticGray: - case GrayScale: - for (y = 0, offset = 0; y < height; y++) { - for (x = 0; x < width; x++, offset++) { - r = *(red_table + *(red + offset)); - g = *(green_table + *(green + offset)); - b = *(blue_table + *(blue + offset)); - - g = ((r * 30) + (g * 59) + (b * 11)) / 100; - *pixel_data++ = colors[g].pixel; - } - - pixel_data = (ppixel_data += image->bytes_per_line); - } - - break; - - default: - unsupported = True; - } - } - - if (unsupported) { - fprintf(stderr, "Image::renderXImage: unsupported visual\n"); - delete [] d; - XDestroyImage(image); - return (XImage *) 0; - } - - image->data = (char *) d; - - return image; -} - - -Pixmap Image::renderPixmap(void) { - Pixmap pixmap = - XCreatePixmap(**display, control->getDrawable(), width, height, - control->getDepth()); - - if (pixmap == None) { - fprintf(stderr, "Image::renderPixmap: error creating pixmap\n"); - return None; - } - - XImage *image = renderXImage(); - - if (! image) { - XFreePixmap(**display, pixmap); - return None; - } - - if (! image->data) { - XDestroyImage(image); - XFreePixmap(**display, pixmap); - return None; - } - - XPutImage(**display, pixmap, - DefaultGC(**display, control->getScreenInfo()->screen()), - image, 0, 0, 0, 0, width, height); - - if (image->data) { - delete [] image->data; - image->data = NULL; - } - - XDestroyImage(image); - - return pixmap; -} - - -void Image::bevel1(void) { - if (width > 2 && height > 2) { - unsigned char *pr = red, *pg = green, *pb = blue; - - register unsigned char r, g, b, rr ,gg ,bb; - register unsigned int w = width, h = height - 1, wh = w * h; - - while (--w) { - r = *pr; - rr = r + (r >> 1); - if (rr < r) rr = ~0; - g = *pg; - gg = g + (g >> 1); - if (gg < g) gg = ~0; - b = *pb; - bb = b + (b >> 1); - if (bb < b) bb = ~0; - - *pr = rr; - *pg = gg; - *pb = bb; - - r = *(pr + wh); - rr = (r >> 2) + (r >> 1); - if (rr > r) rr = 0; - g = *(pg + wh); - gg = (g >> 2) + (g >> 1); - if (gg > g) gg = 0; - b = *(pb + wh); - bb = (b >> 2) + (b >> 1); - if (bb > b) bb = 0; - - *((pr++) + wh) = rr; - *((pg++) + wh) = gg; - *((pb++) + wh) = bb; - } - - r = *pr; - rr = r + (r >> 1); - if (rr < r) rr = ~0; - g = *pg; - gg = g + (g >> 1); - if (gg < g) gg = ~0; - b = *pb; - bb = b + (b >> 1); - if (bb < b) bb = ~0; - - *pr = rr; - *pg = gg; - *pb = bb; - - r = *(pr + wh); - rr = (r >> 2) + (r >> 1); - if (rr > r) rr = 0; - g = *(pg + wh); - gg = (g >> 2) + (g >> 1); - if (gg > g) gg = 0; - b = *(pb + wh); - bb = (b >> 2) + (b >> 1); - if (bb > b) bb = 0; - - *(pr + wh) = rr; - *(pg + wh) = gg; - *(pb + wh) = bb; - - pr = red + width; - pg = green + width; - pb = blue + width; - - while (--h) { - r = *pr; - rr = r + (r >> 1); - if (rr < r) rr = ~0; - g = *pg; - gg = g + (g >> 1); - if (gg < g) gg = ~0; - b = *pb; - bb = b + (b >> 1); - if (bb < b) bb = ~0; - - *pr = rr; - *pg = gg; - *pb = bb; - - pr += width - 1; - pg += width - 1; - pb += width - 1; - - r = *pr; - rr = (r >> 2) + (r >> 1); - if (rr > r) rr = 0; - g = *pg; - gg = (g >> 2) + (g >> 1); - if (gg > g) gg = 0; - b = *pb; - bb = (b >> 2) + (b >> 1); - if (bb > b) bb = 0; - - *(pr++) = rr; - *(pg++) = gg; - *(pb++) = bb; - } - - r = *pr; - rr = r + (r >> 1); - if (rr < r) rr = ~0; - g = *pg; - gg = g + (g >> 1); - if (gg < g) gg = ~0; - b = *pb; - bb = b + (b >> 1); - if (bb < b) bb = ~0; - - *pr = rr; - *pg = gg; - *pb = bb; - - pr += width - 1; - pg += width - 1; - pb += width - 1; - - r = *pr; - rr = (r >> 2) + (r >> 1); - if (rr > r) rr = 0; - g = *pg; - gg = (g >> 2) + (g >> 1); - if (gg > g) gg = 0; - b = *pb; - bb = (b >> 2) + (b >> 1); - if (bb > b) bb = 0; - - *pr = rr; - *pg = gg; - *pb = bb; - } -} - - -void Image::bevel2(void) { - if (width > 4 && height > 4) { - unsigned char r, g, b, rr ,gg ,bb, *pr = red + width + 1, - *pg = green + width + 1, *pb = blue + width + 1; - unsigned int w = width - 2, h = height - 1, wh = width * (height - 3); - - while (--w) { - r = *pr; - rr = r + (r >> 1); - if (rr < r) rr = ~0; - g = *pg; - gg = g + (g >> 1); - if (gg < g) gg = ~0; - b = *pb; - bb = b + (b >> 1); - if (bb < b) bb = ~0; - - *pr = rr; - *pg = gg; - *pb = bb; - - r = *(pr + wh); - rr = (r >> 2) + (r >> 1); - if (rr > r) rr = 0; - g = *(pg + wh); - gg = (g >> 2) + (g >> 1); - if (gg > g) gg = 0; - b = *(pb + wh); - bb = (b >> 2) + (b >> 1); - if (bb > b) bb = 0; - - *((pr++) + wh) = rr; - *((pg++) + wh) = gg; - *((pb++) + wh) = bb; - } - - pr = red + width; - pg = green + width; - pb = blue + width; - - while (--h) { - r = *pr; - rr = r + (r >> 1); - if (rr < r) rr = ~0; - g = *pg; - gg = g + (g >> 1); - if (gg < g) gg = ~0; - b = *pb; - bb = b + (b >> 1); - if (bb < b) bb = ~0; - - *(++pr) = rr; - *(++pg) = gg; - *(++pb) = bb; - - pr += width - 3; - pg += width - 3; - pb += width - 3; - - r = *pr; - rr = (r >> 2) + (r >> 1); - if (rr > r) rr = 0; - g = *pg; - gg = (g >> 2) + (g >> 1); - if (gg > g) gg = 0; - b = *pb; - bb = (b >> 2) + (b >> 1); - if (bb > b) bb = 0; - - *(pr++) = rr; - *(pg++) = gg; - *(pb++) = bb; - - pr++; pg++; pb++; - } - } -} - - -void Image::border(const Texture &texture) { - if (width < 2 || height < 2) return; - - register unsigned int i; - int r = texture.borderColor().red(), - g = texture.borderColor().green(), - b = texture.borderColor().blue(); - - unsigned char *pr, *pg, *pb; - - // top line - pr = red; - pg = green; - pb = blue; - for (i = 0; i < width; ++i) { - *pr++ = r; - *pg++ = g; - *pb++ = b; - } - - if (height > 2) { - // left and right lines (pr,pg,pb are already lined up) - for (i = 1; i < height - 1; ++i) { - *pr = r; - *pg = g; - *pb = b; - pr += width - 1; - pg += width - 1; - pb += width - 1; - *pr++ = r; - *pg++ = g; - *pb++ = b; - } - } - - // bottom line (pr,pg,pb are already lined up) - for (i = 0; i < width; ++i) { - *pr++ = r; - *pg++ = g; - *pb++ = b; - } -} - - -void Image::invert(void) { - register unsigned int i, j, wh = (width * height) - 1; - unsigned char tmp; - - for (i = 0, j = wh; j > i; j--, i++) { - tmp = *(red + j); - *(red + j) = *(red + i); - *(red + i) = tmp; - - tmp = *(green + j); - *(green + j) = *(green + i); - *(green + i) = tmp; - - tmp = *(blue + j); - *(blue + j) = *(blue + i); - *(blue + i) = tmp; - } -} - - -void Image::dgradient(void) { - // diagonal gradient code was written by Mike Cole <mike@mydot.com> - // modified for interlacing by Brad Hughes - - float drx, dgx, dbx, dry, dgy, dby, yr = 0.0, yg = 0.0, yb = 0.0, - xr = (float) from.red(), - xg = (float) from.green(), - xb = (float) from.blue(); - unsigned char *pr = red, *pg = green, *pb = blue; - unsigned int w = width * 2, h = height * 2, *xt = xtable, *yt = ytable; - - register unsigned int x, y; - - dry = drx = (float) (to.red() - from.red()); - dgy = dgx = (float) (to.green() - from.green()); - dby = dbx = (float) (to.blue() - from.blue()); - - // Create X table - drx /= w; - dgx /= w; - dbx /= w; - - for (x = 0; x < width; x++) { - *(xt++) = (unsigned char) (xr); - *(xt++) = (unsigned char) (xg); - *(xt++) = (unsigned char) (xb); - - xr += drx; - xg += dgx; - xb += dbx; - } - - // Create Y table - dry /= h; - dgy /= h; - dby /= h; - - for (y = 0; y < height; y++) { - *(yt++) = ((unsigned char) yr); - *(yt++) = ((unsigned char) yg); - *(yt++) = ((unsigned char) yb); - - yr += dry; - yg += dgy; - yb += dby; - } - - // Combine tables to create gradient - - if (! interlaced) { - // normal dgradient - for (yt = ytable, y = 0; y < height; y++, yt += 3) { - for (xt = xtable, x = 0; x < width; x++) { - *(pr++) = *(xt++) + *(yt); - *(pg++) = *(xt++) + *(yt + 1); - *(pb++) = *(xt++) + *(yt + 2); - } - } - } else { - // faked interlacing effect - unsigned char channel, channel2; - - for (yt = ytable, y = 0; y < height; y++, yt += 3) { - for (xt = xtable, x = 0; x < width; x++) { - if (y & 1) { - channel = *(xt++) + *(yt); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pr++) = channel2; - - channel = *(xt++) + *(yt + 1); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pg++) = channel2; - - channel = *(xt++) + *(yt + 2); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pb++) = channel2; - } else { - channel = *(xt++) + *(yt); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pr++) = channel2; - - channel = *(xt++) + *(yt + 1); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pg++) = channel2; - - channel = *(xt++) + *(yt + 2); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pb++) = channel2; - } - } - } - } -} - - -void Image::hgradient(void) { - float drx, dgx, dbx, - xr = (float) from.red(), - xg = (float) from.green(), - xb = (float) from.blue(); - unsigned char *pr = red, *pg = green, *pb = blue; - - register unsigned int x, y; - - drx = (float) (to.red() - from.red()); - dgx = (float) (to.green() - from.green()); - dbx = (float) (to.blue() - from.blue()); - - drx /= width; - dgx /= width; - dbx /= width; - - if (interlaced && height > 2) { - // faked interlacing effect - unsigned char channel, channel2; - - for (x = 0; x < width; x++, pr++, pg++, pb++) { - channel = (unsigned char) xr; - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *pr = channel2; - - channel = (unsigned char) xg; - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *pg = channel2; - - channel = (unsigned char) xb; - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *pb = channel2; - - - channel = (unsigned char) xr; - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pr + width) = channel2; - - channel = (unsigned char) xg; - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pg + width) = channel2; - - channel = (unsigned char) xb; - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pb + width) = channel2; - - xr += drx; - xg += dgx; - xb += dbx; - } - - pr += width; - pg += width; - pb += width; - - int offset; - - for (y = 2; y < height; y++, pr += width, pg += width, pb += width) { - if (y & 1) offset = width; else offset = 0; - - memcpy(pr, (red + offset), width); - memcpy(pg, (green + offset), width); - memcpy(pb, (blue + offset), width); - } - } else { - // normal hgradient - for (x = 0; x < width; x++) { - *(pr++) = (unsigned char) (xr); - *(pg++) = (unsigned char) (xg); - *(pb++) = (unsigned char) (xb); - - xr += drx; - xg += dgx; - xb += dbx; - } - - for (y = 1; y < height; y++, pr += width, pg += width, pb += width) { - memcpy(pr, red, width); - memcpy(pg, green, width); - memcpy(pb, blue, width); - } - } -} - - -void Image::vgradient(void) { - float dry, dgy, dby, - yr = (float) from.red(), - yg = (float) from.green(), - yb = (float) from.blue(); - unsigned char *pr = red, *pg = green, *pb = blue; - - register unsigned int y; - - dry = (float) (to.red() - from.red()); - dgy = (float) (to.green() - from.green()); - dby = (float) (to.blue() - from.blue()); - - dry /= height; - dgy /= height; - dby /= height; - - if (interlaced) { - // faked interlacing effect - unsigned char channel, channel2; - - for (y = 0; y < height; y++, pr += width, pg += width, pb += width) { - if (y & 1) { - channel = (unsigned char) yr; - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - memset(pr, channel2, width); - - channel = (unsigned char) yg; - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - memset(pg, channel2, width); - - channel = (unsigned char) yb; - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - memset(pb, channel2, width); - } else { - channel = (unsigned char) yr; - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - memset(pr, channel2, width); - - channel = (unsigned char) yg; - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - memset(pg, channel2, width); - - channel = (unsigned char) yb; - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - memset(pb, channel2, width); - } - - yr += dry; - yg += dgy; - yb += dby; - } - } else { - // normal vgradient - for (y = 0; y < height; y++, pr += width, pg += width, pb += width) { - memset(pr, (unsigned char) yr, width); - memset(pg, (unsigned char) yg, width); - memset(pb, (unsigned char) yb, width); - - yr += dry; - yg += dgy; - yb += dby; - } - } -} - - -void Image::pgradient(void) { - // pyramid gradient - based on original dgradient, written by - // Mosfet (mosfet@kde.org) - // adapted from kde sources for Blackbox by Brad Hughes - - float yr, yg, yb, drx, dgx, dbx, dry, dgy, dby, - xr, xg, xb; - int rsign, gsign, bsign; - unsigned char *pr = red, *pg = green, *pb = blue; - unsigned int tr = to.red(), tg = to.green(), tb = to.blue(), - *xt = xtable, *yt = ytable; - - register unsigned int x, y; - - dry = drx = (float) (to.red() - from.red()); - dgy = dgx = (float) (to.green() - from.green()); - dby = dbx = (float) (to.blue() - from.blue()); - - rsign = (drx < 0) ? -1 : 1; - gsign = (dgx < 0) ? -1 : 1; - bsign = (dbx < 0) ? -1 : 1; - - xr = yr = (drx / 2); - xg = yg = (dgx / 2); - xb = yb = (dbx / 2); - - // Create X table - drx /= width; - dgx /= width; - dbx /= width; - - for (x = 0; x < width; x++) { - *(xt++) = (unsigned char) ((xr < 0) ? -xr : xr); - *(xt++) = (unsigned char) ((xg < 0) ? -xg : xg); - *(xt++) = (unsigned char) ((xb < 0) ? -xb : xb); - - xr -= drx; - xg -= dgx; - xb -= dbx; - } - - // Create Y table - dry /= height; - dgy /= height; - dby /= height; - - for (y = 0; y < height; y++) { - *(yt++) = ((unsigned char) ((yr < 0) ? -yr : yr)); - *(yt++) = ((unsigned char) ((yg < 0) ? -yg : yg)); - *(yt++) = ((unsigned char) ((yb < 0) ? -yb : yb)); - - yr -= dry; - yg -= dgy; - yb -= dby; - } - - // Combine tables to create gradient - - if (! interlaced) { - // normal pgradient - for (yt = ytable, y = 0; y < height; y++, yt += 3) { - for (xt = xtable, x = 0; x < width; x++) { - *(pr++) = (unsigned char) (tr - (rsign * (*(xt++) + *(yt)))); - *(pg++) = (unsigned char) (tg - (gsign * (*(xt++) + *(yt + 1)))); - *(pb++) = (unsigned char) (tb - (bsign * (*(xt++) + *(yt + 2)))); - } - } - } else { - // faked interlacing effect - unsigned char channel, channel2; - - for (yt = ytable, y = 0; y < height; y++, yt += 3) { - for (xt = xtable, x = 0; x < width; x++) { - if (y & 1) { - channel = (unsigned char) (tr - (rsign * (*(xt++) + *(yt)))); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pr++) = channel2; - - channel = (unsigned char) (tg - (gsign * (*(xt++) + *(yt + 1)))); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pg++) = channel2; - - channel = (unsigned char) (tb - (bsign * (*(xt++) + *(yt + 2)))); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pb++) = channel2; - } else { - channel = (unsigned char) (tr - (rsign * (*(xt++) + *(yt)))); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pr++) = channel2; - - channel = (unsigned char) (tg - (gsign * (*(xt++) + *(yt + 1)))); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pg++) = channel2; - - channel = (unsigned char) (tb - (bsign * (*(xt++) + *(yt + 2)))); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pb++) = channel2; - } - } - } - } -} - - -void Image::rgradient(void) { - // rectangle gradient - based on original dgradient, written by - // Mosfet (mosfet@kde.org) - // adapted from kde sources for Blackbox by Brad Hughes - - float drx, dgx, dbx, dry, dgy, dby, xr, xg, xb, yr, yg, yb; - int rsign, gsign, bsign; - unsigned char *pr = red, *pg = green, *pb = blue; - unsigned int tr = to.red(), tg = to.green(), tb = to.blue(), - *xt = xtable, *yt = ytable; - - register unsigned int x, y; - - dry = drx = (float) (to.red() - from.red()); - dgy = dgx = (float) (to.green() - from.green()); - dby = dbx = (float) (to.blue() - from.blue()); - - rsign = (drx < 0) ? -2 : 2; - gsign = (dgx < 0) ? -2 : 2; - bsign = (dbx < 0) ? -2 : 2; - - xr = yr = (drx / 2); - xg = yg = (dgx / 2); - xb = yb = (dbx / 2); - - // Create X table - drx /= width; - dgx /= width; - dbx /= width; - - for (x = 0; x < width; x++) { - *(xt++) = (unsigned char) ((xr < 0) ? -xr : xr); - *(xt++) = (unsigned char) ((xg < 0) ? -xg : xg); - *(xt++) = (unsigned char) ((xb < 0) ? -xb : xb); - - xr -= drx; - xg -= dgx; - xb -= dbx; - } - - // Create Y table - dry /= height; - dgy /= height; - dby /= height; - - for (y = 0; y < height; y++) { - *(yt++) = ((unsigned char) ((yr < 0) ? -yr : yr)); - *(yt++) = ((unsigned char) ((yg < 0) ? -yg : yg)); - *(yt++) = ((unsigned char) ((yb < 0) ? -yb : yb)); - - yr -= dry; - yg -= dgy; - yb -= dby; - } - - // Combine tables to create gradient - - if (! interlaced) { - // normal rgradient - for (yt = ytable, y = 0; y < height; y++, yt += 3) { - for (xt = xtable, x = 0; x < width; x++) { - *(pr++) = (unsigned char) (tr - (rsign * max(*(xt++), *(yt)))); - *(pg++) = (unsigned char) (tg - (gsign * max(*(xt++), *(yt + 1)))); - *(pb++) = (unsigned char) (tb - (bsign * max(*(xt++), *(yt + 2)))); - } - } - } else { - // faked interlacing effect - unsigned char channel, channel2; - - for (yt = ytable, y = 0; y < height; y++, yt += 3) { - for (xt = xtable, x = 0; x < width; x++) { - if (y & 1) { - channel = (unsigned char) (tr - (rsign * max(*(xt++), *(yt)))); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pr++) = channel2; - - channel = (unsigned char) (tg - (gsign * max(*(xt++), *(yt + 1)))); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pg++) = channel2; - - channel = (unsigned char) (tb - (bsign * max(*(xt++), *(yt + 2)))); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pb++) = channel2; - } else { - channel = (unsigned char) (tr - (rsign * max(*(xt++), *(yt)))); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pr++) = channel2; - - channel = (unsigned char) (tg - (gsign * max(*(xt++), *(yt + 1)))); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pg++) = channel2; - - channel = (unsigned char) (tb - (bsign * max(*(xt++), *(yt + 2)))); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pb++) = channel2; - } - } - } - } -} - - -void Image::egradient(void) { - // elliptic gradient - based on original dgradient, written by - // Mosfet (mosfet@kde.org) - // adapted from kde sources for Blackbox by Brad Hughes - - float drx, dgx, dbx, dry, dgy, dby, yr, yg, yb, xr, xg, xb; - int rsign, gsign, bsign; - unsigned char *pr = red, *pg = green, *pb = blue; - unsigned int *xt = xtable, *yt = ytable, - tr = (unsigned long) to.red(), - tg = (unsigned long) to.green(), - tb = (unsigned long) to.blue(); - - register unsigned int x, y; - - dry = drx = (float) (to.red() - from.red()); - dgy = dgx = (float) (to.green() - from.green()); - dby = dbx = (float) (to.blue() - from.blue()); - - rsign = (drx < 0) ? -1 : 1; - gsign = (dgx < 0) ? -1 : 1; - bsign = (dbx < 0) ? -1 : 1; - - xr = yr = (drx / 2); - xg = yg = (dgx / 2); - xb = yb = (dbx / 2); - - // Create X table - drx /= width; - dgx /= width; - dbx /= width; - - for (x = 0; x < width; x++) { - *(xt++) = (unsigned long) (xr * xr); - *(xt++) = (unsigned long) (xg * xg); - *(xt++) = (unsigned long) (xb * xb); - - xr -= drx; - xg -= dgx; - xb -= dbx; - } - - // Create Y table - dry /= height; - dgy /= height; - dby /= height; - - for (y = 0; y < height; y++) { - *(yt++) = (unsigned long) (yr * yr); - *(yt++) = (unsigned long) (yg * yg); - *(yt++) = (unsigned long) (yb * yb); - - yr -= dry; - yg -= dgy; - yb -= dby; - } - - // Combine tables to create gradient - - if (! interlaced) { - // normal egradient - for (yt = ytable, y = 0; y < height; y++, yt += 3) { - for (xt = xtable, x = 0; x < width; x++) { - *(pr++) = (unsigned char) - (tr - (rsign * control->getSqrt(*(xt++) + *(yt)))); - *(pg++) = (unsigned char) - (tg - (gsign * control->getSqrt(*(xt++) + *(yt + 1)))); - *(pb++) = (unsigned char) - (tb - (bsign * control->getSqrt(*(xt++) + *(yt + 2)))); - } - } - } else { - // faked interlacing effect - unsigned char channel, channel2; - - for (yt = ytable, y = 0; y < height; y++, yt += 3) { - for (xt = xtable, x = 0; x < width; x++) { - if (y & 1) { - channel = (unsigned char) - (tr - (rsign * control->getSqrt(*(xt++) + *(yt)))); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pr++) = channel2; - - channel = (unsigned char) - (tg - (gsign * control->getSqrt(*(xt++) + *(yt + 1)))); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pg++) = channel2; - - channel = (unsigned char) - (tb - (bsign * control->getSqrt(*(xt++) + *(yt + 2)))); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pb++) = channel2; - } else { - channel = (unsigned char) - (tr - (rsign * control->getSqrt(*(xt++) + *(yt)))); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pr++) = channel2; - - channel = (unsigned char) - (tg - (gsign * control->getSqrt(*(xt++) + *(yt + 1)))); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pg++) = channel2; - - channel = (unsigned char) - (tb - (bsign * control->getSqrt(*(xt++) + *(yt + 2)))); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pb++) = channel2; - } - } - } - } -} - - -void Image::pcgradient(void) { - // pipe cross gradient - based on original dgradient, written by - // Mosfet (mosfet@kde.org) - // adapted from kde sources for Blackbox by Brad Hughes - - float drx, dgx, dbx, dry, dgy, dby, xr, xg, xb, yr, yg, yb; - int rsign, gsign, bsign; - unsigned char *pr = red, *pg = green, *pb = blue; - unsigned int *xt = xtable, *yt = ytable, - tr = to.red(), - tg = to.green(), - tb = to.blue(); - - register unsigned int x, y; - - dry = drx = (float) (to.red() - from.red()); - dgy = dgx = (float) (to.green() - from.green()); - dby = dbx = (float) (to.blue() - from.blue()); - - rsign = (drx < 0) ? -2 : 2; - gsign = (dgx < 0) ? -2 : 2; - bsign = (dbx < 0) ? -2 : 2; - - xr = yr = (drx / 2); - xg = yg = (dgx / 2); - xb = yb = (dbx / 2); - - // Create X table - drx /= width; - dgx /= width; - dbx /= width; - - for (x = 0; x < width; x++) { - *(xt++) = (unsigned char) ((xr < 0) ? -xr : xr); - *(xt++) = (unsigned char) ((xg < 0) ? -xg : xg); - *(xt++) = (unsigned char) ((xb < 0) ? -xb : xb); - - xr -= drx; - xg -= dgx; - xb -= dbx; - } - - // Create Y table - dry /= height; - dgy /= height; - dby /= height; - - for (y = 0; y < height; y++) { - *(yt++) = ((unsigned char) ((yr < 0) ? -yr : yr)); - *(yt++) = ((unsigned char) ((yg < 0) ? -yg : yg)); - *(yt++) = ((unsigned char) ((yb < 0) ? -yb : yb)); - - yr -= dry; - yg -= dgy; - yb -= dby; - } - - // Combine tables to create gradient - - if (! interlaced) { - // normal pcgradient - for (yt = ytable, y = 0; y < height; y++, yt += 3) { - for (xt = xtable, x = 0; x < width; x++) { - *(pr++) = (unsigned char) (tr - (rsign * min(*(xt++), *(yt)))); - *(pg++) = (unsigned char) (tg - (gsign * min(*(xt++), *(yt + 1)))); - *(pb++) = (unsigned char) (tb - (bsign * min(*(xt++), *(yt + 2)))); - } - } - } else { - // faked interlacing effect - unsigned char channel, channel2; - - for (yt = ytable, y = 0; y < height; y++, yt += 3) { - for (xt = xtable, x = 0; x < width; x++) { - if (y & 1) { - channel = (unsigned char) (tr - (rsign * min(*(xt++), *(yt)))); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pr++) = channel2; - - channel = (unsigned char) (tg - (bsign * min(*(xt++), *(yt + 1)))); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pg++) = channel2; - - channel = (unsigned char) (tb - (gsign * min(*(xt++), *(yt + 2)))); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pb++) = channel2; - } else { - channel = (unsigned char) (tr - (rsign * min(*(xt++), *(yt)))); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pr++) = channel2; - - channel = (unsigned char) (tg - (gsign * min(*(xt++), *(yt + 1)))); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pg++) = channel2; - - channel = (unsigned char) (tb - (bsign * min(*(xt++), *(yt + 2)))); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pb++) = channel2; - } - } - } - } -} - - -void Image::cdgradient(void) { - // cross diagonal gradient - based on original dgradient, written by - // Mosfet (mosfet@kde.org) - // adapted from kde sources for Blackbox by Brad Hughes - - float drx, dgx, dbx, dry, dgy, dby, yr = 0.0, yg = 0.0, yb = 0.0, - xr = (float) from.red(), - xg = (float) from.green(), - xb = (float) from.blue(); - unsigned char *pr = red, *pg = green, *pb = blue; - unsigned int w = width * 2, h = height * 2, *xt, *yt; - - register unsigned int x, y; - - dry = drx = (float) (to.red() - from.red()); - dgy = dgx = (float) (to.green() - from.green()); - dby = dbx = (float) (to.blue() - from.blue()); - - // Create X table - drx /= w; - dgx /= w; - dbx /= w; - - for (xt = (xtable + (width * 3) - 1), x = 0; x < width; x++) { - *(xt--) = (unsigned char) xb; - *(xt--) = (unsigned char) xg; - *(xt--) = (unsigned char) xr; - - xr += drx; - xg += dgx; - xb += dbx; - } - - // Create Y table - dry /= h; - dgy /= h; - dby /= h; - - for (yt = ytable, y = 0; y < height; y++) { - *(yt++) = (unsigned char) yr; - *(yt++) = (unsigned char) yg; - *(yt++) = (unsigned char) yb; - - yr += dry; - yg += dgy; - yb += dby; - } - - // Combine tables to create gradient - - if (! interlaced) { - // normal cdgradient - for (yt = ytable, y = 0; y < height; y++, yt += 3) { - for (xt = xtable, x = 0; x < width; x++) { - *(pr++) = *(xt++) + *(yt); - *(pg++) = *(xt++) + *(yt + 1); - *(pb++) = *(xt++) + *(yt + 2); - } - } - } else { - // faked interlacing effect - unsigned char channel, channel2; - - for (yt = ytable, y = 0; y < height; y++, yt += 3) { - for (xt = xtable, x = 0; x < width; x++) { - if (y & 1) { - channel = *(xt++) + *(yt); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pr++) = channel2; - - channel = *(xt++) + *(yt + 1); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pg++) = channel2; - - channel = *(xt++) + *(yt + 2); - channel2 = (channel >> 1) + (channel >> 2); - if (channel2 > channel) channel2 = 0; - *(pb++) = channel2; - } else { - channel = *(xt++) + *(yt); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pr++) = channel2; - - channel = *(xt++) + *(yt + 1); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pg++) = channel2; - - channel = *(xt++) + *(yt + 2); - channel2 = channel + (channel >> 3); - if (channel2 < channel) channel2 = ~0; - *(pb++) = channel2; - } - } - } - } -} - -}
D otk/image.hh

@@ -1,147 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- -#ifndef __image_hh -#define __image_hh - -extern "C" { -#include <X11/Xlib.h> -#include <X11/Xutil.h> -} - -#include <list> - -#include "color.hh" -#include "screeninfo.hh" -#include "timer.hh" - -namespace otk { - -class ImageControl; -class Texture; -class ScreenInfo; - -class Image { -private: - ImageControl *control; - bool interlaced; - XColor *colors; - - Color from, to; - int red_offset, green_offset, blue_offset, red_bits, green_bits, blue_bits, - ncolors, cpc, cpccpc; - unsigned char *red, *green, *blue, *red_table, *green_table, *blue_table; - unsigned int width, height, *xtable, *ytable; - - void TrueColorDither(unsigned int bit_depth, int bytes_per_line, - unsigned char *pixel_data); - void PseudoColorDither(int bytes_per_line, unsigned char *pixel_data); -#ifdef ORDEREDPSEUDO - void OrderedPseudoColorDither(int bytes_per_line, unsigned char *pixel_data); -#endif - - Pixmap renderPixmap(void); - Pixmap render_solid(const Texture &texture); - Pixmap render_gradient(const Texture &texture); - - XImage *renderXImage(void); - - void invert(void); - void bevel1(void); - void bevel2(void); - void border(const Texture &texture); - void dgradient(void); - void egradient(void); - void hgradient(void); - void pgradient(void); - void rgradient(void); - void vgradient(void); - void cdgradient(void); - void pcgradient(void); - - -public: - Image(ImageControl *c, int w, int h); - ~Image(void); - - Pixmap render(const Texture &texture); -}; - - -class ImageControl { -public: -#ifndef SWIG - struct CachedImage { - Pixmap pixmap; - - unsigned int count, width, height; - unsigned long pixel1, pixel2, texture; - }; -#endif - - ImageControl(const otk::ScreenInfo *scrn, - bool _dither= False, int _cpc = 4, - unsigned long cache_timeout = 300000l, - unsigned long cmax = 200l); - virtual ~ImageControl(void); - - inline bool doDither(void) { return dither; } - - inline const ScreenInfo* getScreenInfo() const { return screeninfo; } - - inline Window getDrawable(void) const { return window; } - - inline Visual *getVisual(void) { return screeninfo->visual(); } - - inline int getBitsPerPixel(void) const { return bits_per_pixel; } - inline int getDepth(void) const { return screen_depth; } - inline int getColorsPerChannel(void) const - { return colors_per_channel; } - - unsigned long getSqrt(unsigned int x); - - Pixmap renderImage(unsigned int width, unsigned int height, - const Texture &texture); - - void installRootColormap(void); - void removeImage(Pixmap pixmap); - void getColorTables(unsigned char **rmt, unsigned char **gmt, - unsigned char **bmt, - int *roff, int *goff, int *boff, - int *rbit, int *gbit, int *bbit); - void getXColorTable(XColor **c, int *n); - void getGradientBuffers(unsigned int w, unsigned int h, - unsigned int **xbuf, unsigned int **ybuf); - void setDither(bool d) { dither = d; } - void setColorsPerChannel(int cpc); - - static void timeout(ImageControl *t); - -private: - bool dither; - const ScreenInfo *screeninfo; - Timer *timer; - - Colormap colormap; - - Window window; - XColor *colors; - int colors_per_channel, ncolors, screen_number, screen_depth, - bits_per_pixel, red_offset, green_offset, blue_offset, - red_bits, green_bits, blue_bits; - unsigned char red_color_table[256], green_color_table[256], - blue_color_table[256]; - unsigned int *grad_xbuffer, *grad_ybuffer, grad_buffer_width, - grad_buffer_height; - unsigned long *sqrt_table, cache_max; - - typedef std::list<CachedImage> CacheContainer; - CacheContainer cache; - - Pixmap searchCache(const unsigned int width, const unsigned int height, - const unsigned long texture, - const Color &c1, const Color &c2); -}; - -} - -#endif // __image_hh -
D otk/imagecontrol.cc

@@ -1,556 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif // HAVE_CONFIG_H - -extern "C" { -#ifdef HAVE_STDIO_H -# include <stdio.h> -#endif // HAVE_STDIO_H - -#ifdef HAVE_CTYPE_H -# include <ctype.h> -#endif // HAVE_CTYPE_H - -#include <X11/Xlib.h> -} - -#include <algorithm> - -#include "display.hh" -#include "color.hh" -#include "image.hh" -#include "texture.hh" - -namespace otk { - -static unsigned long bsqrt(unsigned long x) { - if (x <= 0) return 0; - if (x == 1) return 1; - - unsigned long r = x >> 1; - unsigned long q; - - while (1) { - q = x / r; - if (q >= r) return r; - r = (r + q) >> 1; - } -} - -ImageControl *ctrl = 0; - -ImageControl::ImageControl(const ScreenInfo *scrn, - bool _dither, int _cpc, - unsigned long cache_timeout, - unsigned long cmax) { - if (! ctrl) ctrl = this; - - screeninfo = scrn; - setDither(_dither); - setColorsPerChannel(_cpc); - - cache_max = cmax; - if (cache_timeout) - timer = new Timer(cache_timeout, (Timer::TimeoutHandler)timeout, this); - else - timer = (Timer *) 0; - - colors = (XColor *) 0; - ncolors = 0; - - grad_xbuffer = grad_ybuffer = (unsigned int *) 0; - grad_buffer_width = grad_buffer_height = 0; - - sqrt_table = (unsigned long *) 0; - - screen_depth = screeninfo->depth(); - window = screeninfo->rootWindow(); - screen_number = screeninfo->screen(); - colormap = screeninfo->colormap(); - - int count; - XPixmapFormatValues *pmv = XListPixmapFormats(**display, - &count); - if (pmv) { - bits_per_pixel = 0; - for (int i = 0; i < count; i++) - if (pmv[i].depth == screen_depth) { - bits_per_pixel = pmv[i].bits_per_pixel; - break; - } - - XFree(pmv); - } - - if (bits_per_pixel == 0) bits_per_pixel = screen_depth; - if (bits_per_pixel >= 24) setDither(False); - - red_offset = green_offset = blue_offset = 0; - - switch (getVisual()->c_class) { - case TrueColor: { - int i; - - // compute color tables - unsigned long red_mask = getVisual()->red_mask, - green_mask = getVisual()->green_mask, - blue_mask = getVisual()->blue_mask; - - while (! (red_mask & 1)) { red_offset++; red_mask >>= 1; } - while (! (green_mask & 1)) { green_offset++; green_mask >>= 1; } - while (! (blue_mask & 1)) { blue_offset++; blue_mask >>= 1; } - - red_bits = 255 / red_mask; - green_bits = 255 / green_mask; - blue_bits = 255 / blue_mask; - - for (i = 0; i < 256; i++) { - red_color_table[i] = i / red_bits; - green_color_table[i] = i / green_bits; - blue_color_table[i] = i / blue_bits; - } - break; - } - - case PseudoColor: - case StaticColor: { - ncolors = colors_per_channel * colors_per_channel * colors_per_channel; - - if (ncolors > (1 << screen_depth)) { - colors_per_channel = (1 << screen_depth) / 3; - ncolors = colors_per_channel * colors_per_channel * colors_per_channel; - } - - if (colors_per_channel < 2 || ncolors > (1 << screen_depth)) { - fprintf(stderr, - "ImageControl::ImageControl: invalid colormap size %d " - "(%d/%d/%d) - reducing", - ncolors, colors_per_channel, colors_per_channel, - colors_per_channel); - - colors_per_channel = (1 << screen_depth) / 3; - } - - colors = new XColor[ncolors]; - if (! colors) { - fprintf(stderr, "ImageControl::ImageControl: error allocating " - "colormap\n"); - exit(1); - } - - int i = 0, ii, p, r, g, b, - -#ifdef ORDEREDPSEUDO - bits = 256 / colors_per_channel; -#else // !ORDEREDPSEUDO - bits = 255 / (colors_per_channel - 1); -#endif // ORDEREDPSEUDO - - red_bits = green_bits = blue_bits = bits; - - for (i = 0; i < 256; i++) - red_color_table[i] = green_color_table[i] = blue_color_table[i] = - i / bits; - - for (r = 0, i = 0; r < colors_per_channel; r++) - for (g = 0; g < colors_per_channel; g++) - for (b = 0; b < colors_per_channel; b++, i++) { - colors[i].red = (r * 0xffff) / (colors_per_channel - 1); - colors[i].green = (g * 0xffff) / (colors_per_channel - 1); - colors[i].blue = (b * 0xffff) / (colors_per_channel - 1);; - colors[i].flags = DoRed|DoGreen|DoBlue; - } - - for (i = 0; i < ncolors; i++) { - if (! XAllocColor(**display, colormap, &colors[i])) { - fprintf(stderr, "couldn't alloc color %i %i %i\n", - colors[i].red, colors[i].green, colors[i].blue); - colors[i].flags = 0; - } else { - colors[i].flags = DoRed|DoGreen|DoBlue; - } - } - - XColor icolors[256]; - int incolors = (((1 << screen_depth) > 256) ? 256 : (1 << screen_depth)); - - for (i = 0; i < incolors; i++) - icolors[i].pixel = i; - - XQueryColors(**display, colormap, icolors, incolors); - for (i = 0; i < ncolors; i++) { - if (! colors[i].flags) { - unsigned long chk = 0xffffffff, pixel, close = 0; - - p = 2; - while (p--) { - for (ii = 0; ii < incolors; ii++) { - r = (colors[i].red - icolors[i].red) >> 8; - g = (colors[i].green - icolors[i].green) >> 8; - b = (colors[i].blue - icolors[i].blue) >> 8; - pixel = (r * r) + (g * g) + (b * b); - - if (pixel < chk) { - chk = pixel; - close = ii; - } - - colors[i].red = icolors[close].red; - colors[i].green = icolors[close].green; - colors[i].blue = icolors[close].blue; - - if (XAllocColor(**display, colormap, - &colors[i])) { - colors[i].flags = DoRed|DoGreen|DoBlue; - break; - } - } - } - } - } - - break; - } - - case GrayScale: - case StaticGray: { - if (getVisual()->c_class == StaticGray) { - ncolors = 1 << screen_depth; - } else { - ncolors = colors_per_channel * colors_per_channel * colors_per_channel; - - if (ncolors > (1 << screen_depth)) { - colors_per_channel = (1 << screen_depth) / 3; - ncolors = - colors_per_channel * colors_per_channel * colors_per_channel; - } - } - - if (colors_per_channel < 2 || ncolors > (1 << screen_depth)) { - fprintf(stderr, - "ImageControl::ImageControl: invalid colormap size %d " - "(%d/%d/%d) - reducing", - ncolors, colors_per_channel, colors_per_channel, - colors_per_channel); - - colors_per_channel = (1 << screen_depth) / 3; - } - - colors = new XColor[ncolors]; - if (! colors) { - fprintf(stderr, - "ImageControl::ImageControl: error allocating colormap\n"); - exit(1); - } - - int i = 0, ii, p, bits = 255 / (colors_per_channel - 1); - red_bits = green_bits = blue_bits = bits; - - for (i = 0; i < 256; i++) - red_color_table[i] = green_color_table[i] = blue_color_table[i] = - i / bits; - - for (i = 0; i < ncolors; i++) { - colors[i].red = (i * 0xffff) / (colors_per_channel - 1); - colors[i].green = (i * 0xffff) / (colors_per_channel - 1); - colors[i].blue = (i * 0xffff) / (colors_per_channel - 1);; - colors[i].flags = DoRed|DoGreen|DoBlue; - - if (! XAllocColor(**display, colormap, - &colors[i])) { - fprintf(stderr, "couldn't alloc color %i %i %i\n", - colors[i].red, colors[i].green, colors[i].blue); - colors[i].flags = 0; - } else { - colors[i].flags = DoRed|DoGreen|DoBlue; - } - } - - XColor icolors[256]; - int incolors = (((1 << screen_depth) > 256) ? 256 : - (1 << screen_depth)); - - for (i = 0; i < incolors; i++) - icolors[i].pixel = i; - - XQueryColors(**display, colormap, icolors, incolors); - for (i = 0; i < ncolors; i++) { - if (! colors[i].flags) { - unsigned long chk = 0xffffffff, pixel, close = 0; - - p = 2; - while (p--) { - for (ii = 0; ii < incolors; ii++) { - int r = (colors[i].red - icolors[i].red) >> 8; - int g = (colors[i].green - icolors[i].green) >> 8; - int b = (colors[i].blue - icolors[i].blue) >> 8; - pixel = (r * r) + (g * g) + (b * b); - - if (pixel < chk) { - chk = pixel; - close = ii; - } - - colors[i].red = icolors[close].red; - colors[i].green = icolors[close].green; - colors[i].blue = icolors[close].blue; - - if (XAllocColor(**display, colormap, - &colors[i])) { - colors[i].flags = DoRed|DoGreen|DoBlue; - break; - } - } - } - } - } - - break; - } - - default: - fprintf(stderr, "ImageControl::ImageControl: unsupported visual %d\n", - getVisual()->c_class); - exit(1); - } -} - - -ImageControl::~ImageControl(void) { - delete [] sqrt_table; - - delete [] grad_xbuffer; - - delete [] grad_ybuffer; - - if (colors) { - unsigned long *pixels = new unsigned long [ncolors]; - - for (int i = 0; i < ncolors; i++) - *(pixels + i) = (*(colors + i)).pixel; - - XFreeColors(**display, colormap, pixels, ncolors, 0); - - delete [] colors; - } - - if (! cache.empty()) { - //#ifdef DEBUG - fprintf(stderr, "ImageContol::~ImageControl: pixmap cache - " - "releasing %d pixmaps\n", cache.size()); - //#endif - CacheContainer::iterator it = cache.begin(); - const CacheContainer::iterator end = cache.end(); - for (; it != end; ++it) - XFreePixmap(**display, it->pixmap); - } - if (timer) - delete timer; -} - - -Pixmap ImageControl::searchCache(const unsigned int width, - const unsigned int height, - const unsigned long texture, - const Color &c1, const Color &c2) { - if (cache.empty()) - return None; - - CacheContainer::iterator it = cache.begin(); - const CacheContainer::iterator end = cache.end(); - for (; it != end; ++it) { - CachedImage& tmp = *it; - if (tmp.width == width && tmp.height == height && - tmp.texture == texture && tmp.pixel1 == c1.pixel()) - if (texture & Texture::Gradient) { - if (tmp.pixel2 == c2.pixel()) { - tmp.count++; - return tmp.pixmap; - } - } else { - tmp.count++; - return tmp.pixmap; - } - } - return None; -} - - -Pixmap ImageControl::renderImage(unsigned int width, unsigned int height, - const Texture &texture) { - if (texture.texture() & Texture::Parent_Relative) return ParentRelative; - - Pixmap pixmap = searchCache(width, height, texture.texture(), - texture.color(), texture.colorTo()); - if (pixmap) return pixmap; - - Image image(this, width, height); - pixmap = image.render(texture); - - if (! pixmap) - return None; - - CachedImage tmp; - - tmp.pixmap = pixmap; - tmp.width = width; - tmp.height = height; - tmp.count = 1; - tmp.texture = texture.texture(); - tmp.pixel1 = texture.color().pixel(); - - if (texture.texture() & Texture::Gradient) - tmp.pixel2 = texture.colorTo().pixel(); - else - tmp.pixel2 = 0l; - - cache.push_back(tmp); - - if (cache.size() > cache_max) { -#ifdef DEBUG - fprintf(stderr, "ImageControl::renderImage: cache is large, " - "forcing cleanout\n"); -#endif // DEBUG - - timeout(this); - } - - return pixmap; -} - - -void ImageControl::removeImage(Pixmap pixmap) { - if (! pixmap) - return; - - CacheContainer::iterator it = cache.begin(); - const CacheContainer::iterator end = cache.end(); - for (; it != end; ++it) { - CachedImage &tmp = *it; - if (tmp.pixmap == pixmap && tmp.count > 0) - tmp.count--; - } - - if (! timer) - timeout(this); -} - - -void ImageControl::getColorTables(unsigned char **rmt, unsigned char **gmt, - unsigned char **bmt, - int *roff, int *goff, int *boff, - int *rbit, int *gbit, int *bbit) { - if (rmt) *rmt = red_color_table; - if (gmt) *gmt = green_color_table; - if (bmt) *bmt = blue_color_table; - - if (roff) *roff = red_offset; - if (goff) *goff = green_offset; - if (boff) *boff = blue_offset; - - if (rbit) *rbit = red_bits; - if (gbit) *gbit = green_bits; - if (bbit) *bbit = blue_bits; -} - - -void ImageControl::getXColorTable(XColor **c, int *n) { - if (c) *c = colors; - if (n) *n = ncolors; -} - - -void ImageControl::getGradientBuffers(unsigned int w, - unsigned int h, - unsigned int **xbuf, - unsigned int **ybuf) -{ - if (w > grad_buffer_width) { - if (grad_xbuffer) - delete [] grad_xbuffer; - - grad_buffer_width = w; - - grad_xbuffer = new unsigned int[grad_buffer_width * 3]; - } - - if (h > grad_buffer_height) { - if (grad_ybuffer) - delete [] grad_ybuffer; - - grad_buffer_height = h; - - grad_ybuffer = new unsigned int[grad_buffer_height * 3]; - } - - *xbuf = grad_xbuffer; - *ybuf = grad_ybuffer; -} - - -void ImageControl::installRootColormap(void) { - int ncmap = 0; - Colormap *cmaps = - XListInstalledColormaps(**display, window, &ncmap); - - if (cmaps) { - bool install = True; - for (int i = 0; i < ncmap; i++) - if (*(cmaps + i) == colormap) - install = False; - - if (install) - XInstallColormap(**display, colormap); - - XFree(cmaps); - } -} - - -void ImageControl::setColorsPerChannel(int cpc) { - if (cpc < 2) cpc = 2; - if (cpc > 6) cpc = 6; - - colors_per_channel = cpc; -} - - -unsigned long ImageControl::getSqrt(unsigned int x) { - if (! sqrt_table) { - // build sqrt table for use with elliptic gradient - - sqrt_table = new unsigned long[(256 * 256 * 2) + 1]; - - for (int i = 0; i < (256 * 256 * 2); i++) - *(sqrt_table + i) = bsqrt(i); - } - - return (*(sqrt_table + x)); -} - - -struct ZeroRefCheck { - inline bool operator()(const ImageControl::CachedImage &image) const { - return (image.count == 0); - } -}; - -struct CacheCleaner { - ZeroRefCheck ref_check; - CacheCleaner() {} - inline void operator()(const ImageControl::CachedImage& image) const { - if (ref_check(image)) - XFreePixmap(**display, image.pixmap); - } -}; - - -void ImageControl::timeout(ImageControl *t) { - CacheCleaner cleaner; - std::for_each(t->cache.begin(), t->cache.end(), cleaner); - t->cache.remove_if(cleaner.ref_check); -} - -}
D otk/style.cc

@@ -1,273 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif - -#include <assert.h> -#include <iostream> - -#include "display.hh" -#include "util.hh" -#include "style.hh" - -namespace otk { - -Style::Style() : font(NULL) -{ -} - -Style::Style(ImageControl *ctrl) - : image_control(ctrl), font(0), - screen_number(ctrl->getScreenInfo()->screen()) -{ -} - -Style::~Style() { - if (font) - delete font; - - if (close_button.mask != None) - XFreePixmap(**display, close_button.mask); - if (max_button.mask != None) - XFreePixmap(**display, max_button.mask); - if (icon_button.mask != None) - XFreePixmap(**display, icon_button.mask); - if (stick_button.mask != None) - XFreePixmap(**display, stick_button.mask); - - max_button.mask = None; - close_button.mask = None; - icon_button.mask = None; - stick_button.mask = None; -} - -void Style::load(const Configuration &style) { - std::string s; - - // load fonts/fontsets - if (font) - delete font; - - font = readDatabaseFont("window.", style); - - // load window config - t_focus = readDatabaseTexture("window.title.focus", "white", style); - t_unfocus = readDatabaseTexture("window.title.unfocus", "black", style); - - l_focus = readDatabaseTexture("window.label.focus", "white", style); - l_unfocus = readDatabaseTexture("window.label.unfocus", "black", style); - - h_focus = readDatabaseTexture("window.handle.focus", "white", style); - h_unfocus = readDatabaseTexture("window.handle.unfocus", "black", style); - - g_focus = readDatabaseTexture("window.grip.focus", "white", style); - g_unfocus = readDatabaseTexture("window.grip.unfocus", "black", style); - - b_focus = readDatabaseTexture("window.button.focus", "white", style); - b_unfocus = readDatabaseTexture("window.button.unfocus", "black", style); - - //if neither of these can be found, we will use the previous resource - b_pressed_focus = readDatabaseTexture("window.button.pressed.focus", - "black", style, true); - if (b_pressed_focus.texture() == Texture::NoTexture) { - b_pressed_focus = readDatabaseTexture("window.button.pressed", "black", - style); - } - - b_pressed_unfocus = readDatabaseTexture("window.button.pressed.unfocus", - "black", style, true); - if (b_pressed_unfocus.texture() == Texture::NoTexture) { - b_pressed_unfocus = readDatabaseTexture("window.button.pressed", "black", - style); - } - - if (close_button.mask != None) - XFreePixmap(**display, close_button.mask); - if (max_button.mask != None) - XFreePixmap(**display, max_button.mask); - if (icon_button.mask != None) - XFreePixmap(**display, icon_button.mask); - if (stick_button.mask != None) - XFreePixmap(**display, stick_button.mask); - - close_button.mask = max_button.mask = icon_button.mask - = icon_button.mask = None; - - readDatabaseMask("window.button.close.mask", close_button, style); - readDatabaseMask("window.button.max.mask", max_button, style); - readDatabaseMask("window.button.icon.mask", icon_button, style); - readDatabaseMask("window.button.stick.mask", stick_button, style); - - // we create the window.frame texture by hand because it exists only to - // make the code cleaner and is not actually used for display - Color color = readDatabaseColor("window.frame.focusColor", "white", - style); - f_focus = Texture("solid flat", screen_number, image_control); - f_focus.setColor(color); - - color = readDatabaseColor("window.frame.unfocusColor", "white", style); - f_unfocus = Texture("solid flat", screen_number, image_control); - f_unfocus.setColor(color); - - l_text_focus = readDatabaseColor("window.label.focus.textColor", - "black", style); - l_text_unfocus = readDatabaseColor("window.label.unfocus.textColor", - "white", style); - - b_pic_focus = readDatabaseColor("window.button.focus.picColor", - "black", style); - b_pic_unfocus = readDatabaseColor("window.button.unfocus.picColor", - "white", style); - - justify = LeftJustify; - - if (style.getValue("window.justify", s)) { - if (s == "right" || s == "Right") - justify = RightJustify; - else if (s == "center" || s == "Center") - justify = CenterJustify; - } - - // sanity checks - if (t_focus.texture() == Texture::Parent_Relative) - t_focus = f_focus; - if (t_unfocus.texture() == Texture::Parent_Relative) - t_unfocus = f_unfocus; - if (h_focus.texture() == Texture::Parent_Relative) - h_focus = f_focus; - if (h_unfocus.texture() == Texture::Parent_Relative) - h_unfocus = f_unfocus; - - border_color = readDatabaseColor("borderColor", "black", style); - - // load bevel, border and handle widths - - const ScreenInfo *s_info = display->screenInfo(screen_number); - unsigned int width = s_info->rect().width(); - - if (! style.getValue("handleWidth", handle_width) || - handle_width > width/2 || handle_width == 0) - handle_width = 6; - - if (! style.getValue("borderWidth", border_width)) - border_width = 1; - - if (! style.getValue("bevelWidth", bevel_width) - || bevel_width > width/2 || bevel_width == 0) - bevel_width = 3; - - if (! style.getValue("frameWidth", frame_width) - || frame_width > width/2) - frame_width = bevel_width; - - if (style.getValue("rootCommand", s)) - bexec(s, s_info->displayString()); -} - - -void Style::readDatabaseMask(const std::string &rname, PixmapMask &pixmapMask, - const Configuration &style) { - Window root_window = display->screenInfo(screen_number)->rootWindow(); - std::string s; - int hx, hy; //ignored - int ret = BitmapOpenFailed; //default to failure. - - if (style.getValue(rname, s)) { - if (s[0] != '/' && s[0] != '~') { - std::string xbmFile = std::string("~/.openbox/buttons/") + s; - ret = XReadBitmapFile(**display, root_window, - expandTilde(xbmFile).c_str(), &pixmapMask.w, - &pixmapMask.h, &pixmapMask.mask, &hx, &hy); - if (ret != BitmapSuccess) { - xbmFile = std::string(BUTTONSDIR) + "/" + s; - ret = XReadBitmapFile(**display, root_window, - xbmFile.c_str(), &pixmapMask.w, - &pixmapMask.h, &pixmapMask.mask, &hx, &hy); - } - } else - ret = XReadBitmapFile(**display, root_window, - expandTilde(s).c_str(), &pixmapMask.w, - &pixmapMask.h, &pixmapMask.mask, &hx, &hy); - - if (ret == BitmapSuccess) - return; - } - - pixmapMask.mask = None; - pixmapMask.w = pixmapMask.h = 0; -} - - -Texture Style::readDatabaseTexture(const std::string &rname, - const std::string &default_color, - const Configuration &style, - bool allowNoTexture) -{ - Texture texture; - std::string s; - - if (style.getValue(rname, s)) - texture = Texture(s); - else if (allowNoTexture) //no default - texture.setTexture(Texture::NoTexture); - else - texture.setTexture(Texture::Solid | Texture::Flat); - - // associate this texture with this screen - texture.setScreen(screen_number); - texture.setImageControl(image_control); - - if (texture.texture() != Texture::NoTexture) { - texture.setColor(readDatabaseColor(rname + ".color", default_color, - style)); - texture.setColorTo(readDatabaseColor(rname + ".colorTo", default_color, - style)); - texture.setBorderColor(readDatabaseColor(rname + ".borderColor", - default_color, style)); - } - - return texture; -} - - -Color Style::readDatabaseColor(const std::string &rname, - const std::string &default_color, - const Configuration &style) { - Color color; - std::string s; - if (style.getValue(rname, s)) - color = Color(s, screen_number); - else - color = Color(default_color, screen_number); - return color; -} - - -Font *Style::readDatabaseFont(const std::string &rbasename, - const Configuration &style) { - std::string fontstring, s; - - // XXX: load all this font stuff from the style... - - bool dropShadow = True; - - unsigned char offset = 1; - if (style.getValue(rbasename + "xft.shadow.offset", s)) { - offset = atoi(s.c_str()); //doesn't detect errors - if (offset > CHAR_MAX) - offset = 1; - } - - unsigned char tint = 0x40; - if (style.getValue(rbasename + "xft.shadow.tint", s)) { - tint = atoi(s.c_str()); - } - - fontstring = "Arial,Sans-9:bold"; - - // if this fails, it ::exit()'s - return new Font(screen_number, fontstring, dropShadow, offset, tint); -} - -}
D otk/style.hh

@@ -1,151 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- -#ifndef __style_hh -#define __style_hh - -#include <string> - -#include "color.hh" -#include "font.hh" -#include "texture.hh" -#include "image.hh" -#include "configuration.hh" - -// XXX: document - -namespace otk { - -struct PixmapMask { - Pixmap mask; - unsigned int w, h; - PixmapMask() { mask = None; w = h = 0; } -}; - -class Style { -public: - - enum Type { ButtonFocus, ButtonUnfocus, TitleFocus, TitleUnfocus, - LabelFocus, LabelUnfocus, HandleFocus, HandleUnfocus, - GripFocus, GripUnfocus }; - - enum TextJustify { LeftJustify = 1, RightJustify, CenterJustify }; - enum BulletType { RoundBullet = 1, TriangleBullet, SquareBullet, NoBullet }; - -// private: - - ImageControl *image_control; - - Color - l_text_focus, l_text_unfocus, - b_pic_focus, b_pic_unfocus; - - Color border_color; - - Font *font; - - Texture - f_focus, f_unfocus, - t_focus, t_unfocus, - l_focus, l_unfocus, - h_focus, h_unfocus, - b_focus, b_unfocus, - b_pressed_focus, b_pressed_unfocus, - g_focus, g_unfocus; - - PixmapMask close_button, max_button, icon_button, stick_button; - TextJustify justify; - BulletType bullet_type; - - unsigned int handle_width, bevel_width, frame_width, border_width; - - unsigned int screen_number; - - bool shadow_fonts, aa_fonts; - -public: - - Style(); - Style(ImageControl *); - ~Style(); - - void readDatabaseMask(const std::string &rname, - PixmapMask &pixmapMask, - const Configuration &style); - - Texture readDatabaseTexture(const std::string &rname, - const std::string &default_color, - const Configuration &style, - bool allowNoTexture = false); - - Color readDatabaseColor(const std::string &rname, - const std::string &default_color, - const Configuration &style); - - Font *readDatabaseFont(const std::string &rbasename, - const Configuration &style); - - void load(const Configuration &style); - - inline PixmapMask *getCloseButtonMask(void) { return &close_button; } - inline PixmapMask *getMaximizeButtonMask(void) { return &max_button; } - inline PixmapMask *getIconifyButtonMask(void) { return &icon_button; } - inline PixmapMask *getStickyButtonMask(void) { return &stick_button; } - - inline Color *getTextFocus(void) { return &l_text_focus; } - inline Color *getTextUnfocus(void) { return &l_text_unfocus; } - - inline Color *getButtonPicFocus(void) { return &b_pic_focus; } - inline Color *getButtonPicUnfocus(void) { return &b_pic_unfocus; } - - inline Texture *getTitleFocus(void) { return &t_focus; } - inline Texture *getTitleUnfocus(void) { return &t_unfocus; } - - inline Texture *getLabelFocus(void) { return &l_focus; } - inline Texture *getLabelUnfocus(void) { return &l_unfocus; } - - inline Texture *getHandleFocus(void) { return &h_focus; } - inline Texture *getHandleUnfocus(void) { return &h_unfocus; } - - inline Texture *getButtonFocus(void) { return &b_focus; } - inline Texture *getButtonUnfocus(void) { return &b_unfocus; } - - inline Texture *getButtonPressedFocus(void) - { return &b_pressed_focus; } - inline Texture *getButtonPressedUnfocus(void) - { return &b_pressed_unfocus; } - - inline Texture *getGripFocus(void) { return &g_focus; } - inline Texture *getGripUnfocus(void) { return &g_unfocus; } - - inline unsigned int getHandleWidth(void) const { return handle_width; } - inline unsigned int getBevelWidth(void) const { return bevel_width; } - inline unsigned int getFrameWidth(void) const { return frame_width; } - inline unsigned int getBorderWidth(void) const { return border_width; } - - inline const Font *getFont() const { return font; } - - inline void setShadowFonts(bool fonts) { shadow_fonts = fonts; } - inline bool hasShadowFonts(void) const { return shadow_fonts; } - - inline void setAAFonts(bool fonts) { aa_fonts = fonts; } - inline bool hasAAFonts(void) const { return aa_fonts; } - - inline TextJustify textJustify(void) { return justify; } - inline BulletType bulletType(void) { return bullet_type; } - - inline const Color *getBorderColor() const { return &border_color; } - - inline const Texture *getFrameFocus() const { return &f_focus; } - inline const Texture *getFrameUnfocus() const { return &f_unfocus; } - - inline void setImageControl(ImageControl *c) { - image_control = c; - screen_number = c->getScreenInfo()->screen(); - } - inline unsigned int getScreen(void) { return screen_number; } - - // XXX add inline accessors for the rest of the bummy -}; - -} - -#endif // __style_hh
D otk/texture.cc

@@ -1,178 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif // HAVE_CONFIG_H - -extern "C" { -#include <stdio.h> -#ifdef HAVE_CTYPE_H -#include <ctype.h> -#endif -} - -#include <assert.h> - -#include "texture.hh" -#include "display.hh" -#include "image.hh" - -using std::string; - -namespace otk { - -Texture::Texture(unsigned int _screen, ImageControl* _ctrl) - : c(_screen), ct(_screen), - lc(_screen), sc(_screen), bc(_screen), t(0), - ctrl(_ctrl), scrn(_screen) { } - - -Texture::Texture(const string &d,unsigned int _screen, ImageControl* _ctrl) - : c(_screen), ct(_screen), - lc(_screen), sc(_screen), bc(_screen), t(0), - ctrl(_ctrl), scrn(_screen) { - setDescription(d); -} - - -void Texture::setColor(const Color &cc) { - c = cc; - c.setScreen(screen()); - - unsigned char r, g, b, rr, gg, bb; - - // calculate the light color - r = c.red(); - g = c.green(); - b = c.blue(); - rr = r + (r >> 1); - gg = g + (g >> 1); - bb = b + (b >> 1); - if (rr < r) rr = ~0; - if (gg < g) gg = ~0; - if (bb < b) bb = ~0; - lc = Color(rr, gg, bb, screen()); - - // calculate the shadow color - r = c.red(); - g = c.green(); - b = c.blue(); - rr = (r >> 2) + (r >> 1); - gg = (g >> 2) + (g >> 1); - bb = (b >> 2) + (b >> 1); - if (rr > r) rr = 0; - if (gg > g) gg = 0; - if (bb > b) bb = 0; - sc = Color(rr, gg, bb, screen()); -} - - -void Texture::setDescription(const string &d) { - descr.erase(); - descr.reserve(d.length()); - - string::const_iterator it = d.begin(), end = d.end(); - for (; it != end; ++it) - descr += tolower(*it); - - if (descr.find("parentrelative") != string::npos) { - setTexture(Texture::Parent_Relative); - } else { - setTexture(0); - - if (descr.find("gradient") != string::npos) { - addTexture(Texture::Gradient); - if (descr.find("crossdiagonal") != string::npos) - addTexture(Texture::CrossDiagonal); - else if (descr.find("rectangle") != string::npos) - addTexture(Texture::Rectangle); - else if (descr.find("pyramid") != string::npos) - addTexture(Texture::Pyramid); - else if (descr.find("pipecross") != string::npos) - addTexture(Texture::PipeCross); - else if (descr.find("elliptic") != string::npos) - addTexture(Texture::Elliptic); - else if (descr.find("horizontal") != string::npos) - addTexture(Texture::Horizontal); - else if (descr.find("vertical") != string::npos) - addTexture(Texture::Vertical); - else - addTexture(Texture::Diagonal); - } else { - addTexture(Texture::Solid); - } - - if (descr.find("sunken") != string::npos) - addTexture(Texture::Sunken); - else if (descr.find("flat") != string::npos) - addTexture(Texture::Flat); - else - addTexture(Texture::Raised); - - if (texture() & Texture::Flat) { - if (descr.find("border") != string::npos) - addTexture(Texture::Border); - } else { - if (descr.find("bevel2") != string::npos) - addTexture(Texture::Bevel2); - else - addTexture(Texture::Bevel1); - } - - if (descr.find("interlaced") != string::npos) - addTexture(Texture::Interlaced); - } -} - -void Texture::setScreen(const unsigned int _screen) { - if (_screen == screen()) { - // nothing to do - return; - } - - scrn = _screen; - c.setScreen(_screen); - ct.setScreen(_screen); - lc.setScreen(_screen); - sc.setScreen(_screen); - bc.setScreen(_screen); -} - - -Texture& Texture::operator=(const Texture &tt) { - c = tt.c; - ct = tt.ct; - lc = tt.lc; - sc = tt.sc; - bc = tt.bc; - descr = tt.descr; - t = tt.t; - scrn = tt.scrn; - ctrl = tt.ctrl; - - return *this; -} - - -Pixmap Texture::render(const unsigned int width, const unsigned int height, - const Pixmap old) { - assert(texture() != Texture::NoTexture); - -// if (texture() == (Texture::Flat | Texture::Solid)) -// return None; - if (texture() == Texture::Parent_Relative) - return ParentRelative; - - if (screen() == ~(0u)) - scrn = DefaultScreen(**display); - - assert(ctrl != 0); - Pixmap ret = ctrl->renderImage(width, height, *this); - - if (old) - ctrl->removeImage(old); - - return ret; -} - -}
D otk/texture.hh

@@ -1,94 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- -#ifndef TEXTURE_HH -#define TEXTURE_HH - -#include "color.hh" -#include "util.hh" - -#include <string> - -namespace otk { - -class ImageControl; - -class Texture { -public: - enum Type { - // No texture - NoTexture = (0), - // bevel options - Flat = (1l<<0), - Sunken = (1l<<1), - Raised = (1l<<2), - // textures - Solid = (1l<<3), - Gradient = (1l<<4), - // gradients - Horizontal = (1l<<5), - Vertical = (1l<<6), - Diagonal = (1l<<7), - CrossDiagonal = (1l<<8), - Rectangle = (1l<<9), - Pyramid = (1l<<10), - PipeCross = (1l<<11), - Elliptic = (1l<<12), - // bevel types - Bevel1 = (1l<<13), - Bevel2 = (1l<<14), - // flat border - Border = (1l<<15), - // inverted image - Invert = (1l<<16), - // parent relative image - Parent_Relative = (1l<<17), - // fake interlaced image - Interlaced = (1l<<18) - }; - - Texture(unsigned int _screen = ~(0u), ImageControl* _ctrl = 0); - Texture(const std::string &_description, - unsigned int _screen = ~(0u), ImageControl* _ctrl = 0); - - void setColor(const Color &_color); - void setColorTo(const Color &_colorTo) { ct = _colorTo; } - void setBorderColor(const Color &_borderColor) { bc = _borderColor; } - - const Color &color(void) const { return c; } - const Color &colorTo(void) const { return ct; } - const Color &lightColor(void) const { return lc; } - const Color &shadowColor(void) const { return sc; } - const Color &borderColor(void) const { return bc; } - - unsigned long texture(void) const { return t; } - void setTexture(const unsigned long _texture) { t = _texture; } - void addTexture(const unsigned long _texture) { t |= _texture; } - -#ifndef SWIG - Texture &operator=(const Texture &tt); -#endif - inline bool operator==(const Texture &tt) - { return (c == tt.c && ct == tt.ct && lc == tt.lc && - sc == tt.sc && t == tt.t); } - inline bool operator!=(const Texture &tt) - { return (! operator==(tt)); } - - unsigned int screen(void) const { return scrn; } - void setScreen(const unsigned int _screen); - void setImageControl(ImageControl* _ctrl) { ctrl = _ctrl; } - const std::string &description(void) const { return descr; } - void setDescription(const std::string &d); - - Pixmap render(const unsigned int width, const unsigned int height, - const Pixmap old = 0); - -private: - Color c, ct, lc, sc, bc; - std::string descr; - unsigned long t; - ImageControl *ctrl; - unsigned int scrn; -}; - -} - -#endif // TEXTURE_HH