00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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 groups += "Dialog";
00087
00088 QStringList states;
00089 states += "Default";
00090 states += "Active";
00091 states += "Disabled";
00092
00093 QStringList::ConstIterator it, it2;
00094 QString _togray("togray");
00095 QString _colorize("colorize");
00096 QString _desaturate("desaturate");
00097 QString _togamma("togamma");
00098 QString _none("none");
00099 QString _tomonochrome("tomonochrome");
00100
00101 for (it=groups.constBegin(), i=0; it!=groups.constEnd(); ++it, ++i)
00102 {
00103
00104 d->effect[i][0] = NoEffect;
00105 d->effect[i][1] = ((i==0)||(i==4)) ? ToGamma : NoEffect;
00106 d->effect[i][2] = ToGray;
00107
00108 d->trans[i][0] = false;
00109 d->trans[i][1] = false;
00110 d->trans[i][2] = true;
00111 d->value[i][0] = 1.0;
00112 d->value[i][1] = ((i==0)||(i==4)) ? 0.7 : 1.0;
00113 d->value[i][2] = 1.0;
00114 d->color[i][0] = QColor(144,128,248);
00115 d->color[i][1] = QColor(169,156,255);
00116 d->color[i][2] = QColor(34,202,0);
00117 d->color2[i][0] = QColor(0,0,0);
00118 d->color2[i][1] = QColor(0,0,0);
00119 d->color2[i][2] = QColor(0,0,0);
00120
00121 KConfigGroup cg(config, *it + "Icons");
00122 for (it2=states.constBegin(), j=0; it2!=states.constEnd(); ++it2, ++j)
00123 {
00124 QString tmp = cg.readEntry(*it2 + "Effect", QString());
00125 if (tmp == _togray)
00126 effect = ToGray;
00127 else if (tmp == _colorize)
00128 effect = Colorize;
00129 else if (tmp == _desaturate)
00130 effect = DeSaturate;
00131 else if (tmp == _togamma)
00132 effect = ToGamma;
00133 else if (tmp == _tomonochrome)
00134 effect = ToMonochrome;
00135 else if (tmp == _none)
00136 effect = NoEffect;
00137 else
00138 continue;
00139 if(effect != -1)
00140 d->effect[i][j] = effect;
00141 d->value[i][j] = cg.readEntry(*it2 + "Value", 0.0);
00142 d->color[i][j] = cg.readEntry(*it2 + "Color", QColor());
00143 d->color2[i][j] = cg.readEntry(*it2 + "Color2", QColor());
00144 d->trans[i][j] = cg.readEntry(*it2 + "SemiTransparent", false);
00145
00146 }
00147 }
00148 }
00149
00150 bool KIconEffect::hasEffect(int group, int state) const
00151 {
00152 return d->effect[group][state] != NoEffect;
00153 }
00154
00155 QString KIconEffect::fingerprint(int group, int state) const
00156 {
00157 if ( group >= KIconLoader::LastGroup ) return "";
00158 QString cached = d->key[group][state];
00159 if (cached.isEmpty())
00160 {
00161 QString tmp;
00162 cached = tmp.setNum(d->effect[group][state]);
00163 cached += ':';
00164 cached += tmp.setNum(d->value[group][state]);
00165 cached += ':';
00166 cached += d->trans[group][state] ? QLatin1String("trans")
00167 : QLatin1String("notrans");
00168 if (d->effect[group][state] == Colorize || d->effect[group][state] == ToMonochrome)
00169 {
00170 cached += ':';
00171 cached += d->color[group][state].name();
00172 }
00173 if (d->effect[group][state] == ToMonochrome)
00174 {
00175 cached += ':';
00176 cached += d->color2[group][state].name();
00177 }
00178
00179 d->key[group][state] = cached;
00180 }
00181
00182 return cached;
00183 }
00184
00185 QImage KIconEffect::apply(const QImage &image, int group, int state) const
00186 {
00187 if (state >= KIconLoader::LastState)
00188 {
00189 kDebug(265) << "Illegal icon state: " << state << "\n";
00190 return image;
00191 }
00192 if (group >= KIconLoader::LastGroup)
00193 {
00194 kDebug(265) << "Illegal icon group: " << group << "\n";
00195 return image;
00196 }
00197 return apply(image, d->effect[group][state], d->value[group][state],
00198 d->color[group][state], d->color2[group][state], d->trans[group][state]);
00199 }
00200
00201 QImage KIconEffect::apply(const QImage &image, int effect, float value,
00202 const QColor &col, bool trans) const
00203 {
00204 return apply(image, effect, value, col,
00205 KColorScheme(QPalette::Active, KColorScheme::View).background().color(), trans);
00206 }
00207
00208 QImage KIconEffect::apply(const QImage &img, int effect, float value,
00209 const QColor &col, const QColor &col2, bool trans) const
00210 {
00211 QImage image = img;
00212 if (effect >= LastEffect )
00213 {
00214 kDebug(265) << "Illegal icon effect: " << effect << "\n";
00215 return image;
00216 }
00217 if (value > 1.0)
00218 value = 1.0;
00219 else if (value < 0.0)
00220 value = 0.0;
00221 switch (effect)
00222 {
00223 case ToGray:
00224 toGray(image, value);
00225 break;
00226 case DeSaturate:
00227 deSaturate(image, value);
00228 break;
00229 case Colorize:
00230 colorize(image, col, value);
00231 break;
00232 case ToGamma:
00233 toGamma(image, value);
00234 break;
00235 case ToMonochrome:
00236 toMonochrome(image, col, col2, value);
00237 break;
00238 }
00239 if (trans == true)
00240 {
00241 semiTransparent(image);
00242 }
00243 return image;
00244 }
00245
00246 QPixmap KIconEffect::apply(const QPixmap &pixmap, int group, int state) const
00247 {
00248 if (state >= KIconLoader::LastState)
00249 {
00250 kDebug(265) << "Illegal icon state: " << state << "\n";
00251 return pixmap;
00252 }
00253 if (group >= KIconLoader::LastGroup)
00254 {
00255 kDebug(265) << "Illegal icon group: " << group << "\n";
00256 return pixmap;
00257 }
00258 return apply(pixmap, d->effect[group][state], d->value[group][state],
00259 d->color[group][state], d->color2[group][state], d->trans[group][state]);
00260 }
00261
00262 QPixmap KIconEffect::apply(const QPixmap &pixmap, int effect, float value,
00263 const QColor &col, bool trans) const
00264 {
00265 return apply(pixmap, effect, value, col,
00266 KColorScheme(QPalette::Active, KColorScheme::View).background().color(), trans);
00267 }
00268
00269 QPixmap KIconEffect::apply(const QPixmap &pixmap, int effect, float value,
00270 const QColor &col, const QColor &col2, bool trans) const
00271 {
00272 QPixmap result;
00273
00274 if (effect >= LastEffect )
00275 {
00276 kDebug(265) << "Illegal icon effect: " << effect << "\n";
00277 return result;
00278 }
00279
00280 if ((trans == true) && (effect == NoEffect))
00281 {
00282 result = pixmap;
00283 semiTransparent(result);
00284 }
00285 else if ( effect != NoEffect )
00286 {
00287 QImage tmpImg = pixmap.toImage();
00288 tmpImg = apply(tmpImg, effect, value, col, col2, trans);
00289 result = QPixmap::fromImage(tmpImg);
00290 }
00291 else
00292 result = pixmap;
00293
00294 return result;
00295 }
00296
00297 struct KIEImgEdit
00298 {
00299 QImage& img;
00300 QVector <QRgb> colors;
00301 unsigned int* data;
00302 unsigned int pixels;
00303
00304 KIEImgEdit(QImage& _img):img(_img)
00305 {
00306 if (img.depth() > 8)
00307 {
00308
00309
00310 if ((img.format() != QImage::Format_ARGB32) &&
00311 (img.format() != QImage::Format_RGB32))
00312 {
00313 img = img.convertToFormat(QImage::Format_ARGB32);
00314 }
00315 data = (unsigned int*)img.bits();
00316 pixels = img.width()*img.height();
00317 }
00318 else
00319 {
00320 pixels = img.numColors();
00321 colors = img.colorTable();
00322 data = (unsigned int*)colors.data();
00323 }
00324 }
00325
00326 ~KIEImgEdit()
00327 {
00328 if (img.depth() <= 8)
00329 img.setColorTable(colors);
00330 }
00331 };
00332
00333 static bool painterSupportsAntialiasing()
00334 {
00335 #ifdef Q_WS_WIN
00336
00337
00338 return true;
00339 #else
00340 QPaintEngine* const pe = QApplication::desktop()->paintEngine();
00341 return pe && pe->hasFeature(QPaintEngine::Antialiasing);
00342 #endif
00343 }
00344
00345
00346
00347
00348 void KIconEffect::toGray(QImage &img, float value)
00349 {
00350 if(value == 0.0)
00351 return;
00352
00353 KIEImgEdit ii(img);
00354 QRgb *data = ii.data;
00355 QRgb *end = data + ii.pixels;
00356
00357 unsigned char gray;
00358 if(value == 1.0){
00359 while(data != end){
00360 gray = qGray(*data);
00361 *data = qRgba(gray, gray, gray, qAlpha(*data));
00362 ++data;
00363 }
00364 }
00365 else{
00366 unsigned char val = (unsigned char)(255.0*value);
00367 while(data != end){
00368 gray = qGray(*data);
00369 *data = qRgba((val*gray+(0xFF-val)*qRed(*data)) >> 8,
00370 (val*gray+(0xFF-val)*qGreen(*data)) >> 8,
00371 (val*gray+(0xFF-val)*qBlue(*data)) >> 8,
00372 qAlpha(*data));
00373 ++data;
00374 }
00375 }
00376 }
00377
00378 void KIconEffect::colorize(QImage &img, const QColor &col, float value)
00379 {
00380 if(value == 0.0)
00381 return;
00382
00383 KIEImgEdit ii(img);
00384 QRgb *data = ii.data;
00385 QRgb *end = data + ii.pixels;
00386
00387 float rcol = col.red(), gcol = col.green(), bcol = col.blue();
00388 unsigned char red, green, blue, gray;
00389 unsigned char val = (unsigned char)(255.0*value);
00390 while(data != end){
00391 gray = qGray(*data);
00392 if(gray < 128){
00393 red = static_cast<unsigned char>(rcol/128*gray);
00394 green = static_cast<unsigned char>(gcol/128*gray);
00395 blue = static_cast<unsigned char>(bcol/128*gray);
00396 }
00397 else if(gray > 128){
00398 red = static_cast<unsigned char>((gray-128)*(2-rcol/128)+rcol-1);
00399 green = static_cast<unsigned char>((gray-128)*(2-gcol/128)+gcol-1);
00400 blue = static_cast<unsigned char>((gray-128)*(2-bcol/128)+bcol-1);
00401 }
00402 else{
00403 red = static_cast<unsigned char>(rcol);
00404 green = static_cast<unsigned char>(gcol);
00405 blue = static_cast<unsigned char>(bcol);
00406 }
00407
00408 *data = qRgba((val*red+(0xFF-val)*qRed(*data)) >> 8,
00409 (val*green+(0xFF-val)*qGreen(*data)) >> 8,
00410 (val*blue+(0xFF-val)*qBlue(*data)) >> 8,
00411 qAlpha(*data));
00412 ++data;
00413 }
00414 }
00415
00416 void KIconEffect::toMonochrome(QImage &img, const QColor &black,
00417 const QColor &white, float value)
00418 {
00419 if(value == 0.0)
00420 return;
00421
00422 KIEImgEdit ii(img);
00423 QRgb *data = ii.data;
00424 QRgb *end = data + ii.pixels;
00425
00426
00427 double values = 0.0, sum = 0.0;
00428 bool grayscale = true;
00429 while(data != end){
00430 sum += qGray(*data)*qAlpha(*data) + 255*(255-qAlpha(*data));
00431 values += 255;
00432 if((qRed(*data) != qGreen(*data) ) || (qGreen(*data) != qBlue(*data)))
00433 grayscale = false;
00434 ++data;
00435 }
00436 double medium = sum/values;
00437
00438
00439 unsigned char val = (unsigned char)(255.0*value);
00440 int rw = white.red(), gw = white.green(), bw = white.blue();
00441 int rb = black.red(), gb = black.green(), bb = black.blue();
00442 data = ii.data;
00443
00444 if(grayscale){
00445 while(data != end){
00446 if(qRed(*data) <= medium)
00447 *data = qRgba((val*rb+(0xFF-val)*qRed(*data)) >> 8,
00448 (val*gb+(0xFF-val)*qGreen(*data)) >> 8,
00449 (val*bb+(0xFF-val)*qBlue(*data)) >> 8,
00450 qAlpha(*data));
00451 else
00452 *data = qRgba((val*rw+(0xFF-val)*qRed(*data)) >> 8,
00453 (val*gw+(0xFF-val)*qGreen(*data)) >> 8,
00454 (val*bw+(0xFF-val)*qBlue(*data)) >> 8,
00455 qAlpha(*data));
00456 ++data;
00457 }
00458 }
00459 else{
00460 while(data != end){
00461 if(qGray(*data) <= medium)
00462 *data = qRgba((val*rb+(0xFF-val)*qRed(*data)) >> 8,
00463 (val*gb+(0xFF-val)*qGreen(*data)) >> 8,
00464 (val*bb+(0xFF-val)*qBlue(*data)) >> 8,
00465 qAlpha(*data));
00466 else
00467 *data = qRgba((val*rw+(0xFF-val)*qRed(*data)) >> 8,
00468 (val*gw+(0xFF-val)*qGreen(*data)) >> 8,
00469 (val*bw+(0xFF-val)*qBlue(*data)) >> 8,
00470 qAlpha(*data));
00471 ++data;
00472 }
00473 }
00474 }
00475
00476 void KIconEffect::deSaturate(QImage &img, float value)
00477 {
00478 if(value == 0.0)
00479 return;
00480
00481 KIEImgEdit ii(img);
00482 QRgb *data = ii.data;
00483 QRgb *end = data + ii.pixels;
00484
00485 QColor color;
00486 int h, s, v;
00487 while(data != end){
00488 color.setRgb(*data);
00489 color.getHsv(&h, &s, &v);
00490 color.setHsv(h, (int) (s * (1.0 - value) + 0.5), v);
00491 *data = qRgba(color.red(), color.green(), color.blue(),
00492 qAlpha(*data));
00493 ++data;
00494 }
00495 }
00496
00497 void KIconEffect::toGamma(QImage &img, float value)
00498 {
00499 KIEImgEdit ii(img);
00500 QRgb *data = ii.data;
00501 QRgb *end = data + ii.pixels;
00502
00503 float gamma = 1/(2*value+0.5);
00504 while(data != end){
00505 *data = qRgba(static_cast<unsigned char>
00506 (pow(static_cast<float>(qRed(*data))/255 , gamma)*255),
00507 static_cast<unsigned char>
00508 (pow(static_cast<float>(qGreen(*data))/255 , gamma)*255),
00509 static_cast<unsigned char>
00510 (pow(static_cast<float>(qBlue(*data))/255 , gamma)*255),
00511 qAlpha(*data));
00512 ++data;
00513 }
00514 }
00515
00516 void KIconEffect::semiTransparent(QImage &img)
00517 {
00518 int x, y;
00519 if(img.depth() == 32){
00520 if(img.format() == QImage::Format_ARGB32_Premultiplied)
00521 img = img.convertToFormat(QImage::Format_ARGB32);
00522 int width = img.width();
00523 int height = img.height();
00524
00525 if(painterSupportsAntialiasing()){
00526 unsigned char *line;
00527 for(y=0; y<height; y++){
00528 if(QSysInfo::ByteOrder == QSysInfo::BigEndian)
00529 line = img.scanLine(y);
00530 else
00531 line = img.scanLine(y) + 3;
00532 for(x=0; x<width; x++){
00533 *line >>= 1;
00534 line += 4;
00535 }
00536 }
00537 }
00538 else{
00539 for(y=0; y<height; y++){
00540 QRgb* line = (QRgb*)img.scanLine(y);
00541 for(x=(y%2); x<width; x+=2)
00542 line[x] &= 0x00ffffff;
00543 }
00544 }
00545 }
00546 else{
00547 if (img.depth() == 8) {
00548 if (painterSupportsAntialiasing()) {
00549
00550 QVector<QRgb> colorTable = img.colorTable();
00551 for (int i = 0; i < colorTable.size(); ++i) {
00552 colorTable[i] = (colorTable[i] & 0x00ffffff) | ((colorTable[i] & 0xfe000000) >> 1);
00553 }
00554 img.setColorTable(colorTable);
00555 return;
00556 }
00557 }
00558
00559 int transColor = -1;
00560
00561
00562 for(x=0; x<img.numColors(); x++){
00563
00564 if(qAlpha(img.color(x)) < 127){
00565 transColor = x;
00566 break;
00567 }
00568 }
00569
00570
00571 if(transColor < 0 || transColor >= img.numColors())
00572 return;
00573
00574 img.setColor(transColor, 0);
00575 unsigned char *line;
00576 if(img.depth() == 8){
00577 for(y=0; y<img.height(); y++){
00578 line = img.scanLine(y);
00579 for(x=(y%2); x<img.width(); x+=2)
00580 line[x] = transColor;
00581 }
00582 }
00583 else{
00584 bool setOn = (transColor != 0);
00585 if(img.format() == QImage::Format_MonoLSB){
00586 for(y=0; y<img.height(); y++){
00587 line = img.scanLine(y);
00588 for(x=(y%2); x<img.width(); x+=2){
00589 if(!setOn)
00590 *(line + (x >> 3)) &= ~(1 << (x & 7));
00591 else
00592 *(line + (x >> 3)) |= (1 << (x & 7));
00593 }
00594 }
00595 }
00596 else{
00597 for(y=0; y<img.height(); y++){
00598 line = img.scanLine(y);
00599 for(x=(y%2); x<img.width(); x+=2){
00600 if(!setOn)
00601 *(line + (x >> 3)) &= ~(1 << (7-(x & 7)));
00602 else
00603 *(line + (x >> 3)) |= (1 << (7-(x & 7)));
00604 }
00605 }
00606 }
00607 }
00608 }
00609 }
00610
00611 void KIconEffect::semiTransparent(QPixmap &pix)
00612 {
00613 if (painterSupportsAntialiasing()) {
00614 QImage img=pix.toImage();
00615 semiTransparent(img);
00616 pix = QPixmap::fromImage(img);
00617 return;
00618 }
00619
00620 QImage img;
00621 if (!pix.mask().isNull())
00622 img = pix.mask().toImage();
00623 else
00624 {
00625 img = QImage(pix.size(), QImage::Format_Mono);
00626 img.fill(1);
00627 }
00628
00629 for (int y=0; y<img.height(); y++)
00630 {
00631 QRgb* line = (QRgb*)img.scanLine(y);
00632 QRgb pattern = (y % 2) ? 0x55555555 : 0xaaaaaaaa;
00633 for (int x=0; x<(img.width()+31)/32; x++)
00634 line[x] &= pattern;
00635 }
00636 QBitmap mask;
00637 mask = QBitmap::fromImage(img);
00638 pix.setMask(mask);
00639 }
00640
00641 QImage KIconEffect::doublePixels(const QImage &src) const
00642 {
00643 int w = src.width();
00644 int h = src.height();
00645
00646 QImage dst( w*2, h*2, src.format() );
00647
00648 if (src.depth() == 1)
00649 {
00650 kDebug(265) << "image depth 1 not supported\n";
00651 return QImage();
00652 }
00653
00654 int x, y;
00655 if (src.depth() == 32)
00656 {
00657 QRgb* l1, *l2;
00658 for (y=0; y<h; y++)
00659 {
00660 l1 = (QRgb*)src.scanLine(y);
00661 l2 = (QRgb*)dst.scanLine(y*2);
00662 for (x=0; x<w; x++)
00663 {
00664 l2[x*2] = l2[x*2+1] = l1[x];
00665 }
00666 memcpy(dst.scanLine(y*2+1), l2, dst.bytesPerLine());
00667 }
00668 } else
00669 {
00670 for (x=0; x<src.numColors(); x++)
00671 dst.setColor(x, src.color(x));
00672
00673 const unsigned char *l1;
00674 unsigned char *l2;
00675 for (y=0; y<h; y++)
00676 {
00677 l1 = src.scanLine(y);
00678 l2 = dst.scanLine(y*2);
00679 for (x=0; x<w; x++)
00680 {
00681 l2[x*2] = l1[x];
00682 l2[x*2+1] = l1[x];
00683 }
00684 memcpy(dst.scanLine(y*2+1), l2, dst.bytesPerLine());
00685 }
00686 }
00687 return dst;
00688 }
00689
00690 void KIconEffect::overlay(QImage &src, QImage &overlay)
00691 {
00692 if (src.depth() != overlay.depth())
00693 {
00694 kDebug(265) << "Image depth src (" << src.depth() << ") != overlay " << "(" << overlay.depth() << ")!\n";
00695 return;
00696 }
00697 if (src.size() != overlay.size())
00698 {
00699 kDebug(265) << "Image size src != overlay\n";
00700 return;
00701 }
00702 if (src.format() == QImage::Format_ARGB32_Premultiplied)
00703 src = src.convertToFormat(QImage::Format_ARGB32);
00704
00705 if (overlay.format() == QImage::Format_RGB32)
00706 {
00707 kDebug(265) << "Overlay doesn't have alpha buffer!\n";
00708 return;
00709 }
00710 else if (overlay.format() == QImage::Format_ARGB32_Premultiplied)
00711 overlay = overlay.convertToFormat(QImage::Format_ARGB32);
00712
00713 int i, j;
00714
00715
00716
00717 if (src.depth() == 1)
00718 {
00719 kDebug(265) << "1bpp not supported!\n";
00720 return;
00721 }
00722
00723
00724
00725 if (src.depth() == 8)
00726 {
00727 if (src.numColors() + overlay.numColors() > 255)
00728 {
00729 kDebug(265) << "Too many colors in src + overlay!\n";
00730 return;
00731 }
00732
00733
00734 int trans;
00735 for (trans=0; trans<overlay.numColors(); trans++)
00736 {
00737 if (qAlpha(overlay.color(trans)) == 0)
00738 {
00739 kDebug(265) << "transparent pixel found at " << trans << "\n";
00740 break;
00741 }
00742 }
00743 if (trans == overlay.numColors())
00744 {
00745 kDebug(265) << "transparent pixel not found!\n";
00746 return;
00747 }
00748
00749
00750 int nc = src.numColors();
00751 src.setNumColors(nc + overlay.numColors());
00752 for (i=0; i<overlay.numColors(); i++)
00753 {
00754 src.setColor(nc+i, overlay.color(i));
00755 }
00756
00757
00758 unsigned char *oline, *sline;
00759 for (i=0; i<src.height(); i++)
00760 {
00761 oline = overlay.scanLine(i);
00762 sline = src.scanLine(i);
00763 for (j=0; j<src.width(); j++)
00764 {
00765 if (oline[j] != trans)
00766 sline[j] = oline[j]+nc;
00767 }
00768 }
00769 }
00770
00771
00772
00773 if (src.depth() == 32)
00774 {
00775 QRgb* oline, *sline;
00776 int r1, g1, b1, a1;
00777 int r2, g2, b2, a2;
00778
00779 for (i=0; i<src.height(); i++)
00780 {
00781 oline = (QRgb*)overlay.scanLine(i);
00782 sline = (QRgb*)src.scanLine(i);
00783
00784 for (j=0; j<src.width(); j++)
00785 {
00786 r1 = qRed(oline[j]);
00787 g1 = qGreen(oline[j]);
00788 b1 = qBlue(oline[j]);
00789 a1 = qAlpha(oline[j]);
00790
00791 r2 = qRed(sline[j]);
00792 g2 = qGreen(sline[j]);
00793 b2 = qBlue(sline[j]);
00794 a2 = qAlpha(sline[j]);
00795
00796 r2 = (a1 * r1 + (0xff - a1) * r2) >> 8;
00797 g2 = (a1 * g1 + (0xff - a1) * g2) >> 8;
00798 b2 = (a1 * b1 + (0xff - a1) * b2) >> 8;
00799 a2 = qMax(a1, a2);
00800
00801 sline[j] = qRgba(r2, g2, b2, a2);
00802 }
00803 }
00804 }
00805
00806 return;
00807 }
00808