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

KDEUI

  • sources
  • kde-4.12
  • kdelibs
  • kdeui
  • icons
kiconeffect.cpp
Go to the documentation of this file.
1 /* vi: ts=8 sts=4 sw=4
2  *
3  * This file is part of the KDE project, module kdecore.
4  * Copyright (C) 2000 Geert Jansen <jansen@kde.org>
5  * (C) 2007 Daniel M. Duley <daniel.duley@verizon.net>
6  * with minor additions and based on ideas from
7  * Torsten Rahn <torsten@kde.org>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License version 2 as published by the Free Software Foundation.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB. If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23 
24 #include "kiconeffect.h"
25 
26 #include <config.h>
27 #include <unistd.h>
28 #include <math.h>
29 
30 #include <QtCore/QSysInfo>
31 #include <QtGui/QApplication>
32 #include <QtGui/QPaintEngine>
33 #include <QtGui/QDesktopWidget>
34 #include <QtCore/QCharRef>
35 #include <QtCore/QMutableStringListIterator>
36 #include <QtGui/QBitmap>
37 #include <QtGui/QPixmap>
38 #include <QtGui/QImage>
39 #include <QtGui/QColor>
40 #include <QtGui/QWidget>
41 #include <QtGui/QPainter>
42 #include <QtGui/QPen>
43 
44 #include <kdebug.h>
45 #include <kglobal.h>
46 #include <ksharedconfig.h>
47 #include <kglobalsettings.h>
48 #include <kcolorscheme.h>
49 #include <kicontheme.h>
50 #include <kconfiggroup.h>
51 
52 
53 class KIconEffectPrivate
54 {
55 public:
56  int effect[6][3];
57  float value[6][3];
58  QColor color[6][3];
59  bool trans[6][3];
60  QString key[6][3];
61  QColor color2[6][3];
62 };
63 
64 KIconEffect::KIconEffect()
65  :d(new KIconEffectPrivate)
66 {
67  init();
68 }
69 
70 KIconEffect::~KIconEffect()
71 {
72  delete d;
73 }
74 
75 void KIconEffect::init()
76 {
77  KSharedConfig::Ptr config = KGlobal::config();
78 
79  int i, j, effect=-1;
80  //FIXME: this really should be using KIconLoader::metaObject() to guarantee synchronization
81  // performance wise it's also practically guaranteed to be faster
82  QStringList groups;
83  groups += "Desktop";
84  groups += "Toolbar";
85  groups += "MainToolbar";
86  groups += "Small";
87  groups += "Panel";
88  groups += "Dialog";
89 
90  QStringList states;
91  states += "Default";
92  states += "Active";
93  states += "Disabled";
94 
95  QStringList::ConstIterator it, it2;
96  QString _togray("togray");
97  QString _colorize("colorize");
98  QString _desaturate("desaturate");
99  QString _togamma("togamma");
100  QString _none("none");
101  QString _tomonochrome("tomonochrome");
102 
103  for (it=groups.constBegin(), i=0; it!=groups.constEnd(); ++it, ++i)
104  {
105  // Default effects
106  d->effect[i][0] = NoEffect;
107  d->effect[i][1] = ((i==0)||(i==4)) ? ToGamma : NoEffect;
108  d->effect[i][2] = ToGray;
109 
110  d->trans[i][0] = false;
111  d->trans[i][1] = false;
112  d->trans[i][2] = true;
113  d->value[i][0] = 1.0;
114  d->value[i][1] = ((i==0)||(i==4)) ? 0.7 : 1.0;
115  d->value[i][2] = 1.0;
116  d->color[i][0] = QColor(144,128,248);
117  d->color[i][1] = QColor(169,156,255);
118  d->color[i][2] = QColor(34,202,0);
119  d->color2[i][0] = QColor(0,0,0);
120  d->color2[i][1] = QColor(0,0,0);
121  d->color2[i][2] = QColor(0,0,0);
122 
123  KConfigGroup cg(config, *it + "Icons");
124  for (it2=states.constBegin(), j=0; it2!=states.constEnd(); ++it2, ++j)
125  {
126  QString tmp = cg.readEntry(*it2 + "Effect", QString());
127  if (tmp == _togray)
128  effect = ToGray;
129  else if (tmp == _colorize)
130  effect = Colorize;
131  else if (tmp == _desaturate)
132  effect = DeSaturate;
133  else if (tmp == _togamma)
134  effect = ToGamma;
135  else if (tmp == _tomonochrome)
136  effect = ToMonochrome;
137  else if (tmp == _none)
138  effect = NoEffect;
139  else
140  continue;
141  if(effect != -1)
142  d->effect[i][j] = effect;
143  d->value[i][j] = cg.readEntry(*it2 + "Value", 0.0);
144  d->color[i][j] = cg.readEntry(*it2 + "Color", QColor());
145  d->color2[i][j] = cg.readEntry(*it2 + "Color2", QColor());
146  d->trans[i][j] = cg.readEntry(*it2 + "SemiTransparent", false);
147 
148  }
149  }
150 }
151 
152 bool KIconEffect::hasEffect(int group, int state) const
153 {
154  if (group < 0 || group >= KIconLoader::LastGroup ||
155  state < 0 || state >= KIconLoader::LastState) {
156  return false;
157  }
158 
159  return d->effect[group][state] != NoEffect;
160 }
161 
162 QString KIconEffect::fingerprint(int group, int state) const
163 {
164  if (group < 0 || group >= KIconLoader::LastGroup ||
165  state < 0 || state >= KIconLoader::LastState) {
166  return QString();
167  }
168 
169  QString cached = d->key[group][state];
170  if (cached.isEmpty())
171  {
172  QString tmp;
173  cached = tmp.setNum(d->effect[group][state]);
174  cached += ':';
175  cached += tmp.setNum(d->value[group][state]);
176  cached += ':';
177  cached += d->trans[group][state] ? QLatin1String("trans")
178  : QLatin1String("notrans");
179  if (d->effect[group][state] == Colorize || d->effect[group][state] == ToMonochrome)
180  {
181  cached += ':';
182  cached += d->color[group][state].name();
183  }
184  if (d->effect[group][state] == ToMonochrome)
185  {
186  cached += ':';
187  cached += d->color2[group][state].name();
188  }
189 
190  d->key[group][state] = cached;
191  }
192 
193  return cached;
194 }
195 
196 QImage KIconEffect::apply(const QImage &image, int group, int state) const
197 {
198  if (state >= KIconLoader::LastState)
199  {
200  kDebug(265) << "Illegal icon state: " << state << "\n";
201  return image;
202  }
203  if (group >= KIconLoader::LastGroup)
204  {
205  kDebug(265) << "Illegal icon group: " << group << "\n";
206  return image;
207  }
208  return apply(image, d->effect[group][state], d->value[group][state],
209  d->color[group][state], d->color2[group][state], d->trans[group][state]);
210 }
211 
212 QImage KIconEffect::apply(const QImage &image, int effect, float value,
213  const QColor &col, bool trans) const
214 {
215  return apply(image, effect, value, col,
216  KColorScheme(QPalette::Active, KColorScheme::View).background().color(), trans);
217 }
218 
219 QImage KIconEffect::apply(const QImage &img, int effect, float value,
220  const QColor &col, const QColor &col2, bool trans) const
221 {
222  QImage image = img;
223  if (effect >= LastEffect )
224  {
225  kDebug(265) << "Illegal icon effect: " << effect << "\n";
226  return image;
227  }
228  if (value > 1.0)
229  value = 1.0;
230  else if (value < 0.0)
231  value = 0.0;
232  switch (effect)
233  {
234  case ToGray:
235  toGray(image, value);
236  break;
237  case DeSaturate:
238  deSaturate(image, value);
239  break;
240  case Colorize:
241  colorize(image, col, value);
242  break;
243  case ToGamma:
244  toGamma(image, value);
245  break;
246  case ToMonochrome:
247  toMonochrome(image, col, col2, value);
248  break;
249  }
250  if (trans == true)
251  {
252  semiTransparent(image);
253  }
254  return image;
255 }
256 
257 QPixmap KIconEffect::apply(const QPixmap &pixmap, int group, int state) const
258 {
259  if (state >= KIconLoader::LastState)
260  {
261  kDebug(265) << "Illegal icon state: " << state << "\n";
262  return pixmap;
263  }
264  if (group >= KIconLoader::LastGroup)
265  {
266  kDebug(265) << "Illegal icon group: " << group << "\n";
267  return pixmap;
268  }
269  return apply(pixmap, d->effect[group][state], d->value[group][state],
270  d->color[group][state], d->color2[group][state], d->trans[group][state]);
271 }
272 
273 QPixmap KIconEffect::apply(const QPixmap &pixmap, int effect, float value,
274  const QColor &col, bool trans) const
275 {
276  return apply(pixmap, effect, value, col,
277  KColorScheme(QPalette::Active, KColorScheme::View).background().color(), trans);
278 }
279 
280 QPixmap KIconEffect::apply(const QPixmap &pixmap, int effect, float value,
281  const QColor &col, const QColor &col2, bool trans) const
282 {
283  QPixmap result;
284 
285  if (effect >= LastEffect )
286  {
287  kDebug(265) << "Illegal icon effect: " << effect << "\n";
288  return result;
289  }
290 
291  if ((trans == true) && (effect == NoEffect))
292  {
293  result = pixmap;
294  semiTransparent(result);
295  }
296  else if ( effect != NoEffect )
297  {
298  QImage tmpImg = pixmap.toImage();
299  tmpImg = apply(tmpImg, effect, value, col, col2, trans);
300  result = QPixmap::fromImage(tmpImg);
301  }
302  else
303  result = pixmap;
304 
305  return result;
306 }
307 
308 struct KIEImgEdit
309 {
310  QImage& img;
311  QVector <QRgb> colors;
312  unsigned int* data;
313  unsigned int pixels;
314 
315  KIEImgEdit(QImage& _img):img(_img)
316  {
317  if (img.depth() > 8)
318  {
319  //Code using data and pixels assumes that the pixels are stored
320  //in 32bit values and that the image is not premultiplied
321  if ((img.format() != QImage::Format_ARGB32) &&
322  (img.format() != QImage::Format_RGB32))
323  {
324  img = img.convertToFormat(QImage::Format_ARGB32);
325  }
326  data = (unsigned int*)img.bits();
327  pixels = img.width()*img.height();
328  }
329  else
330  {
331  pixels = img.numColors();
332  colors = img.colorTable();
333  data = (unsigned int*)colors.data();
334  }
335  }
336 
337  ~KIEImgEdit()
338  {
339  if (img.depth() <= 8)
340  img.setColorTable(colors);
341  }
342 };
343 
344 static bool painterSupportsAntialiasing()
345 {
346 #ifdef Q_WS_WIN
347  // apparently QApplication::desktop()->paintEngine() is null on windows
348  // but we can assume the paint engine supports antialiasing there, right?
349  return true;
350 #else
351  QPaintEngine* const pe = QApplication::desktop()->paintEngine();
352  return pe && pe->hasFeature(QPaintEngine::Antialiasing);
353 #endif
354 }
355 
356 // Taken from KImageEffect. We don't want to link kdecore to kdeui! As long
357 // as this code is not too big, it doesn't seem much of a problem to me.
358 
359 void KIconEffect::toGray(QImage &img, float value)
360 {
361  if(value == 0.0)
362  return;
363 
364  KIEImgEdit ii(img);
365  QRgb *data = ii.data;
366  QRgb *end = data + ii.pixels;
367 
368  unsigned char gray;
369  if(value == 1.0){
370  while(data != end){
371  gray = qGray(*data);
372  *data = qRgba(gray, gray, gray, qAlpha(*data));
373  ++data;
374  }
375  }
376  else{
377  unsigned char val = (unsigned char)(255.0*value);
378  while(data != end){
379  gray = qGray(*data);
380  *data = qRgba((val*gray+(0xFF-val)*qRed(*data)) >> 8,
381  (val*gray+(0xFF-val)*qGreen(*data)) >> 8,
382  (val*gray+(0xFF-val)*qBlue(*data)) >> 8,
383  qAlpha(*data));
384  ++data;
385  }
386  }
387 }
388 
389 void KIconEffect::colorize(QImage &img, const QColor &col, float value)
390 {
391  if(value == 0.0)
392  return;
393 
394  KIEImgEdit ii(img);
395  QRgb *data = ii.data;
396  QRgb *end = data + ii.pixels;
397 
398  float rcol = col.red(), gcol = col.green(), bcol = col.blue();
399  unsigned char red, green, blue, gray;
400  unsigned char val = (unsigned char)(255.0*value);
401  while(data != end){
402  gray = qGray(*data);
403  if(gray < 128){
404  red = static_cast<unsigned char>(rcol/128*gray);
405  green = static_cast<unsigned char>(gcol/128*gray);
406  blue = static_cast<unsigned char>(bcol/128*gray);
407  }
408  else if(gray > 128){
409  red = static_cast<unsigned char>((gray-128)*(2-rcol/128)+rcol-1);
410  green = static_cast<unsigned char>((gray-128)*(2-gcol/128)+gcol-1);
411  blue = static_cast<unsigned char>((gray-128)*(2-bcol/128)+bcol-1);
412  }
413  else{
414  red = static_cast<unsigned char>(rcol);
415  green = static_cast<unsigned char>(gcol);
416  blue = static_cast<unsigned char>(bcol);
417  }
418 
419  *data = qRgba((val*red+(0xFF-val)*qRed(*data)) >> 8,
420  (val*green+(0xFF-val)*qGreen(*data)) >> 8,
421  (val*blue+(0xFF-val)*qBlue(*data)) >> 8,
422  qAlpha(*data));
423  ++data;
424  }
425 }
426 
427 void KIconEffect::toMonochrome(QImage &img, const QColor &black,
428  const QColor &white, float value)
429 {
430  if(value == 0.0)
431  return;
432 
433  KIEImgEdit ii(img);
434  QRgb *data = ii.data;
435  QRgb *end = data + ii.pixels;
436 
437  // Step 1: determine the average brightness
438  double values = 0.0, sum = 0.0;
439  bool grayscale = true;
440  while(data != end){
441  sum += qGray(*data)*qAlpha(*data) + 255*(255-qAlpha(*data));
442  values += 255;
443  if((qRed(*data) != qGreen(*data) ) || (qGreen(*data) != qBlue(*data)))
444  grayscale = false;
445  ++data;
446  }
447  double medium = sum/values;
448 
449  // Step 2: Modify the image
450  unsigned char val = (unsigned char)(255.0*value);
451  int rw = white.red(), gw = white.green(), bw = white.blue();
452  int rb = black.red(), gb = black.green(), bb = black.blue();
453  data = ii.data;
454 
455  if(grayscale){
456  while(data != end){
457  if(qRed(*data) <= medium)
458  *data = qRgba((val*rb+(0xFF-val)*qRed(*data)) >> 8,
459  (val*gb+(0xFF-val)*qGreen(*data)) >> 8,
460  (val*bb+(0xFF-val)*qBlue(*data)) >> 8,
461  qAlpha(*data));
462  else
463  *data = qRgba((val*rw+(0xFF-val)*qRed(*data)) >> 8,
464  (val*gw+(0xFF-val)*qGreen(*data)) >> 8,
465  (val*bw+(0xFF-val)*qBlue(*data)) >> 8,
466  qAlpha(*data));
467  ++data;
468  }
469  }
470  else{
471  while(data != end){
472  if(qGray(*data) <= medium)
473  *data = qRgba((val*rb+(0xFF-val)*qRed(*data)) >> 8,
474  (val*gb+(0xFF-val)*qGreen(*data)) >> 8,
475  (val*bb+(0xFF-val)*qBlue(*data)) >> 8,
476  qAlpha(*data));
477  else
478  *data = qRgba((val*rw+(0xFF-val)*qRed(*data)) >> 8,
479  (val*gw+(0xFF-val)*qGreen(*data)) >> 8,
480  (val*bw+(0xFF-val)*qBlue(*data)) >> 8,
481  qAlpha(*data));
482  ++data;
483  }
484  }
485 }
486 
487 void KIconEffect::deSaturate(QImage &img, float value)
488 {
489  if(value == 0.0)
490  return;
491 
492  KIEImgEdit ii(img);
493  QRgb *data = ii.data;
494  QRgb *end = data + ii.pixels;
495 
496  QColor color;
497  int h, s, v;
498  while(data != end){
499  color.setRgb(*data);
500  color.getHsv(&h, &s, &v);
501  color.setHsv(h, (int) (s * (1.0 - value) + 0.5), v);
502  *data = qRgba(color.red(), color.green(), color.blue(),
503  qAlpha(*data));
504  ++data;
505  }
506 }
507 
508 void KIconEffect::toGamma(QImage &img, float value)
509 {
510  KIEImgEdit ii(img);
511  QRgb *data = ii.data;
512  QRgb *end = data + ii.pixels;
513 
514  float gamma = 1/(2*value+0.5);
515  while(data != end){
516  *data = qRgba(static_cast<unsigned char>
517  (pow(static_cast<float>(qRed(*data))/255 , gamma)*255),
518  static_cast<unsigned char>
519  (pow(static_cast<float>(qGreen(*data))/255 , gamma)*255),
520  static_cast<unsigned char>
521  (pow(static_cast<float>(qBlue(*data))/255 , gamma)*255),
522  qAlpha(*data));
523  ++data;
524  }
525 }
526 
527 void KIconEffect::semiTransparent(QImage &img)
528 {
529  int x, y;
530  if(img.depth() == 32){
531  if(img.format() == QImage::Format_ARGB32_Premultiplied)
532  img = img.convertToFormat(QImage::Format_ARGB32);
533  int width = img.width();
534  int height = img.height();
535 
536  if(painterSupportsAntialiasing()){
537  unsigned char *line;
538  for(y=0; y<height; ++y){
539  if(QSysInfo::ByteOrder == QSysInfo::BigEndian)
540  line = img.scanLine(y);
541  else
542  line = img.scanLine(y) + 3;
543  for(x=0; x<width; ++x){
544  *line >>= 1;
545  line += 4;
546  }
547  }
548  }
549  else{
550  for(y=0; y<height; ++y){
551  QRgb* line = (QRgb*)img.scanLine(y);
552  for(x=(y%2); x<width; x+=2)
553  line[x] &= 0x00ffffff;
554  }
555  }
556  }
557  else{
558  if (img.depth() == 8) {
559  if (painterSupportsAntialiasing()) {
560  // not running on 8 bit, we can safely install a new colorTable
561  QVector<QRgb> colorTable = img.colorTable();
562  for (int i = 0; i < colorTable.size(); ++i) {
563  colorTable[i] = (colorTable[i] & 0x00ffffff) | ((colorTable[i] & 0xfe000000) >> 1);
564  }
565  img.setColorTable(colorTable);
566  return;
567  }
568  }
569  // Insert transparent pixel into the clut.
570  int transColor = -1;
571 
572  // search for a color that is already transparent
573  for(x=0; x<img.numColors(); ++x){
574  // try to find already transparent pixel
575  if(qAlpha(img.color(x)) < 127){
576  transColor = x;
577  break;
578  }
579  }
580 
581  // FIXME: image must have transparency
582  if(transColor < 0 || transColor >= img.numColors())
583  return;
584 
585  img.setColor(transColor, 0);
586  unsigned char *line;
587  if(img.depth() == 8){
588  for(y=0; y<img.height(); ++y){
589  line = img.scanLine(y);
590  for(x=(y%2); x<img.width(); x+=2)
591  line[x] = transColor;
592  }
593  }
594  else{
595  bool setOn = (transColor != 0);
596  if(img.format() == QImage::Format_MonoLSB){
597  for(y=0; y<img.height(); ++y){
598  line = img.scanLine(y);
599  for(x=(y%2); x<img.width(); x+=2){
600  if(!setOn)
601  *(line + (x >> 3)) &= ~(1 << (x & 7));
602  else
603  *(line + (x >> 3)) |= (1 << (x & 7));
604  }
605  }
606  }
607  else{
608  for(y=0; y<img.height(); ++y){
609  line = img.scanLine(y);
610  for(x=(y%2); x<img.width(); x+=2){
611  if(!setOn)
612  *(line + (x >> 3)) &= ~(1 << (7-(x & 7)));
613  else
614  *(line + (x >> 3)) |= (1 << (7-(x & 7)));
615  }
616  }
617  }
618  }
619  }
620 }
621 
622 void KIconEffect::semiTransparent(QPixmap &pix)
623 {
624  if (painterSupportsAntialiasing()) {
625  QImage img=pix.toImage();
626  semiTransparent(img);
627  pix = QPixmap::fromImage(img);
628  return;
629  }
630 
631  QImage img;
632  if (!pix.mask().isNull())
633  img = pix.mask().toImage();
634  else
635  {
636  img = QImage(pix.size(), QImage::Format_Mono);
637  img.fill(1);
638  }
639 
640  for (int y=0; y<img.height(); y++)
641  {
642  QRgb* line = (QRgb*)img.scanLine(y);
643  QRgb pattern = (y % 2) ? 0x55555555 : 0xaaaaaaaa;
644  for (int x=0; x<(img.width()+31)/32; x++)
645  line[x] &= pattern;
646  }
647  QBitmap mask;
648  mask = QBitmap::fromImage(img);
649  pix.setMask(mask);
650 }
651 
652 QImage KIconEffect::doublePixels(const QImage &src) const
653 {
654  int w = src.width();
655  int h = src.height();
656 
657  QImage dst( w*2, h*2, src.format() );
658 
659  if (src.depth() == 1)
660  {
661  kDebug(265) << "image depth 1 not supported\n";
662  return QImage();
663  }
664 
665  int x, y;
666  if (src.depth() == 32)
667  {
668  QRgb* l1, *l2;
669  for (y=0; y<h; ++y)
670  {
671  l1 = (QRgb*)src.scanLine(y);
672  l2 = (QRgb*)dst.scanLine(y*2);
673  for (x=0; x<w; ++x)
674  {
675  l2[x*2] = l2[x*2+1] = l1[x];
676  }
677  memcpy(dst.scanLine(y*2+1), l2, dst.bytesPerLine());
678  }
679  } else
680  {
681  for (x=0; x<src.numColors(); ++x)
682  dst.setColor(x, src.color(x));
683 
684  const unsigned char *l1;
685  unsigned char *l2;
686  for (y=0; y<h; ++y)
687  {
688  l1 = src.scanLine(y);
689  l2 = dst.scanLine(y*2);
690  for (x=0; x<w; ++x)
691  {
692  l2[x*2] = l1[x];
693  l2[x*2+1] = l1[x];
694  }
695  memcpy(dst.scanLine(y*2+1), l2, dst.bytesPerLine());
696  }
697  }
698  return dst;
699 }
700 
701 void KIconEffect::overlay(QImage &src, QImage &overlay)
702 {
703  if (src.depth() != overlay.depth())
704  {
705  kDebug(265) << "Image depth src (" << src.depth() << ") != overlay " << "(" << overlay.depth() << ")!\n";
706  return;
707  }
708  if (src.size() != overlay.size())
709  {
710  kDebug(265) << "Image size src != overlay\n";
711  return;
712  }
713  if (src.format() == QImage::Format_ARGB32_Premultiplied)
714  src = src.convertToFormat(QImage::Format_ARGB32);
715 
716  if (overlay.format() == QImage::Format_RGB32)
717  {
718  kDebug(265) << "Overlay doesn't have alpha buffer!\n";
719  return;
720  }
721  else if (overlay.format() == QImage::Format_ARGB32_Premultiplied)
722  overlay = overlay.convertToFormat(QImage::Format_ARGB32);
723 
724  int i, j;
725 
726  // We don't do 1 bpp
727 
728  if (src.depth() == 1)
729  {
730  kDebug(265) << "1bpp not supported!\n";
731  return;
732  }
733 
734  // Overlay at 8 bpp doesn't use alpha blending
735 
736  if (src.depth() == 8)
737  {
738  if (src.numColors() + overlay.numColors() > 255)
739  {
740  kDebug(265) << "Too many colors in src + overlay!\n";
741  return;
742  }
743 
744  // Find transparent pixel in overlay
745  int trans;
746  for (trans=0; trans<overlay.numColors(); trans++)
747  {
748  if (qAlpha(overlay.color(trans)) == 0)
749  {
750  kDebug(265) << "transparent pixel found at " << trans << "\n";
751  break;
752  }
753  }
754  if (trans == overlay.numColors())
755  {
756  kDebug(265) << "transparent pixel not found!\n";
757  return;
758  }
759 
760  // Merge color tables
761  int nc = src.numColors();
762  src.setNumColors(nc + overlay.numColors());
763  for (i=0; i<overlay.numColors(); ++i)
764  {
765  src.setColor(nc+i, overlay.color(i));
766  }
767 
768  // Overwrite nontransparent pixels.
769  unsigned char *oline, *sline;
770  for (i=0; i<src.height(); ++i)
771  {
772  oline = overlay.scanLine(i);
773  sline = src.scanLine(i);
774  for (j=0; j<src.width(); ++j)
775  {
776  if (oline[j] != trans)
777  sline[j] = oline[j]+nc;
778  }
779  }
780  }
781 
782  // Overlay at 32 bpp does use alpha blending
783 
784  if (src.depth() == 32)
785  {
786  QRgb* oline, *sline;
787  int r1, g1, b1, a1;
788  int r2, g2, b2, a2;
789 
790  for (i=0; i<src.height(); ++i)
791  {
792  oline = (QRgb*)overlay.scanLine(i);
793  sline = (QRgb*)src.scanLine(i);
794 
795  for (j=0; j<src.width(); ++j)
796  {
797  r1 = qRed(oline[j]);
798  g1 = qGreen(oline[j]);
799  b1 = qBlue(oline[j]);
800  a1 = qAlpha(oline[j]);
801 
802  r2 = qRed(sline[j]);
803  g2 = qGreen(sline[j]);
804  b2 = qBlue(sline[j]);
805  a2 = qAlpha(sline[j]);
806 
807  r2 = (a1 * r1 + (0xff - a1) * r2) >> 8;
808  g2 = (a1 * g1 + (0xff - a1) * g2) >> 8;
809  b2 = (a1 * b1 + (0xff - a1) * b2) >> 8;
810  a2 = qMax(a1, a2);
811 
812  sline[j] = qRgba(r2, g2, b2, a2);
813  }
814  }
815  }
816 
817  return;
818 }
819 
QColor
KSharedPtr< KSharedConfig >
KIconEffect::semiTransparent
static void semiTransparent(QImage &image)
Renders an image semi-transparent.
Definition: kiconeffect.cpp:527
kdebug.h
KIconEffect::LastEffect
Definition: kiconeffect.h:74
kglobalsettings.h
mask
#define mask
QString
kDebug
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KIconEffect::toMonochrome
static void toMonochrome(QImage &image, const QColor &black, const QColor &white, float value)
Produces a monochrome icon with a given foreground and background color.
Definition: kiconeffect.cpp:427
KIconEffect::NoEffect
Definition: kiconeffect.h:72
config
KSharedConfigPtr config()
KIconEffect::overlay
static void overlay(QImage &src, QImage &overlay)
Overlays an image with an other image.
Definition: kiconeffect.cpp:701
KIconEffect::DeSaturate
Definition: kiconeffect.h:72
KIconEffect::KIconEffect
KIconEffect()
Create a new KIconEffect.
Definition: kiconeffect.cpp:64
kglobal.h
KIconEffect::colorize
static void colorize(QImage &image, const QColor &col, float value)
Colorizes an image with a specific color.
Definition: kiconeffect.cpp:389
KIconEffect::deSaturate
static void deSaturate(QImage &image, float value)
Desaturates an image.
Definition: kiconeffect.cpp:487
KIconLoader::LastGroup
Last group.
Definition: kiconloader.h:145
KIconEffect::Colorize
Definition: kiconeffect.h:72
QStringList
KIconEffect::init
void init()
Rereads configuration.
Definition: kiconeffect.cpp:75
KIconEffect::toGamma
static void toGamma(QImage &image, float value)
Changes the gamma value of an image.
Definition: kiconeffect.cpp:508
ksharedconfig.h
KColorScheme::View
Views; for example, frames, input fields, etc.
Definition: kcolorscheme.h:87
kicontheme.h
KConfigGroup
KIconLoader::LastState
Last state (last constant)
Definition: kiconloader.h:175
KColorScheme
A set of methods used to work with colors.
Definition: kcolorscheme.h:71
KIconEffect::fingerprint
QString fingerprint(int group, int state) const
Returns a fingerprint for the effect by encoding the given group and state into a QString...
Definition: kiconeffect.cpp:162
painterSupportsAntialiasing
static bool painterSupportsAntialiasing()
Definition: kiconeffect.cpp:344
KIconEffect::hasEffect
bool hasEffect(int group, int state) const
Tests whether an effect has been configured for the given icon group.
Definition: kiconeffect.cpp:152
KIconEffect::toGray
static void toGray(QImage &image, float value)
Tints an image gray.
Definition: kiconeffect.cpp:359
KIconEffect::ToMonochrome
Definition: kiconeffect.h:73
KIconEffect::apply
QImage apply(const QImage &src, int group, int state) const
Applies an effect to an image.
Definition: kiconeffect.cpp:196
KIconEffect::ToGray
Definition: kiconeffect.h:72
KStandardShortcut::end
const KShortcut & end()
Goto end of the document.
Definition: kstandardshortcut.cpp:348
KConfigGroup::readEntry
T readEntry(const QString &key, const T &aDefault) const
kcolorscheme.h
kconfiggroup.h
KIconEffect::ToGamma
Definition: kiconeffect.h:72
KIconEffect::doublePixels
QImage doublePixels(const QImage &src) const
Returns an image twice as large, consisting of 2x2 pixels.
Definition: kiconeffect.cpp:652
kiconeffect.h
KIconEffect::~KIconEffect
~KIconEffect()
Definition: kiconeffect.cpp:70
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:49:14 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEUI

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

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal