KIconThemes

kiconeffect.cpp
1 /* vi: ts=8 sts=4 sw=4
2 
3  This file is part of the KDE project, module kdecore.
4  SPDX-FileCopyrightText: 2000 Geert Jansen <[email protected]>
5  SPDX-FileCopyrightText: 2007 Daniel M. Duley <[email protected]>
6 
7  with minor additions and based on ideas from
8  SPDX-FileContributor: Torsten Rahn <[email protected]>
9 
10  SPDX-License-Identifier: LGPL-2.0-only
11 */
12 
13 #include "kiconeffect.h"
14 
15 #include <qplatformdefs.h>
16 #include <math.h>
17 
18 #include <QSysInfo>
19 #include <QDebug>
20 
21 #include <KColorScheme>
22 #include <kicontheme.h>
23 #include <KConfigGroup>
24 
25 class KIconEffectPrivate
26 {
27 public:
28  // http://en.cppreference.com/w/cpp/language/zero_initialization
29  KIconEffectPrivate()
30  : effect{{}}
31  , value{{}}
32  , color{{}}
33  , trans{{}}
34  , key{{}}
35  , color2{{}}
36  {
37  }
38 
39 public:
46 };
47 
49  : d(new KIconEffectPrivate)
50 {
51  init();
52 }
53 
54 KIconEffect::~KIconEffect()
55 {
56  delete d;
57 }
58 
60 {
61  KSharedConfig::Ptr config = KSharedConfig::openConfig();
62 
63  int i, j, effect = -1;
64  //FIXME: this really should be using KIconLoader::metaObject() to guarantee synchronization
65  // performance wise it's also practically guaranteed to be faster
66  QStringList groups;
67  groups += QStringLiteral("Desktop");
68  groups += QStringLiteral("Toolbar");
69  groups += QStringLiteral("MainToolbar");
70  groups += QStringLiteral("Small");
71  groups += QStringLiteral("Panel");
72  groups += QStringLiteral("Dialog");
73 
74  QStringList states;
75  states += QStringLiteral("Default");
76  states += QStringLiteral("Active");
77  states += QStringLiteral("Disabled");
78 
80  QString _togray(QStringLiteral("togray"));
81  QString _colorize(QStringLiteral("colorize"));
82  QString _desaturate(QStringLiteral("desaturate"));
83  QString _togamma(QStringLiteral("togamma"));
84  QString _none(QStringLiteral("none"));
85  QString _tomonochrome(QStringLiteral("tomonochrome"));
86 
87  for (it = groups.constBegin(), i = 0; it != groups.constEnd(); ++it, ++i) {
88  // Default effects
89  d->effect[i][0] = NoEffect;
90  d->effect[i][1] = ((i == 0) || (i == 4)) ? ToGamma : NoEffect;
91  d->effect[i][2] = ToGray;
92 
93  d->trans[i][0] = false;
94  d->trans[i][1] = false;
95  d->trans[i][2] = true;
96  d->value[i][0] = 1.0;
97  d->value[i][1] = ((i == 0) || (i == 4)) ? 0.7 : 1.0;
98  d->value[i][2] = 1.0;
99  d->color[i][0] = QColor(144, 128, 248);
100  d->color[i][1] = QColor(169, 156, 255);
101  d->color[i][2] = QColor(34, 202, 0);
102  d->color2[i][0] = QColor(0, 0, 0);
103  d->color2[i][1] = QColor(0, 0, 0);
104  d->color2[i][2] = QColor(0, 0, 0);
105 
106  KConfigGroup cg(config, *it + QStringLiteral("Icons"));
107  for (it2 = states.constBegin(), j = 0; it2 != states.constEnd(); ++it2, ++j) {
108  QString tmp = cg.readEntry(*it2 + QStringLiteral("Effect"), QString());
109  if (tmp == _togray) {
110  effect = ToGray;
111  } else if (tmp == _colorize) {
112  effect = Colorize;
113  } else if (tmp == _desaturate) {
114  effect = DeSaturate;
115  } else if (tmp == _togamma) {
116  effect = ToGamma;
117  } else if (tmp == _tomonochrome) {
118  effect = ToMonochrome;
119  } else if (tmp == _none) {
120  effect = NoEffect;
121  } else {
122  continue;
123  }
124  if (effect != -1) {
125  d->effect[i][j] = effect;
126  }
127  d->value[i][j] = cg.readEntry(*it2 + QStringLiteral("Value"), 0.0);
128  d->color[i][j] = cg.readEntry(*it2 + QStringLiteral("Color"), QColor());
129  d->color2[i][j] = cg.readEntry(*it2 + QStringLiteral("Color2"), QColor());
130  d->trans[i][j] = cg.readEntry(*it2 + QStringLiteral("SemiTransparent"), false);
131 
132  }
133  }
134 }
135 
136 bool KIconEffect::hasEffect(int group, int state) const
137 {
138  if (group < 0 || group >= KIconLoader::LastGroup ||
139  state < 0 || state >= KIconLoader::LastState) {
140  return false;
141  }
142 
143  return d->effect[group][state] != NoEffect;
144 }
145 
146 QString KIconEffect::fingerprint(int group, int state) const
147 {
148  if (group < 0 || group >= KIconLoader::LastGroup ||
149  state < 0 || state >= KIconLoader::LastState) {
150  return QString();
151  }
152 
153  QString cached = d->key[group][state];
154  if (cached.isEmpty()) {
155  QString tmp;
156  cached = tmp.setNum(d->effect[group][state]);
157  cached += QLatin1Char(':');
158  cached += tmp.setNum(d->value[group][state]);
159  cached += QLatin1Char(':');
160  cached += d->trans[group][state] ? QLatin1String("trans")
161  : QLatin1String("notrans");
162  if (d->effect[group][state] == Colorize || d->effect[group][state] == ToMonochrome) {
163  cached += QLatin1Char(':');
164  cached += d->color[group][state].name();
165  }
166  if (d->effect[group][state] == ToMonochrome) {
167  cached += QLatin1Char(':');
168  cached += d->color2[group][state].name();
169  }
170 
171  d->key[group][state] = cached;
172  }
173 
174  return cached;
175 }
176 
177 QImage KIconEffect::apply(const QImage &image, int group, int state) const
178 {
179  if (state >= KIconLoader::LastState) {
180  qWarning() << "Illegal icon state: " << state;
181  return image;
182  }
183  if (group >= KIconLoader::LastGroup) {
184  qWarning() << "Illegal icon group: " << group;
185  return image;
186  }
187  return apply(image, d->effect[group][state], d->value[group][state],
188  d->color[group][state], d->color2[group][state], d->trans[group][state]);
189 }
190 
191 QImage KIconEffect::apply(const QImage &image, int effect, float value,
192  const QColor &col, bool trans) const
193 {
194  return apply(image, effect, value, col,
195  KColorScheme(QPalette::Active, KColorScheme::View).background().color(), trans);
196 }
197 
198 QImage KIconEffect::apply(const QImage &img, int effect, float value,
199  const QColor &col, const QColor &col2, bool trans) const
200 {
201  QImage image = img;
202  if (effect >= LastEffect) {
203  qWarning() << "Illegal icon effect: " << effect;
204  return image;
205  }
206  if (value > 1.0) {
207  value = 1.0;
208  } else if (value < 0.0) {
209  value = 0.0;
210  }
211  switch (effect) {
212  case ToGray:
213  toGray(image, value);
214  break;
215  case DeSaturate:
216  deSaturate(image, value);
217  break;
218  case Colorize:
219  colorize(image, col, value);
220  break;
221  case ToGamma:
222  toGamma(image, value);
223  break;
224  case ToMonochrome:
225  toMonochrome(image, col, col2, value);
226  break;
227  }
228  if (trans == true) {
229  semiTransparent(image);
230  }
231  return image;
232 }
233 
234 QPixmap KIconEffect::apply(const QPixmap &pixmap, int group, int state) const
235 {
236  if (state >= KIconLoader::LastState) {
237  qWarning() << "Illegal icon state: " << state;
238  return pixmap;
239  }
240  if (group >= KIconLoader::LastGroup) {
241  qWarning() << "Illegal icon group: " << group;
242  return pixmap;
243  }
244  return apply(pixmap, d->effect[group][state], d->value[group][state],
245  d->color[group][state], d->color2[group][state], d->trans[group][state]);
246 }
247 
248 QPixmap KIconEffect::apply(const QPixmap &pixmap, int effect, float value,
249  const QColor &col, bool trans) const
250 {
251  return apply(pixmap, effect, value, col,
252  KColorScheme(QPalette::Active, KColorScheme::View).background().color(), trans);
253 }
254 
255 QPixmap KIconEffect::apply(const QPixmap &pixmap, int effect, float value,
256  const QColor &col, const QColor &col2, bool trans) const
257 {
258  QPixmap result;
259 
260  if (effect >= LastEffect) {
261  qWarning() << "Illegal icon effect: " << effect;
262  return result;
263  }
264 
265  if ((trans == true) && (effect == NoEffect)) {
266  result = pixmap;
267  semiTransparent(result);
268  } else if (effect != NoEffect) {
269  QImage tmpImg = pixmap.toImage();
270  tmpImg = apply(tmpImg, effect, value, col, col2, trans);
271  result = QPixmap::fromImage(tmpImg);
272  } else {
273  result = pixmap;
274  }
275 
276  return result;
277 }
278 
279 struct KIEImgEdit {
280  QImage &img;
281  QVector <QRgb> colors;
282  unsigned int *data;
283  unsigned int pixels;
284 
285  KIEImgEdit(QImage &_img): img(_img)
286  {
287  if (img.depth() > 8) {
288  //Code using data and pixels assumes that the pixels are stored
289  //in 32bit values and that the image is not premultiplied
290  if ((img.format() != QImage::Format_ARGB32) &&
291  (img.format() != QImage::Format_RGB32)) {
293  }
294  data = (unsigned int *)img.bits();
295  pixels = img.width() * img.height();
296  } else {
297  pixels = img.colorCount();
298  colors = img.colorTable();
299  data = (unsigned int *)colors.data();
300  }
301  }
302 
303  ~KIEImgEdit()
304  {
305  if (img.depth() <= 8) {
306  img.setColorTable(colors);
307  }
308  }
309 
310  KIEImgEdit(const KIEImgEdit &) = delete;
311  KIEImgEdit &operator=(const KIEImgEdit &) = delete;
312 };
313 
314 // Taken from KImageEffect. We don't want to link kdecore to kdeui! As long
315 // as this code is not too big, it doesn't seem much of a problem to me.
316 
317 void KIconEffect::toGray(QImage &img, float value)
318 {
319  if (value == 0.0) {
320  return;
321  }
322 
323  KIEImgEdit ii(img);
324  QRgb *data = ii.data;
325  QRgb *end = data + ii.pixels;
326 
327  unsigned char gray;
328  if (value == 1.0) {
329  while (data != end) {
330  gray = qGray(*data);
331  *data = qRgba(gray, gray, gray, qAlpha(*data));
332  ++data;
333  }
334  } else {
335  unsigned char val = (unsigned char)(255.0 * value);
336  while (data != end) {
337  gray = qGray(*data);
338  *data = qRgba((val * gray + (0xFF - val) * qRed(*data)) >> 8,
339  (val * gray + (0xFF - val) * qGreen(*data)) >> 8,
340  (val * gray + (0xFF - val) * qBlue(*data)) >> 8,
341  qAlpha(*data));
342  ++data;
343  }
344  }
345 }
346 
347 void KIconEffect::colorize(QImage &img, const QColor &col, float value)
348 {
349  if (value == 0.0) {
350  return;
351  }
352 
353  KIEImgEdit ii(img);
354  QRgb *data = ii.data;
355  QRgb *end = data + ii.pixels;
356 
357  float rcol = col.red(), gcol = col.green(), bcol = col.blue();
358  unsigned char red, green, blue, gray;
359  unsigned char val = (unsigned char)(255.0 * value);
360  while (data != end) {
361  gray = qGray(*data);
362  if (gray < 128) {
363  red = static_cast<unsigned char>(rcol / 128 * gray);
364  green = static_cast<unsigned char>(gcol / 128 * gray);
365  blue = static_cast<unsigned char>(bcol / 128 * gray);
366  } else if (gray > 128) {
367  red = static_cast<unsigned char>((gray - 128) * (2 - rcol / 128) + rcol - 1);
368  green = static_cast<unsigned char>((gray - 128) * (2 - gcol / 128) + gcol - 1);
369  blue = static_cast<unsigned char>((gray - 128) * (2 - bcol / 128) + bcol - 1);
370  } else {
371  red = static_cast<unsigned char>(rcol);
372  green = static_cast<unsigned char>(gcol);
373  blue = static_cast<unsigned char>(bcol);
374  }
375 
376  *data = qRgba((val * red + (0xFF - val) * qRed(*data)) >> 8,
377  (val * green + (0xFF - val) * qGreen(*data)) >> 8,
378  (val * blue + (0xFF - val) * qBlue(*data)) >> 8,
379  qAlpha(*data));
380  ++data;
381  }
382 }
383 
384 void KIconEffect::toMonochrome(QImage &img, const QColor &black,
385  const QColor &white, float value)
386 {
387  if (value == 0.0) {
388  return;
389  }
390 
391  KIEImgEdit ii(img);
392  QRgb *data = ii.data;
393  QRgb *end = data + ii.pixels;
394 
395  // Step 1: determine the average brightness
396  double values = 0.0, sum = 0.0;
397  bool grayscale = true;
398  while (data != end) {
399  sum += qGray(*data) * qAlpha(*data) + 255 * (255 - qAlpha(*data));
400  values += 255;
401  if ((qRed(*data) != qGreen(*data)) || (qGreen(*data) != qBlue(*data))) {
402  grayscale = false;
403  }
404  ++data;
405  }
406  double medium = sum / values;
407 
408  // Step 2: Modify the image
409  unsigned char val = (unsigned char)(255.0 * value);
410  int rw = white.red(), gw = white.green(), bw = white.blue();
411  int rb = black.red(), gb = black.green(), bb = black.blue();
412  data = ii.data;
413 
414  if (grayscale) {
415  while (data != end) {
416  if (qRed(*data) <= medium)
417  *data = qRgba((val * rb + (0xFF - val) * qRed(*data)) >> 8,
418  (val * gb + (0xFF - val) * qGreen(*data)) >> 8,
419  (val * bb + (0xFF - val) * qBlue(*data)) >> 8,
420  qAlpha(*data));
421  else
422  *data = qRgba((val * rw + (0xFF - val) * qRed(*data)) >> 8,
423  (val * gw + (0xFF - val) * qGreen(*data)) >> 8,
424  (val * bw + (0xFF - val) * qBlue(*data)) >> 8,
425  qAlpha(*data));
426  ++data;
427  }
428  } else {
429  while (data != end) {
430  if (qGray(*data) <= medium)
431  *data = qRgba((val * rb + (0xFF - val) * qRed(*data)) >> 8,
432  (val * gb + (0xFF - val) * qGreen(*data)) >> 8,
433  (val * bb + (0xFF - val) * qBlue(*data)) >> 8,
434  qAlpha(*data));
435  else
436  *data = qRgba((val * rw + (0xFF - val) * qRed(*data)) >> 8,
437  (val * gw + (0xFF - val) * qGreen(*data)) >> 8,
438  (val * bw + (0xFF - val) * qBlue(*data)) >> 8,
439  qAlpha(*data));
440  ++data;
441  }
442  }
443 }
444 
445 void KIconEffect::deSaturate(QImage &img, float value)
446 {
447  if (value == 0.0) {
448  return;
449  }
450 
451  KIEImgEdit ii(img);
452  QRgb *data = ii.data;
453  QRgb *end = data + ii.pixels;
454 
455  QColor color;
456  int h, s, v;
457  while (data != end) {
458  color.setRgb(*data);
459  color.getHsv(&h, &s, &v);
460  color.setHsv(h, (int)(s * (1.0 - value) + 0.5), v);
461  *data = qRgba(color.red(), color.green(), color.blue(),
462  qAlpha(*data));
463  ++data;
464  }
465 }
466 
467 void KIconEffect::toGamma(QImage &img, float value)
468 {
469  KIEImgEdit ii(img);
470  QRgb *data = ii.data;
471  QRgb *end = data + ii.pixels;
472 
473  float gamma = 1 / (2 * value + 0.5);
474  while (data != end) {
475  *data = qRgba(static_cast<unsigned char>
476  (pow(static_cast<float>(qRed(*data)) / 255, gamma) * 255),
477  static_cast<unsigned char>
478  (pow(static_cast<float>(qGreen(*data)) / 255, gamma) * 255),
479  static_cast<unsigned char>
480  (pow(static_cast<float>(qBlue(*data)) / 255, gamma) * 255),
481  qAlpha(*data));
482  ++data;
483  }
484 }
485 
487 {
488  if (img.depth() == 32) {
491  }
492  int width = img.width();
493  int height = img.height();
494 
495  unsigned char *line;
496  for (int y = 0; y < height; ++y) {
498  line = img.scanLine(y);
499  } else {
500  line = img.scanLine(y) + 3;
501  }
502  for (int x = 0; x < width; ++x) {
503  *line >>= 1;
504  line += 4;
505  }
506  }
507  } else if (img.depth() == 8) {
508  // not running on 8 bit, we can safely install a new colorTable
509  QVector<QRgb> colorTable = img.colorTable();
510  for (int i = 0; i < colorTable.size(); ++i) {
511  colorTable[i] = (colorTable[i] & 0x00ffffff) | ((colorTable[i] & 0xfe000000) >> 1);
512  }
513  img.setColorTable(colorTable);
514  } else {
515  // Insert transparent pixel into the clut.
516  int transColor = -1;
517 
518  // search for a color that is already transparent
519  for (int x = 0; x < img.colorCount(); ++x) {
520  // try to find already transparent pixel
521  if (qAlpha(img.color(x)) < 127) {
522  transColor = x;
523  break;
524  }
525  }
526 
527  // FIXME: image must have transparency
528  if (transColor < 0 || transColor >= img.colorCount()) {
529  return;
530  }
531 
532  img.setColor(transColor, 0);
533  unsigned char *line;
534  if (img.depth() == 8) {
535  for (int y = 0; y < img.height(); ++y) {
536  line = img.scanLine(y);
537  for (int x = (y % 2); x < img.width(); x += 2) {
538  line[x] = transColor;
539  }
540  }
541  } else {
542  const bool setOn = (transColor != 0);
543  if (img.format() == QImage::Format_MonoLSB) {
544  for (int y = 0; y < img.height(); ++y) {
545  line = img.scanLine(y);
546  for (int x = (y % 2); x < img.width(); x += 2) {
547  if (!setOn) {
548  *(line + (x >> 3)) &= ~(1 << (x & 7));
549  } else {
550  *(line + (x >> 3)) |= (1 << (x & 7));
551  }
552  }
553  }
554  } else {
555  for (int y = 0; y < img.height(); ++y) {
556  line = img.scanLine(y);
557  for (int x = (y % 2); x < img.width(); x += 2) {
558  if (!setOn) {
559  *(line + (x >> 3)) &= ~(1 << (7 - (x & 7)));
560  } else {
561  *(line + (x >> 3)) |= (1 << (7 - (x & 7)));
562  }
563  }
564  }
565  }
566  }
567  }
568 }
569 
571 {
572  QImage img = pix.toImage();
573  semiTransparent(img);
574  pix = QPixmap::fromImage(img);
575 }
576 
578 {
579  int w = src.width();
580  int h = src.height();
581 
582  QImage dst(w * 2, h * 2, src.format());
583 
584  if (src.depth() == 1) {
585  qWarning() << "image depth 1 not supported";
586  return QImage();
587  }
588 
589  int x, y;
590  if (src.depth() == 32) {
591  QRgb *l1, *l2;
592  for (y = 0; y < h; ++y) {
593  l1 = (QRgb *)src.scanLine(y);
594  l2 = (QRgb *)dst.scanLine(y * 2);
595  for (x = 0; x < w; ++x) {
596  l2[x * 2] = l2[x * 2 + 1] = l1[x];
597  }
598  memcpy(dst.scanLine(y * 2 + 1), l2, dst.bytesPerLine());
599  }
600  } else {
601  for (x = 0; x < src.colorCount(); ++x) {
602  dst.setColor(x, src.color(x));
603  }
604 
605  const unsigned char *l1;
606  unsigned char *l2;
607  for (y = 0; y < h; ++y) {
608  l1 = src.scanLine(y);
609  l2 = dst.scanLine(y * 2);
610  for (x = 0; x < w; ++x) {
611  l2[x * 2] = l1[x];
612  l2[x * 2 + 1] = l1[x];
613  }
614  memcpy(dst.scanLine(y * 2 + 1), l2, dst.bytesPerLine());
615  }
616  }
617  return dst;
618 }
619 
621 {
622  if (src.depth() != overlay.depth()) {
623  qWarning() << "Image depth src (" << src.depth() << ") != overlay " << "(" << overlay.depth() << ")!";
624  return;
625  }
626  if (src.size() != overlay.size()) {
627  qWarning() << "Image size src != overlay";
628  return;
629  }
632  }
633 
634  if (overlay.format() == QImage::Format_RGB32) {
635  qWarning() << "Overlay doesn't have alpha buffer!";
636  return;
637  } else if (overlay.format() == QImage::Format_ARGB32_Premultiplied) {
638  overlay = overlay.convertToFormat(QImage::Format_ARGB32);
639  }
640 
641  int i, j;
642 
643  // We don't do 1 bpp
644 
645  if (src.depth() == 1) {
646  qWarning() << "1bpp not supported!";
647  return;
648  }
649 
650  // Overlay at 8 bpp doesn't use alpha blending
651 
652  if (src.depth() == 8) {
653  if (src.colorCount() + overlay.colorCount() > 255) {
654  qWarning() << "Too many colors in src + overlay!";
655  return;
656  }
657 
658  // Find transparent pixel in overlay
659  int trans;
660  for (trans = 0; trans < overlay.colorCount(); trans++) {
661  if (qAlpha(overlay.color(trans)) == 0) {
662  qWarning() << "transparent pixel found at " << trans;
663  break;
664  }
665  }
666  if (trans == overlay.colorCount()) {
667  qWarning() << "transparent pixel not found!";
668  return;
669  }
670 
671  // Merge color tables
672  int nc = src.colorCount();
673  src.setColorCount(nc + overlay.colorCount());
674  for (i = 0; i < overlay.colorCount(); ++i) {
675  src.setColor(nc + i, overlay.color(i));
676  }
677 
678  // Overwrite nontransparent pixels.
679  unsigned char *oline, *sline;
680  for (i = 0; i < src.height(); ++i) {
681  oline = overlay.scanLine(i);
682  sline = src.scanLine(i);
683  for (j = 0; j < src.width(); ++j) {
684  if (oline[j] != trans) {
685  sline[j] = oline[j] + nc;
686  }
687  }
688  }
689  }
690 
691  // Overlay at 32 bpp does use alpha blending
692 
693  if (src.depth() == 32) {
694  QRgb *oline, *sline;
695  int r1, g1, b1, a1;
696  int r2, g2, b2, a2;
697 
698  for (i = 0; i < src.height(); ++i) {
699  oline = (QRgb *)overlay.scanLine(i);
700  sline = (QRgb *)src.scanLine(i);
701 
702  for (j = 0; j < src.width(); ++j) {
703  r1 = qRed(oline[j]);
704  g1 = qGreen(oline[j]);
705  b1 = qBlue(oline[j]);
706  a1 = qAlpha(oline[j]);
707 
708  r2 = qRed(sline[j]);
709  g2 = qGreen(sline[j]);
710  b2 = qBlue(sline[j]);
711  a2 = qAlpha(sline[j]);
712 
713  r2 = (a1 * r1 + (0xff - a1) * r2) >> 8;
714  g2 = (a1 * g1 + (0xff - a1) * g2) >> 8;
715  b2 = (a1 * b1 + (0xff - a1) * b2) >> 8;
716  a2 = qMax(a1, a2);
717 
718  sline[j] = qRgba(r2, g2, b2, a2);
719  }
720  }
721  }
722 }
723 
uchar * scanLine(int i)
QImage convertToFormat(QImage::Format format, Qt::ImageConversionFlags flags) const &const
static void semiTransparent(QImage &image)
Renders an image semi-transparent.
int depth() const const
int colorCount() const const
void setColorCount(int colorCount)
QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags)
QRgb color(int i) const const
void setRgb(int r, int g, int b, int a)
static void toMonochrome(QImage &image, const QColor &black, const QColor &white, float value)
Produces a monochrome icon with a given foreground and background color.
void getHsv(int *h, int *s, int *v, int *a) const const
void setColor(int index, QRgb colorValue)
static void overlay(QImage &src, QImage &overlay)
Overlays an image with an other image.
QVector< V > values(const QMultiHash< K, V > &c)
T * data()
KIconEffect()
Create a new KIconEffect.
Definition: kiconeffect.cpp:48
static void colorize(QImage &image, const QColor &col, float value)
Colorizes an image with a specific color.
static void deSaturate(QImage &image, float value)
Desaturates an image.
int red() const const
int width() const const
bool isEmpty() const const
void init()
Rereads configuration.
Definition: kiconeffect.cpp:59
static void toGamma(QImage &image, float value)
Changes the gamma value of an image.
int green() const const
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
int blue() const const
Last state (last constant)
Definition: kiconloader.h:168
QString & setNum(short n, int base)
QString fingerprint(int group, int state) const
Returns a fingerprint for the effect by encoding the given group and state into a QString...
bool hasEffect(int group, int state) const
Tests whether an effect has been configured for the given icon group.
typedef ConstIterator
void setColorTable(const QVector< QRgb > colors)
static void toGray(QImage &image, float value)
Tints an image gray.
QSize size() const const
void setHsv(int h, int s, int v, int a)
uchar * bits()
int height() const const
QImage apply(const QImage &src, int group, int state) const
Applies an effect to an image.
QImage toImage() const const
QList::const_iterator constEnd() const const
QList::const_iterator constBegin() const const
int size() const const
QImage::Format format() const const
T readEntry(const QString &key, const T &aDefault) const
QImage doublePixels(const QImage &src) const
Returns an image twice as large, consisting of 2x2 pixels.
QVector< QRgb > colorTable() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sat Nov 21 2020 22:42:01 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.