summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am40
-rw-r--r--src/color.cc223
-rw-r--r--src/color.hh106
-rw-r--r--src/font.cc128
-rw-r--r--src/font.hh82
-rw-r--r--src/gccache.cc188
-rw-r--r--src/gccache.hh119
-rw-r--r--src/image.cc1677
-rw-r--r--src/image.hh144
-rw-r--r--src/imagecontrol.cc561
-rw-r--r--src/texture.cc183
-rw-r--r--src/texture.hh92
12 files changed, 15 insertions, 3528 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 70c7013a..72645d2f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,9 +8,12 @@ CXXFLAGS=`pkg-config --cflags xft` @CXXFLAGS@ \
LDFLAGS=`pkg-config --libs xft`
+INCLUDES= -I../otk
+
bin_PROGRAMS= openbox
-openbox_SOURCES= basedisplay.cc color.cc configuration.cc font.cc gccache.cc image.cc imagecontrol.cc screen.cc texture.cc timer.cc util.cc window.cc workspace.cc xatom.cc blackbox.cc main.cc
+openbox_LDADD=../otk/libotk.a
+openbox_SOURCES= basedisplay.cc configuration.cc screen.cc timer.cc util.cc window.cc workspace.cc xatom.cc blackbox.cc main.cc
MAINTAINERCLEANFILES= Makefile.in
@@ -19,37 +22,24 @@ distclean-local:
# local dependencies
basedisplay.o: basedisplay.cc basedisplay.hh timer.hh util.hh \
- gccache.hh color.hh
+ ../otk/gccache.hh ../otk/color.hh
blackbox.o: blackbox.cc blackbox.hh basedisplay.hh timer.hh util.hh \
- configuration.hh xatom.hh gccache.hh color.hh image.hh screen.hh \
- texture.hh workspace.hh window.hh
-color.o: color.cc color.hh basedisplay.hh timer.hh util.hh
+ configuration.hh xatom.hh ../otk/gccache.hh ../otk/color.hh ../otk/image.hh screen.hh \
+ ../otk/texture.hh workspace.hh window.hh
configuration.o: configuration.cc configuration.hh util.hh
-font.o: font.cc font.hh screen.hh color.hh texture.hh util.hh image.hh \
- timer.hh basedisplay.hh workspace.hh xatom.hh blackbox.hh \
- configuration.hh gccache.hh
-gccache.o: gccache.cc gccache.hh basedisplay.hh timer.hh util.hh \
- color.hh
-image.o: image.cc blackbox.hh basedisplay.hh timer.hh util.hh \
- configuration.hh xatom.hh gccache.hh color.hh image.hh texture.hh
-imagecontrol.o: imagecontrol.cc blackbox.hh basedisplay.hh timer.hh \
- util.hh configuration.hh xatom.hh color.hh image.hh texture.hh
main.o: main.cc ../version.h blackbox.hh basedisplay.hh timer.hh \
util.hh configuration.hh xatom.hh
screen.o: screen.cc blackbox.hh basedisplay.hh timer.hh util.hh \
- configuration.hh xatom.hh font.hh screen.hh color.hh texture.hh \
- image.hh workspace.hh gccache.hh window.hh
-texture.o: texture.cc texture.hh color.hh util.hh basedisplay.hh \
- timer.hh image.hh screen.hh workspace.hh xatom.hh blackbox.hh \
- configuration.hh
+ configuration.hh xatom.hh ../otk/font.hh screen.hh ../otk/color.hh ../otk/texture.hh \
+ ../otk/image.hh workspace.hh ../otk/gccache.hh window.hh
timer.o: timer.cc basedisplay.hh timer.hh util.hh
util.o: util.cc util.hh
window.o: window.cc blackbox.hh basedisplay.hh timer.hh util.hh \
- configuration.hh xatom.hh font.hh screen.hh color.hh texture.hh \
- image.hh workspace.hh gccache.hh window.hh
+ configuration.hh xatom.hh ../otk/font.hh screen.hh ../otk/color.hh ../otk/texture.hh \
+ ../otk/image.hh workspace.hh ../otk/gccache.hh window.hh
workspace.o: workspace.cc blackbox.hh basedisplay.hh timer.hh util.hh \
- configuration.hh xatom.hh font.hh screen.hh color.hh texture.hh \
- image.hh workspace.hh window.hh
-xatom.o: xatom.cc ../config.h xatom.hh screen.hh color.hh texture.hh \
- util.hh image.hh timer.hh basedisplay.hh workspace.hh blackbox.hh \
+ configuration.hh xatom.hh ../otk/font.hh screen.hh ../otk/color.hh ../otk/texture.hh \
+ ../otk/image.hh workspace.hh window.hh
+xatom.o: xatom.cc ../config.h xatom.hh screen.hh ../otk/color.hh ../otk/texture.hh \
+ util.hh ../otk/image.hh timer.hh basedisplay.hh workspace.hh blackbox.hh \
configuration.hh
diff --git a/src/color.cc b/src/color.cc
deleted file mode 100644
index ad30c7a3..00000000
--- a/src/color.cc
+++ /dev/null
@@ -1,223 +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 "basedisplay.hh"
-
-
-BColor::ColorCache BColor::colorcache;
-bool BColor::cleancache = false;
-
-BColor::BColor(const BaseDisplay * const _display, unsigned int _screen)
- : allocated(false), r(-1), g(-1), b(-1), p(0), dpy(_display), scrn(_screen)
-{}
-
-BColor::BColor(int _r, int _g, int _b,
- const BaseDisplay * const _display, unsigned int _screen)
- : allocated(false), r(_r), g(_g), b(_b), p(0), dpy(_display), scrn(_screen)
-{}
-
-
-BColor::BColor(const std::string &_name,
- const BaseDisplay * const _display, unsigned int _screen)
- : allocated(false), r(-1), g(-1), b(-1), p(0), dpy(_display), scrn(_screen),
- colorname(_name) {
- parseColorName();
-}
-
-
-BColor::~BColor(void) {
- deallocate();
-}
-
-
-void BColor::setDisplay(const BaseDisplay * const _display,
- unsigned int _screen) {
- if (_display == display() && _screen == screen()) {
- // nothing to do
- return;
- }
-
- deallocate();
-
- dpy = _display;
- scrn = _screen;
-
- if (! colorname.empty()) {
- parseColorName();
- }
-}
-
-
-unsigned long BColor::pixel(void) const {
- if (! allocated) {
- // mutable
- BColor *that = (BColor *) this;
- that->allocate();
- }
-
- return p;
-}
-
-
-void BColor::parseColorName(void) {
- assert(dpy != 0);
-
- if (colorname.empty()) {
- fprintf(stderr, "BColor: empty colorname, cannot parse (using black)\n");
- setRGB(0, 0, 0);
- }
-
- if (scrn == ~(0u))
- scrn = DefaultScreen(display()->getXDisplay());
- Colormap colormap = display()->getScreenInfo(scrn)->getColormap();
-
- // get rgb values from colorname
- XColor xcol;
- xcol.red = 0;
- xcol.green = 0;
- xcol.blue = 0;
- xcol.pixel = 0;
-
- if (! XParseColor(display()->getXDisplay(), colormap,
- colorname.c_str(), &xcol)) {
- fprintf(stderr, "BColor::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 BColor::allocate(void) {
- assert(dpy != 0);
-
- if (scrn == ~(0u)) scrn = DefaultScreen(display()->getXDisplay());
- Colormap colormap = display()->getScreenInfo(scrn)->getColormap();
-
- if (! isValid()) {
- if (colorname.empty()) {
- fprintf(stderr, "BColor: cannot allocate invalid color (using black)\n");
- setRGB(0, 0, 0);
- } else {
- parseColorName();
- }
- }
-
- // see if we have allocated this color before
- RGB rgb(display(), 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()->getXDisplay(), colormap, &xcol)) {
- fprintf(stderr, "BColor::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 BColor::deallocate(void) {
- if (! allocated)
- return;
-
- assert(dpy != 0);
-
- ColorCache::iterator it = colorcache.find(RGB(display(), scrn, r, g, b));
- if (it != colorcache.end()) {
- if ((*it).second.count >= 1)
- (*it).second.count--;
- }
-
- if (cleancache)
- doCacheCleanup();
-
- allocated = false;
-}
-
-
-BColor &BColor::operator=(const BColor &c) {
- deallocate();
-
- setRGB(c.r, c.g, c.b);
- colorname = c.colorname;
- dpy = c.dpy;
- scrn = c.scrn;
- return *this;
-}
-
-
-void BColor::cleanupColorCache(void) {
- cleancache = true;
-}
-
-
-void BColor::doCacheCleanup(void) {
- // ### TODO - support multiple displays!
- ColorCache::iterator it = colorcache.begin();
- if (it == colorcache.end()) {
- // nothing to do
- return;
- }
-
- const BaseDisplay* const display = (*it).first.display;
- unsigned long *pixels = new unsigned long[ colorcache.size() ];
- unsigned int i, count;
-
- for (i = 0; i < display->getNumberOfScreens(); 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->getXDisplay(),
- display->getScreenInfo(i)->getColormap(),
- pixels, count, 0);
- }
-
- delete [] pixels;
- cleancache = false;
-}
diff --git a/src/color.hh b/src/color.hh
deleted file mode 100644
index 5f3cb955..00000000
--- a/src/color.hh
+++ /dev/null
@@ -1,106 +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>
-
-class BaseDisplay;
-
-class BColor {
-public:
- BColor(const BaseDisplay * const _display = 0, unsigned int _screen = ~(0u));
- BColor(int _r, int _g, int _b,
- const BaseDisplay * const _display, unsigned int _screen = ~(0u));
- BColor(const std::string &_name,
- const BaseDisplay * const _display, unsigned int _screen = ~(0u));
- ~BColor(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 const BaseDisplay *display(void) const { return dpy; }
- inline unsigned int screen(void) const { return scrn; }
- void setDisplay(const BaseDisplay * const _display,
- 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
- BColor &operator=(const BColor &c);
- inline bool operator==(const BColor &c) const
- { return (r == c.r && b == c.b && b == c.b); }
- inline bool operator!=(const BColor &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;
- const BaseDisplay *dpy;
- unsigned int scrn;
- std::string colorname;
-
- // global color allocator/deallocator
- struct RGB {
- const BaseDisplay* const display;
- const unsigned int screen;
- const int r, g, b;
-
- RGB(void) : display(0), screen(~(0u)), r(-1), g(-1), b(-1) { }
- RGB(const BaseDisplay * const a, const unsigned int b,
- const int x, const int y, const int z)
- : display(a), screen(b), r(x), g(y), b(z) {}
- RGB(const RGB &x)
- : display(x.display), screen(x.screen), r(x.r), g(x.g), b(x.b) {}
-
- inline bool operator==(const RGB &x) const {
- return display == x.display &&
- 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
diff --git a/src/font.cc b/src/font.cc
deleted file mode 100644
index 91f8ffb6..00000000
--- a/src/font.cc
+++ /dev/null
@@ -1,128 +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_STDLIB_H
-# include <stdlib.h>
-#endif // HAVE_STDLIB_H
-}
-
-#include <iostream>
-#include <algorithm>
-
-using std::string;
-using std::cerr;
-using std::endl;
-
-#include "font.hh"
-#include "util.hh"
-#include "gccache.hh"
-#include "color.hh"
-
-string BFont::_fallback_font = "fixed";
-
-BFont::BFont(Display *d, BScreen *screen, const string &family, int size,
- bool bold, bool italic, bool shadow, unsigned char offset,
- unsigned char tint, bool antialias) :
- _display(d),
- _screen(screen),
- _family(family),
- _simplename(False),
- _size(size),
- _bold(bold),
- _italic(italic),
- _antialias(antialias),
- _shadow(shadow),
- _offset(offset),
- _tint(tint),
- _xftfont(0) {
- _valid = False;
-
- _xftfont = XftFontOpen(_display, _screen->getScreenNumber(),
- XFT_FAMILY, XftTypeString, _family.c_str(),
- XFT_SIZE, XftTypeInteger, _size,
- XFT_WEIGHT, XftTypeInteger, (_bold ?
- XFT_WEIGHT_BOLD :
- XFT_WEIGHT_MEDIUM),
- XFT_SLANT, XftTypeInteger, (_italic ?
- XFT_SLANT_ITALIC :
- XFT_SLANT_ROMAN),
- XFT_ANTIALIAS, XftTypeBool, _antialias,
- 0);
- if (! _xftfont)
- return; // failure
-
- _valid = True;
-}
-
-
-BFont::~BFont(void) {
- if (_xftfont)
- XftFontClose(_display, _xftfont);
-}
-
-
-void BFont::drawString(Drawable d, int x, int y, const BColor &color,
- const string &string) const {
- assert(_valid);
-
- XftDraw *draw = XftDrawCreate(_display, d, _screen->getVisual(),
- _screen->getColormap());
- assert(draw);
-
- if (_shadow) {
- XftColor c;
- c.color.red = 0;
- c.color.green = 0;
- c.color.blue = 0;
- c.color.alpha = _tint | _tint << 8; // transparent shadow
- c.pixel = BlackPixel(_display, _screen->getScreenNumber());
-
- XftDrawStringUtf8(draw, &c, _xftfont, x + _offset,
- _xftfont->ascent + y + _offset,
- (XftChar8 *) string.c_str(),
- string.size());
- }
-
- XftColor c;
- c.color.red = color.red() | color.red() << 8;
- c.color.green = color.green() | color.green() << 8;
- c.color.blue = color.blue() | color.blue() << 8;
- c.pixel = color.pixel();
- c.color.alpha = 0xff | 0xff << 8; // no transparency in BColor yet
-
- XftDrawStringUtf8(draw, &c, _xftfont, x, _xftfont->ascent + y,
- (XftChar8 *) string.c_str(), string.size());
-
- XftDrawDestroy(draw);
- return;
-}
-
-
-unsigned int BFont::measureString(const string &string) const {
- assert(_valid);
-
- XGlyphInfo info;
-
- XftTextExtentsUtf8(_display, _xftfont, (XftChar8 *) string.c_str(),
- string.size(), &info);
-
- return info.xOff + (_shadow ? _offset : 0);
-}
-
-
-unsigned int BFont::height(void) const {
- assert(_valid);
-
- return _xftfont->height + (_shadow ? _offset : 0);
-}
-
-
-unsigned int BFont::maxCharWidth(void) const {
- assert(_valid);
-
- return _xftfont->max_advance_width;
-}
diff --git a/src/font.hh b/src/font.hh
deleted file mode 100644
index c070bbff..00000000
--- a/src/font.hh
+++ /dev/null
@@ -1,82 +0,0 @@
-// -*- mode: C++; indent-tabs-mode: nil; -*-
-#ifndef __Font_hh
-#define __Font_hh
-
-extern "C" {
-#include <X11/Xlib.h>
-
-#include <X11/Xft/Xft.h>
-}
-
-#include <assert.h>
-
-#include <string>
-
-class BGCCache;
-class BGCCacheItem;
-class BColor;
-
-#include "screen.hh"
-
-class BFont {
- /*
- * static members
- */
-private:
- static std::string _fallback_font;
-
-public:
- // the fallback is only used for X fonts, not for Xft fonts, since it is
- // assumed that X fonts will be the fallback from Xft.
- inline static std::string fallbackFont(void) { return _fallback_font; }
- inline static void setFallbackFont(const std::string &f)
- { _fallback_font = f; }
-
- /*
- * instance members
- */
-private:
- Display *_display;
- BScreen *_screen;
-
- std::string _family;
- bool _simplename; // true if not spec'd as a -*-* string
- int _size;
- bool _bold;
- bool _italic;
-
- bool _antialias;
- bool _shadow;
- unsigned char _offset;
- unsigned char _tint;
-
- XftFont *_xftfont;
-
- bool createXftFont(void);
-
- bool _valid;
-
-public:
- // loads an Xft font
- BFont(Display *d, BScreen *screen, const std::string &family, int size,
- bool bold, bool italic, bool shadow, unsigned char offset,
- unsigned char tint, bool antialias = True);
- virtual ~BFont(void);
-
- inline bool valid(void) const { return _valid; }
-
- inline std::string family(void) const { assert(_valid); return _family; }
- inline int size(void) const { assert(_valid); return _size; }
- inline bool bold(void) const { assert(_valid); return _bold; }
- inline bool italic(void) const { assert(_valid); return _italic; }
-
- unsigned int height(void) const;
- unsigned int maxCharWidth(void) const;
-
- unsigned int measureString(const std::string &string) const;
-
- void drawString(Drawable d, int x, int y, const BColor &color,
- const std::string &string) const;
-};
-
-#endif // __Font_hh
diff --git a/src/gccache.cc b/src/gccache.cc
deleted file mode 100644
index 2ab37f34..00000000
--- a/src/gccache.cc
+++ /dev/null
@@ -1,188 +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 "gccache.hh"
-#include "basedisplay.hh"
-#include "color.hh"
-#include "util.hh"
-
-
-BGCCacheContext::~BGCCacheContext(void) {
- if (gc)
- XFreeGC(display->getXDisplay(), gc);
-}
-
-
-void BGCCacheContext::set(const BColor &_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->getXDisplay(), gc, mask, &gcv);
-}
-
-
-void BGCCacheContext::set(const XFontStruct * const _font) {
- if (! _font) {
- fontid = 0;
- return;
- }
-
- XGCValues gcv;
- fontid = gcv.font = _font->fid;
- XChangeGC(display->getXDisplay(), gc, GCFont, &gcv);
-}
-
-
-BGCCache::BGCCache(const BaseDisplay * const _display,
- unsigned int screen_count)
- : display(_display), context_count(128u),
- cache_size(16u), cache_buckets(8u * screen_count),
- cache_total_size(cache_size * cache_buckets) {
-
- contexts = new BGCCacheContext*[context_count];
- unsigned int i;
- for (i = 0; i < context_count; i++) {
- contexts[i] = new BGCCacheContext(display);
- }
-
- cache = new BGCCacheItem*[cache_total_size];
- for (i = 0; i < cache_total_size; ++i) {
- cache[i] = new BGCCacheItem;
- }
-}
-
-
-BGCCache::~BGCCache(void) {
- std::for_each(contexts, contexts + context_count, PointerAssassin());
- std::for_each(cache, cache + cache_total_size, PointerAssassin());
- delete [] cache;
- delete [] contexts;
-}
-
-
-BGCCacheContext *BGCCache::nextContext(unsigned int scr) {
- Window hd = display->getScreenInfo(scr)->getRootWindow();
-
- BGCCacheContext *c;
-
- for (unsigned int i = 0; i < context_count; ++i) {
- c = contexts[i];
-
- if (! c->gc) {
- c->gc = XCreateGC(display->getXDisplay(), hd, 0, 0);
- c->used = false;
- c->screen = scr;
- }
- if (! c->used && c->screen == scr)
- return c;
- }
-
- fprintf(stderr, "BGCCache: context fault!\n");
- abort();
- return (BGCCacheContext*) 0; // not reached
-}
-
-
-void BGCCache::release(BGCCacheContext *ctx) {
- ctx->used = false;
-}
-
-
-BGCCacheItem *BGCCache::find(const BColor &_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
- BGCCacheItem *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, "BGCCache: 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 BGCCache::release(BGCCacheItem *_item) {
- _item->count--;
-}
-
-
-void BGCCache::purge(void) {
- for (unsigned int i = 0; i < cache_total_size; ++i) {
- BGCCacheItem *d = cache[ i ];
-
- if (d->ctx && d->count == 0) {
- release(d->ctx);
- d->ctx = 0;
- }
- }
-}
diff --git a/src/gccache.hh b/src/gccache.hh
deleted file mode 100644
index 499ed8a4..00000000
--- a/src/gccache.hh
+++ /dev/null
@@ -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 "basedisplay.hh"
-#include "color.hh"
-
-class BGCCacheItem;
-
-class BGCCacheContext {
-public:
- void set(const BColor &_color, const XFontStruct * const _font,
- const int _function, const int _subwindow, const int _linewidth);
- void set(const XFontStruct * const _font);
-
- ~BGCCacheContext(void);
-
-private:
- BGCCacheContext(const BaseDisplay * const _display)
- : display(_display), gc(0), pixel(0ul), fontid(0ul),
- function(0), subwindow(0), used(false), screen(~(0u)), linewidth(0) {}
-
- const BaseDisplay *display;
- GC gc;
- unsigned long pixel;
- unsigned long fontid;
- int function;
- int subwindow;
- bool used;
- unsigned int screen;
- int linewidth;
-
- BGCCacheContext(const BGCCacheContext &_nocopy);
- BGCCacheContext &operator=(const BGCCacheContext &_nocopy);
-
- friend class BGCCache;
- friend class BGCCacheItem;
-};
-
-class BGCCacheItem {
-public:
- inline const GC &gc(void) const { return ctx->gc; }
-
-private:
- BGCCacheItem(void) : ctx(0), count(0), hits(0), fault(false) { }
-
- BGCCacheContext *ctx;
- unsigned int count;
- unsigned int hits;
- bool fault;
-
- BGCCacheItem(const BGCCacheItem &_nocopy);
- BGCCacheItem &operator=(const BGCCacheItem &_nocopy);
-
- friend class BGCCache;
-};
-
-class BGCCache {
-public:
- BGCCache(const BaseDisplay * const _display, unsigned int screen_count);
- ~BGCCache(void);
-
- // cleans up the cache
- void purge(void);
-
- BGCCacheItem *find(const BColor &_color, const XFontStruct * const _font = 0,
- int _function = GXcopy, int _subwindow = ClipByChildren,
- int _linewidth = 0);
- void release(BGCCacheItem *_item);
-
-private:
- BGCCacheContext *nextContext(unsigned int _screen);
- void release(BGCCacheContext *ctx);
-
- // this is closely modelled after the Qt GC cache, but with some of the
- // complexity stripped out
- const BaseDisplay *display;
-
- const unsigned int context_count;
- const unsigned int cache_size;
- const unsigned int cache_buckets;
- const unsigned int cache_total_size;
- BGCCacheContext **contexts;
- BGCCacheItem **cache;
-};
-
-class BPen {
-public:
- inline BPen(const BColor &_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(_color.display()->gcCache()), item(0) { }
-
- inline ~BPen(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 BColor &color;
- const XFontStruct *font;
- int linewidth;
- int function;
- int subwindow;
-
- mutable BGCCache *cache;
- mutable BGCCacheItem *item;
-};
-
-
-#endif // GCCACHE_HH
diff --git a/src/image.cc b/src/image.cc
deleted file mode 100644
index 21e9d690..00000000
--- a/src/image.cc
+++ /dev/null
@@ -1,1677 +0,0 @@
-// -*- mode: C++; indent-tabs-mode: nil; -*-
-
-#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 "blackbox.hh"
-#include "basedisplay.hh"
-#include "gccache.hh"
-#include "image.hh"
-#include "texture.hh"
-
-
-BImage::BImage(BImageControl *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);
-}
-
-
-BImage::~BImage(void) {
- delete [] red;
- delete [] green;
- delete [] blue;
-}
-
-
-Pixmap BImage::render(const BTexture &texture) {
- if (texture.texture() & BTexture::Parent_Relative)
- return ParentRelative;
- else if (texture.texture() & BTexture::Solid)
- return render_solid(texture);
- else if (texture.texture() & BTexture::Gradient)
- return render_gradient(texture);
- return None;
-}
-
-
-Pixmap BImage::render_solid(const BTexture &texture) {
- Pixmap pixmap = XCreatePixmap(control->getBaseDisplay()->getXDisplay(),
- control->getDrawable(), width,
- height, control->getDepth());
- if (pixmap == None) {
- fprintf(stderr, "BImage::render_solid: error creating pixmap\n");
- return None;
- }
-
- Display *display = control->getBaseDisplay()->getXDisplay();
-
- BPen pen(texture.color());
- BPen penlight(texture.lightColor());
- BPen penshadow(texture.shadowColor());
-
- XFillRectangle(display, pixmap, pen.gc(), 0, 0, width, height);
-
- if (texture.texture() & BTexture::Interlaced) {
- BPen 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() & BTexture::Border) {
- BPen penborder(texture.borderColor());
- XDrawRectangle(display, pixmap, penborder.gc(),
- left, top, right, bottom);
- }
-
- if (texture.texture() & BTexture::Bevel1) {
- if (texture.texture() & BTexture::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() & BTexture::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() & BTexture::Bevel2) {
- if (texture.texture() & BTexture::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() & BTexture::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 BImage::render_gradient(const BTexture &texture) {
- bool inverted = False;
-
- interlaced = texture.texture() & BTexture::Interlaced;
-
- if (texture.texture() & BTexture::Sunken) {
- from = texture.colorTo();
- to = texture.color();
-
- if (! (texture.texture() & BTexture::Invert)) inverted = True;
- } else {
- from = texture.color();
- to = texture.colorTo();
-
- if (texture.texture() & BTexture::Invert) inverted = True;
- }
-
- control->getGradientBuffers(width, height, &xtable, &ytable);
-
- if (texture.texture() & BTexture::Diagonal) dgradient();
- else if (texture.texture() & BTexture::Elliptic) egradient();
- else if (texture.texture() & BTexture::Horizontal) hgradient();
- else if (texture.texture() & BTexture::Pyramid) pgradient();
- else if (texture.texture() & BTexture::Rectangle) rgradient();
- else if (texture.texture() & BTexture::Vertical) vgradient();
- else if (texture.texture() & BTexture::CrossDiagonal) cdgradient();
- else if (texture.texture() & BTexture::PipeCross) pcgradient();
-
- if (texture.texture() & BTexture::Bevel1) bevel1();
- else if (texture.texture() & BTexture::Bevel2) bevel2();
-
- if (texture.texture() & BTexture::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 BImage::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 BImage::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 BImage::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 *BImage::renderXImage(void) {
- XImage *image =
- XCreateImage(control->getBaseDisplay()->getXDisplay(),
- control->getVisual(), control->getDepth(), ZPixmap, 0, 0,
- width, height, 32, 0);
-
- if (! image) {
- fprintf(stderr, "BImage::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, "BImage::renderXImage: unsupported visual\n");
- delete [] d;
- XDestroyImage(image);
- return (XImage *) 0;
- }
-
- image->data = (char *) d;
-
- return image;
-}
-
-
-Pixmap BImage::renderPixmap(void) {
- Pixmap pixmap =
- XCreatePixmap(control->getBaseDisplay()->getXDisplay(),
- control->getDrawable(), width, height, control->getDepth());
-
- if (pixmap == None) {
- fprintf(stderr, "BImage::renderPixmap: error creating pixmap\n");
- return None;
- }
-
- XImage *image = renderXImage();
-
- if (! image) {
- XFreePixmap(control->getBaseDisplay()->getXDisplay(), pixmap);
- return None;
- }
-
- if (! image->data) {
- XDestroyImage(image);
- XFreePixmap(control->getBaseDisplay()->getXDisplay(), pixmap);
- return None;
- }
-
- XPutImage(control->getBaseDisplay()->getXDisplay(), pixmap,
- DefaultGC(control->getBaseDisplay()->getXDisplay(),
- control->getScreenInfo()->getScreenNumber()),
- image, 0, 0, 0, 0, width, height);
-
- if (image->data) {
- delete [] image->data;
- image->data = NULL;
- }
-
- XDestroyImage(image);
-
- return pixmap;
-}
-
-
-void BImage::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 BImage::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 BImage::border(const BTexture &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 BImage::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 BImage::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 BImage::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 BImage::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 BImage::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 BImage::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 BImage::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 BImage::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 BImage::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;
- }
- }
- }
- }
-}
diff --git a/src/image.hh b/src/image.hh
deleted file mode 100644
index 85ad287d..00000000
--- a/src/image.hh
+++ /dev/null
@@ -1,144 +0,0 @@
-// -*- mode: C++; indent-tabs-mode: nil; -*-
-#ifndef __Image_hh
-#define __Image_hh
-
-extern "C" {
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-}
-
-#include <list>
-
-#include "timer.hh"
-#include "basedisplay.hh"
-#include "color.hh"
-
-class BImageControl;
-class BTexture;
-
-class BImage {
-private:
- BImageControl *control;
- bool interlaced;
- XColor *colors;
-
- BColor 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 BTexture &texture);
- Pixmap render_gradient(const BTexture &texture);
-
- XImage *renderXImage(void);
-
- void invert(void);
- void bevel1(void);
- void bevel2(void);
- void border(const BTexture &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:
- BImage(BImageControl *c, int w, int h);
- ~BImage(void);
-
- Pixmap render(const BTexture &texture);
-};
-
-
-class BImageControl : public TimeoutHandler {
-public:
- struct CachedImage {
- Pixmap pixmap;
-
- unsigned int count, width, height;
- unsigned long pixel1, pixel2, texture;
- };
-
- BImageControl(BaseDisplay *dpy, const ScreenInfo *scrn,
- bool _dither= False, int _cpc = 4,
- unsigned long cache_timeout = 300000l,
- unsigned long cmax = 200l);
- virtual ~BImageControl(void);
-
- inline BaseDisplay *getBaseDisplay(void) const { return basedisplay; }
-
- inline bool doDither(void) { return dither; }
-
- inline const ScreenInfo *getScreenInfo(void) { return screeninfo; }
-
- inline Window getDrawable(void) const { return window; }
-
- inline Visual *getVisual(void) { return screeninfo->getVisual(); }
-
- 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 BTexture &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);
-
- virtual void timeout(void);
-
-private:
- bool dither;
- BaseDisplay *basedisplay;
- const ScreenInfo *screeninfo;
- BTimer *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 BColor &c1, const BColor &c2);
-};
-
-
-#endif // __Image_hh
-
diff --git a/src/imagecontrol.cc b/src/imagecontrol.cc
deleted file mode 100644
index 7d091bb8..00000000
--- a/src/imagecontrol.cc
+++ /dev/null
@@ -1,561 +0,0 @@
-// -*- mode: C++; indent-tabs-mode: nil; -*-
-
-#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 "blackbox.hh"
-#include "basedisplay.hh"
-#include "color.hh"
-#include "image.hh"
-#include "texture.hh"
-
-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;
- }
-}
-
-BImageControl *ctrl = 0;
-
-BImageControl::BImageControl(BaseDisplay *dpy, const ScreenInfo *scrn,
- bool _dither, int _cpc,
- unsigned long cache_timeout,
- unsigned long cmax) {
- if (! ctrl) ctrl = this;
-
- basedisplay = dpy;
- screeninfo = scrn;
- setDither(_dither);
- setColorsPerChannel(_cpc);
-
- cache_max = cmax;
- if (cache_timeout) {
- timer = new BTimer(basedisplay, this);
- timer->setTimeout(cache_timeout);
- timer->start();
- } else {
- timer = (BTimer *) 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->getDepth();
- window = screeninfo->getRootWindow();
- screen_number = screeninfo->getScreenNumber();
- colormap = screeninfo->getColormap();
-
- int count;
- XPixmapFormatValues *pmv = XListPixmapFormats(basedisplay->getXDisplay(),
- &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,
- "BImageControl::BImageControl: 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, "BImageControl::BImageControl: 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(basedisplay->getXDisplay(), 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(basedisplay->getXDisplay(), 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(basedisplay->getXDisplay(), 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,
- "BImageControl::BImageControl: 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,
- "BImageControl::BImageControl: 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(basedisplay->getXDisplay(), 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(basedisplay->getXDisplay(), 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(basedisplay->getXDisplay(), colormap,
- &colors[i])) {
- colors[i].flags = DoRed|DoGreen|DoBlue;
- break;
- }
- }
- }
- }
- }
-
- break;
- }
-
- default:
- fprintf(stderr, "BImageControl::BImageControl: unsupported visual %d\n",
- getVisual()->c_class);
- exit(1);
- }
-}
-
-
-BImageControl::~BImageControl(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(basedisplay->getXDisplay(), colormap, pixels, ncolors, 0);
-
- delete [] colors;
- }
-
- if (! cache.empty()) {
- //#ifdef DEBUG
- fprintf(stderr, "BImageContol::~BImageControl: 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(basedisplay->getXDisplay(), it->pixmap);
- }
- if (timer) {
- timer->stop();
- delete timer;
- }
-}
-
-
-Pixmap BImageControl::searchCache(const unsigned int width,
- const unsigned int height,
- const unsigned long texture,
- const BColor &c1, const BColor &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 & BTexture::Gradient) {
- if (tmp.pixel2 == c2.pixel()) {
- tmp.count++;
- return tmp.pixmap;
- }
- } else {
- tmp.count++;
- return tmp.pixmap;
- }
- }
- return None;
-}
-
-
-Pixmap BImageControl::renderImage(unsigned int width, unsigned int height,
- const BTexture &texture) {
- if (texture.texture() & BTexture::Parent_Relative) return ParentRelative;
-
- Pixmap pixmap = searchCache(width, height, texture.texture(),
- texture.color(), texture.colorTo());
- if (pixmap) return pixmap;
-
- BImage 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() & BTexture::Gradient)
- tmp.pixel2 = texture.colorTo().pixel();
- else
- tmp.pixel2 = 0l;
-
- cache.push_back(tmp);
-
- if (cache.size() > cache_max) {
-#ifdef DEBUG
- fprintf(stderr, "BImageControl::renderImage: cache is large, "
- "forcing cleanout\n");
-#endif // DEBUG
-
- timeout();
- }
-
- return pixmap;
-}
-
-
-void BImageControl::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();
-}
-
-
-void BImageControl::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 BImageControl::getXColorTable(XColor **c, int *n) {
- if (c) *c = colors;
- if (n) *n = ncolors;
-}
-
-
-void BImageControl::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 BImageControl::installRootColormap(void) {
- int ncmap = 0;
- Colormap *cmaps =
- XListInstalledColormaps(basedisplay->getXDisplay(), window, &ncmap);
-
- if (cmaps) {
- bool install = True;
- for (int i = 0; i < ncmap; i++)
- if (*(cmaps + i) == colormap)
- install = False;
-
- if (install)
- XInstallColormap(basedisplay->getXDisplay(), colormap);
-
- XFree(cmaps);
- }
-}
-
-
-void BImageControl::setColorsPerChannel(int cpc) {
- if (cpc < 2) cpc = 2;
- if (cpc > 6) cpc = 6;
-
- colors_per_channel = cpc;
-}
-
-
-unsigned long BImageControl::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 BImageControl::CachedImage &image) const {
- return (image.count == 0);
- }
-};
-
-struct CacheCleaner {
- Display *display;
- ZeroRefCheck ref_check;
- CacheCleaner(Display *d): display(d) {}
- inline void operator()(const BImageControl::CachedImage& image) const {
- if (ref_check(image))
- XFreePixmap(display, image.pixmap);
- }
-};
-
-
-void BImageControl::timeout(void) {
- CacheCleaner cleaner(basedisplay->getXDisplay());
- std::for_each(cache.begin(), cache.end(), cleaner);
- cache.remove_if(cleaner.ref_check);
-}
-
diff --git a/src/texture.cc b/src/texture.cc
deleted file mode 100644
index 22454c59..00000000
--- a/src/texture.cc
+++ /dev/null
@@ -1,183 +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 "basedisplay.hh"
-#include "image.hh"
-#include "screen.hh"
-#include "blackbox.hh"
-
-using std::string;
-
-
-BTexture::BTexture(const BaseDisplay * const _display,
- unsigned int _screen, BImageControl* _ctrl)
- : c(_display, _screen), ct(_display, _screen),
- lc(_display, _screen), sc(_display, _screen), bc(_display, _screen), t(0),
- dpy(_display), ctrl(_ctrl), scrn(_screen) { }
-
-
-BTexture::BTexture(const string &d, const BaseDisplay * const _display,
- unsigned int _screen, BImageControl* _ctrl)
- : c(_display, _screen), ct(_display, _screen),
- lc(_display, _screen), sc(_display, _screen), bc(_display, _screen), t(0),
- dpy(_display), ctrl(_ctrl), scrn(_screen) {
- setDescription(d);
-}
-
-
-void BTexture::setColor(const BColor &cc) {
- c = cc;
- c.setDisplay(display(), 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 = BColor(rr, gg, bb, display(), 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 = BColor(rr, gg, bb, display(), screen());
-}
-
-
-void BTexture::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(BTexture::Parent_Relative);
- } else {
- setTexture(0);
-
- if (descr.find("gradient") != string::npos) {
- addTexture(BTexture::Gradient);
- if (descr.find("crossdiagonal") != string::npos)
- addTexture(BTexture::CrossDiagonal);
- else if (descr.find("rectangle") != string::npos)
- addTexture(BTexture::Rectangle);
- else if (descr.find("pyramid") != string::npos)
- addTexture(BTexture::Pyramid);
- else if (descr.find("pipecross") != string::npos)
- addTexture(BTexture::PipeCross);
- else if (descr.find("elliptic") != string::npos)
- addTexture(BTexture::Elliptic);
- else if (descr.find("horizontal") != string::npos)
- addTexture(BTexture::Horizontal);
- else if (descr.find("vertical") != string::npos)
- addTexture(BTexture::Vertical);
- else
- addTexture(BTexture::Diagonal);
- } else {
- addTexture(BTexture::Solid);
- }
-
- if (descr.find("sunken") != string::npos)
- addTexture(BTexture::Sunken);
- else if (descr.find("flat") != string::npos)
- addTexture(BTexture::Flat);
- else
- addTexture(BTexture::Raised);
-
- if (texture() & BTexture::Flat) {
- if (descr.find("border") != string::npos)
- addTexture(BTexture::Border);
- } else {
- if (descr.find("bevel2") != string::npos)
- addTexture(BTexture::Bevel2);
- else
- addTexture(BTexture::Bevel1);
- }
-
- if (descr.find("interlaced") != string::npos)
- addTexture(BTexture::Interlaced);
- }
-}
-
-void BTexture::setDisplay(const BaseDisplay * const _display,
- const unsigned int _screen) {
- if (_display == display() && _screen == screen()) {
- // nothing to do
- return;
- }
-
- dpy = _display;
- scrn = _screen;
- c.setDisplay(_display, _screen);
- ct.setDisplay(_display, _screen);
- lc.setDisplay(_display, _screen);
- sc.setDisplay(_display, _screen);
- bc.setDisplay(_display, _screen);
-}
-
-
-BTexture& BTexture::operator=(const BTexture &tt) {
- c = tt.c;
- ct = tt.ct;
- lc = tt.lc;
- sc = tt.sc;
- bc = tt.bc;
- descr = tt.descr;
- t = tt.t;
- dpy = tt.dpy;
- scrn = tt.scrn;
- ctrl = tt.ctrl;
-
- return *this;
-}
-
-
-Pixmap BTexture::render(const unsigned int width, const unsigned int height,
- const Pixmap old) {
- assert(display() != 0);
- assert(texture() != BTexture::NoTexture);
-
- if (texture() == (BTexture::Flat | BTexture::Solid))
- return None;
- if (texture() == BTexture::Parent_Relative)
- return ParentRelative;
-
- if (screen() == ~(0u))
- scrn = DefaultScreen(display()->getXDisplay());
-
- assert(ctrl != 0);
- Pixmap ret = ctrl->renderImage(width, height, *this);
-
- if (old)
- ctrl->removeImage(old);
-
- return ret;
-}
diff --git a/src/texture.hh b/src/texture.hh
deleted file mode 100644
index 514a0584..00000000
--- a/src/texture.hh
+++ /dev/null
@@ -1,92 +0,0 @@
-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-#ifndef TEXTURE_HH
-#define TEXTURE_HH
-
-#include "color.hh"
-#include "util.hh"
-class BImageControl;
-
-#include <string>
-
-class BTexture {
-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)
- };
-
- BTexture(const BaseDisplay * const _display = 0,
- unsigned int _screen = ~(0u), BImageControl* _ctrl = 0);
- BTexture(const std::string &_description,
- const BaseDisplay * const _display = 0,
- unsigned int _screen = ~(0u), BImageControl* _ctrl = 0);
-
- void setColor(const BColor &_color);
- void setColorTo(const BColor &_colorTo) { ct = _colorTo; }
- void setBorderColor(const BColor &_borderColor) { bc = _borderColor; }
-
- const BColor &color(void) const { return c; }
- const BColor &colorTo(void) const { return ct; }
- const BColor &lightColor(void) const { return lc; }
- const BColor &shadowColor(void) const { return sc; }
- const BColor &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; }
-
- BTexture &operator=(const BTexture &tt);
- inline bool operator==(const BTexture &tt)
- { return (c == tt.c && ct == tt.ct && lc == tt.lc &&
- sc == tt.sc && t == tt.t); }
- inline bool operator!=(const BTexture &tt)
- { return (! operator==(tt)); }
-
- const BaseDisplay *display(void) const { return dpy; }
- unsigned int screen(void) const { return scrn; }
- void setDisplay(const BaseDisplay * const _display,
- const unsigned int _screen);
- void setImageControl(BImageControl* _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:
- BColor c, ct, lc, sc, bc;
- std::string descr;
- unsigned long t;
- const BaseDisplay *dpy;
- BImageControl *ctrl;
- unsigned int scrn;
-};
-
-#endif // TEXTURE_HH