Qt 4.8
qpixmap_blitter.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 QtGui 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 "qpixmap_blitter_p.h"
43 
44 #include <qpainter.h>
45 #include <qimage.h>
46 
47 #include <private/qapplication_p.h>
48 #include <private/qgraphicssystem_p.h>
49 #include <private/qblittable_p.h>
50 
51 #include <private/qdrawhelper_p.h>
52 #include <private/qfont_p.h>
53 
54 #ifndef QT_NO_BLITTABLE
56 
57 static int global_ser_no = 0;
58 
60  : QPixmapData(QPixmapData::PixmapType,BlitterClass)
61  , m_alpha(false)
62 #ifdef QT_BLITTER_RASTEROVERLAY
63  ,m_rasterOverlay(0), m_unmergedCopy(0)
64 #endif //QT_BLITTER_RASTEROVERLAY
65 {
67 }
68 
70 {
71 #ifdef QT_BLITTER_RASTEROVERLAY
72  delete m_rasterOverlay;
73  delete m_unmergedCopy;
74 #endif //QT_BLITTER_RASTEROVERLAY
75 }
76 
78 {
79  if (!m_blittable) {
80  QBlittablePixmapData *that = const_cast<QBlittablePixmapData *>(this);
82  }
83 
84  return m_blittable.data();
85 }
86 
88 {
89  resize(blittable->size().width(),blittable->size().height());
90  m_blittable.reset(blittable);
91 }
92 
94 {
95 
96  m_blittable.reset(0);
97  m_engine.reset(0);
98 #ifdef Q_WS_QPA
99  d = QApplicationPrivate::platformIntegration()->screens().at(0)->depth();
100 #endif
101  w = width;
102  h = height;
103  is_null = (w <= 0 || h <= 0);
105 }
106 
108 {
109  switch (metric) {
111  return w;
113  return h;
115  return qRound(w * 25.4 / qt_defaultDpiX());
117  return qRound(h * 25.4 / qt_defaultDpiY());
119  return 32;
120  case QPaintDevice::PdmDpiX: // fall-through
122  return qt_defaultDpiX();
123  case QPaintDevice::PdmDpiY: // fall-through
125  return qt_defaultDpiY();
126  default:
127  qWarning("QRasterPixmapData::metric(): Unhandled metric type %d", metric);
128  break;
129  }
130 
131  return 0;
132 }
133 
135 {
136  if (blittable()->capabilities() & QBlittable::AlphaFillRectCapability) {
137  blittable()->unlock();
139  } else if (color.alpha() == 255 && blittable()->capabilities() & QBlittable::SolidRectCapability) {
140  blittable()->unlock();
141  blittable()->fillRect(QRectF(0,0,w,h),color);
142  } else {
143  // Need to be backed with an alpha channel now. It would be nice
144  // if we could just change the format, e.g. when going from
145  // RGB32 -> ARGB8888.
146  if (color.alpha() != 255 && !hasAlphaChannel()) {
147  m_blittable.reset(0);
148  m_engine.reset(0);
149  m_alpha = true;
150  }
151 
152  uint pixel;
153  switch (blittable()->lock()->format()) {
155  pixel = PREMUL(color.rgba());
156  break;
158  pixel = qargb8565(color.rgba()).rawValue();
159  break;
161  pixel = qargb8555(color.rgba()).rawValue();
162  break;
164  pixel = qargb6666(color.rgba()).rawValue();
165  break;
167  pixel = qargb4444(color.rgba()).rawValue();
168  break;
169  default:
170  pixel = color.rgba();
171  break;
172  }
173  //so premultiplied formats are supported and ARGB32 and RGB32
174  blittable()->lock()->fill(pixel);
175  }
176 
177 }
178 
180 {
181  return blittable()->lock();
182 }
183 
185 {
186  return blittable()->lock()->copy();
187 }
188 
190 {
191  return blittable()->lock()->hasAlphaChannel();
192 }
193 
195  Qt::ImageConversionFlags flags)
196 {
197  m_alpha = image.hasAlphaChannel();
198  resize(image.width(),image.height());
199  markRasterOverlay(QRect(0,0,w,h));
200  QImage *thisImg = buffer();
201 
202  QImage correctFormatPic = image;
203  if (correctFormatPic.format() != thisImg->format())
204  correctFormatPic = correctFormatPic.convertToFormat(thisImg->format(), flags);
205 
206  uchar *mem = thisImg->bits();
207  const uchar *bits = correctFormatPic.bits();
208  int bytesCopied = 0;
209  while (bytesCopied < correctFormatPic.byteCount()) {
210  memcpy(mem,bits,correctFormatPic.bytesPerLine());
211  mem += thisImg->bytesPerLine();
212  bits += correctFormatPic.bytesPerLine();
213  bytesCopied+=correctFormatPic.bytesPerLine();
214  }
215 }
216 
218 {
219  if (!m_engine) {
220  QBlittablePixmapData *that = const_cast<QBlittablePixmapData *>(this);
221  that->m_engine.reset(new QBlitterPaintEngine(that));
222  }
223  return m_engine.data();
224 }
225 
226 #ifdef QT_BLITTER_RASTEROVERLAY
227 
228 static bool showRasterOverlay = !qgetenv("QT_BLITTER_RASTEROVERLAY").isEmpty();
229 
230 void QBlittablePixmapData::mergeOverlay()
231 {
232  if (m_unmergedCopy || !showRasterOverlay)
233  return;
234  m_unmergedCopy = new QImage(buffer()->copy());
235  QPainter p(buffer());
237  p.drawImage(0,0,*overlay());
238  p.end();
239 }
240 
241 void QBlittablePixmapData::unmergeOverlay()
242 {
243  if (!m_unmergedCopy || !showRasterOverlay)
244  return;
245  QPainter p(buffer());
247  p.drawImage(0,0,*m_unmergedCopy);
248  p.end();
249 
250  delete m_unmergedCopy;
251  m_unmergedCopy = 0;
252 }
253 
254 QImage *QBlittablePixmapData::overlay()
255 {
256  if (!m_rasterOverlay||
257  m_rasterOverlay->size() != QSize(w,h)){
258  m_rasterOverlay = new QImage(w,h,QImage::Format_ARGB32_Premultiplied);
259  m_rasterOverlay->fill(0x00000000);
260  uint color = (qrand() % 11)+7;
261  m_overlayColor = QColor(Qt::GlobalColor(color));
262  m_overlayColor.setAlpha(0x88);
263 
264  }
265  return m_rasterOverlay;
266 }
267 
268 void QBlittablePixmapData::markRasterOverlayImpl(const QRectF &rect)
269 {
270  if (!showRasterOverlay)
271  return;
272  QRectF transformationRect = clipAndTransformRect(rect);
273  if(!transformationRect.isEmpty()) {
274  QPainter p(overlay());
275  p.setBrush(m_overlayColor);
277  p.fillRect(transformationRect,QBrush(m_overlayColor));
278  }
279 }
280 
281 void QBlittablePixmapData::unmarkRasterOverlayImpl(const QRectF &rect)
282 {
283  if (!showRasterOverlay)
284  return;
285  QRectF transformationRect = clipAndTransformRect(rect);
286  if (!transformationRect.isEmpty()) {
287  QPainter p(overlay());
288  QColor color(0x00,0x00,0x00,0x00);
289  p.setBrush(color);
291  p.fillRect(transformationRect,QBrush(color));
292  }
293 }
294 
295 QRectF QBlittablePixmapData::clipAndTransformRect(const QRectF &rect) const
296 {
297  QRectF transformationRect = rect;
298  paintEngine();
299  if (m_engine->state()) {
300  transformationRect = m_engine->state()->matrix.mapRect(rect);
301  const QClipData *clipData = m_engine->clip();
302  if (clipData) {
303  if (clipData->hasRectClip) {
304  transformationRect &= clipData->clipRect;
305  } else if (clipData->hasRegionClip) {
306  const QVector<QRect> rects = clipData->clipRegion.rects();
307  for (int i = 0; i < rects.size(); i++) {
308  transformationRect &= rects.at(i);
309  }
310  }
311  }
312  }
313  return transformationRect;
314 }
315 
316 #endif //QT_BLITTER_RASTEROVERLAY
317 
319 
320 #endif //QT_NO_BLITTABLE
virtual void fillRect(const QRectF &rect, const QColor &color)=0
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
QImage copy(const QRect &rect=QRect()) const
Returns a sub-area of the image as a new image.
Definition: qimage.cpp:1410
void fill(const QColor &color)
void fromImage(const QImage &image, Qt::ImageConversionFlags flags)
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QRasterPaintEngineState * state()
T * data() const
Returns the value of the pointer referenced by this object.
Q_GUI_EXPORT int qt_defaultDpiY()
Definition: qfont.cpp:201
void fill(uint pixel)
Fills the entire image with the given pixelValue.
Definition: qimage.cpp:2032
Q_GUI_EXPORT int qt_defaultDpiX()
Definition: qfont.cpp:162
int width() const
int byteCount() const
Returns the number of bytes occupied by the image data.
Definition: qimage.cpp:1800
bool hasAlphaChannel() const
Returns true if the image has a format that respects the alpha channel, otherwise returns false...
Definition: qimage.cpp:6495
int bytesPerLine() const
Returns the number of bytes per image scanline.
Definition: qimage.cpp:1812
QImage * lock()
Definition: qblittable.cpp:89
void setBlittable(QBlittable *blittable)
QTransform matrix
Definition: qpainter_p.h:161
Q_CORE_EXPORT int qrand()
Format format() const
Returns the format of the image.
Definition: qimage.cpp:2305
GlobalColor
Definition: qnamespace.h:104
void markRasterOverlay(const QRectF &)
unsigned char uchar
Definition: qglobal.h:994
int width() const
Returns the width.
Definition: qsize.h:126
QRect mapRect(const QRect &) const
Creates and returns a QRect object that is a copy of the given rectangle, mapped into the coordinate ...
#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
bool hasAlphaChannel() const
Q_STATIC_INLINE_FUNCTION uint PREMUL(uint x)
Q_CORE_EXPORT void qWarning(const char *,...)
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
unsigned int uint
Definition: qglobal.h:996
void clip(const QVectorPath &path, Qt::ClipOperation op)
The QPaintEngine class provides an abstract definition of how QPainter draws to a given device on a g...
Definition: qpaintengine.h:90
QScopedPointer< QBlitterPaintEngine > m_engine
void reset(T *other=0)
Deletes the existing object it is pointing to if any, and sets its pointer to other.
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
Capabilities capabilities() const
Definition: qblittable.cpp:71
The QBrush class defines the fill pattern of shapes drawn by QPainter.
Definition: qbrush.h:76
uchar * bits()
Returns a pointer to the first pixel data.
Definition: qimage.cpp:1946
int width() const
Returns the width of the image.
Definition: qimage.cpp:1557
QPaintEngine * paintEngine() const
QImage convertToFormat(Format f, Qt::ImageConversionFlags flags=Qt::AutoColor) const Q_REQUIRED_RESULT
Returns a copy of the image in the given format.
Definition: qimage.cpp:3966
void setCompositionMode(CompositionMode mode)
Sets the composition mode to the given mode.
Definition: qpainter.cpp:2422
virtual void alphaFillRect(const QRectF &rect, const QColor &color, QPainter::CompositionMode cmode)
Definition: qblittable_p.h:81
ushort alpha
Returns the alpha color component of this color.
Definition: qcolor.h:242
void unlock()
Definition: qblittable.cpp:100
QVector< QRect > rects() const
Returns an array of non-overlapping rectangles that make up the region.
Definition: qregion.cpp:4412
void setBrush(const QBrush &brush)
Sets the painter&#39;s brush to the given brush.
Definition: qpainter.cpp:4171
static QReadWriteLock lock
Definition: proxyconf.cpp:399
virtual void copy(const QPixmapData *data, const QRect &rect)
int height() const
Returns the height.
Definition: qsize.h:129
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
int height() const
Returns the height of the image.
Definition: qimage.cpp:1572
void drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect, Qt::ImageConversionFlags flags=Qt::AutoColor)
Definition: qpainter.cpp:5936
void resize(int width, int height)
static int global_ser_no
int height() const
QSize size() const
Definition: qblittable.cpp:77
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
virtual QBlittable * createBlittable(const QSize &size, bool alpha) const =0
QScopedPointer< QBlittable > m_blittable
QRgb rgba() const
Returns the RGB value of the color, including its alpha.
Definition: qcolor.cpp:1019
QBlittable * blittable() const
bool isEmpty() const
Returns true if the rectangle is empty, otherwise returns false.
Definition: qrect.h:658
int metric(QPaintDevice::PaintDeviceMetric metric) const
void setSerialNumber(int serNo)
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
bool end()
Ends painting.
Definition: qpainter.cpp:1929
void fillRect(const QRectF &, const QBrush &)
Fills the given rectangle with the brush specified.
Definition: qpainter.cpp:7420