• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDEUI

kiconeffect.cpp

Go to the documentation of this file.
00001 /* vi: ts=8 sts=4 sw=4
00002  *
00003  * This file is part of the KDE project, module kdecore.
00004  * Copyright (C) 2000 Geert Jansen <jansen@kde.org>
00005  * (C) 2007 Daniel M. Duley <daniel.duley@verizon.net>
00006  * with minor additions and based on ideas from
00007  * Torsten Rahn <torsten@kde.org>
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Library General Public
00011  * License version 2 as published by the Free Software Foundation.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Library General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Library General Public License
00019  * along with this library; see the file COPYING.LIB.  If not, write to
00020  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00021  * Boston, MA 02110-1301, USA.
00022  */
00023 
00024 #include "kiconeffect.h"
00025 
00026 #include <config.h>
00027 #include <unistd.h>
00028 #include <math.h>
00029 
00030 #include <QtCore/QSysInfo>
00031 #include <QtGui/QApplication>
00032 #include <QtGui/QPaintEngine>
00033 #include <QtGui/QDesktopWidget>
00034 #include <QtCore/QCharRef>
00035 #include <QtCore/QMutableStringListIterator>
00036 #include <QtGui/QBitmap>
00037 #include <QtGui/QPixmap>
00038 #include <QtGui/QImage>
00039 #include <QtGui/QColor>
00040 #include <QtGui/QWidget>
00041 #include <QtGui/QPainter>
00042 #include <QtGui/QPen>
00043 
00044 #include <kdebug.h>
00045 #include <kglobal.h>
00046 #include <ksharedconfig.h>
00047 #include <kglobalsettings.h>
00048 #include <kcolorscheme.h>
00049 #include <kicontheme.h>
00050 #include <kconfiggroup.h>
00051 
00052 
00053 class KIconEffectPrivate
00054 {
00055 public:
00056     int effect[6][3];
00057     float value[6][3];
00058     QColor color[6][3];
00059     bool trans[6][3];
00060     QString key[6][3];
00061     QColor color2[6][3];
00062 };
00063 
00064 KIconEffect::KIconEffect()
00065     :d(new KIconEffectPrivate)
00066 {
00067     init();
00068 }
00069 
00070 KIconEffect::~KIconEffect()
00071 {
00072     delete d;
00073 }
00074 
00075 void KIconEffect::init()
00076 {
00077     KSharedConfig::Ptr config = KGlobal::config();
00078 
00079     int i, j, effect=-1;
00080     QStringList groups;
00081     groups += "Desktop";
00082     groups += "Toolbar";
00083     groups += "MainToolbar";
00084     groups += "Small";
00085     groups += "Panel";
00086 
00087     QStringList states;
00088     states += "Default";
00089     states += "Active";
00090     states += "Disabled";
00091 
00092     QStringList::ConstIterator it, it2;
00093     QString _togray("togray");
00094     QString _colorize("colorize");
00095     QString _desaturate("desaturate");
00096     QString _togamma("togamma");
00097     QString _none("none");
00098     QString _tomonochrome("tomonochrome");
00099 
00100     for (it=groups.constBegin(), i=0; it!=groups.constEnd(); ++it, ++i)
00101     {
00102     // Default effects
00103     d->effect[i][0] = NoEffect;
00104     d->effect[i][1] =  ((i==0)||(i==4)) ? ToGamma : NoEffect;
00105     d->effect[i][2] = ToGray;
00106 
00107     d->trans[i][0] = false;
00108     d->trans[i][1] = false;
00109     d->trans[i][2] = true;
00110         d->value[i][0] = 1.0;
00111         d->value[i][1] = ((i==0)||(i==4)) ? 0.7 : 1.0;
00112         d->value[i][2] = 1.0;
00113         d->color[i][0] = QColor(144,128,248);
00114         d->color[i][1] = QColor(169,156,255);
00115         d->color[i][2] = QColor(34,202,0);
00116         d->color2[i][0] = QColor(0,0,0);
00117         d->color2[i][1] = QColor(0,0,0);
00118         d->color2[i][2] = QColor(0,0,0);
00119 
00120     KConfigGroup cg(config, *it + "Icons");
00121     for (it2=states.constBegin(), j=0; it2!=states.constEnd(); ++it2, ++j)
00122     {
00123         QString tmp = cg.readEntry(*it2 + "Effect", QString());
00124         if (tmp == _togray)
00125         effect = ToGray;
00126         else if (tmp == _colorize)
00127         effect = Colorize;
00128         else if (tmp == _desaturate)
00129         effect = DeSaturate;
00130         else if (tmp == _togamma)
00131         effect = ToGamma;
00132         else if (tmp == _tomonochrome)
00133         effect = ToMonochrome;
00134             else if (tmp == _none)
00135         effect = NoEffect;
00136         else
00137         continue;
00138         if(effect != -1)
00139                 d->effect[i][j] = effect;
00140         d->value[i][j] = cg.readEntry(*it2 + "Value", 0.0);
00141         d->color[i][j] = cg.readEntry(*it2 + "Color", QColor());
00142         d->color2[i][j] = cg.readEntry(*it2 + "Color2", QColor());
00143         d->trans[i][j] = cg.readEntry(*it2 + "SemiTransparent", false);
00144 
00145     }
00146     }
00147 }
00148 
00149 bool KIconEffect::hasEffect(int group, int state) const
00150 {
00151     return d->effect[group][state] != NoEffect;
00152 }
00153 
00154 QString KIconEffect::fingerprint(int group, int state) const
00155 {
00156     if ( group >= KIconLoader::LastGroup ) return "";
00157     QString cached = d->key[group][state];
00158     if (cached.isEmpty())
00159     {
00160         QString tmp;
00161         cached = tmp.setNum(d->effect[group][state]);
00162         cached += ':';
00163         cached += tmp.setNum(d->value[group][state]);
00164         cached += ':';
00165         cached += d->trans[group][state] ? QLatin1String("trans")
00166             : QLatin1String("notrans");
00167         if (d->effect[group][state] == Colorize || d->effect[group][state] == ToMonochrome)
00168         {
00169             cached += ':';
00170             cached += d->color[group][state].name();
00171         }
00172         if (d->effect[group][state] == ToMonochrome)
00173         {
00174             cached += ':';
00175             cached += d->color2[group][state].name();
00176         }
00177 
00178         d->key[group][state] = cached;
00179     }
00180 
00181     return cached;
00182 }
00183 
00184 QImage KIconEffect::apply(const QImage &image, int group, int state) const
00185 {
00186     if (state >= KIconLoader::LastState)
00187     {
00188     kDebug(265) << "Illegal icon state: " << state << "\n";
00189     return image;
00190     }
00191     if (group >= KIconLoader::LastGroup)
00192     {
00193     kDebug(265) << "Illegal icon group: " << group << "\n";
00194     return image;
00195     }
00196     return apply(image, d->effect[group][state], d->value[group][state],
00197         d->color[group][state], d->color2[group][state], d->trans[group][state]);
00198 }
00199 
00200 QImage KIconEffect::apply(const QImage &image, int effect, float value,
00201                           const QColor &col, bool trans) const
00202 {
00203     return apply(image, effect, value, col,
00204                  KColorScheme(QPalette::Active, KColorScheme::View).background().color(), trans);
00205 }
00206 
00207 QImage KIconEffect::apply(const QImage &img, int effect, float value,
00208                           const QColor &col, const QColor &col2, bool trans) const
00209 {
00210     QImage image = img;
00211     if (effect >= LastEffect )
00212     {
00213     kDebug(265) << "Illegal icon effect: " << effect << "\n";
00214     return image;
00215     }
00216     if (value > 1.0)
00217     value = 1.0;
00218     else if (value < 0.0)
00219     value = 0.0;
00220     switch (effect)
00221     {
00222     case ToGray:
00223     toGray(image, value);
00224     break;
00225     case DeSaturate:
00226     deSaturate(image, value);
00227     break;
00228     case Colorize:
00229         colorize(image, col, value);
00230         break;
00231     case ToGamma:
00232         toGamma(image, value);
00233         break;
00234     case ToMonochrome:
00235         toMonochrome(image, col, col2, value);
00236         break;
00237     }
00238     if (trans == true)
00239     {
00240     semiTransparent(image);
00241     }
00242     return image;
00243 }
00244 
00245 QPixmap KIconEffect::apply(const QPixmap &pixmap, int group, int state) const
00246 {
00247     if (state >= KIconLoader::LastState)
00248     {
00249     kDebug(265) << "Illegal icon state: " << state << "\n";
00250     return pixmap;
00251     }
00252     if (group >= KIconLoader::LastGroup)
00253     {
00254     kDebug(265) << "Illegal icon group: " << group << "\n";
00255     return pixmap;
00256     }
00257     return apply(pixmap, d->effect[group][state], d->value[group][state],
00258         d->color[group][state], d->color2[group][state], d->trans[group][state]);
00259 }
00260 
00261 QPixmap KIconEffect::apply(const QPixmap &pixmap, int effect, float value,
00262     const QColor &col, bool trans) const
00263 {
00264     return apply(pixmap, effect, value, col,
00265                  KColorScheme(QPalette::Active, KColorScheme::View).background().color(), trans);
00266 }
00267 
00268 QPixmap KIconEffect::apply(const QPixmap &pixmap, int effect, float value,
00269     const QColor &col, const QColor &col2, bool trans) const
00270 {
00271     QPixmap result;
00272 
00273     if (effect >= LastEffect )
00274     {
00275     kDebug(265) << "Illegal icon effect: " << effect << "\n";
00276     return result;
00277     }
00278 
00279     if ((trans == true) && (effect == NoEffect))
00280     {
00281         result = pixmap;
00282         semiTransparent(result);
00283     }
00284     else if ( effect != NoEffect )
00285     {
00286         QImage tmpImg = pixmap.toImage();
00287         tmpImg = apply(tmpImg, effect, value, col, col2, trans);
00288         result = QPixmap::fromImage(tmpImg);
00289     }
00290     else
00291         result = pixmap;
00292 
00293     return result;
00294 }
00295 
00296 struct KIEImgEdit
00297 {
00298     QImage& img;
00299     QVector <QRgb> colors;
00300     unsigned int*  data;
00301     unsigned int   pixels;
00302 
00303     KIEImgEdit(QImage& _img):img(_img)
00304     {
00305     if (img.depth() > 8)
00306         {
00307             if(img.format() == QImage::Format_ARGB32_Premultiplied)
00308                 img = img.convertToFormat(QImage::Format_ARGB32);
00309             data   = (unsigned int*)img.bits();
00310         pixels = img.width()*img.height();
00311     }
00312     else
00313     {
00314         pixels = img.numColors();
00315         colors = img.colorTable();
00316         data   = (unsigned int*)colors.data();
00317     }
00318     }
00319 
00320     ~KIEImgEdit()
00321     {
00322     if (img.depth() <= 8)
00323         img.setColorTable(colors);
00324     }
00325 };
00326 
00327 // Taken from KImageEffect. We don't want to link kdecore to kdeui! As long
00328 // as this code is not too big, it doesn't seem much of a problem to me.
00329 
00330 void KIconEffect::toGray(QImage &img, float value)
00331 {
00332     if(value == 0.0)
00333         return;
00334 
00335     KIEImgEdit ii(img);
00336     QRgb *data = ii.data;
00337     QRgb *end = data + ii.pixels;
00338 
00339     unsigned char gray;
00340     if(value == 1.0){
00341         while(data != end){
00342             gray = qGray(*data);
00343             *data = qRgba(gray, gray, gray, qAlpha(*data));
00344             ++data;
00345         }
00346     }
00347     else{
00348         unsigned char val = (unsigned char)(255.0*value);
00349         while(data != end){
00350             gray = qGray(*data);
00351             *data = qRgba((val*gray+(0xFF-val)*qRed(*data)) >> 8,
00352                           (val*gray+(0xFF-val)*qGreen(*data)) >> 8,
00353                           (val*gray+(0xFF-val)*qBlue(*data)) >> 8,
00354                           qAlpha(*data));
00355             ++data;
00356         }
00357     }
00358 }
00359 
00360 void KIconEffect::colorize(QImage &img, const QColor &col, float value)
00361 {
00362     if(value == 0.0)
00363         return;
00364 
00365     KIEImgEdit ii(img);
00366     QRgb *data = ii.data;
00367     QRgb *end = data + ii.pixels;
00368 
00369     float rcol = col.red(), gcol = col.green(), bcol = col.blue();
00370     unsigned char red, green, blue, gray;
00371     unsigned char val = (unsigned char)(255.0*value);
00372     while(data != end){
00373         gray = qGray(*data);
00374         if(gray < 128){
00375             red = static_cast<unsigned char>(rcol/128*gray);
00376             green = static_cast<unsigned char>(gcol/128*gray);
00377             blue = static_cast<unsigned char>(bcol/128*gray);
00378         }
00379         else if(gray > 128){
00380             red = static_cast<unsigned char>((gray-128)*(2-rcol/128)+rcol-1);
00381             green = static_cast<unsigned char>((gray-128)*(2-gcol/128)+gcol-1);
00382             blue = static_cast<unsigned char>((gray-128)*(2-bcol/128)+bcol-1);
00383         }
00384         else{
00385             red = static_cast<unsigned char>(rcol);
00386             green = static_cast<unsigned char>(gcol);
00387             blue = static_cast<unsigned char>(bcol);
00388         }
00389 
00390         *data = qRgba((val*red+(0xFF-val)*qRed(*data)) >> 8,
00391                       (val*green+(0xFF-val)*qGreen(*data)) >> 8,
00392                       (val*blue+(0xFF-val)*qBlue(*data)) >> 8,
00393                       qAlpha(*data));
00394         ++data;
00395     }
00396 }
00397 
00398 void KIconEffect::toMonochrome(QImage &img, const QColor &black,
00399                                const QColor &white, float value)
00400 {
00401     if(value == 0.0)
00402         return;
00403 
00404     KIEImgEdit ii(img);
00405     QRgb *data = ii.data;
00406     QRgb *end = data + ii.pixels;
00407 
00408     // Step 1: determine the average brightness
00409     double values = 0.0, sum = 0.0;
00410     bool grayscale = true;
00411     while(data != end){
00412         sum += qGray(*data)*qAlpha(*data) + 255*(255-qAlpha(*data));
00413         values += 255;
00414         if((qRed(*data) != qGreen(*data) ) || (qGreen(*data) != qBlue(*data)))
00415             grayscale = false;
00416         ++data;
00417     }
00418     double medium = sum/values;
00419 
00420     // Step 2: Modify the image
00421     unsigned char val = (unsigned char)(255.0*value);
00422     int rw = white.red(), gw = white.green(), bw = white.blue();
00423     int rb = black.red(), gb = black.green(), bb = black.blue();
00424     data = ii.data;
00425 
00426     if(grayscale){
00427         while(data != end){
00428             if(qRed(*data) <= medium)
00429                 *data = qRgba((val*rb+(0xFF-val)*qRed(*data)) >> 8,
00430                               (val*gb+(0xFF-val)*qGreen(*data)) >> 8,
00431                               (val*bb+(0xFF-val)*qBlue(*data)) >> 8,
00432                               qAlpha(*data));
00433             else
00434                 *data = qRgba((val*rw+(0xFF-val)*qRed(*data)) >> 8,
00435                               (val*gw+(0xFF-val)*qGreen(*data)) >> 8,
00436                               (val*bw+(0xFF-val)*qBlue(*data)) >> 8,
00437                               qAlpha(*data));
00438             ++data;
00439         }
00440     }
00441     else{
00442         while(data != end){
00443             if(qGray(*data) <= medium) 
00444                 *data = qRgba((val*rb+(0xFF-val)*qRed(*data)) >> 8,
00445                               (val*gb+(0xFF-val)*qGreen(*data)) >> 8,
00446                               (val*bb+(0xFF-val)*qBlue(*data)) >> 8,
00447                               qAlpha(*data));
00448             else
00449                 *data = qRgba((val*rw+(0xFF-val)*qRed(*data)) >> 8,
00450                               (val*gw+(0xFF-val)*qGreen(*data)) >> 8,
00451                               (val*bw+(0xFF-val)*qBlue(*data)) >> 8,
00452                               qAlpha(*data));
00453             ++data;
00454         }
00455     }
00456 }
00457 
00458 void KIconEffect::deSaturate(QImage &img, float value)
00459 {
00460     if(value == 0.0)
00461         return;
00462 
00463     KIEImgEdit ii(img);
00464     QRgb *data = ii.data;
00465     QRgb *end = data + ii.pixels;
00466 
00467     QColor color;
00468     int h, s, v;
00469     while(data != end){
00470         color.setRgb(*data);
00471         color.getHsv(&h, &s, &v);
00472         color.setHsv(h, (int) (s * (1.0 - value) + 0.5), v);
00473     *data = qRgba(color.red(), color.green(), color.blue(),
00474                       qAlpha(*data));
00475         ++data;
00476     }
00477 }
00478 
00479 void KIconEffect::toGamma(QImage &img, float value)
00480 {
00481     KIEImgEdit ii(img);
00482     QRgb *data = ii.data;
00483     QRgb *end = data + ii.pixels;
00484 
00485     float gamma = 1/(2*value+0.5);
00486     while(data != end){
00487         *data = qRgba(static_cast<unsigned char>
00488                       (pow(static_cast<float>(qRed(*data))/255 , gamma)*255),
00489                       static_cast<unsigned char>
00490                       (pow(static_cast<float>(qGreen(*data))/255 , gamma)*255),
00491                       static_cast<unsigned char>
00492                       (pow(static_cast<float>(qBlue(*data))/255 , gamma)*255),
00493                       qAlpha(*data));
00494         ++data;
00495     }
00496 }
00497 
00498 void KIconEffect::semiTransparent(QImage &img)
00499 {
00500     int x, y;
00501     if(img.depth() == 32){
00502         if(img.format() == QImage::Format_ARGB32_Premultiplied)
00503             img = img.convertToFormat(QImage::Format_ARGB32);
00504         int width  = img.width();
00505     int height = img.height();
00506 
00507         QPaintEngine* pe = QApplication::desktop()->paintEngine();
00508         if(pe && pe->hasFeature(QPaintEngine::Antialiasing)){
00509             unsigned char *line;
00510             for(y=0; y<height; y++){
00511                 if(QSysInfo::ByteOrder == QSysInfo::BigEndian)
00512                     line = img.scanLine(y);
00513                 else
00514                     line = img.scanLine(y) + 3;
00515                 for(x=0; x<width; x++){
00516                     *line >>= 1;
00517                     line += 4;
00518                 }
00519             }
00520         }
00521         else{
00522             for(y=0; y<height; y++){
00523                 QRgb* line = (QRgb*)img.scanLine(y);
00524                 for(x=(y%2); x<width; x+=2)
00525                     line[x] &= 0x00ffffff;
00526             }
00527         }
00528     }
00529     else{
00530         // Insert transparent pixel into the clut.
00531         int transColor = -1;
00532 
00533         // search for a color that is already transparent
00534         for(x=0; x<img.numColors(); x++){
00535             // try to find already transparent pixel
00536             if(qAlpha(img.color(x)) < 127){
00537                 transColor = x;
00538                 break;
00539             }
00540         }
00541 
00542         // FIXME: image must have transparency
00543         if(transColor < 0 || transColor >= img.numColors())
00544             return;
00545 
00546     img.setColor(transColor, 0);
00547         unsigned char *line;
00548         if(img.depth() == 8){
00549             for(y=0; y<img.height(); y++){
00550                 line = img.scanLine(y);
00551                 for(x=(y%2); x<img.width(); x+=2)
00552                     line[x] = transColor;
00553             }
00554     }
00555         else{
00556             bool setOn = (transColor != 0);
00557             if(img.format() == QImage::Format_MonoLSB){
00558                 for(y=0; y<img.height(); y++){
00559                     line = img.scanLine(y);
00560                     for(x=(y%2); x<img.width(); x+=2){
00561                         if(!setOn)
00562                             *(line + (x >> 3)) &= ~(1 << (x & 7));
00563                         else
00564                             *(line + (x >> 3)) |= (1 << (x & 7));
00565                     }
00566                 }
00567             }
00568             else{
00569                 for(y=0; y<img.height(); y++){
00570                     line = img.scanLine(y);
00571                     for(x=(y%2); x<img.width(); x+=2){
00572                         if(!setOn)
00573                             *(line + (x >> 3)) &= ~(1 << (7-(x & 7)));
00574                         else
00575                             *(line + (x >> 3)) |= (1 << (7-(x & 7)));
00576                     }
00577                 }
00578             }
00579         }
00580     }
00581 }
00582 
00583 void KIconEffect::semiTransparent(QPixmap &pix)
00584 {
00585     if (QApplication::desktop()->paintEngine()->hasFeature(QPaintEngine::Antialiasing))
00586     {
00587     QImage img=pix.toImage();
00588     semiTransparent(img);
00589     pix = QPixmap::fromImage(img);
00590     return;
00591     }
00592 
00593     QImage img;
00594     if (!pix.mask().isNull())
00595     img = pix.mask().toImage();
00596     else
00597     {
00598     img = QImage(pix.size(), QImage::Format_Mono);
00599     img.fill(1);
00600     }
00601 
00602     for (int y=0; y<img.height(); y++)
00603     {
00604     QRgb* line = (QRgb*)img.scanLine(y);
00605     QRgb pattern = (y % 2) ? 0x55555555 : 0xaaaaaaaa;
00606     for (int x=0; x<(img.width()+31)/32; x++)
00607         line[x] &= pattern;
00608     }
00609     QBitmap mask;
00610     mask = QBitmap::fromImage(img);
00611     pix.setMask(mask);
00612 }
00613 
00614 QImage KIconEffect::doublePixels(const QImage &src) const
00615 {
00616     int w = src.width();
00617     int h = src.height();
00618 
00619     QImage dst( w*2, h*2, src.format() );
00620 
00621     if (src.depth() == 1)
00622     {
00623     kDebug(265) << "image depth 1 not supported\n";
00624     return QImage();
00625     }
00626 
00627     int x, y;
00628     if (src.depth() == 32)
00629     {
00630     QRgb* l1, *l2;
00631     for (y=0; y<h; y++)
00632     {
00633         l1 = (QRgb*)src.scanLine(y);
00634         l2 = (QRgb*)dst.scanLine(y*2);
00635         for (x=0; x<w; x++)
00636         {
00637         l2[x*2] = l2[x*2+1] = l1[x];
00638         }
00639         memcpy(dst.scanLine(y*2+1), l2, dst.bytesPerLine());
00640     }
00641     } else
00642     {
00643     for (x=0; x<src.numColors(); x++)
00644         dst.setColor(x, src.color(x));
00645 
00646     const unsigned char *l1;
00647     unsigned char *l2;
00648     for (y=0; y<h; y++)
00649     {
00650         l1 = src.scanLine(y);
00651         l2 = dst.scanLine(y*2);
00652         for (x=0; x<w; x++)
00653         {
00654         l2[x*2] = l1[x];
00655         l2[x*2+1] = l1[x];
00656         }
00657         memcpy(dst.scanLine(y*2+1), l2, dst.bytesPerLine());
00658     }
00659     }
00660     return dst;
00661 }
00662 
00663 void KIconEffect::overlay(QImage &src, QImage &overlay)
00664 {
00665     if (src.depth() != overlay.depth())
00666     {
00667     kDebug(265) << "Image depth src (" << src.depth() << ") != overlay " << "(" << overlay.depth() << ")!\n";
00668     return;
00669     }
00670     if (src.size() != overlay.size())
00671     {
00672     kDebug(265) << "Image size src != overlay\n";
00673     return;
00674     }
00675     if (src.format() == QImage::Format_ARGB32_Premultiplied)
00676         src.convertToFormat(QImage::Format_ARGB32);
00677 
00678     if (overlay.format() == QImage::Format_RGB32)
00679     {
00680     kDebug(265) << "Overlay doesn't have alpha buffer!\n";
00681     return;
00682     }
00683     else if (overlay.format() == QImage::Format_ARGB32_Premultiplied)
00684         overlay.convertToFormat(QImage::Format_ARGB32);
00685 
00686     int i, j;
00687 
00688     // We don't do 1 bpp
00689 
00690     if (src.depth() == 1)
00691     {
00692     kDebug(265) << "1bpp not supported!\n";
00693     return;
00694     }
00695 
00696     // Overlay at 8 bpp doesn't use alpha blending
00697 
00698     if (src.depth() == 8)
00699     {
00700     if (src.numColors() + overlay.numColors() > 255)
00701     {
00702         kDebug(265) << "Too many colors in src + overlay!\n";
00703         return;
00704     }
00705 
00706     // Find transparent pixel in overlay
00707     int trans;
00708     for (trans=0; trans<overlay.numColors(); trans++)
00709     {
00710         if (qAlpha(overlay.color(trans)) == 0)
00711         {
00712         kDebug(265) << "transparent pixel found at " << trans << "\n";
00713         break;
00714         }
00715     }
00716     if (trans == overlay.numColors())
00717     {
00718         kDebug(265) << "transparent pixel not found!\n";
00719         return;
00720     }
00721 
00722     // Merge color tables
00723     int nc = src.numColors();
00724     src.setNumColors(nc + overlay.numColors());
00725     for (i=0; i<overlay.numColors(); i++)
00726     {
00727         src.setColor(nc+i, overlay.color(i));
00728     }
00729 
00730     // Overwrite nontransparent pixels.
00731     unsigned char *oline, *sline;
00732     for (i=0; i<src.height(); i++)
00733     {
00734         oline = overlay.scanLine(i);
00735         sline = src.scanLine(i);
00736         for (j=0; j<src.width(); j++)
00737         {
00738         if (oline[j] != trans)
00739             sline[j] = oline[j]+nc;
00740         }
00741     }
00742     }
00743 
00744     // Overlay at 32 bpp does use alpha blending
00745 
00746     if (src.depth() == 32)
00747     {
00748     QRgb* oline, *sline;
00749     int r1, g1, b1, a1;
00750     int r2, g2, b2, a2;
00751 
00752     for (i=0; i<src.height(); i++)
00753     {
00754         oline = (QRgb*)overlay.scanLine(i);
00755         sline = (QRgb*)src.scanLine(i);
00756 
00757         for (j=0; j<src.width(); j++)
00758         {
00759         r1 = qRed(oline[j]);
00760         g1 = qGreen(oline[j]);
00761         b1 = qBlue(oline[j]);
00762         a1 = qAlpha(oline[j]);
00763 
00764         r2 = qRed(sline[j]);
00765         g2 = qGreen(sline[j]);
00766         b2 = qBlue(sline[j]);
00767         a2 = qAlpha(sline[j]);
00768 
00769         r2 = (a1 * r1 + (0xff - a1) * r2) >> 8;
00770         g2 = (a1 * g1 + (0xff - a1) * g2) >> 8;
00771         b2 = (a1 * b1 + (0xff - a1) * b2) >> 8;
00772         a2 = qMax(a1, a2);
00773 
00774         sline[j] = qRgba(r2, g2, b2, a2);
00775         }
00776     }
00777     }
00778 
00779     return;
00780 }
00781 

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal