kdecore Library API Documentation

kiconeffect.cpp

00001 /* vi: ts=8 sts=4 sw=4 00002 * $Id: kiconeffect.cpp,v 1.54 2005/02/16 15:51:35 gunnar Exp $ 00003 * 00004 * This file is part of the KDE project, module kdecore. 00005 * Copyright (C) 2000 Geert Jansen <jansen@kde.org> 00006 * with minor additions and based on ideas from 00007 * Torsten Rahn <torsten@kde.org> 00008 * 00009 * This is free software; it comes under the GNU Library General 00010 * Public License, version 2. See the file "COPYING.LIB" for the 00011 * exact licensing terms. 00012 */ 00013 00014 #include <config.h> 00015 #include <unistd.h> 00016 #include <math.h> 00017 00018 #include <qstring.h> 00019 #include <qstringlist.h> 00020 #include <qbitmap.h> 00021 #include <qpixmap.h> 00022 #include <qimage.h> 00023 #include <qcolor.h> 00024 #include <qwidget.h> 00025 #include <qpainter.h> 00026 #include <qpen.h> 00027 00028 #include <kdebug.h> 00029 #include <kglobal.h> 00030 #include <kconfig.h> 00031 #include <kglobalsettings.h> 00032 #include <kicontheme.h> 00033 #include "kiconeffect.h" 00034 00035 #if defined(Q_WS_WIN) || defined(Q_WS_MACX) 00036 static bool qt_use_xrender=true; 00037 static bool qt_has_xft=true; 00038 #else 00039 extern bool qt_use_xrender; 00040 extern bool qt_has_xft; 00041 #endif 00042 class KIconEffectPrivate 00043 { 00044 public: 00045 QString mKey[6][3]; 00046 QColor mColor2[6][3]; 00047 }; 00048 00049 KIconEffect::KIconEffect() 00050 { 00051 d = new KIconEffectPrivate; 00052 init(); 00053 } 00054 00055 KIconEffect::~KIconEffect() 00056 { 00057 delete d; 00058 d = 0L; 00059 } 00060 00061 void KIconEffect::init() 00062 { 00063 KConfig *config = KGlobal::config(); 00064 00065 int i, j, effect=-1; 00066 QStringList groups; 00067 groups += "Desktop"; 00068 groups += "Toolbar"; 00069 groups += "MainToolbar"; 00070 groups += "Small"; 00071 groups += "Panel"; 00072 00073 QStringList states; 00074 states += "Default"; 00075 states += "Active"; 00076 states += "Disabled"; 00077 00078 QStringList::ConstIterator it, it2; 00079 QString _togray("togray"); 00080 QString _colorize("colorize"); 00081 QString _desaturate("desaturate"); 00082 QString _togamma("togamma"); 00083 QString _none("none"); 00084 QString _tomonochrome("tomonochrome"); 00085 00086 KConfigGroupSaver cs(config, "default"); 00087 00088 for (it=groups.begin(), i=0; it!=groups.end(); it++, i++) 00089 { 00090 // Default effects 00091 mEffect[i][0] = NoEffect; 00092 mEffect[i][1] = ((i==0)||(i==4)) ? ToGamma : NoEffect; 00093 mEffect[i][2] = ToGray; 00094 00095 mTrans[i][0] = false; 00096 mTrans[i][1] = false; 00097 mTrans[i][2] = true; 00098 mValue[i][0] = 1.0; 00099 mValue[i][1] = ((i==0)||(i==4)) ? 0.7 : 1.0; 00100 mValue[i][2] = 1.0; 00101 mColor[i][0] = QColor(144,128,248); 00102 mColor[i][1] = QColor(169,156,255); 00103 mColor[i][2] = QColor(34,202,0); 00104 d->mColor2[i][0] = QColor(0,0,0); 00105 d->mColor2[i][1] = QColor(0,0,0); 00106 d->mColor2[i][2] = QColor(0,0,0); 00107 00108 config->setGroup(*it + "Icons"); 00109 for (it2=states.begin(), j=0; it2!=states.end(); it2++, j++) 00110 { 00111 QString tmp = config->readEntry(*it2 + "Effect"); 00112 if (tmp == _togray) 00113 effect = ToGray; 00114 else if (tmp == _colorize) 00115 effect = Colorize; 00116 else if (tmp == _desaturate) 00117 effect = DeSaturate; 00118 else if (tmp == _togamma) 00119 effect = ToGamma; 00120 else if (tmp == _tomonochrome) 00121 effect = ToMonochrome; 00122 else if (tmp == _none) 00123 effect = NoEffect; 00124 else 00125 continue; 00126 if(effect != -1) 00127 mEffect[i][j] = effect; 00128 mValue[i][j] = config->readDoubleNumEntry(*it2 + "Value"); 00129 mColor[i][j] = config->readColorEntry(*it2 + "Color"); 00130 d->mColor2[i][j] = config->readColorEntry(*it2 + "Color2"); 00131 mTrans[i][j] = config->readBoolEntry(*it2 + "SemiTransparent"); 00132 00133 } 00134 } 00135 } 00136 00137 bool KIconEffect::hasEffect(int group, int state) const 00138 { 00139 return mEffect[group][state] != NoEffect; 00140 } 00141 00142 QString KIconEffect::fingerprint(int group, int state) const 00143 { 00144 if ( group >= KIcon::LastGroup ) return ""; 00145 QString cached = d->mKey[group][state]; 00146 if (cached.isEmpty()) 00147 { 00148 QString tmp; 00149 cached = tmp.setNum(mEffect[group][state]); 00150 cached += ':'; 00151 cached += tmp.setNum(mValue[group][state]); 00152 cached += ':'; 00153 cached += mTrans[group][state] ? QString::fromLatin1("trans") 00154 : QString::fromLatin1("notrans"); 00155 if (mEffect[group][state] == Colorize || mEffect[group][state] == ToMonochrome) 00156 { 00157 cached += ':'; 00158 cached += mColor[group][state].name(); 00159 } 00160 if (mEffect[group][state] == ToMonochrome) 00161 { 00162 cached += ':'; 00163 cached += d->mColor2[group][state].name(); 00164 } 00165 00166 d->mKey[group][state] = cached; 00167 } 00168 00169 return cached; 00170 } 00171 00172 QImage KIconEffect::apply(QImage image, int group, int state) const 00173 { 00174 if (state >= KIcon::LastState) 00175 { 00176 kdDebug(265) << "Illegal icon state: " << state << "\n"; 00177 return image; 00178 } 00179 if (group >= KIcon::LastGroup) 00180 { 00181 kdDebug(265) << "Illegal icon group: " << group << "\n"; 00182 return image; 00183 } 00184 return apply(image, mEffect[group][state], mValue[group][state], 00185 mColor[group][state], d->mColor2[group][state], mTrans[group][state]); 00186 } 00187 00188 QImage KIconEffect::apply(QImage image, int effect, float value, const QColor col, bool trans) const 00189 { 00190 return apply (image, effect, value, col, KGlobalSettings::baseColor(), trans); 00191 } 00192 00193 QImage KIconEffect::apply(QImage image, int effect, float value, const QColor col, const QColor col2, bool trans) const 00194 { 00195 if (effect >= LastEffect ) 00196 { 00197 kdDebug(265) << "Illegal icon effect: " << effect << "\n"; 00198 return image; 00199 } 00200 if (value > 1.0) 00201 value = 1.0; 00202 else if (value < 0.0) 00203 value = 0.0; 00204 switch (effect) 00205 { 00206 case ToGray: 00207 toGray(image, value); 00208 break; 00209 case DeSaturate: 00210 deSaturate(image, value); 00211 break; 00212 case Colorize: 00213 colorize(image, col, value); 00214 break; 00215 case ToGamma: 00216 toGamma(image, value); 00217 break; 00218 case ToMonochrome: 00219 toMonochrome(image, col, col2, value); 00220 break; 00221 } 00222 if (trans == true) 00223 { 00224 semiTransparent(image); 00225 } 00226 return image; 00227 } 00228 00229 QPixmap KIconEffect::apply(QPixmap pixmap, int group, int state) const 00230 { 00231 if (state >= KIcon::LastState) 00232 { 00233 kdDebug(265) << "Illegal icon state: " << state << "\n"; 00234 return pixmap; 00235 } 00236 if (group >= KIcon::LastGroup) 00237 { 00238 kdDebug(265) << "Illegal icon group: " << group << "\n"; 00239 return pixmap; 00240 } 00241 return apply(pixmap, mEffect[group][state], mValue[group][state], 00242 mColor[group][state], d->mColor2[group][state], mTrans[group][state]); 00243 } 00244 00245 QPixmap KIconEffect::apply(QPixmap pixmap, int effect, float value, 00246 const QColor col, bool trans) const 00247 { 00248 return apply (pixmap, effect, value, col, KGlobalSettings::baseColor(), trans); 00249 } 00250 00251 QPixmap KIconEffect::apply(QPixmap pixmap, int effect, float value, 00252 const QColor col, const QColor col2, bool trans) const 00253 { 00254 QPixmap result; 00255 00256 if (effect >= LastEffect ) 00257 { 00258 kdDebug(265) << "Illegal icon effect: " << effect << "\n"; 00259 return result; 00260 } 00261 00262 if ((trans == true) && (effect == NoEffect)) 00263 { 00264 result = pixmap; 00265 semiTransparent(result); 00266 } 00267 else if ( effect != NoEffect ) 00268 { 00269 QImage tmpImg = pixmap.convertToImage(); 00270 tmpImg = apply(tmpImg, effect, value, col, col2, trans); 00271 result.convertFromImage(tmpImg); 00272 } 00273 else 00274 result = pixmap; 00275 00276 return result; 00277 } 00278 00279 // Taken from KImageEffect. We don't want to link kdecore to kdeui! As long 00280 // as this code is not too big, it doesn't seem much of a problem to me. 00281 00282 void KIconEffect::toGray(QImage &img, float value) 00283 { 00284 int pixels = (img.depth() > 8) ? img.width()*img.height() 00285 : img.numColors(); 00286 unsigned int *data = img.depth() > 8 ? (unsigned int *) img.bits() 00287 : (unsigned int *) img.colorTable(); 00288 int rval, gval, bval, val, alpha, i; 00289 for (i=0; i<pixels; i++) 00290 { 00291 val = qGray(data[i]); 00292 alpha = qAlpha(data[i]); 00293 if (value < 1.0) 00294 { 00295 rval = static_cast<int>(value*val+(1.0-value)*qRed(data[i])); 00296 gval = static_cast<int>(value*val+(1.0-value)*qGreen(data[i])); 00297 bval = static_cast<int>(value*val+(1.0-value)*qBlue(data[i])); 00298 data[i] = qRgba(rval, gval, bval, alpha); 00299 } else 00300 data[i] = qRgba(val, val, val, alpha); 00301 } 00302 } 00303 00304 void KIconEffect::colorize(QImage &img, const QColor &col, float value) 00305 { 00306 int pixels = (img.depth() > 8) ? img.width()*img.height() 00307 : img.numColors(); 00308 unsigned int *data = img.depth() > 8 ? (unsigned int *) img.bits() 00309 : (unsigned int *) img.colorTable(); 00310 int rval, gval, bval, val, alpha, i; 00311 float rcol = col.red(), gcol = col.green(), bcol = col.blue(); 00312 for (i=0; i<pixels; i++) 00313 { 00314 val = qGray(data[i]); 00315 if (val < 128) 00316 { 00317 rval = static_cast<int>(rcol/128*val); 00318 gval = static_cast<int>(gcol/128*val); 00319 bval = static_cast<int>(bcol/128*val); 00320 } 00321 else if (val > 128) 00322 { 00323 rval = static_cast<int>((val-128)*(2-rcol/128)+rcol-1); 00324 gval = static_cast<int>((val-128)*(2-gcol/128)+gcol-1); 00325 bval = static_cast<int>((val-128)*(2-bcol/128)+bcol-1); 00326 } 00327 else // val == 128 00328 { 00329 rval = static_cast<int>(rcol); 00330 gval = static_cast<int>(gcol); 00331 bval = static_cast<int>(bcol); 00332 } 00333 if (value < 1.0) 00334 { 00335 rval = static_cast<int>(value*rval+(1.0 - value)*qRed(data[i])); 00336 gval = static_cast<int>(value*gval+(1.0 - value)*qGreen(data[i])); 00337 bval = static_cast<int>(value*bval+(1.0 - value)*qBlue(data[i])); 00338 } 00339 00340 alpha = qAlpha(data[i]); 00341 data[i] = qRgba(rval, gval, bval, alpha); 00342 } 00343 } 00344 00345 void KIconEffect::toMonochrome(QImage &img, const QColor &black, const QColor &white, float value) { 00346 int pixels = (img.depth() > 8) ? img.width()*img.height() : img.numColors(); 00347 unsigned int *data = img.depth() > 8 ? (unsigned int *) img.bits() 00348 : (unsigned int *) img.colorTable(); 00349 int rval, gval, bval, alpha, i; 00350 int rw = white.red(), gw = white.green(), bw = white.blue(); 00351 int rb = black.red(), gb = black.green(), bb = black.blue(); 00352 00353 double values = 0, sum = 0; 00354 bool grayscale = true; 00355 // Step 1: determine the average brightness 00356 for (i=0; i<pixels; i++) { 00357 sum += qGray(data[i])*qAlpha(data[i]) + 255*(255-qAlpha(data[i])); 00358 values += 255; 00359 if ((qRed(data[i]) != qGreen(data[i]) ) || (qGreen(data[i]) != qBlue(data[i]) )) 00360 grayscale = false; 00361 } 00362 double medium = sum/values; 00363 00364 // Step 2: Modify the image 00365 if (grayscale) { 00366 for (i=0; i<pixels; i++) { 00367 int v = qRed(data[i]); 00368 rval = static_cast<int>( ((255-v)*rb + v*rw)*value/255 + (1.0-value)*qRed(data[i])); 00369 gval = static_cast<int>( ((255-v)*gb + v*gw)*value/255 + (1.0-value)*qGreen(data[i])); 00370 bval = static_cast<int>( ((255-v)*bb + v*bw)*value/255 + (1.0-value)*qBlue(data[i])); 00371 00372 alpha = qAlpha(data[i]); 00373 data[i] = qRgba(rval, gval, bval, alpha); 00374 } 00375 } 00376 else { 00377 for (i=0; i<pixels; i++) { 00378 if (qGray(data[i]) <= medium) { 00379 rval = static_cast<int>(value*rb+(1.0-value)*qRed(data[i])); 00380 gval = static_cast<int>(value*gb+(1.0-value)*qGreen(data[i])); 00381 bval = static_cast<int>(value*bb+(1.0-value)*qBlue(data[i])); 00382 } 00383 else { 00384 rval = static_cast<int>(value*rw+(1.0-value)*qRed(data[i])); 00385 gval = static_cast<int>(value*gw+(1.0-value)*qGreen(data[i])); 00386 bval = static_cast<int>(value*bw+(1.0-value)*qBlue(data[i])); 00387 } 00388 00389 alpha = qAlpha(data[i]); 00390 data[i] = qRgba(rval, gval, bval, alpha); 00391 } 00392 } 00393 } 00394 00395 void KIconEffect::deSaturate(QImage &img, float value) 00396 { 00397 int pixels = (img.depth() > 8) ? img.width()*img.height() 00398 : img.numColors(); 00399 unsigned int *data = (img.depth() > 8) ? (unsigned int *) img.bits() 00400 : (unsigned int *) img.colorTable(); 00401 QColor color; 00402 int h, s, v, i; 00403 for (i=0; i<pixels; i++) 00404 { 00405 color.setRgb(data[i]); 00406 color.hsv(&h, &s, &v); 00407 color.setHsv(h, (int) (s * (1.0 - value) + 0.5), v); 00408 data[i] = qRgba(color.red(), color.green(), color.blue(), 00409 qAlpha(data[i])); 00410 } 00411 } 00412 00413 void KIconEffect::toGamma(QImage &img, float value) 00414 { 00415 int pixels = (img.depth() > 8) ? img.width()*img.height() 00416 : img.numColors(); 00417 unsigned int *data = (img.depth() > 8) ? (unsigned int *) img.bits() 00418 : (unsigned int *) img.colorTable(); 00419 QColor color; 00420 int i, rval, gval, bval; 00421 float gamma; 00422 gamma = 1/(2*value+0.5); 00423 00424 for (i=0; i<pixels; i++) 00425 { 00426 color.setRgb(data[i]); 00427 color.rgb(&rval, &gval, &bval); 00428 rval = static_cast<int>(pow(static_cast<float>(rval)/255 , gamma)*255); 00429 gval = static_cast<int>(pow(static_cast<float>(gval)/255 , gamma)*255); 00430 bval = static_cast<int>(pow(static_cast<float>(bval)/255 , gamma)*255); 00431 data[i] = qRgba(rval, gval, bval, qAlpha(data[i])); 00432 } 00433 } 00434 00435 void KIconEffect::semiTransparent(QImage &img) 00436 { 00437 img.setAlphaBuffer(true); 00438 00439 int x, y; 00440 if (img.depth() == 32) 00441 { 00442 int width = img.width(); 00443 int height = img.height(); 00444 00445 if (qt_use_xrender && qt_has_xft ) 00446 for (y=0; y<height; y++) 00447 { 00448 #ifdef WORDS_BIGENDIAN 00449 uchar *line = (uchar*) img.scanLine(y); 00450 #else 00451 uchar *line = (uchar*) img.scanLine(y) + 3; 00452 #endif 00453 for (x=0; x<width; x++) 00454 { 00455 *line >>= 1; 00456 line += 4; 00457 } 00458 } 00459 else 00460 for (y=0; y<height; y++) 00461 { 00462 QRgb *line = (QRgb *) img.scanLine(y); 00463 for (x=(y%2); x<width; x+=2) 00464 line[x] &= 0x00ffffff; 00465 } 00466 00467 } else 00468 { 00469 // Insert transparent pixel into the clut. 00470 int transColor = -1; 00471 00472 // search for a color that is already transparent 00473 for (x=0; x<img.numColors(); x++) 00474 { 00475 // try to find already transparent pixel 00476 if (qAlpha(img.color(x)) < 127) 00477 { 00478 transColor = x; 00479 break; 00480 } 00481 } 00482 00483 00484 // FIXME: image must have transparency 00485 if(transColor < 0 || transColor >= img.numColors()) 00486 return; 00487 00488 img.setColor(transColor, 0); 00489 if(img.depth() == 8) 00490 { 00491 for (y=0; y<img.height(); y++) 00492 { 00493 unsigned char *line = img.scanLine(y); 00494 for (x=(y%2); x<img.width(); x+=2) 00495 line[x] = transColor; 00496 } 00497 } 00498 else 00499 { 00500 // SLOOW, but simple, as we would have to 00501 // deal with endianess etc on our own here 00502 for (y=0; y<img.height(); y++) 00503 for (x=(y%2); x<img.width(); x+=2) 00504 img.setPixel(x, y, transColor); 00505 } 00506 } 00507 } 00508 00509 void KIconEffect::semiTransparent(QPixmap &pix) 00510 { 00511 if ( qt_use_xrender && qt_has_xft ) 00512 { 00513 QImage img=pix.convertToImage(); 00514 semiTransparent(img); 00515 pix.convertFromImage(img); 00516 return; 00517 } 00518 00519 QImage img; 00520 if (pix.mask() != 0L) 00521 img = pix.mask()->convertToImage(); 00522 else 00523 { 00524 img.create(pix.size(), 1, 2, QImage::BigEndian); 00525 img.fill(1); 00526 } 00527 00528 for (int y=0; y<img.height(); y++) 00529 { 00530 QRgb *line = (QRgb *) img.scanLine(y); 00531 QRgb pattern = (y % 2) ? 0x55555555 : 0xaaaaaaaa; 00532 for (int x=0; x<(img.width()+31)/32; x++) 00533 line[x] &= pattern; 00534 } 00535 QBitmap mask; 00536 mask.convertFromImage(img); 00537 pix.setMask(mask); 00538 } 00539 00540 QImage KIconEffect::doublePixels(QImage src) const 00541 { 00542 QImage dst; 00543 if (src.depth() == 1) 00544 { 00545 kdDebug(265) << "image depth 1 not supported\n"; 00546 return dst; 00547 } 00548 00549 int w = src.width(); 00550 int h = src.height(); 00551 dst.create(w*2, h*2, src.depth()); 00552 dst.setAlphaBuffer(src.hasAlphaBuffer()); 00553 00554 int x, y; 00555 if (src.depth() == 32) 00556 { 00557 QRgb *l1, *l2; 00558 for (y=0; y<h; y++) 00559 { 00560 l1 = (QRgb *) src.scanLine(y); 00561 l2 = (QRgb *) dst.scanLine(y*2); 00562 for (x=0; x<w; x++) 00563 { 00564 l2[x*2] = l2[x*2+1] = l1[x]; 00565 } 00566 memcpy(dst.scanLine(y*2+1), l2, dst.bytesPerLine()); 00567 } 00568 } else 00569 { 00570 for (x=0; x<src.numColors(); x++) 00571 dst.setColor(x, src.color(x)); 00572 00573 unsigned char *l1, *l2; 00574 for (y=0; y<h; y++) 00575 { 00576 l1 = src.scanLine(y); 00577 l2 = dst.scanLine(y*2); 00578 for (x=0; x<w; x++) 00579 { 00580 l2[x*2] = l1[x]; 00581 l2[x*2+1] = l1[x]; 00582 } 00583 memcpy(dst.scanLine(y*2+1), l2, dst.bytesPerLine()); 00584 } 00585 } 00586 return dst; 00587 } 00588 00589 void KIconEffect::overlay(QImage &src, QImage &overlay) 00590 { 00591 if (src.depth() != overlay.depth()) 00592 { 00593 kdDebug(265) << "Image depth src != overlay!\n"; 00594 return; 00595 } 00596 if (src.size() != overlay.size()) 00597 { 00598 kdDebug(265) << "Image size src != overlay\n"; 00599 return; 00600 } 00601 if (!overlay.hasAlphaBuffer()) 00602 { 00603 kdDebug(265) << "Overlay doesn't have alpha buffer!\n"; 00604 return; 00605 } 00606 00607 int i, j; 00608 00609 // We don't do 1 bpp 00610 00611 if (src.depth() == 1) 00612 { 00613 kdDebug(265) << "1bpp not supported!\n"; 00614 return; 00615 } 00616 00617 // Overlay at 8 bpp doesn't use alpha blending 00618 00619 if (src.depth() == 8) 00620 { 00621 if (src.numColors() + overlay.numColors() > 255) 00622 { 00623 kdDebug(265) << "Too many colors in src + overlay!\n"; 00624 return; 00625 } 00626 00627 // Find transparent pixel in overlay 00628 int trans; 00629 for (trans=0; trans<overlay.numColors(); trans++) 00630 { 00631 if (qAlpha(overlay.color(trans)) == 0) 00632 { 00633 kdDebug(265) << "transparent pixel found at " << trans << "\n"; 00634 break; 00635 } 00636 } 00637 if (trans == overlay.numColors()) 00638 { 00639 kdDebug(265) << "transparent pixel not found!\n"; 00640 return; 00641 } 00642 00643 // Merge color tables 00644 int nc = src.numColors(); 00645 src.setNumColors(nc + overlay.numColors()); 00646 for (i=0; i<overlay.numColors(); i++) 00647 { 00648 src.setColor(nc+i, overlay.color(i)); 00649 } 00650 00651 // Overwrite nontransparent pixels. 00652 unsigned char *oline, *sline; 00653 for (i=0; i<src.height(); i++) 00654 { 00655 oline = overlay.scanLine(i); 00656 sline = src.scanLine(i); 00657 for (j=0; j<src.width(); j++) 00658 { 00659 if (oline[j] != trans) 00660 sline[j] = oline[j]+nc; 00661 } 00662 } 00663 } 00664 00665 // Overlay at 32 bpp does use alpha blending 00666 00667 if (src.depth() == 32) 00668 { 00669 QRgb *oline, *sline; 00670 int r1, g1, b1, a1; 00671 int r2, g2, b2, a2; 00672 00673 for (i=0; i<src.height(); i++) 00674 { 00675 oline = (QRgb *) overlay.scanLine(i); 00676 sline = (QRgb *) src.scanLine(i); 00677 00678 for (j=0; j<src.width(); j++) 00679 { 00680 r1 = qRed(oline[j]); 00681 g1 = qGreen(oline[j]); 00682 b1 = qBlue(oline[j]); 00683 a1 = qAlpha(oline[j]); 00684 00685 r2 = qRed(sline[j]); 00686 g2 = qGreen(sline[j]); 00687 b2 = qBlue(sline[j]); 00688 a2 = qAlpha(sline[j]); 00689 00690 r2 = (a1 * r1 + (0xff - a1) * r2) >> 8; 00691 g2 = (a1 * g1 + (0xff - a1) * g2) >> 8; 00692 b2 = (a1 * b1 + (0xff - a1) * b2) >> 8; 00693 a2 = QMAX(a1, a2); 00694 00695 sline[j] = qRgba(r2, g2, b2, a2); 00696 } 00697 } 00698 } 00699 00700 return; 00701 } 00702 00703 void 00704 KIconEffect::visualActivate(QWidget * widget, QRect rect) 00705 { 00706 if (!KGlobalSettings::visualActivate()) 00707 return; 00708 00709 uint actSpeed = KGlobalSettings::visualActivateSpeed(); 00710 00711 uint actCount = QMIN(rect.width(), rect.height()) / 2; 00712 00713 // Clip actCount to range 1..10. 00714 00715 if (actCount < 1) 00716 actCount = 1; 00717 00718 else if (actCount > 10) 00719 actCount = 10; 00720 00721 // Clip actSpeed to range 1..100. 00722 00723 if (actSpeed < 1) 00724 actSpeed = 1; 00725 00726 else if (actSpeed > 100) 00727 actSpeed = 100; 00728 00729 // actSpeed needs to be converted to actDelay. 00730 // actDelay is inversely proportional to actSpeed and needs to be 00731 // divided up into actCount portions. 00732 // We also convert the us value to ms. 00733 00734 unsigned int actDelay = (1000 * (100 - actSpeed)) / actCount; 00735 00736 //kdDebug() << "actCount=" << actCount << " actDelay=" << actDelay << endl; 00737 00738 QPoint c = rect.center(); 00739 00740 QPainter p(widget); 00741 00742 // Use NotROP to avoid having to repaint the pixmap each time. 00743 p.setPen(QPen(Qt::black, 2, Qt::DotLine)); 00744 p.setRasterOp(Qt::NotROP); 00745 00746 // The spacing between the rects we draw. 00747 // Use the minimum of width and height to avoid painting outside the 00748 // pixmap area. 00749 //unsigned int delta(QMIN(rect.width() / actCount, rect.height() / actCount)); 00750 00751 // Support for rectangles by David 00752 unsigned int deltaX = rect.width() / actCount; 00753 unsigned int deltaY = rect.height() / actCount; 00754 00755 for (unsigned int i = 1; i < actCount; i++) { 00756 00757 int w = i * deltaX; 00758 int h = i * deltaY; 00759 00760 rect.setRect(c.x() - w / 2, c.y() - h / 2, w, h); 00761 00762 p.drawRect(rect); 00763 p.flush(); 00764 00765 usleep(actDelay); 00766 00767 p.drawRect(rect); 00768 } 00769 } 00770
KDE Logo
This file is part of the documentation for kdecore Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Apr 14 00:03:29 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003