Qt 4.8
qpixmapfilter_vg.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtOpenVG 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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qpixmapfilter_vg_p.h"
43 #include "qvgimagepool_p.h"
44 #include <QtCore/qvarlengtharray.h>
45 #include <QtGui/qpainter.h>
46 
48 
49 #if !defined(QT_SHIVAVG)
50 
53 {
54 }
55 
57 {
58 }
59 
60 extern void qt_vg_drawVGImage
61  (QPainter *painter, const QPointF& pos, VGImage vgImg);
62 extern void qt_vg_drawVGImageStencil
63  (QPainter *painter, const QPointF& pos, VGImage vgImg, const QBrush& brush);
64 
66  (QPainter *painter, const QPointF &dest,
67  const QPixmap &src, const QRectF &srcRect) const
68 {
69  if (src.isNull())
70  return;
71 
73  // The pixmap data is not an instance of QVGPixmapData, so fall
74  // back to the default convolution filter implementation.
75  QPixmapConvolutionFilter::draw(painter, dest, src, srcRect);
76  return;
77  }
78 
79  QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());
80 
81  VGImage srcImage = pd->toVGImage();
82  if (srcImage == VG_INVALID_HANDLE)
83  return;
84 
85  QSize size = pd->size();
86  VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
87  (VG_sARGB_8888_PRE, size.width(), size.height(),
88  VG_IMAGE_QUALITY_FASTER, pd);
89  if (dstImage == VG_INVALID_HANDLE)
90  return;
91 
92  int kernelWidth = rows();
93  int kernelHeight = columns();
94  const qreal *kern = convolutionKernel();
96  for (int i = 0; i < kernelWidth; ++i) {
97  for (int j = 0; j < kernelHeight; ++j) {
98  kernel.append((VGshort)(kern[j * kernelWidth + i] * 1024.0f));
99  }
100  }
101 
102  VGfloat values[4];
103  values[0] = 0.0f;
104  values[1] = 0.0f;
105  values[2] = 0.0f;
106  values[3] = 0.0f;
107  vgSetfv(VG_TILE_FILL_COLOR, 4, values);
108 
109  vgConvolve(dstImage, srcImage,
110  kernelWidth, kernelHeight, 0, 0,
111  kernel.constData(), 1.0f / 1024.0f, 0.0f,
112  VG_TILE_FILL);
113 
114  VGImage child = VG_INVALID_HANDLE;
115 
116  if (srcRect.isNull() ||
117  (srcRect.topLeft().isNull() && srcRect.size() == size)) {
118  child = dstImage;
119  } else {
120  QRect src = srcRect.toRect();
121  child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height());
122  }
123 
124  qt_vg_drawVGImage(painter, dest, child);
125 
126  if(child != dstImage)
127  vgDestroyImage(child);
128  QVGImagePool::instance()->releaseImage(0, dstImage);
129 }
130 
133 {
134 }
135 
137 {
138 }
139 
140 void QVGPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
141 {
142  if (src.isNull())
143  return;
144 
145  if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
146  // The pixmap data is not an instance of QVGPixmapData, so fall
147  // back to the default colorize filter implementation.
148  QPixmapColorizeFilter::draw(painter, dest, src, srcRect);
149  return;
150  }
151 
152  QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());
153 
154  VGImage srcImage = pd->toVGImage();
155  if (srcImage == VG_INVALID_HANDLE)
156  return;
157 
158  QSize size = pd->size();
159  VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
160  (VG_sARGB_8888_PRE, size.width(), size.height(),
161  VG_IMAGE_QUALITY_FASTER, pd);
162  if (dstImage == VG_INVALID_HANDLE)
163  return;
164 
165  // Determine the weights for the matrix from the color and strength.
166  QColor c = color();
167  VGfloat strength = this->strength();
168  VGfloat weights[3];
169  VGfloat invweights[3];
170  VGfloat alpha = c.alphaF();
171  weights[0] = c.redF() * alpha;
172  weights[1] = c.greenF() * alpha;
173  weights[2] = c.blueF() * alpha;
174  invweights[0] = (1.0f - weights[0]) * strength;
175  invweights[1] = (1.0f - weights[1]) * strength;
176  invweights[2] = (1.0f - weights[2]) * strength;
177 
178  // Grayscale weights.
179  static const VGfloat redGray = 11.0f / 32.0f;
180  static const VGfloat greenGray = 16.0f / 32.0f;
181  static const VGfloat blueGray = 1.0f - (redGray + greenGray);
182 
183  VGfloat matrix[5][4];
184  matrix[0][0] = redGray * invweights[0] + (1.0f - strength);
185  matrix[0][1] = redGray * invweights[1];
186  matrix[0][2] = redGray * invweights[2];
187  matrix[0][3] = 0.0f;
188  matrix[1][0] = greenGray * invweights[0];
189  matrix[1][1] = greenGray * invweights[1] + (1.0f - strength);
190  matrix[1][2] = greenGray * invweights[2];
191  matrix[1][3] = 0.0f;
192  matrix[2][0] = blueGray * invweights[0];
193  matrix[2][1] = blueGray * invweights[1];
194  matrix[2][2] = blueGray * invweights[2] + (1.0f - strength);
195  matrix[2][3] = 0.0f;
196  matrix[3][0] = 0.0f;
197  matrix[3][1] = 0.0f;
198  matrix[3][2] = 0.0f;
199  matrix[3][3] = 1.0f;
200  matrix[4][0] = weights[0] * strength;
201  matrix[4][1] = weights[1] * strength;
202  matrix[4][2] = weights[2] * strength;
203  matrix[4][3] = 0.0f;
204 
205  vgColorMatrix(dstImage, srcImage, matrix[0]);
206 
207  VGImage child = VG_INVALID_HANDLE;
208 
209  if (srcRect.isNull() ||
210  (srcRect.topLeft().isNull() && srcRect.size() == size)) {
211  child = dstImage;
212  } else {
213  QRect src = srcRect.toRect();
214  child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height());
215  }
216 
217  qt_vg_drawVGImage(painter, dest, child);
218 
219  if(child != dstImage)
220  vgDestroyImage(child);
221  QVGImagePool::instance()->releaseImage(0, dstImage);
222 }
223 
226 {
227 }
228 
230 {
231 }
232 
233 void QVGPixmapDropShadowFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
234 {
235  if (src.isNull())
236  return;
237 
238  if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
239  // The pixmap data is not an instance of QVGPixmapData, so fall
240  // back to the default drop shadow filter implementation.
241  QPixmapDropShadowFilter::draw(painter, dest, src, srcRect);
242  return;
243  }
244 
245  QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());
246 
247  VGImage srcImage = pd->toVGImage();
248  if (srcImage == VG_INVALID_HANDLE)
249  return;
250 
251  QSize size = pd->size();
252  VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
253  (VG_A_8, size.width(), size.height(),
254  VG_IMAGE_QUALITY_FASTER, pd);
255  if (dstImage == VG_INVALID_HANDLE)
256  return;
257 
258  // Clamp the radius range. We divide by 2 because the OpenVG blur
259  // is "too blurry" compared to the default raster implementation.
260  VGfloat maxRadius = VGfloat(vgGeti(VG_MAX_GAUSSIAN_STD_DEVIATION));
261  VGfloat radiusF = VGfloat(blurRadius()) / 2.0f;
262  if (radiusF < 0.001f)
263  radiusF = 0.001f;
264  else if (radiusF > maxRadius)
265  radiusF = maxRadius;
266 
267  // Blur the blackened source image.
268  vgGaussianBlur(dstImage, srcImage, radiusF, radiusF, VG_TILE_PAD);
269 
270  VGImage child = VG_INVALID_HANDLE;
271 
272  QRect srect;
273  if (srcRect.isNull() ||
274  (srcRect.topLeft().isNull() && srcRect.size() == size)) {
275  child = dstImage;
276  srect = QRect(0, 0, size.width(), size.height());
277  } else {
278  srect = srcRect.toRect();
279  child = vgChildImage(dstImage, srect.x(), srect.y(), srect.width(), srect.height());
280  }
281 
282  qt_vg_drawVGImageStencil(painter, dest + offset(), child, color());
283 
284  if(child != dstImage)
285  vgDestroyImage(child);
286  QVGImagePool::instance()->releaseImage(0, dstImage);
287 
288  // Now draw the actual pixmap over the top.
289  painter->drawPixmap(dest, src, srect);
290 }
291 
293  : QPixmapBlurFilter(parent)
294 {
295 }
296 
298 {
299 }
300 
301 void QVGPixmapBlurFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
302 {
303  if (src.isNull())
304  return;
305 
306  if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
307  // The pixmap data is not an instance of QVGPixmapData, so fall
308  // back to the default blur filter implementation.
309  QPixmapBlurFilter::draw(painter, dest, src, srcRect);
310  return;
311  }
312 
313  QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());
314 
315  VGImage srcImage = pd->toVGImage();
316  if (srcImage == VG_INVALID_HANDLE)
317  return;
318 
319  QSize size = pd->size();
320  VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
321  (VG_sARGB_8888_PRE, size.width(), size.height(),
322  VG_IMAGE_QUALITY_FASTER, pd);
323  if (dstImage == VG_INVALID_HANDLE)
324  return;
325 
326  // Clamp the radius range. We divide by 2 because the OpenVG blur
327  // is "too blurry" compared to the default raster implementation.
328  VGfloat maxRadius = VGfloat(vgGeti(VG_MAX_GAUSSIAN_STD_DEVIATION));
329  VGfloat radiusF = VGfloat(radius()) / 2.0f;
330  if (radiusF < 0.001f)
331  radiusF = 0.001f;
332  else if (radiusF > maxRadius)
333  radiusF = maxRadius;
334 
335  vgGaussianBlur(dstImage, srcImage, radiusF, radiusF, VG_TILE_PAD);
336 
337  VGImage child = VG_INVALID_HANDLE;
338 
339  if (srcRect.isNull() ||
340  (srcRect.topLeft().isNull() && srcRect.size() == size)) {
341  child = dstImage;
342  } else {
343  QRect src = srcRect.toRect();
344  child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height());
345  }
346 
347  qt_vg_drawVGImage(painter, dest, child);
348 
349  if(child != dstImage)
350  vgDestroyImage(child);
351  QVGImagePool::instance()->releaseImage(0, dstImage);
352 }
353 
354 #endif
355 
qreal radius() const
Gets the radius of the blur filter.
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
QSize size() const
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
const T * constData() const
qreal alphaF() const
Returns the alpha color component of this color.
Definition: qcolor.cpp:1106
double qreal
Definition: qglobal.h:1193
unsigned char c[8]
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
qreal greenF() const
Returns the green color component of this color.
Definition: qcolor.cpp:1241
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
QPointF topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:539
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
void append(const T &t)
void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect=QRectF()) const
virtual VGImage createTemporaryImage(VGImageFormat format, VGint width, VGint height, VGbitfield allowedQuality, QVGPixmapData *keepData=0)
int width() const
Returns the width.
Definition: qsize.h:126
QPainter * painter() const
Returns the paint engine&#39;s painter.
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
virtual VGImage toVGImage()
QColor color() const
Gets the color of the colorize filter.
const qreal * convolutionKernel() const
Gets the convolution kernel data.
The QPixmapColorizeFilter class provides colorizing filtering for pixmaps.
void draw(QPainter *p, const QPointF &pos, const QPixmap &px, const QRectF &src) const
The QPixmapBlurFilter class provides blur filtering for pixmaps.
qreal blurRadius() const
Returns the radius in pixels of the blur on the drop shadow.
ClassId classId() const
quint16 values[128]
QRect toRect() const
Returns a QRect based on the values of this rectangle.
Definition: qrect.h:845
int rows() const
Gets the number of rows in the convolution kernel.
The QBrush class defines the fill pattern of shapes drawn by QPainter.
Definition: qbrush.h:76
static QVGImagePool * instance()
int columns() const
Gets the number of columns in the convolution kernel.
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
QColor color() const
Returns the color of the drop shadow.
QVGPixmapBlurFilter(QObject *parent=0)
qreal redF() const
Returns the red color component of this color.
Definition: qcolor.cpp:1213
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
The QPixmapDropShadowFilter class is a convenience class for drawing pixmaps with drop shadows...
int height() const
Returns the height.
Definition: qsize.h:129
qreal blueF() const
Returns the blue color component of this color.
Definition: qcolor.cpp:1269
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
bool isNull() const
Returns true if both the x and y coordinates are set to +0.
Definition: qpoint.h:277
QSizeF size() const
Returns the size of the rectangle.
Definition: qrect.h:713
The QPixmap class is an off-screen image representation that can be used as a paint device...
Definition: qpixmap.h:71
The QPixmapConvolutionFilter class provides convolution filtering for pixmaps.
void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Draws the rectangular portion source of the given pixmap into the given target in the paint device...
Definition: qpainter.cpp:5619
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
bool isNull() const
Returns true if this is a null pixmap; otherwise returns false.
Definition: qpixmap.cpp:615
void qt_vg_drawVGImage(QPainter *painter, const QPointF &pos, VGImage vgImg)
void qt_vg_drawVGImageStencil(QPainter *painter, const QPointF &pos, VGImage vgImg, const QBrush &brush)
void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect=QRectF()) const
qreal strength() const
Gets the strength of the colorize filter, 1.0 means full colorized while 0.0 equals to no filtering a...
void draw(QPainter *p, const QPointF &pos, const QPixmap &px, const QRectF &src=QRectF()) const
bool isNull() const
Returns true if the rectangle is a null rectangle, otherwise returns false.
Definition: qrect.h:655
virtual void releaseImage(QVGPixmapData *data, VGImage image)
QPointF offset() const
Returns the shadow offset in pixels.
void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect=QRectF()) const
void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect=QRectF()) const
QPixmapData * pixmapData() const
Definition: qpixmap.cpp:2277