/* Keramik Style for KDE3, gradient routines.. Copyright (c) 2002 Malte Starostik (c) 2002 Maksim Orlovich This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // $Id$ #include #include #include #include "gradients.h" #include "colorutil.h" #include #include #include namespace { struct GradientCacheEntry { TQPixmap* m_pixmap; TQRgb m_color; bool m_menu; int m_width; int m_height; GradientCacheEntry(int width, int height, const TQColor& color, bool menu): m_pixmap(0), m_color(color.rgb()), m_menu(menu), m_width(width), m_height(height) {} int key() { return (int)m_menu ^ m_width ^ (m_height << 16) ^ ((m_color)<<8); } bool operator == (const GradientCacheEntry& other) { return ((m_width == other.m_width) && (m_height == other.m_height) && (m_menu == other.m_menu) && (m_color == other.m_color)); } ~GradientCacheEntry() { delete m_pixmap; } }; TQIntCache cache(65636, 17); } using namespace Keramik; void GradientPainter::releaseCache() { cache.clear(); } void GradientPainter::renderGradient( TQPainter* p, const TQRect& r, TQColor c, bool horizontal, bool menu, int px, int py, int pwidth, int pheight) { int width = r.width(), height = r.height(); if (pwidth != -1) width = pwidth; if (pheight != -1) height = pheight; if (horizontal) width = 18; else height = 18; GradientCacheEntry entry (width, height, c, menu); GradientCacheEntry* cacheEntry = 0; cache.setAutoDelete(true); int key = entry.key(); if ((cacheEntry = cache.find(key, false))) { if (entry == *cacheEntry) { p->drawTiledPixmap(r, *cacheEntry->m_pixmap, horizontal? TQPoint(0,py): TQPoint(px,0)); return; } else cache.remove(key); //Remove old entry in case of conflicts.. otherwise we end up w/unreachable items in cache } if (horizontal) { TQPixmap* pix = new TQPixmap(18, height); if (menu) { TQImage gr = KImageEffect::gradient(TQSize(4,height), c.light(93), ColorUtil::lighten(c,109), KImageEffect::VerticalGradient ); TQPixmap grT(gr); TQPainter p2(pix); p2.drawTiledPixmap(0,0, 18, height, grT); p2.end(); } else { int h1 = 3 * height/4; int h2 = height - h1; TQImage top = KImageEffect::gradient(TQSize(4,h1), ColorUtil::lighten(c,110), c.light(94), KImageEffect::VerticalGradient ); TQImage bot = KImageEffect::gradient(TQSize(4,h2), c.light(94), ColorUtil::lighten(c,109), KImageEffect::VerticalGradient ); TQPixmap topT(top); TQPixmap botT(bot); TQPainter p2(pix); p2.drawTiledPixmap(0, 0, 18, h1, topT); p2.drawTiledPixmap(0, h1, 18, h2, botT); p2.end(); } entry.m_pixmap = pix; } else { TQPixmap* pix = new TQPixmap(width, 18); int h1 = 3 * width/4; int h2 = width - h1; TQImage top = KImageEffect::gradient(TQSize(h1,4), ColorUtil::lighten(c,110), c.light(94), KImageEffect::HorizontalGradient ); TQImage bot = KImageEffect::gradient(TQSize(h2,4), c.light(94), ColorUtil::lighten(c,109), KImageEffect::HorizontalGradient ); TQPixmap topT(top); TQPixmap botT(bot); TQPainter p2(pix); p2.drawTiledPixmap(0, 0, h1, 18, topT); p2.drawTiledPixmap(h1, 0, h2, 18, botT); p2.end(); entry.m_pixmap = pix; } bool cacheOK = false; GradientCacheEntry* imgToAdd = new GradientCacheEntry(entry); cacheOK = cache.insert(imgToAdd->key(), imgToAdd, imgToAdd->m_pixmap->width() * imgToAdd->m_pixmap->height()* imgToAdd->m_pixmap->depth()/8); p->drawTiledPixmap(r, *imgToAdd->m_pixmap, horizontal? TQPoint(0,py): TQPoint(px,0)); if (!cacheOK) delete imgToAdd; entry.m_pixmap = 0;//Don't free too early.. }