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

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