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
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
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
00328
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
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
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
00531 int transColor = -1;
00532
00533
00534 for(x=0; x<img.numColors(); x++){
00535
00536 if(qAlpha(img.color(x)) < 127){
00537 transColor = x;
00538 break;
00539 }
00540 }
00541
00542
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
00689
00690 if (src.depth() == 1)
00691 {
00692 kDebug(265) << "1bpp not supported!\n";
00693 return;
00694 }
00695
00696
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
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
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
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
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