OpenCoverage

qpixmapfilter.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/widgets/effects/qpixmapfilter.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtWidgets module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include <qglobal.h>-
41-
42#include <QDebug>-
43-
44#include "qpainter.h"-
45#include "qpixmap.h"-
46#include "qpixmapfilter_p.h"-
47#include "qvarlengtharray.h"-
48-
49#include "private/qguiapplication_p.h"-
50#include "private/qpaintengineex_p.h"-
51#include "private/qpaintengine_raster_p.h"-
52#include "qmath.h"-
53#include "private/qmath_p.h"-
54#include "private/qmemrotate_p.h"-
55#include "private/qdrawhelper_p.h"-
56-
57#ifndef QT_NO_GRAPHICSEFFECT-
58QT_BEGIN_NAMESPACE-
59-
60class QPixmapFilterPrivate : public QObjectPrivate-
61{-
62 Q_DECLARE_PUBLIC(QPixmapFilter)-
63public:-
64 QPixmapFilter::FilterType type;-
65};-
66-
67/*!-
68 \class QPixmapFilter-
69 \since 4.5-
70 \ingroup painting-
71-
72 \brief The QPixmapFilter class provides the basic functionality for-
73 pixmap filter classes. Pixmap filter can be for example colorize or blur.-
74-
75 QPixmapFilter is the base class for every pixmap filter. QPixmapFilter is-
76 an abstract class and cannot itself be instantiated. It provides a standard-
77 interface for filter processing.-
78-
79 \internal-
80*/-
81-
82/*!-
83 \enum QPixmapFilter::FilterType-
84-
85 \internal-
86-
87 This enum describes the types of filter that can be applied to pixmaps.-
88-
89 \value ConvolutionFilter A filter that is used to calculate the convolution-
90 of the image with a kernel. See-
91 QPixmapConvolutionFilter for more information.-
92 \value ColorizeFilter A filter that is used to change the overall color-
93 of an image. See QPixmapColorizeFilter for more-
94 information.-
95 \value DropShadowFilter A filter that is used to add a drop shadow to an-
96 image. See QPixmapDropShadowFilter for more-
97 information.-
98 \value BlurFilter A filter that is used to blur an image using-
99 a simple blur radius. See QPixmapBlurFilter-
100 for more information.-
101-
102 \value UserFilter The first filter type that can be used for-
103 application-specific purposes.-
104*/-
105-
106-
107/*!-
108 Constructs a default QPixmapFilter with the given \a type.-
109-
110 This constructor should be used when subclassing QPixmapFilter to-
111 create custom user filters.-
112-
113 \internal-
114*/-
115QPixmapFilter::QPixmapFilter(FilterType type, QObject *parent)-
116 : QObject(*new QPixmapFilterPrivate, parent)-
117{-
118 d_func()->type = type;-
119}
never executed: end of block
0
120-
121-
122-
123/*!-
124 \internal-
125*/-
126QPixmapFilter::QPixmapFilter(QPixmapFilterPrivate&d, QPixmapFilter::FilterType type, QObject *parent)-
127 : QObject(d, parent)-
128{-
129 d_func()->type = type;-
130}
never executed: end of block
0
131-
132-
133/*!-
134 Destroys the pixmap filter.-
135-
136 \internal-
137*/-
138QPixmapFilter::~QPixmapFilter()-
139{-
140}-
141-
142/*!-
143 Returns the type of the filter. All standard pixmap filter classes-
144 are associated with a unique value.-
145-
146 \internal-
147*/-
148QPixmapFilter::FilterType QPixmapFilter::type() const-
149{-
150 Q_D(const QPixmapFilter);-
151 return d->type;
never executed: return d->type;
0
152}-
153-
154/*!-
155 Returns the bounding rectangle that is affected by the pixmap-
156 filter if the filter is applied to the specified \a rect.-
157-
158 \internal-
159*/-
160QRectF QPixmapFilter::boundingRectFor(const QRectF &rect) const-
161{-
162 return rect;
never executed: return rect;
0
163}-
164-
165/*!-
166 \fn void QPixmapFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF& srcRect) const-
167-
168 Uses \a painter to draw filtered result of \a src at the point-
169 specified by \a p. If \a srcRect is specified the it will-
170 be used as a source rectangle to only draw a part of the source.-
171-
172 draw() will affect the area which boundingRectFor() returns.-
173-
174 \internal-
175*/-
176-
177/*!-
178 \class QPixmapConvolutionFilter-
179 \since 4.5-
180 \ingroup painting-
181-
182 \brief The QPixmapConvolutionFilter class provides convolution-
183 filtering for pixmaps.-
184-
185 QPixmapConvolutionFilter implements a convolution pixmap filter,-
186 which is applied when \l{QPixmapFilter::}{draw()} is called. A-
187 convolution filter lets you distort an image by setting the values-
188 of a matrix of qreal values called its-
189 \l{setConvolutionKernel()}{kernel}. The matrix's values are-
190 usually between -1.0 and 1.0.-
191-
192 \omit-
193 In convolution filtering, the pixel value is calculated from the-
194 neighboring pixels based on the weighting convolution kernel.-
195 This needs explaining to be useful.-
196 \endomit-
197-
198 Example:-
199 \snippet code/src_gui_image_qpixmapfilter.cpp 1-
200-
201 \sa {Pixmap Filters Example}, QPixmapColorizeFilter, QPixmapDropShadowFilter-
202-
203-
204 \internal-
205*/-
206-
207class QPixmapConvolutionFilterPrivate : public QPixmapFilterPrivate-
208{-
209public:-
210 QPixmapConvolutionFilterPrivate(): convolutionKernel(0), kernelWidth(0), kernelHeight(0), convoluteAlpha(false) {}
never executed: end of block
0
211 ~QPixmapConvolutionFilterPrivate() {-
212 delete[] convolutionKernel;-
213 }
never executed: end of block
0
214-
215 qreal *convolutionKernel;-
216 int kernelWidth;-
217 int kernelHeight;-
218 bool convoluteAlpha;-
219};-
220-
221-
222/*!-
223 Constructs a pixmap convolution filter.-
224-
225 By default there is no convolution kernel.-
226-
227 \internal-
228*/-
229QPixmapConvolutionFilter::QPixmapConvolutionFilter(QObject *parent)-
230 : QPixmapFilter(*new QPixmapConvolutionFilterPrivate, ConvolutionFilter, parent)-
231{-
232 Q_D(QPixmapConvolutionFilter);-
233 d->convoluteAlpha = true;-
234}
never executed: end of block
0
235-
236/*!-
237 Destructor of pixmap convolution filter.-
238-
239 \internal-
240*/-
241QPixmapConvolutionFilter::~QPixmapConvolutionFilter()-
242{-
243}-
244-
245/*!-
246 Sets convolution kernel with the given number of \a rows and \a columns.-
247 Values from \a kernel are copied to internal data structure.-
248-
249 To preserve the intensity of the pixmap, the sum of all the-
250 values in the convolution kernel should add up to 1.0. A sum-
251 greater than 1.0 produces a lighter result and a sum less than 1.0-
252 produces a darker and transparent result.-
253-
254 \internal-
255*/-
256void QPixmapConvolutionFilter::setConvolutionKernel(const qreal *kernel, int rows, int columns)-
257{-
258 Q_D(QPixmapConvolutionFilter);-
259 delete [] d->convolutionKernel;-
260 d->convolutionKernel = new qreal[rows * columns];-
261 memcpy(d->convolutionKernel, kernel, sizeof(qreal) * rows * columns);-
262 d->kernelWidth = columns;-
263 d->kernelHeight = rows;-
264}
never executed: end of block
0
265-
266/*!-
267 Gets the convolution kernel data.-
268-
269 \internal-
270*/-
271const qreal *QPixmapConvolutionFilter::convolutionKernel() const-
272{-
273 Q_D(const QPixmapConvolutionFilter);-
274 return d->convolutionKernel;
never executed: return d->convolutionKernel;
0
275}-
276-
277/*!-
278 Gets the number of rows in the convolution kernel.-
279-
280 \internal-
281*/-
282int QPixmapConvolutionFilter::rows() const-
283{-
284 Q_D(const QPixmapConvolutionFilter);-
285 return d->kernelHeight;
never executed: return d->kernelHeight;
0
286}-
287-
288/*!-
289 Gets the number of columns in the convolution kernel.-
290-
291 \internal-
292*/-
293int QPixmapConvolutionFilter::columns() const-
294{-
295 Q_D(const QPixmapConvolutionFilter);-
296 return d->kernelWidth;
never executed: return d->kernelWidth;
0
297}-
298-
299-
300/*!-
301 \internal-
302*/-
303QRectF QPixmapConvolutionFilter::boundingRectFor(const QRectF &rect) const-
304{-
305 Q_D(const QPixmapConvolutionFilter);-
306 return rect.adjusted(-d->kernelWidth / 2, -d->kernelHeight / 2, (d->kernelWidth - 1) / 2, (d->kernelHeight - 1) / 2);
never executed: return rect.adjusted(-d->kernelWidth / 2, -d->kernelHeight / 2, (d->kernelWidth - 1) / 2, (d->kernelHeight - 1) / 2);
0
307}-
308-
309// Convolutes the image-
310static void convolute(-
311 QImage *destImage,-
312 const QPointF &pos,-
313 const QImage &srcImage,-
314 const QRectF &srcRect,-
315 QPainter::CompositionMode mode,-
316 qreal *kernel,-
317 int kernelWidth,-
318 int kernelHeight )-
319{-
320 const QImage processImage = (srcImage.format() != QImage::Format_ARGB32_Premultiplied ) ? srcImage.convertToFormat(QImage::Format_ARGB32_Premultiplied) : srcImage;
(srcImage.form...remultiplied )Description
TRUEnever evaluated
FALSEnever evaluated
0
321 // TODO: support also other formats directly without copying-
322-
323 int *fixedKernel = new int[kernelWidth*kernelHeight];-
324 for(int i = 0; i < kernelWidth*kernelHeight; i++)
i < kernelWidth*kernelHeightDescription
TRUEnever evaluated
FALSEnever evaluated
0
325 {-
326 fixedKernel[i] = (int)(65536 * kernel[i]);-
327 }
never executed: end of block
0
328 QRectF trect = srcRect.isNull() ? processImage.rect() : srcRect;
srcRect.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
329 trect.moveTo(pos);-
330 QRectF bounded = trect.adjusted(-kernelWidth / 2, -kernelHeight / 2, (kernelWidth - 1) / 2, (kernelHeight - 1) / 2);-
331 QRect rect = bounded.toAlignedRect();-
332 QRect targetRect = rect.intersected(destImage->rect());-
333-
334 QRectF srect = srcRect.isNull() ? processImage.rect() : srcRect;
srcRect.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
335 QRectF sbounded = srect.adjusted(-kernelWidth / 2, -kernelHeight / 2, (kernelWidth - 1) / 2, (kernelHeight - 1) / 2);-
336 QPoint srcStartPoint = sbounded.toAlignedRect().topLeft()+(targetRect.topLeft()-rect.topLeft());-
337-
338 const uint *sourceStart = (const uint*)processImage.scanLine(0);-
339 uint *outputStart = (uint*)destImage->scanLine(0);-
340-
341 int yk = srcStartPoint.y();-
342 for (int y = targetRect.top(); y <= targetRect.bottom(); y++) {
y <= targetRect.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
343 uint* output = outputStart + (destImage->bytesPerLine()/sizeof(uint))*y+targetRect.left();-
344 int xk = srcStartPoint.x();-
345 for(int x = targetRect.left(); x <= targetRect.right(); x++) {
x <= targetRect.right()Description
TRUEnever evaluated
FALSEnever evaluated
0
346 int r = 0;-
347 int g = 0;-
348 int b = 0;-
349 int a = 0;-
350-
351 // some out of bounds pre-checking to avoid inner-loop ifs-
352 int kernely = -kernelHeight/2;-
353 int starty = 0;-
354 int endy = kernelHeight;-
355 if(yk+kernely+endy >= srcImage.height())
yk+kernely+end...Image.height()Description
TRUEnever evaluated
FALSEnever evaluated
0
356 endy = kernelHeight-((yk+kernely+endy)-srcImage.height())-1;
never executed: endy = kernelHeight-((yk+kernely+endy)-srcImage.height())-1;
0
357 if(yk+kernely < 0)
yk+kernely < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
358 starty = -(yk+kernely);
never executed: starty = -(yk+kernely);
0
359-
360 int kernelx = -kernelWidth/2;-
361 int startx = 0;-
362 int endx = kernelWidth;-
363 if(xk+kernelx+endx >= srcImage.width())
xk+kernelx+end...cImage.width()Description
TRUEnever evaluated
FALSEnever evaluated
0
364 endx = kernelWidth-((xk+kernelx+endx)-srcImage.width())-1;
never executed: endx = kernelWidth-((xk+kernelx+endx)-srcImage.width())-1;
0
365 if(xk+kernelx < 0)
xk+kernelx < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
366 startx = -(xk+kernelx);
never executed: startx = -(xk+kernelx);
0
367-
368 for (int ys = starty; ys < endy; ys ++) {
ys < endyDescription
TRUEnever evaluated
FALSEnever evaluated
0
369 const uint *pix = sourceStart + (processImage.bytesPerLine()/sizeof(uint))*(yk+kernely+ys) + ((xk+kernelx+startx));-
370 const uint *endPix = pix+endx-startx;-
371 int kernelPos = ys*kernelWidth+startx;-
372 while (pix < endPix) {
pix < endPixDescription
TRUEnever evaluated
FALSEnever evaluated
0
373 int factor = fixedKernel[kernelPos++];-
374 a += (((*pix) & 0xff000000)>>24) * factor;-
375 r += (((*pix) & 0x00ff0000)>>16) * factor;-
376 g += (((*pix) & 0x0000ff00)>>8 ) * factor;-
377 b += (((*pix) & 0x000000ff) ) * factor;-
378 pix++;-
379 }
never executed: end of block
0
380 }
never executed: end of block
0
381-
382 r = qBound((int)0, r >> 16, (int)255);-
383 g = qBound((int)0, g >> 16, (int)255);-
384 b = qBound((int)0, b >> 16, (int)255);-
385 a = qBound((int)0, a >> 16, (int)255);-
386 // composition mode checking could be moved outside of loop-
387 if(mode == QPainter::CompositionMode_Source) {
mode == QPaint...ionMode_SourceDescription
TRUEnever evaluated
FALSEnever evaluated
0
388 uint color = (a<<24)+(r<<16)+(g<<8)+b;-
389 *output++ = color;-
390 } else {
never executed: end of block
0
391 uint current = *output;-
392 uchar ca = (current&0xff000000)>>24;-
393 uchar cr = (current&0x00ff0000)>>16;-
394 uchar cg = (current&0x0000ff00)>>8;-
395 uchar cb = (current&0x000000ff);-
396 uint color =-
397 (((ca*(255-a) >> 8)+a) << 24)+-
398 (((cr*(255-a) >> 8)+r) << 16)+-
399 (((cg*(255-a) >> 8)+g) << 8)+-
400 (((cb*(255-a) >> 8)+b));-
401 *output++ = color;;-
402 }
never executed: end of block
0
403 xk++;-
404 }
never executed: end of block
0
405 yk++;-
406 }
never executed: end of block
0
407 delete[] fixedKernel;-
408}
never executed: end of block
0
409-
410/*!-
411 \internal-
412*/-
413void QPixmapConvolutionFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF& srcRect) const-
414{-
415 Q_D(const QPixmapConvolutionFilter);-
416 if (!painter->isActive())
!painter->isActive()Description
TRUEnever evaluated
FALSEnever evaluated
0
417 return;
never executed: return;
0
418-
419 if(d->kernelWidth<=0 || d->kernelHeight <= 0)
d->kernelWidth<=0Description
TRUEnever evaluated
FALSEnever evaluated
d->kernelHeight <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
420 return;
never executed: return;
0
421-
422 if (src.isNull())
src.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
423 return;
never executed: return;
0
424-
425 // raster implementation-
426-
427 QImage *target = 0;-
428 if (painter->paintEngine()->paintDevice()->devType() == QInternal::Image) {
painter->paint...nternal::ImageDescription
TRUEnever evaluated
FALSEnever evaluated
0
429 target = static_cast<QImage *>(painter->paintEngine()->paintDevice());-
430-
431 QTransform mat = painter->combinedTransform();-
432-
433 if (mat.type() > QTransform::TxTranslate) {
mat.type() > Q...m::TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
0
434 // Disabled because of transformation...-
435 target = 0;-
436 } else {
never executed: end of block
0
437 QRasterPaintEngine *pe = static_cast<QRasterPaintEngine *>(painter->paintEngine());-
438 if (pe->clipType() == QRasterPaintEngine::ComplexClip)
pe->clipType()...e::ComplexClipDescription
TRUEnever evaluated
FALSEnever evaluated
0
439 // disabled because of complex clipping...-
440 target = 0;
never executed: target = 0;
0
441 else {-
442 QRectF clip = pe->clipBoundingRect();-
443 QRectF rect = boundingRectFor(srcRect.isEmpty() ? src.rect() : srcRect);-
444 QTransform x = painter->deviceTransform();-
445 if (!clip.contains(rect.translated(x.dx() + p.x(), x.dy() + p.y()))) {
!clip.contains...dy() + p.y()))Description
TRUEnever evaluated
FALSEnever evaluated
0
446 target = 0;-
447 }
never executed: end of block
0
448-
449 }
never executed: end of block
0
450 }-
451 }-
452-
453 if (target) {
targetDescription
TRUEnever evaluated
FALSEnever evaluated
0
454 QTransform x = painter->deviceTransform();-
455 QPointF offset(x.dx(), x.dy());-
456-
457 convolute(target, p+offset, src.toImage(), srcRect, QPainter::CompositionMode_SourceOver, d->convolutionKernel, d->kernelWidth, d->kernelHeight);-
458 } else {
never executed: end of block
0
459 QRect srect = srcRect.isNull() ? src.rect() : srcRect.toRect();
srcRect.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
460 QRect rect = boundingRectFor(srect).toRect();-
461 QImage result = QImage(rect.size(), QImage::Format_ARGB32_Premultiplied);-
462 QPoint offset = srect.topLeft() - rect.topLeft();-
463 convolute(&result,-
464 offset,-
465 src.toImage(),-
466 srect,-
467 QPainter::CompositionMode_Source,-
468 d->convolutionKernel,-
469 d->kernelWidth,-
470 d->kernelHeight);-
471 painter->drawImage(p - offset, result);-
472 }
never executed: end of block
0
473}-
474-
475/*!-
476 \class QPixmapBlurFilter-
477 \since 4.6-
478 \ingroup multimedia-
479-
480 \brief The QPixmapBlurFilter class provides blur filtering-
481 for pixmaps.-
482-
483 QPixmapBlurFilter implements a blur pixmap filter,-
484 which is applied when \l{QPixmapFilter::}{draw()} is called.-
485-
486 The filter lets you specialize the radius of the blur as well-
487 as hints as to whether to prefer performance or quality.-
488-
489 By default, the blur effect is produced by applying an exponential-
490 filter generated from the specified blurRadius(). Paint engines-
491 may override this with a custom blur that is faster on the-
492 underlying hardware.-
493-
494 \sa {Pixmap Filters Example}, QPixmapConvolutionFilter, QPixmapDropShadowFilter-
495-
496 \internal-
497*/-
498-
499class QPixmapBlurFilterPrivate : public QPixmapFilterPrivate-
500{-
501public:-
502 QPixmapBlurFilterPrivate() : radius(5), hints(QGraphicsBlurEffect::PerformanceHint) {}
never executed: end of block
0
503-
504 qreal radius;-
505 QGraphicsBlurEffect::BlurHints hints;-
506};-
507-
508-
509/*!-
510 Constructs a pixmap blur filter.-
511-
512 \internal-
513*/-
514QPixmapBlurFilter::QPixmapBlurFilter(QObject *parent)-
515 : QPixmapFilter(*new QPixmapBlurFilterPrivate, BlurFilter, parent)-
516{-
517}
never executed: end of block
0
518-
519/*!-
520 Destructor of pixmap blur filter.-
521-
522 \internal-
523*/-
524QPixmapBlurFilter::~QPixmapBlurFilter()-
525{-
526}-
527-
528/*!-
529 Sets the radius of the blur filter. Higher radius produces increased blurriness.-
530-
531 \internal-
532*/-
533void QPixmapBlurFilter::setRadius(qreal radius)-
534{-
535 Q_D(QPixmapBlurFilter);-
536 d->radius = radius;-
537}
never executed: end of block
0
538-
539/*!-
540 Gets the radius of the blur filter.-
541-
542 \internal-
543*/-
544qreal QPixmapBlurFilter::radius() const-
545{-
546 Q_D(const QPixmapBlurFilter);-
547 return d->radius;
never executed: return d->radius;
0
548}-
549-
550/*!-
551 Setting the blur hints to PerformanceHint causes the implementation-
552 to trade off visual quality to blur the image faster. Setting the-
553 blur hints to QualityHint causes the implementation to improve-
554 visual quality at the expense of speed.-
555-
556 AnimationHint causes the implementation to optimize for animating-
557 the blur radius, possibly by caching blurred versions of the source-
558 pixmap.-
559-
560 The implementation is free to ignore this value if it only has a single-
561 blur algorithm.-
562-
563 \internal-
564*/-
565void QPixmapBlurFilter::setBlurHints(QGraphicsBlurEffect::BlurHints hints)-
566{-
567 Q_D(QPixmapBlurFilter);-
568 d->hints = hints;-
569}
never executed: end of block
0
570-
571/*!-
572 Gets the blur hints of the blur filter.-
573-
574 \internal-
575*/-
576QGraphicsBlurEffect::BlurHints QPixmapBlurFilter::blurHints() const-
577{-
578 Q_D(const QPixmapBlurFilter);-
579 return d->hints;
never executed: return d->hints;
0
580}-
581-
582const qreal radiusScale = qreal(2.5);-
583-
584/*!-
585 \internal-
586*/-
587QRectF QPixmapBlurFilter::boundingRectFor(const QRectF &rect) const-
588{-
589 Q_D(const QPixmapBlurFilter);-
590 const qreal delta = radiusScale * d->radius + 1;-
591 return rect.adjusted(-delta, -delta, delta, delta);
never executed: return rect.adjusted(-delta, -delta, delta, delta);
0
592}-
593-
594template <int shift>-
595inline int qt_static_shift(int value)-
596{-
597 if (shift == 0)
shift == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
598 return value;
never executed: return value;
0
599 else if (shift > 0)
shift > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
600 return value << (uint(shift) & 0x1f);
never executed: return value << (uint(shift) & 0x1f);
0
601 else-
602 return value >> (uint(-shift) & 0x1f);
never executed: return value >> (uint(-shift) & 0x1f);
0
603}-
604-
605template<int aprec, int zprec>-
606inline void qt_blurinner(uchar *bptr, int &zR, int &zG, int &zB, int &zA, int alpha)-
607{-
608 QRgb *pixel = (QRgb *)bptr;-
609-
610#define Z_MASK (0xff << zprec)-
611 const int A_zprec = qt_static_shift<zprec - 24>(*pixel) & Z_MASK;-
612 const int R_zprec = qt_static_shift<zprec - 16>(*pixel) & Z_MASK;-
613 const int G_zprec = qt_static_shift<zprec - 8>(*pixel) & Z_MASK;-
614 const int B_zprec = qt_static_shift<zprec>(*pixel) & Z_MASK;-
615#undef Z_MASK-
616-
617 const int zR_zprec = zR >> aprec;-
618 const int zG_zprec = zG >> aprec;-
619 const int zB_zprec = zB >> aprec;-
620 const int zA_zprec = zA >> aprec;-
621-
622 zR += alpha * (R_zprec - zR_zprec);-
623 zG += alpha * (G_zprec - zG_zprec);-
624 zB += alpha * (B_zprec - zB_zprec);-
625 zA += alpha * (A_zprec - zA_zprec);-
626-
627#define ZA_MASK (0xff << (zprec + aprec))-
628 *pixel =-
629 qt_static_shift<24 - zprec - aprec>(zA & ZA_MASK)-
630 | qt_static_shift<16 - zprec - aprec>(zR & ZA_MASK)-
631 | qt_static_shift<8 - zprec - aprec>(zG & ZA_MASK)-
632 | qt_static_shift<-zprec - aprec>(zB & ZA_MASK);-
633#undef ZA_MASK-
634}
never executed: end of block
0
635-
636const int alphaIndex = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);-
637-
638template<int aprec, int zprec>-
639inline void qt_blurinner_alphaOnly(uchar *bptr, int &z, int alpha)-
640{-
641 const int A_zprec = int(*(bptr)) << zprec;-
642 const int z_zprec = z >> aprec;-
643 z += alpha * (A_zprec - z_zprec);-
644 *(bptr) = z >> (zprec + aprec);-
645}
never executed: end of block
0
646-
647template<int aprec, int zprec, bool alphaOnly>-
648inline void qt_blurrow(QImage & im, int line, int alpha)-
649{-
650 uchar *bptr = im.scanLine(line);-
651-
652 int zR = 0, zG = 0, zB = 0, zA = 0;-
653-
654 if (alphaOnly && im.format() != QImage::Format_Indexed8)
alphaOnlyDescription
TRUEnever evaluated
FALSEnever evaluated
im.format() !=...ormat_Indexed8Description
TRUEnever evaluated
FALSEnever evaluated
0
655 bptr += alphaIndex;
never executed: bptr += alphaIndex;
0
656-
657 const int stride = im.depth() >> 3;-
658 const int im_width = im.width();-
659 for (int index = 0; index < im_width; ++index) {
index < im_widthDescription
TRUEnever evaluated
FALSEnever evaluated
0
660 if (alphaOnly)
alphaOnlyDescription
TRUEnever evaluated
FALSEnever evaluated
0
661 qt_blurinner_alphaOnly<aprec, zprec>(bptr, zA, alpha);
never executed: qt_blurinner_alphaOnly<aprec, zprec>(bptr, zA, alpha);
0
662 else-
663 qt_blurinner<aprec, zprec>(bptr, zR, zG, zB, zA, alpha);
never executed: qt_blurinner<aprec, zprec>(bptr, zR, zG, zB, zA, alpha);
0
664 bptr += stride;-
665 }
never executed: end of block
0
666-
667 bptr -= stride;-
668-
669 for (int index = im_width - 2; index >= 0; --index) {
index >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
670 bptr -= stride;-
671 if (alphaOnly)
alphaOnlyDescription
TRUEnever evaluated
FALSEnever evaluated
0
672 qt_blurinner_alphaOnly<aprec, zprec>(bptr, zA, alpha);
never executed: qt_blurinner_alphaOnly<aprec, zprec>(bptr, zA, alpha);
0
673 else-
674 qt_blurinner<aprec, zprec>(bptr, zR, zG, zB, zA, alpha);
never executed: qt_blurinner<aprec, zprec>(bptr, zR, zG, zB, zA, alpha);
0
675 }-
676}
never executed: end of block
0
677-
678/*-
679* expblur(QImage &img, int radius)-
680*-
681* Based on exponential blur algorithm by Jani Huhtanen-
682*-
683* In-place blur of image 'img' with kernel-
684* of approximate radius 'radius'.-
685*-
686* Blurs with two sided exponential impulse-
687* response.-
688*-
689* aprec = precision of alpha parameter-
690* in fixed-point format 0.aprec-
691*-
692* zprec = precision of state parameters-
693* zR,zG,zB and zA in fp format 8.zprec-
694*/-
695template <int aprec, int zprec, bool alphaOnly>-
696void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transposed = 0)-
697{-
698 // halve the radius if we're using two passes-
699 if (improvedQuality)
improvedQualityDescription
TRUEnever evaluated
FALSEnever evaluated
0
700 radius *= qreal(0.5);
never executed: radius *= qreal(0.5);
0
701-
702 Q_ASSERT(img.format() == QImage::Format_ARGB32_Premultiplied-
703 || img.format() == QImage::Format_RGB32-
704 || img.format() == QImage::Format_Indexed8-
705 || img.format() == QImage::Format_Grayscale8);-
706-
707 // choose the alpha such that pixels at radius distance from a fully-
708 // saturated pixel will have an alpha component of no greater than-
709 // the cutOffIntensity-
710 const qreal cutOffIntensity = 2;-
711 int alpha = radius <= qreal(1e-5)
radius <= qreal(1e-5)Description
TRUEnever evaluated
FALSEnever evaluated
0
712 ? ((1 << aprec)-1)-
713 : qRound((1<<aprec)*(1 - qPow(cutOffIntensity * (1 / qreal(255)), 1 / radius)));-
714-
715 int img_height = img.height();-
716 for (int row = 0; row < img_height; ++row) {
row < img_heightDescription
TRUEnever evaluated
FALSEnever evaluated
0
717 for (int i = 0; i <= int(improvedQuality); ++i)
i <= int(improvedQuality)Description
TRUEnever evaluated
FALSEnever evaluated
0
718 qt_blurrow<aprec, zprec, alphaOnly>(img, row, alpha);
never executed: qt_blurrow<aprec, zprec, alphaOnly>(img, row, alpha);
0
719 }
never executed: end of block
0
720-
721 QImage temp(img.height(), img.width(), img.format());-
722 if (transposed >= 0) {
transposed >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
723 if (img.depth() == 8) {
img.depth() == 8Description
TRUEnever evaluated
FALSEnever evaluated
0
724 qt_memrotate270(reinterpret_cast<const quint8*>(img.bits()),-
725 img.width(), img.height(), img.bytesPerLine(),-
726 reinterpret_cast<quint8*>(temp.bits()),-
727 temp.bytesPerLine());-
728 } else {
never executed: end of block
0
729 qt_memrotate270(reinterpret_cast<const quint32*>(img.bits()),-
730 img.width(), img.height(), img.bytesPerLine(),-
731 reinterpret_cast<quint32*>(temp.bits()),-
732 temp.bytesPerLine());-
733 }
never executed: end of block
0
734 } else {-
735 if (img.depth() == 8) {
img.depth() == 8Description
TRUEnever evaluated
FALSEnever evaluated
0
736 qt_memrotate90(reinterpret_cast<const quint8*>(img.bits()),-
737 img.width(), img.height(), img.bytesPerLine(),-
738 reinterpret_cast<quint8*>(temp.bits()),-
739 temp.bytesPerLine());-
740 } else {
never executed: end of block
0
741 qt_memrotate90(reinterpret_cast<const quint32*>(img.bits()),-
742 img.width(), img.height(), img.bytesPerLine(),-
743 reinterpret_cast<quint32*>(temp.bits()),-
744 temp.bytesPerLine());-
745 }
never executed: end of block
0
746 }-
747-
748 img_height = temp.height();-
749 for (int row = 0; row < img_height; ++row) {
row < img_heightDescription
TRUEnever evaluated
FALSEnever evaluated
0
750 for (int i = 0; i <= int(improvedQuality); ++i)
i <= int(improvedQuality)Description
TRUEnever evaluated
FALSEnever evaluated
0
751 qt_blurrow<aprec, zprec, alphaOnly>(temp, row, alpha);
never executed: qt_blurrow<aprec, zprec, alphaOnly>(temp, row, alpha);
0
752 }
never executed: end of block
0
753-
754 if (transposed == 0) {
transposed == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
755 if (img.depth() == 8) {
img.depth() == 8Description
TRUEnever evaluated
FALSEnever evaluated
0
756 qt_memrotate90(reinterpret_cast<const quint8*>(temp.bits()),-
757 temp.width(), temp.height(), temp.bytesPerLine(),-
758 reinterpret_cast<quint8*>(img.bits()),-
759 img.bytesPerLine());-
760 } else {
never executed: end of block
0
761 qt_memrotate90(reinterpret_cast<const quint32*>(temp.bits()),-
762 temp.width(), temp.height(), temp.bytesPerLine(),-
763 reinterpret_cast<quint32*>(img.bits()),-
764 img.bytesPerLine());-
765 }
never executed: end of block
0
766 } else {-
767 img = temp;-
768 }
never executed: end of block
0
769}-
770#define AVG(a,b) ( ((((a)^(b)) & 0xfefefefeUL) >> 1) + ((a)&(b)) )-
771#define AVG16(a,b) ( ((((a)^(b)) & 0xf7deUL) >> 1) + ((a)&(b)) )-
772-
773Q_WIDGETS_EXPORT QImage qt_halfScaled(const QImage &source)-
774{-
775 if (source.width() < 2 || source.height() < 2)
source.width() < 2Description
TRUEnever evaluated
FALSEnever evaluated
source.height() < 2Description
TRUEnever evaluated
FALSEnever evaluated
0
776 return QImage();
never executed: return QImage();
0
777-
778 QImage srcImage = source;-
779-
780 if (source.format() == QImage::Format_Indexed8 || source.format() == QImage::Format_Grayscale8) {
source.format(...ormat_Indexed8Description
TRUEnever evaluated
FALSEnever evaluated
source.format(...mat_Grayscale8Description
TRUEnever evaluated
FALSEnever evaluated
0
781 // assumes grayscale-
782 QImage dest(source.width() / 2, source.height() / 2, srcImage.format());-
783-
784 const uchar *src = reinterpret_cast<const uchar*>(const_cast<const QImage &>(srcImage).bits());-
785 int sx = srcImage.bytesPerLine();-
786 int sx2 = sx << 1;-
787-
788 uchar *dst = reinterpret_cast<uchar*>(dest.bits());-
789 int dx = dest.bytesPerLine();-
790 int ww = dest.width();-
791 int hh = dest.height();-
792-
793 for (int y = hh; y; --y, dst += dx, src += sx2) {
yDescription
TRUEnever evaluated
FALSEnever evaluated
0
794 const uchar *p1 = src;-
795 const uchar *p2 = src + sx;-
796 uchar *q = dst;-
797 for (int x = ww; x; --x, ++q, p1 += 2, p2 += 2)
xDescription
TRUEnever evaluated
FALSEnever evaluated
0
798 *q = ((int(p1[0]) + int(p1[1]) + int(p2[0]) + int(p2[1])) + 2) >> 2;
never executed: *q = ((int(p1[0]) + int(p1[1]) + int(p2[0]) + int(p2[1])) + 2) >> 2;
0
799 }
never executed: end of block
0
800-
801 return dest;
never executed: return dest;
0
802 } else if (source.format() == QImage::Format_ARGB8565_Premultiplied) {
source.format(..._PremultipliedDescription
TRUEnever evaluated
FALSEnever evaluated
0
803 QImage dest(source.width() / 2, source.height() / 2, srcImage.format());-
804-
805 const uchar *src = reinterpret_cast<const uchar*>(const_cast<const QImage &>(srcImage).bits());-
806 int sx = srcImage.bytesPerLine();-
807 int sx2 = sx << 1;-
808-
809 uchar *dst = reinterpret_cast<uchar*>(dest.bits());-
810 int dx = dest.bytesPerLine();-
811 int ww = dest.width();-
812 int hh = dest.height();-
813-
814 for (int y = hh; y; --y, dst += dx, src += sx2) {
yDescription
TRUEnever evaluated
FALSEnever evaluated
0
815 const uchar *p1 = src;-
816 const uchar *p2 = src + sx;-
817 uchar *q = dst;-
818 for (int x = ww; x; --x, q += 3, p1 += 6, p2 += 6) {
xDescription
TRUEnever evaluated
FALSEnever evaluated
0
819 // alpha-
820 q[0] = AVG(AVG(p1[0], p1[3]), AVG(p2[0], p2[3]));-
821 // rgb-
822 const quint16 p16_1 = (p1[2] << 8) | p1[1];-
823 const quint16 p16_2 = (p1[5] << 8) | p1[4];-
824 const quint16 p16_3 = (p2[2] << 8) | p2[1];-
825 const quint16 p16_4 = (p2[5] << 8) | p2[4];-
826 const quint16 result = AVG16(AVG16(p16_1, p16_2), AVG16(p16_3, p16_4));-
827 q[1] = result & 0xff;-
828 q[2] = result >> 8;-
829 }
never executed: end of block
0
830 }
never executed: end of block
0
831-
832 return dest;
never executed: return dest;
0
833 } else if (source.format() != QImage::Format_ARGB32_Premultiplied
source.format(..._PremultipliedDescription
TRUEnever evaluated
FALSEnever evaluated
0
834 && source.format() != QImage::Format_RGB32)
source.format(...::Format_RGB32Description
TRUEnever evaluated
FALSEnever evaluated
0
835 {-
836 srcImage = source.convertToFormat(QImage::Format_ARGB32_Premultiplied);-
837 }
never executed: end of block
0
838-
839 QImage dest(source.width() / 2, source.height() / 2, srcImage.format());-
840-
841 const quint32 *src = reinterpret_cast<const quint32*>(const_cast<const QImage &>(srcImage).bits());-
842 int sx = srcImage.bytesPerLine() >> 2;-
843 int sx2 = sx << 1;-
844-
845 quint32 *dst = reinterpret_cast<quint32*>(dest.bits());-
846 int dx = dest.bytesPerLine() >> 2;-
847 int ww = dest.width();-
848 int hh = dest.height();-
849-
850 for (int y = hh; y; --y, dst += dx, src += sx2) {
yDescription
TRUEnever evaluated
FALSEnever evaluated
0
851 const quint32 *p1 = src;-
852 const quint32 *p2 = src + sx;-
853 quint32 *q = dst;-
854 for (int x = ww; x; --x, q++, p1 += 2, p2 += 2)
xDescription
TRUEnever evaluated
FALSEnever evaluated
0
855 *q = AVG(AVG(p1[0], p1[1]), AVG(p2[0], p2[1]));
never executed: *q = ( ((((( ((((p1[0])^(p1[1])) & 0xfefefefeUL) >> 1) + ((p1[0])&(p1[1])) ))^(( ((((p2[0])^(p2[1])) & 0xfefefefeUL) >> 1) + ((p2[0])&(p2[1])) ))) & 0xfefefefeUL) >> 1) + ((( ((((p1[0])^(p1[1])) & 0xfefefefeUL) >> 1) + ((p1[0])&(p1[1])) ))&(( ((((p2[0])^(p2[1])) & 0xfefefefeUL) >> 1) + ((p2[0])&(p2[1])) ))) );
0
856 }
never executed: end of block
0
857-
858 return dest;
never executed: return dest;
0
859}-
860-
861Q_WIDGETS_EXPORT void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0)-
862{-
863 if (blurImage.format() != QImage::Format_ARGB32_Premultiplied
blurImage.form..._PremultipliedDescription
TRUEnever evaluated
FALSEnever evaluated
0
864 && blurImage.format() != QImage::Format_RGB32)
blurImage.form...::Format_RGB32Description
TRUEnever evaluated
FALSEnever evaluated
0
865 {-
866 blurImage = blurImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);-
867 }
never executed: end of block
0
868-
869 qreal scale = 1;-
870 if (radius >= 4 && blurImage.width() >= 2 && blurImage.height() >= 2) {
radius >= 4Description
TRUEnever evaluated
FALSEnever evaluated
blurImage.width() >= 2Description
TRUEnever evaluated
FALSEnever evaluated
blurImage.height() >= 2Description
TRUEnever evaluated
FALSEnever evaluated
0
871 blurImage = qt_halfScaled(blurImage);-
872 scale = 2;-
873 radius *= qreal(0.5);-
874 }
never executed: end of block
0
875-
876 if (alphaOnly)
alphaOnlyDescription
TRUEnever evaluated
FALSEnever evaluated
0
877 expblur<12, 10, true>(blurImage, radius, quality, transposed);
never executed: expblur<12, 10, true>(blurImage, radius, quality, transposed);
0
878 else-
879 expblur<12, 10, false>(blurImage, radius, quality, transposed);
never executed: expblur<12, 10, false>(blurImage, radius, quality, transposed);
0
880-
881 if (p) {
pDescription
TRUEnever evaluated
FALSEnever evaluated
0
882 p->scale(scale, scale);-
883 p->setRenderHint(QPainter::SmoothPixmapTransform);-
884 p->drawImage(QRect(0, 0, blurImage.width(), blurImage.height()), blurImage);-
885 }
never executed: end of block
0
886}
never executed: end of block
0
887-
888Q_WIDGETS_EXPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0)-
889{-
890 if (blurImage.format() == QImage::Format_Indexed8 || blurImage.format() == QImage::Format_Grayscale8)
blurImage.form...ormat_Indexed8Description
TRUEnever evaluated
FALSEnever evaluated
blurImage.form...mat_Grayscale8Description
TRUEnever evaluated
FALSEnever evaluated
0
891 expblur<12, 10, true>(blurImage, radius, quality, transposed);
never executed: expblur<12, 10, true>(blurImage, radius, quality, transposed);
0
892 else-
893 expblur<12, 10, false>(blurImage, radius, quality, transposed);
never executed: expblur<12, 10, false>(blurImage, radius, quality, transposed);
0
894}-
895-
896Q_GUI_EXPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale);-
897-
898/*!-
899 \internal-
900*/-
901void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF &rect) const-
902{-
903 Q_D(const QPixmapBlurFilter);-
904 if (!painter->isActive())
!painter->isActive()Description
TRUEnever evaluated
FALSEnever evaluated
0
905 return;
never executed: return;
0
906-
907 if (src.isNull())
src.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
908 return;
never executed: return;
0
909-
910 QRectF srcRect = rect;-
911 if (srcRect.isNull())
srcRect.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
912 srcRect = src.rect();
never executed: srcRect = src.rect();
0
913-
914 if (d->radius <= 1) {
d->radius <= 1Description
TRUEnever evaluated
FALSEnever evaluated
0
915 painter->drawPixmap(srcRect.translated(p), src, srcRect);-
916 return;
never executed: return;
0
917 }-
918-
919 qreal scaledRadius = radiusScale * d->radius;-
920 qreal scale;-
921 if (qt_scaleForTransform(painter->transform(), &scale))
qt_scaleForTra...orm(), &scale)Description
TRUEnever evaluated
FALSEnever evaluated
0
922 scaledRadius /= scale;
never executed: scaledRadius /= scale;
0
923-
924 QImage srcImage;-
925 QImage destImage;-
926-
927 if (srcRect == src.rect()) {
srcRect == src.rect()Description
TRUEnever evaluated
FALSEnever evaluated
0
928 srcImage = src.toImage();-
929 } else {
never executed: end of block
0
930 QRect rect = srcRect.toAlignedRect().intersected(src.rect());-
931 srcImage = src.copy(rect).toImage();-
932 }
never executed: end of block
0
933-
934 QTransform transform = painter->worldTransform();-
935 painter->translate(p);-
936 qt_blurImage(painter, srcImage, scaledRadius, (d->hints & QGraphicsBlurEffect::QualityHint), false);-
937 painter->setWorldTransform(transform);-
938}
never executed: end of block
0
939-
940// grayscales the image to dest (could be same). If rect isn't defined-
941// destination image size is used to determine the dimension of grayscaling-
942// process.-
943static void grayscale(const QImage &image, QImage &dest, const QRect& rect = QRect())-
944{-
945 QRect destRect = rect;-
946 QRect srcRect = rect;-
947 if (rect.isNull()) {
rect.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
948 srcRect = dest.rect();-
949 destRect = dest.rect();-
950 }
never executed: end of block
0
951 if (&image != &dest) {
&image != &destDescription
TRUEnever evaluated
FALSEnever evaluated
0
952 destRect.moveTo(QPoint(0, 0));-
953 }
never executed: end of block
0
954-
955 const unsigned int *data = (const unsigned int *)image.bits();-
956 unsigned int *outData = (unsigned int *)dest.bits();-
957-
958 if (dest.size() == image.size() && image.rect() == srcRect) {
dest.size() == image.size()Description
TRUEnever evaluated
FALSEnever evaluated
image.rect() == srcRectDescription
TRUEnever evaluated
FALSEnever evaluated
0
959 // a bit faster loop for grayscaling everything-
960 int pixels = dest.width() * dest.height();-
961 for (int i = 0; i < pixels; ++i) {
i < pixelsDescription
TRUEnever evaluated
FALSEnever evaluated
0
962 int val = qGray(data[i]);-
963 outData[i] = qRgba(val, val, val, qAlpha(data[i]));-
964 }
never executed: end of block
0
965 } else {
never executed: end of block
0
966 int yd = destRect.top();-
967 for (int y = srcRect.top(); y <= srcRect.bottom() && y < image.height(); y++) {
y <= srcRect.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
y < image.height()Description
TRUEnever evaluated
FALSEnever evaluated
0
968 data = (const unsigned int*)image.scanLine(y);-
969 outData = (unsigned int*)dest.scanLine(yd++);-
970 int xd = destRect.left();-
971 for (int x = srcRect.left(); x <= srcRect.right() && x < image.width(); x++) {
x <= srcRect.right()Description
TRUEnever evaluated
FALSEnever evaluated
x < image.width()Description
TRUEnever evaluated
FALSEnever evaluated
0
972 int val = qGray(data[x]);-
973 outData[xd++] = qRgba(val, val, val, qAlpha(data[x]));-
974 }
never executed: end of block
0
975 }
never executed: end of block
0
976 }
never executed: end of block
0
977}-
978-
979/*!-
980 \class QPixmapColorizeFilter-
981 \since 4.5-
982 \ingroup painting-
983-
984 \brief The QPixmapColorizeFilter class provides colorizing-
985 filtering for pixmaps.-
986-
987 A colorize filter gives the pixmap a tint of its color(). The-
988 filter first grayscales the pixmap and then converts those to-
989 colorized values using QPainter::CompositionMode_Screen with the-
990 chosen color. The alpha-channel is not changed.-
991-
992 Example:-
993 \snippet code/src_gui_image_qpixmapfilter.cpp 0-
994-
995 \sa QPainter::CompositionMode-
996-
997 \internal-
998*/-
999class QPixmapColorizeFilterPrivate : public QPixmapFilterPrivate-
1000{-
1001 Q_DECLARE_PUBLIC(QPixmapColorizeFilter)-
1002public:-
1003 QColor color;-
1004 qreal strength;-
1005 quint32 opaque : 1;-
1006 quint32 alphaBlend : 1;-
1007 quint32 padding : 30;-
1008};-
1009-
1010/*!-
1011 Constructs an pixmap colorize filter.-
1012-
1013 Default color value for colorizing is QColor(0, 0, 192).-
1014-
1015 \internal-
1016*/-
1017QPixmapColorizeFilter::QPixmapColorizeFilter(QObject *parent)-
1018 : QPixmapFilter(*new QPixmapColorizeFilterPrivate, ColorizeFilter, parent)-
1019{-
1020 Q_D(QPixmapColorizeFilter);-
1021 d->color = QColor(0, 0, 192);-
1022 d->strength = qreal(1);-
1023 d->opaque = true;-
1024 d->alphaBlend = false;-
1025}
never executed: end of block
0
1026-
1027/*!-
1028 \internal-
1029*/-
1030QPixmapColorizeFilter::~QPixmapColorizeFilter()-
1031{-
1032 // was inline until Qt 5.6, so essentially-
1033 // must stay empty until ### Qt 6-
1034}-
1035-
1036/*!-
1037 Gets the color of the colorize filter.-
1038-
1039 \internal-
1040*/-
1041QColor QPixmapColorizeFilter::color() const-
1042{-
1043 Q_D(const QPixmapColorizeFilter);-
1044 return d->color;
never executed: return d->color;
0
1045}-
1046-
1047/*!-
1048 Sets the color of the colorize filter to the \a color specified.-
1049-
1050 \internal-
1051*/-
1052void QPixmapColorizeFilter::setColor(const QColor &color)-
1053{-
1054 Q_D(QPixmapColorizeFilter);-
1055 d->color = color;-
1056}
never executed: end of block
0
1057-
1058/*!-
1059 Gets the strength of the colorize filter, 1.0 means full colorized while-
1060 0.0 equals to no filtering at all.-
1061-
1062 \internal-
1063*/-
1064qreal QPixmapColorizeFilter::strength() const-
1065{-
1066 Q_D(const QPixmapColorizeFilter);-
1067 return d->strength;
never executed: return d->strength;
0
1068}-
1069-
1070/*!-
1071 Sets the strength of the colorize filter to \a strength.-
1072-
1073 \internal-
1074*/-
1075void QPixmapColorizeFilter::setStrength(qreal strength)-
1076{-
1077 Q_D(QPixmapColorizeFilter);-
1078 d->strength = qBound(qreal(0), strength, qreal(1));-
1079 d->opaque = !qFuzzyIsNull(d->strength);-
1080 d->alphaBlend = !qFuzzyIsNull(d->strength - 1);-
1081}
never executed: end of block
0
1082-
1083/*!-
1084 \internal-
1085*/-
1086void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const-
1087{-
1088 Q_D(const QPixmapColorizeFilter);-
1089-
1090 if (src.isNull())
src.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
1091 return;
never executed: return;
0
1092-
1093 // raster implementation-
1094-
1095 if (!d->opaque) {
!d->opaqueDescription
TRUEnever evaluated
FALSEnever evaluated
0
1096 painter->drawPixmap(dest, src, srcRect);-
1097 return;
never executed: return;
0
1098 }-
1099-
1100 QImage srcImage;-
1101 QImage destImage;-
1102-
1103 if (srcRect.isNull()) {
srcRect.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
1104 srcImage = src.toImage();-
1105 srcImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);-
1106 destImage = QImage(srcImage.size(), srcImage.format());-
1107 } else {
never executed: end of block
0
1108 QRect rect = srcRect.toAlignedRect().intersected(src.rect());-
1109-
1110 srcImage = src.copy(rect).toImage();-
1111 srcImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);-
1112 destImage = QImage(rect.size(), srcImage.format());-
1113 }
never executed: end of block
0
1114-
1115 // do colorizing-
1116 QPainter destPainter(&destImage);-
1117 grayscale(srcImage, destImage, srcImage.rect());-
1118 destPainter.setCompositionMode(QPainter::CompositionMode_Screen);-
1119 destPainter.fillRect(srcImage.rect(), d->color);-
1120 destPainter.end();-
1121-
1122 if (d->alphaBlend) {
d->alphaBlendDescription
TRUEnever evaluated
FALSEnever evaluated
0
1123 // alpha blending srcImage and destImage-
1124 QImage buffer = srcImage;-
1125 QPainter bufPainter(&buffer);-
1126 bufPainter.setOpacity(d->strength);-
1127 bufPainter.drawImage(0, 0, destImage);-
1128 bufPainter.end();-
1129 destImage = buffer;-
1130 }
never executed: end of block
0
1131-
1132 if (srcImage.hasAlphaChannel())
srcImage.hasAlphaChannel()Description
TRUEnever evaluated
FALSEnever evaluated
0
1133 destImage.setAlphaChannel(srcImage.alphaChannel());
never executed: destImage.setAlphaChannel(srcImage.alphaChannel());
0
1134-
1135 painter->drawImage(dest, destImage);-
1136}
never executed: end of block
0
1137-
1138class QPixmapDropShadowFilterPrivate : public QPixmapFilterPrivate-
1139{-
1140public:-
1141 QPixmapDropShadowFilterPrivate()-
1142 : offset(8, 8), color(63, 63, 63, 180), radius(1) {}
never executed: end of block
0
1143-
1144 QPointF offset;-
1145 QColor color;-
1146 qreal radius;-
1147};-
1148-
1149/*!-
1150 \class QPixmapDropShadowFilter-
1151 \since 4.5-
1152 \ingroup painting-
1153-
1154 \brief The QPixmapDropShadowFilter class is a convenience class-
1155 for drawing pixmaps with drop shadows.-
1156-
1157 The drop shadow is produced by taking a copy of the source pixmap-
1158 and applying a color to the copy using a-
1159 QPainter::CompositionMode_DestinationIn operation. This produces a-
1160 homogeneously-colored pixmap which is then drawn using a-
1161 QPixmapConvolutionFilter at an offset. The original pixmap is-
1162 drawn on top.-
1163-
1164 The QPixmapDropShadowFilter class provides some customization-
1165 options to specify how the drop shadow should appear. The color of-
1166 the drop shadow can be modified using the setColor() function, the-
1167 drop shadow offset can be modified using the setOffset() function,-
1168 and the blur radius of the drop shadow can be changed through the-
1169 setBlurRadius() function.-
1170-
1171 By default, the drop shadow is a dark gray shadow, blurred with a-
1172 radius of 1 at an offset of 8 pixels towards the lower right.-
1173-
1174 Example:-
1175 \snippet code/src_gui_image_qpixmapfilter.cpp 2-
1176-
1177 \sa QPixmapColorizeFilter, QPixmapConvolutionFilter-
1178-
1179 \internal-
1180 */-
1181-
1182/*!-
1183 Constructs drop shadow filter.-
1184-
1185 \internal-
1186*/-
1187QPixmapDropShadowFilter::QPixmapDropShadowFilter(QObject *parent)-
1188 : QPixmapFilter(*new QPixmapDropShadowFilterPrivate, DropShadowFilter, parent)-
1189{-
1190}
never executed: end of block
0
1191-
1192/*!-
1193 Destroys drop shadow filter.-
1194-
1195 \internal-
1196*/-
1197QPixmapDropShadowFilter::~QPixmapDropShadowFilter()-
1198{-
1199}-
1200-
1201/*!-
1202 Returns the radius in pixels of the blur on the drop shadow.-
1203-
1204 A smaller radius results in a sharper shadow.-
1205-
1206 \sa color(), offset()-
1207-
1208 \internal-
1209*/-
1210qreal QPixmapDropShadowFilter::blurRadius() const-
1211{-
1212 Q_D(const QPixmapDropShadowFilter);-
1213 return d->radius;
never executed: return d->radius;
0
1214}-
1215-
1216/*!-
1217 Sets the radius in pixels of the blur on the drop shadow to the \a radius specified.-
1218-
1219 Using a smaller radius results in a sharper shadow.-
1220-
1221 \sa setColor(), setOffset()-
1222-
1223 \internal-
1224*/-
1225void QPixmapDropShadowFilter::setBlurRadius(qreal radius)-
1226{-
1227 Q_D(QPixmapDropShadowFilter);-
1228 d->radius = radius;-
1229}
never executed: end of block
0
1230-
1231/*!-
1232 Returns the color of the drop shadow.-
1233-
1234 \sa blurRadius(), offset()-
1235-
1236 \internal-
1237*/-
1238QColor QPixmapDropShadowFilter::color() const-
1239{-
1240 Q_D(const QPixmapDropShadowFilter);-
1241 return d->color;
never executed: return d->color;
0
1242}-
1243-
1244/*!-
1245 Sets the color of the drop shadow to the \a color specified.-
1246-
1247 \sa setBlurRadius(), setOffset()-
1248-
1249 \internal-
1250*/-
1251void QPixmapDropShadowFilter::setColor(const QColor &color)-
1252{-
1253 Q_D(QPixmapDropShadowFilter);-
1254 d->color = color;-
1255}
never executed: end of block
0
1256-
1257/*!-
1258 Returns the shadow offset in pixels.-
1259-
1260 \sa blurRadius(), color()-
1261-
1262 \internal-
1263*/-
1264QPointF QPixmapDropShadowFilter::offset() const-
1265{-
1266 Q_D(const QPixmapDropShadowFilter);-
1267 return d->offset;
never executed: return d->offset;
0
1268}-
1269-
1270/*!-
1271 Sets the shadow offset in pixels to the \a offset specified.-
1272-
1273 \sa setBlurRadius(), setColor()-
1274-
1275 \internal-
1276*/-
1277void QPixmapDropShadowFilter::setOffset(const QPointF &offset)-
1278{-
1279 Q_D(QPixmapDropShadowFilter);-
1280 d->offset = offset;-
1281}
never executed: end of block
0
1282-
1283/*!-
1284 \fn void QPixmapDropShadowFilter::setOffset(qreal dx, qreal dy)-
1285 \overload-
1286-
1287 Sets the shadow offset in pixels to be the displacement specified by the-
1288 horizontal \a dx and vertical \a dy coordinates.-
1289-
1290 \sa setBlurRadius(), setColor()-
1291-
1292 \internal-
1293*/-
1294-
1295/*!-
1296 \internal-
1297 */-
1298QRectF QPixmapDropShadowFilter::boundingRectFor(const QRectF &rect) const-
1299{-
1300 Q_D(const QPixmapDropShadowFilter);-
1301 return rect.united(rect.translated(d->offset).adjusted(-d->radius, -d->radius, d->radius, d->radius));
never executed: return rect.united(rect.translated(d->offset).adjusted(-d->radius, -d->radius, d->radius, d->radius));
0
1302}-
1303-
1304/*!-
1305 \internal-
1306 */-
1307void QPixmapDropShadowFilter::draw(QPainter *p,-
1308 const QPointF &pos,-
1309 const QPixmap &px,-
1310 const QRectF &src) const-
1311{-
1312 Q_D(const QPixmapDropShadowFilter);-
1313-
1314 if (px.isNull())
px.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
1315 return;
never executed: return;
0
1316-
1317 QImage tmp(px.size(), QImage::Format_ARGB32_Premultiplied);-
1318 tmp.fill(0);-
1319 QPainter tmpPainter(&tmp);-
1320 tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);-
1321 tmpPainter.drawPixmap(d->offset, px);-
1322 tmpPainter.end();-
1323-
1324 // blur the alpha channel-
1325 QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied);-
1326 blurred.fill(0);-
1327 QPainter blurPainter(&blurred);-
1328 qt_blurImage(&blurPainter, tmp, d->radius, false, true);-
1329 blurPainter.end();-
1330-
1331 tmp = blurred;-
1332-
1333 // blacken the image...-
1334 tmpPainter.begin(&tmp);-
1335 tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);-
1336 tmpPainter.fillRect(tmp.rect(), d->color);-
1337 tmpPainter.end();-
1338-
1339 // draw the blurred drop shadow...-
1340 p->drawImage(pos, tmp);-
1341-
1342 // Draw the actual pixmap...-
1343 p->drawPixmap(pos, px, src);-
1344}
never executed: end of block
0
1345-
1346QT_END_NAMESPACE-
1347-
1348#include "moc_qpixmapfilter_p.cpp"-
1349-
1350#endif //QT_NO_GRAPHICSEFFECT-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9