From c9299fff8f5492df6aafce4455c1ee7cff1ab1f8 Mon Sep 17 00:00:00 2001 From: fluxgen <fluxgen> Date: Thu, 9 Jan 2003 21:52:09 +0000 Subject: moved to FbTk --- src/ImageControl.cc | 636 ------------------ src/ImageControl.hh | 125 ---- src/TextureRender.cc | 1788 -------------------------------------------------- src/TextureRender.hh | 94 --- src/Timer.cc | 177 ----- src/Timer.hh | 91 --- 6 files changed, 2911 deletions(-) delete mode 100644 src/ImageControl.cc delete mode 100644 src/ImageControl.hh delete mode 100644 src/TextureRender.cc delete mode 100644 src/TextureRender.hh delete mode 100644 src/Timer.cc delete mode 100644 src/Timer.hh diff --git a/src/ImageControl.cc b/src/ImageControl.cc deleted file mode 100644 index f27f46c..0000000 --- a/src/ImageControl.cc +++ /dev/null @@ -1,636 +0,0 @@ -// ImageControl.cc for Fluxbox Window Manager -// Copyright (c) 2001 - 2002 Henrik Kinnunen (fluxbox at linuxmail.org) -// -// Image.cc for Blackbox - an X11 Window manager -// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -// $Id: ImageControl.cc,v 1.2 2002/12/01 13:41:57 rathnor Exp $ - -#include "ImageControl.hh" - -#include "TextureRender.hh" -#include "App.hh" - -//use GNU extensions -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif // _GNU_SOURCE - -#include "i18n.hh" - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif // HAVE_CONFIG_H - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif // HAVE_SYS_TYPES_H - -#include <cstdlib> -#include <cstring> -#include <cstdio> - -#ifdef HAVE_CTYPE_H -#include <ctype.h> -#endif // HAVE_CTYPE_H - -#include <iostream> - -using namespace std; - -// lookup table for texture -unsigned long *BImageControl::sqrt_table = 0; - -namespace { // anonymous - -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::BImageControl(int screen_num, bool dither, - int cpc, unsigned long cache_timeout, unsigned long cmax): - m_dither(dither), - m_timer(this), - m_colors(0), - m_num_colors(0), - m_colors_per_channel(cpc) { - - Display *disp = FbTk::App::instance()->display(); - - m_screen_depth = DefaultDepth(disp, screen_num); - m_screen_num = screen_num; - m_root_window = RootWindow(disp, screen_num); - m_visual = DefaultVisual(disp, screen_num); - m_colormap = DefaultColormap(disp, screen_num); - - cache_max = cmax; -#ifdef TIMEDCACHE - if (cache_timeout) { - m_timer.setTimeout(cache_timeout); - m_timer.start(); - } -#endif // TIMEDCACHE - - createColorTable(); -} - - -BImageControl::~BImageControl() { - if (sqrt_table) { - delete [] sqrt_table; - } - - if (grad_xbuffer) { - delete [] grad_xbuffer; - } - - if (grad_ybuffer) { - delete [] grad_ybuffer; - } - - if (m_colors) { - unsigned long *pixels = new unsigned long [m_num_colors]; - - for (unsigned int color = 0; color < m_num_colors; color++) - *(pixels + color) = (*(m_colors + color)).pixel; - - XFreeColors(FbTk::App::instance()->display(), m_colormap, pixels, m_num_colors, 0); - - delete [] m_colors; - } - - if (cache.size() > 0) { - fprintf(stderr, - I18n::instance()-> - getMessage( - FBNLS::ImageSet, FBNLS::ImagePixmapRelease, - "BImageContol::~BImageControl: pixmap cache - " - "releasing %d pixmaps\n"), cache.size()); - - CacheList::iterator it = cache.begin(); - CacheList::iterator it_end = cache.end(); - Display *disp = FbTk::App::instance()->display(); - for (; it != it_end; ++it) { - XFreePixmap(disp, (*it)->pixmap); - delete (*it); - } - - } -} - - -Pixmap BImageControl::searchCache(unsigned int width, unsigned int height, - unsigned long texture_type, - const FbTk::Color &color, const FbTk::Color &color_to) const { - CacheList::iterator it = cache.begin(); - CacheList::iterator it_end = cache.end(); - for (; it != it_end; ++it) { - if (((*it)->width == width) && - ((*it)->height == height) && - ((*it)->texture == texture_type) && - ((*it)->pixel1 == color.pixel())) { - if (texture_type & FbTk::Texture::GRADIENT) { - if ((*it)->pixel2 == color_to.pixel()) { - (*it)->count++; - return (*it)->pixmap; - } - } else { - (*it)->count++; - return (*it)->pixmap; - } - } - } - - return None; -} - - -Pixmap BImageControl::renderImage(unsigned int width, unsigned int height, - const FbTk::Texture &texture) { - - if (texture.type() & FbTk::Texture::PARENTRELATIVE) - return ParentRelative; - - // search cache first - Pixmap pixmap = searchCache(width, height, texture.type(), - texture.color(), texture.colorTo()); - if (pixmap) - return pixmap; // return cache item - - // render new image - TextureRender image(*this, width, height); - pixmap = image.render(texture); - - if (pixmap) { - // create new cache item and add it to cache list - - Cache *tmp = new Cache; - - tmp->pixmap = pixmap; - tmp->width = width; - tmp->height = height; - tmp->count = 1; - tmp->texture = texture.type(); - tmp->pixel1 = texture.color().pixel(); - - if (texture.type() & FbTk::Texture::GRADIENT) - tmp->pixel2 = texture.colorTo().pixel(); - else - tmp->pixel2 = 0l; - - cache.push_back(tmp); - - if ((unsigned) cache.size() > cache_max) { -#ifdef DEBUG - cerr<<I18n::instance()-> - getMessage( - FBNLS::ImageSet, FBNLS::ImagePixmapCacheLarge, - "BImageControl::renderImage: cache is large, " - "forcing cleanout\n")<<endl; -#endif // DEBUG - timeout(); - } - - return pixmap; - } - - return None; -} - - -void BImageControl::removeImage(Pixmap pixmap) { - if (!pixmap) - return; - - CacheList::iterator it = cache.begin(); - CacheList::iterator it_end = cache.end(); - for (; it != it_end; ++it) { - if ((*it)->pixmap == pixmap) { - if ((*it)->count) { - (*it)->count--; - -#ifdef TIMEDCACHE - timeout(); -#else // !TIMEDCACHE - if (! (*it)->count) timeout(); -#endif // TIMEDCACHE - } - - return; - } - } -} - - -void BImageControl::colorTables(const unsigned char **rmt, const unsigned char **gmt, - const unsigned char **bmt, - int *roff, int *goff, int *boff, - int *rbit, int *gbit, int *bbit) const { - - 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 = m_colors; - if (n) *n = m_num_colors; -} - - -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() { - XGrabServer(FbTk::App::instance()->display()); - - - Display *disp = FbTk::App::instance()->display(); - bool install = true; - int i = 0, ncmap = 0; - Colormap *cmaps = - XListInstalledColormaps(disp, m_root_window, &ncmap); - - if (cmaps) { - for (i = 0; i < ncmap; i++) { - if (*(cmaps + i) == m_colormap) - install = false; - } - - if (install) - XInstallColormap(disp, m_colormap); - - XFree(cmaps); - } - - XUngrabServer(FbTk::App::instance()->display()); -} - - -void BImageControl::setColorsPerChannel(int cpc) { - if (cpc < 2) cpc = 2; - if (cpc > 6) cpc = 6; - - m_colors_per_channel = cpc; -} - - -unsigned long BImageControl::getSqrt(unsigned int x) const { - if (! sqrt_table) { - // build sqrt table for use with elliptic gradient - - sqrt_table = new unsigned long[(256 * 256 * 2) + 1]; - int i = 0; - - for (; i < (256 * 256 * 2); i++) - *(sqrt_table + i) = bsqrt(i); - } - - return (*(sqrt_table + x)); -} - -void BImageControl::timeout() { - Display *disp = FbTk::App::instance()->display(); - CacheList::iterator it = cache.begin(); - CacheList::iterator it_end = cache.end(); - for (; it != it_end; ++it) { - Cache *tmp = (*it); - - if (tmp->count <= 0) { - XFreePixmap(disp, tmp->pixmap); - it = cache.erase(it); - delete tmp; - if (it == it_end) break; - } - } -} - -void BImageControl::createColorTable() { - Display *disp = FbTk::App::instance()->display(); - - grad_xbuffer = grad_ybuffer = (unsigned int *) 0; - grad_buffer_width = grad_buffer_height = 0; - - int count; - XPixmapFormatValues *pmv = XListPixmapFormats(disp, &count); - - if (pmv) { - bits_per_pixel = 0; - for (int i = 0; i < count; i++) { - if (pmv[i].depth == m_screen_depth) { - bits_per_pixel = pmv[i].bits_per_pixel; - break; - } - } - - XFree(pmv); - } - - if (bits_per_pixel == 0) - bits_per_pixel = m_screen_depth; - if (bits_per_pixel >= 24) - setDither(false); - - red_offset = green_offset = blue_offset = 0; - I18n *i18n = I18n::instance(); - switch (visual()->c_class) { - case TrueColor: { - int i; - - // compute color tables - unsigned long red_mask = visual()->red_mask, - green_mask = visual()->green_mask, - blue_mask = visual()->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: { - - m_num_colors = m_colors_per_channel * m_colors_per_channel * m_colors_per_channel; - - if (m_num_colors > static_cast<unsigned int>(1 << m_screen_depth)) { - m_colors_per_channel = (1 << m_screen_depth) / 3; - m_num_colors = m_colors_per_channel * m_colors_per_channel * m_colors_per_channel; - } - - if (m_colors_per_channel < 2 || m_num_colors > static_cast<unsigned int>(1 << m_screen_depth)) { - fprintf(stderr, - i18n-> - getMessage( - FBNLS::ImageSet, FBNLS::ImageInvalidColormapSize, - "BImageControl::BImageControl: invalid colormap size %d " - "(%d/%d/%d) - reducing"), - m_num_colors, m_colors_per_channel, m_colors_per_channel, - m_colors_per_channel); - - m_colors_per_channel = (1 << m_screen_depth) / 3; - } - - m_colors = new XColor[m_num_colors]; - - int bits = 256 / m_colors_per_channel; - -#ifndef ORDEREDPSEUDO - bits = 255 / (m_colors_per_channel - 1); -#endif // ORDEREDPSEUDO - - red_bits = green_bits = blue_bits = bits; - - for (unsigned int i = 0; i < 256; i++) { - red_color_table[i] = green_color_table[i] = blue_color_table[i] = - i / bits; - } - - for (int r = 0, i = 0; r < m_colors_per_channel; r++) { - for (int g = 0; g < m_colors_per_channel; g++) { - for (int b = 0; b < m_colors_per_channel; b++, i++) { - m_colors[i].red = (r * 0xffff) / (m_colors_per_channel - 1); - m_colors[i].green = (g * 0xffff) / (m_colors_per_channel - 1); - m_colors[i].blue = (b * 0xffff) / (m_colors_per_channel - 1);; - m_colors[i].flags = DoRed|DoGreen|DoBlue; - } - } - } - - for (unsigned int i = 0; i < m_num_colors; i++) { - if (! XAllocColor(disp, m_colormap, &m_colors[i])) { - fprintf(stderr, - i18n->getMessage( - FBNLS::ImageSet, FBNLS::ImageColorAllocFail, - "couldn't alloc color %i %i %i\n"), - m_colors[i].red, m_colors[i].green, m_colors[i].blue); - m_colors[i].flags = 0; - } else - m_colors[i].flags = DoRed|DoGreen|DoBlue; - } - - XColor icolors[256]; - unsigned int incolors = (((1 << m_screen_depth) > 256) ? 256 : (1 << m_screen_depth)); - - for (unsigned int i = 0; i < incolors; i++) - icolors[i].pixel = i; - - XQueryColors(disp, m_colormap, icolors, incolors); - for (unsigned int i = 0; i < m_num_colors; i++) { - if (! m_colors[i].flags) { - unsigned long chk = 0xffffffff, pixel, close = 0; - char p = 2; - - while (p--) { - for (unsigned int ii = 0; ii < incolors; ii++) { - int r = (m_colors[i].red - icolors[i].red) >> 8; - int g = (m_colors[i].green - icolors[i].green) >> 8; - int b = (m_colors[i].blue - icolors[i].blue) >> 8; - pixel = (r * r) + (g * g) + (b * b); - - if (pixel < chk) { - chk = pixel; - close = ii; - } - - m_colors[i].red = icolors[close].red; - m_colors[i].green = icolors[close].green; - m_colors[i].blue = icolors[close].blue; - - if (XAllocColor(disp, m_colormap, - &m_colors[i])) { - m_colors[i].flags = DoRed|DoGreen|DoBlue; - break; - } - } - } - } - } - - break; - } - - case GrayScale: - case StaticGray: - { - - if (visual()->c_class == StaticGray) { - m_num_colors = 1 << m_screen_depth; - } else { - m_num_colors = m_colors_per_channel * m_colors_per_channel * m_colors_per_channel; - - if (m_num_colors > static_cast<unsigned int>(1 << m_screen_depth)) { - m_colors_per_channel = (1 << m_screen_depth) / 3; - m_num_colors = m_colors_per_channel * m_colors_per_channel * m_colors_per_channel; - } - } - - if (m_colors_per_channel < 2 || m_num_colors > static_cast<unsigned int>(1 << m_screen_depth)) { - fprintf(stderr, - i18n-> - getMessage( - FBNLS::ImageSet, FBNLS::ImageInvalidColormapSize, - "BImageControl::BImageControl: invalid colormap size %d " - "(%d/%d/%d) - reducing"), - m_num_colors, m_colors_per_channel, m_colors_per_channel, - m_colors_per_channel); - - m_colors_per_channel = (1 << m_screen_depth) / 3; - } - - m_colors = new XColor[m_num_colors]; - - int p, bits = 255 / (m_colors_per_channel - 1); - red_bits = green_bits = blue_bits = bits; - - for (unsigned int i = 0; i < 256; i++) - red_color_table[i] = green_color_table[i] = blue_color_table[i] = - i / bits; - - for (unsigned int i = 0; i < m_num_colors; i++) { - m_colors[i].red = (i * 0xffff) / (m_colors_per_channel - 1); - m_colors[i].green = (i * 0xffff) / (m_colors_per_channel - 1); - m_colors[i].blue = (i * 0xffff) / (m_colors_per_channel - 1);; - m_colors[i].flags = DoRed|DoGreen|DoBlue; - - if (! XAllocColor(disp, m_colormap, - &m_colors[i])) { - fprintf(stderr, - i18n-> - getMessage( - FBNLS::ImageSet, FBNLS::ImageColorAllocFail, - "couldn't alloc color %i %i %i\n"), - m_colors[i].red, m_colors[i].green, m_colors[i].blue); - m_colors[i].flags = 0; - } else - m_colors[i].flags = DoRed|DoGreen|DoBlue; - } - - - XColor icolors[256]; - unsigned int incolors = (((1 << m_screen_depth) > 256) ? 256 : - (1 << m_screen_depth)); - - for (unsigned int i = 0; i < incolors; i++) - icolors[i].pixel = i; - - XQueryColors(disp, m_colormap, icolors, incolors); - for (unsigned int i = 0; i < m_num_colors; i++) { - if (! m_colors[i].flags) { - unsigned long chk = 0xffffffff, pixel, close = 0; - - p = 2; - while (p--) { - for (unsigned int ii = 0; ii < incolors; ii++) { - int r = (m_colors[i].red - icolors[i].red) >> 8; - int g = (m_colors[i].green - icolors[i].green) >> 8; - int b = (m_colors[i].blue - icolors[i].blue) >> 8; - pixel = (r * r) + (g * g) + (b * b); - - if (pixel < chk) { - chk = pixel; - close = ii; - } - - m_colors[i].red = icolors[close].red; - m_colors[i].green = icolors[close].green; - m_colors[i].blue = icolors[close].blue; - - if (XAllocColor(disp, m_colormap, &m_colors[i])) { - m_colors[i].flags = DoRed|DoGreen|DoBlue; - break; - } - } - } - } - } - - break; - } - - default: - throw string(i18n-> - getMessage( - FBNLS::ImageSet, FBNLS::ImageUnsupVisual, - "BImageControl::BImageControl: unsupported visual")); - - } -} diff --git a/src/ImageControl.hh b/src/ImageControl.hh deleted file mode 100644 index 7377081..0000000 --- a/src/ImageControl.hh +++ /dev/null @@ -1,125 +0,0 @@ -// ImageControl.hh for Fluxbox Window Manager -// Copyright (c) 2001 - 2002 Henrik Kinnunen (fluxbox at linuxmail.org) -// -// from Image.hh for Blackbox - an X11 Window manager -// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -// $Id: ImageControl.hh,v 1.3 2002/12/01 13:41:57 rathnor Exp $ - -#ifndef IMAGECONTROL_HH -#define IMAGECONTROL_HH - -#include "Texture.hh" -#include "Timer.hh" - -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <list> - -/** - Holds screen info and color tables -*/ -class BImageControl : public TimeoutHandler { -public: - BImageControl(int screen_num, bool dither = false, int colors_per_channel = 4, - unsigned long cache_timeout = 300000l, unsigned long cache_max = 200l); - virtual ~BImageControl(); - - inline bool doDither() const { return m_dither; } - inline int bitsPerPixel() const { return bits_per_pixel; } - inline int depth() const { return m_screen_depth; } - inline int colorsPerChannel() const { return m_colors_per_channel; } - int screenNum() const { return m_screen_num; } - Visual *visual() const { return m_visual; } - unsigned long getSqrt(unsigned int val) const; - - /** - Render to pixmap - @param width width of pixmap - @param height height of pixmap - @param src_texture texture type to render - @return pixmap of the rendered image, on failure None - */ - Pixmap renderImage(unsigned int width, unsigned int height, - const FbTk::Texture &src_texture); - - void installRootColormap(); - void removeImage(Pixmap thepix); - void colorTables(const unsigned char **, const unsigned char **, const unsigned char **, - int *, int *, int *, int *, int *, int *) const; - void getXColorTable(XColor **, int *); - void getGradientBuffers(unsigned int, unsigned int, - unsigned int **, unsigned int **); - void setDither(bool d) { m_dither = d; } - void setColorsPerChannel(int cpc); - - virtual void timeout(); - -private: - /** - Search cache for a specific pixmap - @return None if no cache was found - */ - Pixmap searchCache(unsigned int width, unsigned int height, unsigned long texture_type, - const FbTk::Color &color, const FbTk::Color &color_to) const; - - void createColorTable(); - bool m_dither; - - BTimer m_timer; - - Colormap m_colormap; - - Window m_root_window; - - XColor *m_colors; ///< color table - unsigned int m_num_colors; ///< number of colors in color table - - Visual *m_visual; - - int bits_per_pixel, red_offset, green_offset, blue_offset, - red_bits, green_bits, blue_bits; - int m_colors_per_channel; ///< number of colors per channel - int m_screen_depth; ///< bit depth of screen - int m_screen_num; ///< screen number - 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; - - static unsigned long *sqrt_table; /// sqrt lookup table - - typedef struct Cache { - Pixmap pixmap; - - unsigned int count, width, height; - unsigned long pixel1, pixel2, texture; - } Cache; - - unsigned long cache_max; - typedef std::list<Cache *> CacheList; - - mutable CacheList cache; -}; - - -#endif // IMAGECONTROL_HH - diff --git a/src/TextureRender.cc b/src/TextureRender.cc deleted file mode 100644 index d3ef8f6..0000000 --- a/src/TextureRender.cc +++ /dev/null @@ -1,1788 +0,0 @@ -// TextureRender.cc for fluxbox -// Copyright (c) 2002 Henrik Kinnunen (fluxgen at fluxbox.org) -// -// from Image.cc for Blackbox - an X11 Window manager -// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -// $Id: TextureRender.cc,v 1.7 2003/01/05 22:36:28 fluxgen Exp $ - -#include "TextureRender.hh" - -#include "ImageControl.hh" -#include "i18n.hh" -#include "App.hh" - -#include <iostream> -#include <string> -#include <cstdio> -using namespace std; - -TextureRender::TextureRender(BImageControl &imgctrl, - unsigned int w, unsigned int h, - XColor *_colors, size_t num_colors): - control(imgctrl), - colors(_colors), - ncolors(ncolors), - xtable(0), ytable(0) { - - width = ((signed) w > 0) ? w : 1; - height = ((signed) h > 0) ? h : 1; - // clamp to "normal" size - if (width > 3200) { - cerr<<"TextureRender: Warning! Width > 3200 setting Width = 3200"<<endl; - width = 3200; - } - - if (height > 3200) { - cerr<<"TextureRender: Warning! Height > 3200 setting Height = 3200"<<endl; - height = 3200; - } - - red = new (nothrow) unsigned char[width * height]; - if (red == 0) { - char sbuf[128]; - sprintf(sbuf, "%d", width*height); - throw string("TextureRender::TextureRender(): Out of memory while allocating red buffer."+ string(sbuf)); - } - - - green = new (nothrow) unsigned char[width * height]; - if (green == 0) { - char sbuf[128]; - sprintf(sbuf, "%d", width*height); - throw string("TextureRender::TextureRender(): Out of memory while allocating green buffer. size " + string(sbuf)); - } - - blue = new (nothrow) unsigned char[width * height]; - if (blue == 0) { - char sbuf[128]; - sprintf(sbuf, "%d", width*height); - throw string("TextureRender::TextureRender(): Out of memory while allocating blue buffer. size " + string(sbuf)); - } - - cpc = imgctrl.colorsPerChannel(); - cpccpc = cpc * cpc; - - imgctrl.colorTables(&red_table, &green_table, &blue_table, - &red_offset, &green_offset, &blue_offset, - &red_bits, &green_bits, &blue_bits); - -} - - -TextureRender::~TextureRender() { - delete [] red; - delete [] green; - delete [] blue; -} - - -Pixmap TextureRender::render(const FbTk::Texture &texture) { - - if (texture.type() & FbTk::Texture::PARENTRELATIVE) - return ParentRelative; - else if (texture.type() & FbTk::Texture::SOLID) - return renderSolid(texture); - else if (texture.type() & FbTk::Texture::GRADIENT) - return renderGradient(texture); - - return None; -} - - -Pixmap TextureRender::renderSolid(const FbTk::Texture &texture) { - - Display *disp = FbTk::App::instance()->display(); - - Pixmap pixmap = XCreatePixmap(disp, - RootWindow(disp, control.screenNum()), width, - height, control.depth()); - if (pixmap == None) { - cerr<<I18n::instance()-> - getMessage( - FBNLS::ImageSet, FBNLS::ImageErrorCreatingSolidPixmap, - "BImage::render_solid: error creating pixmap")<<endl; - return None; - } - - XGCValues gcv; - GC gc, hgc, lgc; - - gcv.foreground = texture.color().pixel(); - gcv.fill_style = FillSolid; - gc = XCreateGC(disp, pixmap, GCForeground | GCFillStyle, &gcv); - - gcv.foreground = texture.hiColor().pixel(); - hgc = XCreateGC(disp, pixmap, GCForeground, &gcv); - - gcv.foreground = texture.loColor().pixel(); - lgc = XCreateGC(disp, pixmap, GCForeground, &gcv); - - XFillRectangle(disp, pixmap, gc, 0, 0, width, height); - - using namespace FbTk; - - if (texture.type() & Texture::INTERLACED) { - gcv.foreground = texture.colorTo().pixel(); - GC igc = XCreateGC(disp, pixmap, - GCForeground, &gcv); - - register unsigned int i = 0; - for (; i < height; i += 2) - XDrawLine(disp, pixmap, igc, 0, i, width, i); - - XFreeGC(disp, igc); - } - - if (texture.type() & Texture::BEVEL1) { - if (texture.type() & Texture::RAISED) { - XDrawLine(disp, pixmap, lgc, - 0, height - 1, width - 1, height - 1); - XDrawLine(disp, pixmap, lgc, - width - 1, height - 1, width - 1, 0); - - XDrawLine(disp, pixmap, hgc, - 0, 0, width - 1, 0); - XDrawLine(disp, pixmap, hgc, - 0, height - 1, 0, 0); - } else if (texture.type() & Texture::SUNKEN) { - XDrawLine(disp, pixmap, hgc, - 0, height - 1, width - 1, height - 1); - XDrawLine(disp, pixmap, hgc, - width - 1, height - 1, width - 1, 0); - - XDrawLine(disp, pixmap, lgc, - 0, 0, width - 1, 0); - XDrawLine(disp, pixmap, lgc, - 0, height - 1, 0, 0); - } - } else if (texture.type() & Texture::BEVEL2) { - if (texture.type() & Texture::RAISED) { - XDrawLine(disp, pixmap, lgc, - 1, height - 3, width - 3, height - 3); - XDrawLine(disp, pixmap, lgc, - width - 3, height - 3, width - 3, 1); - - XDrawLine(disp, pixmap, hgc, - 1, 1, width - 3, 1); - XDrawLine(disp, pixmap, hgc, - 1, height - 3, 1, 1); - } else if (texture.type() & Texture::SUNKEN) { - XDrawLine(disp, pixmap, hgc, - 1, height - 3, width - 3, height - 3); - XDrawLine(disp, pixmap, hgc, - width - 3, height - 3, width - 3, 1); - - XDrawLine(disp, pixmap, lgc, - 1, 1, width - 3, 1); - XDrawLine(disp, pixmap, lgc, - 1, height - 3, 1, 1); - } - } - - XFreeGC(disp, gc); - XFreeGC(disp, hgc); - XFreeGC(disp, lgc); - - return pixmap; -} - - -Pixmap TextureRender::renderGradient(const FbTk::Texture &texture) { - - bool inverted = false; - - using namespace FbTk; - - interlaced = texture.type() & Texture::INTERLACED; - - if (texture.type() & Texture::SUNKEN) { - from = &(texture.colorTo()); - to = &(texture.color()); - - if (! (texture.type() & Texture::INVERT)) - inverted = true; - } else { - from = &(texture.color()); - to = &(texture.colorTo()); - - if (texture.type() & Texture::INVERT) - inverted = true; - } - - control.getGradientBuffers(width, height, &xtable, &ytable); - - if (texture.type() & Texture::DIAGONAL) - dgradient(); - else if (texture.type() & Texture::ELLIPTIC) - egradient(); - else if (texture.type() & Texture::HORIZONTAL) - hgradient(); - else if (texture.type() & Texture::PYRAMID) - pgradient(); - else if (texture.type() & Texture::RECTANGLE) - rgradient(); - else if (texture.type() & Texture::VERTICAL) - vgradient(); - else if (texture.type() & Texture::CROSSDIAGONAL) - cdgradient(); - else if (texture.type() & Texture::PIPECROSS) - pcgradient(); - - if (texture.type() & Texture::BEVEL1) - bevel1(); - else if (texture.type() & Texture::BEVEL2) - bevel2(); - - if (inverted) - invert(); - - return renderPixmap(); - -} - - -XImage *TextureRender::renderXImage() { - I18n *i18n = I18n::instance(); - Display *disp = FbTk::App::instance()->display(); - XImage *image = - XCreateImage(disp, - DefaultVisual(disp, control.screenNum()), control.depth(), ZPixmap, 0, 0, - width, height, 32, 0); - - if (! image) { - fprintf(stderr, - i18n-> - getMessage( - FBNLS::ImageSet, FBNLS::ImageErrorCreatingXImage, - "BImage::renderXImage: error creating XImage\n")); - return 0; - } - - image->data = 0; - - unsigned char *d = new unsigned char[image->bytes_per_line * (height + 1)]; - register unsigned int x, y, dithx, dithy, r, g, b, o, er, eg, eb, offset; - - unsigned char *pixel_data = d, *ppixel_data = d; - unsigned long pixel; - - o = image->bits_per_pixel + ((image->byte_order == MSBFirst) ? 1 : 0); - - if (control.doDither() && width > 1 && height > 1) { - unsigned char dither4[4][4] = { - {0, 4, 1, 5}, - {6, 2, 7, 3}, - {1, 5, 0, 4}, - {7, 3, 6, 2} }; - -#ifdef ORDEREDPSEUDO - 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 } }; -#endif // ORDEREDPSEUDO - - switch (control.visual()->c_class) { - case TrueColor: - // 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 - 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); - - switch (o) { - 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; - } - } - - pixel_data = (ppixel_data += image->bytes_per_line); - } - - break; - - case StaticColor: - case PseudoColor: { -#ifndef ORDEREDPSEUDO - 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.colorsPerChannel(); - - 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; -#endif // ORDEREDPSEUDO - - for (y = 0, offset = 0; y < height; y++) { -#ifdef ORDEREDPSEUDO - 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 += image->bytes_per_line); - } -#else // !ORDEREDPSEUDO - 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 += image->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; -#endif // ORDEREDPSUEDO - - } break; - - /* - case StaticGray: - case GrayScale: - 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 & 0x7; - eg = g & 0x7; - eb = b & 0x7; - - if ((dither[dithy][dithx] < er) && (r < (256 - 8))) - r += 8; - if ((dither[dithy][dithx] < (eg << 1)) && (g < (256 - 4))) - g += 4; - if ((dither[dithy][dithx] < eb) && (b < (256 - 8))) - b += 8; - - r = *(red_table + r); - g = *(green_table + g); - b = *(blue_table + b); - - g = ((r * 30) + (g * 59) + (b * 11)) / 100; - *pixel_data++ = colors[g].pixel; - } - - pixel_data = (ppixel_data += image->bytes_per_line); - } - - break; - */ - - default: - fprintf(stderr, - i18n-> - getMessage( - FBNLS::ImageSet, FBNLS::ImageUnsupVisual, - "BImage::renderXImage: unsupported visual\n")); - delete [] d; - XDestroyImage(image); - return (XImage *) 0; - } -} else { - switch (control.visual()->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); - - switch (o) { - 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; - } - } - - 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: - fprintf(stderr, - i18n-> - getMessage( - FBNLS::ImageSet, FBNLS::ImageUnsupVisual, - "BImage::renderXImage: unsupported visual\n")); - delete [] d; - XDestroyImage(image); - return (XImage *) 0; - } -} - -image->data = (char *) d; -return image; -} - - -Pixmap TextureRender::renderPixmap() { -Display *disp = FbTk::App::instance()->display(); -I18n *i18n = I18n::instance(); -Pixmap pixmap = -XCreatePixmap(disp, - RootWindow(disp, control.screenNum()), width, height, control.depth()); - -if (pixmap == None) { -fprintf(stderr, - i18n->getMessage( -FBNLS::ImageSet, FBNLS::ImageErrorCreatingPixmap, - "BImage::renderPixmap: error creating pixmap\n")); -return None; -} - -XImage *image = renderXImage(); - -if (! image) { -XFreePixmap(disp, pixmap); -return None; -} else if (! image->data) { -XDestroyImage(image); -XFreePixmap(disp, pixmap); -return None; -} - -XPutImage(disp, pixmap, - DefaultGC(disp, control.screenNum()), - image, 0, 0, 0, 0, width, height); - -if (image->data != 0) { -delete [] image->data; -image->data = 0; -} - -XDestroyImage(image); - -return pixmap; -} - - -void TextureRender::bevel1() { -if (! (width > 2 && height > 2)) - return; - -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 TextureRender::bevel2() { -if (! (width > 4 && height > 4)) - return; - -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 TextureRender::invert() { -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 TextureRender::dgradient() { -// 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; -unsigned int *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 TextureRender::hgradient() { -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 TextureRender::vgradient() { -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 TextureRender::pgradient() { -// 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(); -unsigned int *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 TextureRender::rgradient() { -// 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(); -unsigned int *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 * std::max(*(xt++), *(yt)))); -*(pg++) = (unsigned char) (tg - (gsign * std::max(*(xt++), *(yt + 1)))); -*(pb++) = (unsigned char) (tb - (bsign * std::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 * std::max(*(xt++), *(yt)))); -channel2 = (channel >> 1) + (channel >> 2); -if (channel2 > channel) channel2 = 0; -*(pr++) = channel2; - -channel = (unsigned char) (tg - (gsign * std::max(*(xt++), *(yt + 1)))); -channel2 = (channel >> 1) + (channel >> 2); -if (channel2 > channel) channel2 = 0; -*(pg++) = channel2; - -channel = (unsigned char) (tb - (bsign * std::max(*(xt++), *(yt + 2)))); -channel2 = (channel >> 1) + (channel >> 2); -if (channel2 > channel) channel2 = 0; -*(pb++) = channel2; -} else { -channel = (unsigned char) (tr - (rsign * std::max(*(xt++), *(yt)))); -channel2 = channel + (channel >> 3); -if (channel2 < channel) channel2 = ~0; -*(pr++) = channel2; - -channel = (unsigned char) (tg - (gsign * std::max(*(xt++), *(yt + 1)))); -channel2 = channel + (channel >> 3); -if (channel2 < channel) channel2 = ~0; -*(pg++) = channel2; - -channel = (unsigned char) (tb - (bsign * std::max(*(xt++), *(yt + 2)))); -channel2 = channel + (channel >> 3); -if (channel2 < channel) channel2 = ~0; -*(pb++) = channel2; -} -} -} -} - -} - - -void TextureRender::egradient() { -// 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; -unsigned int 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 TextureRender::pcgradient() { -// 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; -unsigned int 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 * std::min(*(xt++), *(yt)))); -*(pg++) = (unsigned char) (tg - (gsign * std::min(*(xt++), *(yt + 1)))); -*(pb++) = (unsigned char) (tb - (bsign * std::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 * std::min(*(xt++), *(yt)))); -channel2 = (channel >> 1) + (channel >> 2); -if (channel2 > channel) channel2 = 0; -*(pr++) = channel2; - -channel = (unsigned char) (tg - (bsign * std::min(*(xt++), *(yt + 1)))); -channel2 = (channel >> 1) + (channel >> 2); -if (channel2 > channel) channel2 = 0; -*(pg++) = channel2; - -channel = (unsigned char) (tb - (gsign * std::min(*(xt++), *(yt + 2)))); -channel2 = (channel >> 1) + (channel >> 2); -if (channel2 > channel) channel2 = 0; -*(pb++) = channel2; -} else { -channel = (unsigned char) (tr - (rsign * std::min(*(xt++), *(yt)))); -channel2 = channel + (channel >> 3); -if (channel2 < channel) channel2 = ~0; -*(pr++) = channel2; - -channel = (unsigned char) (tg - (gsign * std::min(*(xt++), *(yt + 1)))); -channel2 = channel + (channel >> 3); -if (channel2 < channel) channel2 = ~0; -*(pg++) = channel2; - -channel = (unsigned char) (tb - (bsign * std::min(*(xt++), *(yt + 2)))); -channel2 = channel + (channel >> 3); -if (channel2 < channel) channel2 = ~0; -*(pb++) = channel2; -} -} -} -} - -} - - -void TextureRender::cdgradient() { -// 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/TextureRender.hh b/src/TextureRender.hh deleted file mode 100644 index 06d5bb1..0000000 --- a/src/TextureRender.hh +++ /dev/null @@ -1,94 +0,0 @@ -// TextureRender.hh for fluxbox -// Copyright (c) 2002 Henrik Kinnunen (fluxgen at fluxbox.org) -// -// Image.hh for Blackbox - an X11 Window manager -// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -// $Id: TextureRender.hh,v 1.3 2002/12/01 13:42:00 rathnor Exp $ - -#ifndef TEXTURRENDER_HH -#define TEXTURRENDER_HH - -#include "Texture.hh" - -#include <X11/Xlib.h> - -class BImageControl; - -/** - Renders texture to pixmap -*/ -class TextureRender { -public: - TextureRender(BImageControl &ic, unsigned int width, unsigned int height, - XColor *_colors=0, size_t num_colors=0); - ~TextureRender(); - /// render to pixmap - Pixmap render(const FbTk::Texture &src_texture); - /// render solid texture to pixmap - Pixmap renderSolid(const FbTk::Texture &src_texture); - /// render gradient texture to pixmap - Pixmap renderGradient(const FbTk::Texture &src_texture); - -private: - /** - Render to pixmap - @return rendered pixmap - */ - Pixmap renderPixmap(); - /** - Render to XImage - @returns allocated and rendered XImage, user is responsible to deallocate - */ - XImage *renderXImage(); - /** - @name render functions - */ - //@{ - void invert(); - void bevel1(); - void bevel2(); - void dgradient(); - void egradient(); - void hgradient(); - void pgradient(); - void rgradient(); - void vgradient(); - void cdgradient(); - void pcgradient(); - //@} - void makeGradientBuffers(); - - BImageControl &control; - bool interlaced; - - XColor *colors; // color table - - const FbTk::Color *from, *to; - int red_offset, green_offset, blue_offset, red_bits, green_bits, blue_bits, - ncolors, cpc, cpccpc; - unsigned char *red, *green, *blue; - const unsigned char *red_table, *green_table, *blue_table; - unsigned int width, height; - unsigned int *xtable, *ytable; -}; - -#endif // TEXTURERENDER_HH diff --git a/src/Timer.cc b/src/Timer.cc deleted file mode 100644 index ebc1cd8..0000000 --- a/src/Timer.cc +++ /dev/null @@ -1,177 +0,0 @@ -// Timer.cc for Blackbox - An X11 Window Manager -// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -#include "Timer.hh" - -//use GNU extensions -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif // _GNU_SOURCE - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif // HAVE_CONFIG_H - -#include <sys/time.h> -#include <sys/types.h> -#include <unistd.h> -#include <cassert> - -//static var -BTimer::TimerList BTimer::m_timerlist; - -BTimer::BTimer(TimeoutHandler *h): - m_handler(h), - m_timing(false), - m_once(false) { -} - - -BTimer::~BTimer() { - if (isTiming()) stop(); -} - - -void BTimer::setTimeout(long t) { - m_timeout.tv_sec = t / 1000; - m_timeout.tv_usec = t; - m_timeout.tv_usec -= (m_timeout.tv_sec * 1000); - m_timeout.tv_usec *= 1000; -} - - -void BTimer::setTimeout(timeval t) { - m_timeout.tv_sec = t.tv_sec; - m_timeout.tv_usec = t.tv_usec; -} - - -void BTimer::start() { - gettimeofday(&m_start, 0); - - if (! m_timing) { - m_timing = true; - addTimer(this); //add us to the list - } -} - - -void BTimer::stop() { - m_timing = false; - removeTimer(this); //remove us from the list -} - - -void BTimer::fireTimeout() { - if (m_handler) m_handler->timeout(); -} - -void BTimer::updateTimers(int fd) { - fd_set rfds; - timeval now, tm, *timeout = 0; - - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - - if (m_timerlist.size() > 0) { - gettimeofday(&now, 0); - - tm.tv_sec = tm.tv_usec = 0l; - - BTimer *timer = m_timerlist.front(); - - tm.tv_sec = timer->getStartTime().tv_sec + - timer->getTimeout().tv_sec - now.tv_sec; - tm.tv_usec = timer->getStartTime().tv_usec + - timer->getTimeout().tv_usec - now.tv_usec; - - while (tm.tv_usec >= 1000000) { - tm.tv_sec++; - tm.tv_usec -= 1000000; - } - - while (tm.tv_usec < 0) { - if (tm.tv_sec > 0) { - tm.tv_sec--; - tm.tv_usec += 1000000; - } else { - tm.tv_usec = 0; - break; - } - } - - timeout = &tm; - } - - select(fd + 1, &rfds, 0, 0, timeout); - - // check for timer timeout - gettimeofday(&now, 0); - - TimerList::iterator it = m_timerlist.begin(); - //must check end ...the timer might remove - //it self from the list (should be fixed in the future) - for(; it != m_timerlist.end(); ++it) { - //This is to make sure we don't get an invalid iterator - //when we do fireTimeout - BTimer &t = *(*it); - tm.tv_sec = t.getStartTime().tv_sec + - t.getTimeout().tv_sec; - tm.tv_usec = t.getStartTime().tv_usec + - t.getTimeout().tv_usec; - - if ((now.tv_sec < tm.tv_sec) || - (now.tv_sec == tm.tv_sec && now.tv_usec < tm.tv_usec)) - break; - - t.fireTimeout(); - // restart the current timer so that the start time is updated - if (! t.doOnce()) - t.start(); - else { - t.stop(); - it--; - } - } -} - -void BTimer::addTimer(BTimer *timer) { - assert(timer); - - TimerList::iterator it = m_timerlist.begin(); - TimerList::iterator it_end = m_timerlist.end(); - int index = 0; - for (; it != it_end; ++it, ++index) { - if (((*it)->getTimeout().tv_sec > timer->getTimeout().tv_sec) || - (((*it)->getTimeout().tv_sec == timer->getTimeout().tv_sec) && - ((*it)->getTimeout().tv_usec >= timer->getTimeout().tv_usec))) { - break; - } - } - m_timerlist.insert(it, timer); - -} - -void BTimer::removeTimer(BTimer *timer) { - assert(timer); - m_timerlist.remove(timer); -} - diff --git a/src/Timer.hh b/src/Timer.hh deleted file mode 100644 index 873aaef..0000000 --- a/src/Timer.hh +++ /dev/null @@ -1,91 +0,0 @@ -// Timer.hh for fluxbox -// Copyright (c) 2002 Henrik Kinnunen (fluxgen at linuxmail.org) -// -// Timer.hh for Blackbox - An X11 Window Manager -// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -#ifndef TIMER_HH -#define TIMER_HH - -#include <ctime> -#include <list> - -/** - Inherit this to have a timed object, that calls - timeout function when the time is out -*/ -class TimeoutHandler { -public: - /// called when the time is out - virtual void timeout() = 0; -}; - -/** - Handles TimeoutHandles -*/ -class BTimer { -public: - explicit BTimer(TimeoutHandler *handler); - virtual ~BTimer(); - - inline int isTiming() const { return m_timing; } - inline int doOnce() const { return m_once; } - - inline const timeval &getTimeout() const { return m_timeout; } - inline const timeval &getStartTime() const { return m_start; } - - inline void fireOnce(bool once) { m_once = once; } - /// set timeout - void setTimeout(long val); - /// set timeout - void setTimeout(timeval val); - /// start timing - void start(); - /// stop timing - void stop(); - /// update all timers - static void updateTimers(int file_descriptor); - -protected: - /// force a timeout - void fireTimeout(); - -private: - /// add a timer to the static list - static void addTimer(BTimer *timer); - /// remove a timer from the static list - static void removeTimer(BTimer *timer); - - typedef std::list<BTimer *> TimerList; - static TimerList m_timerlist; ///< list of all timers - - TimeoutHandler *m_handler; ///< handler - - bool m_timing; ///< clock running? - bool m_once; ///< do timeout only once? - - timeval m_start; ///< start time - timeval m_timeout; ///< time length - -}; - -#endif // TIMER_HH - -- cgit v0.11.2