Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qpixmap_blitter.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qpixmap_blitter_p.h"
5
6#include <qpainter.h>
7#include <qimage.h>
8#include <qrandom.h>
9#include <qscreen.h>
10
11#include <private/qguiapplication_p.h>
12#include <private/qblittable_p.h>
13
14#include <private/qdrawhelper_p.h>
15#include <private/qfont_p.h>
16
17#ifndef QT_NO_BLITTABLE
19
20static int global_ser_no = 0;
21
23 : QPlatformPixmap(QPlatformPixmap::PixmapType,BlitterClass)
24 , m_alpha(false)
25 , m_devicePixelRatio(1.0)
26#ifdef QT_BLITTER_RASTEROVERLAY
27 ,m_rasterOverlay(0), m_unmergedCopy(0)
28#endif //QT_BLITTER_RASTEROVERLAY
29{
31}
32
34{
35#ifdef QT_BLITTER_RASTEROVERLAY
36 delete m_rasterOverlay;
37 delete m_unmergedCopy;
38#endif //QT_BLITTER_RASTEROVERLAY
39}
40
42{
43 if (!m_blittable) {
44 QBlittablePlatformPixmap *that = const_cast<QBlittablePlatformPixmap *>(this);
46 }
47
48 return m_blittable.data();
49}
50
56
58{
59 m_blittable.reset(nullptr);
60 m_engine.reset(nullptr);
62 w = width;
63 h = height;
64 is_null = (w <= 0 || h <= 0);
66}
67
69{
70 switch (metric) {
72 return w;
74 return h;
76 return qRound(w * 25.4 / qt_defaultDpiX());
78 return qRound(h * 25.4 / qt_defaultDpiY());
80 return 32;
83 return qt_defaultDpiX();
86 return qt_defaultDpiY();
88 return devicePixelRatio();
91 default:
92 qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric);
93 break;
94 }
95
96 return 0;
97}
98
100{
101 if (blittable()->capabilities() & QBlittable::AlphaFillRectCapability) {
102 blittable()->unlock();
104 } else if (color.alpha() == 255 && blittable()->capabilities() & QBlittable::SolidRectCapability) {
105 blittable()->unlock();
106 blittable()->fillRect(QRectF(0,0,w,h),color);
107 } else {
108 // Need to be backed with an alpha channel now. It would be nice
109 // if we could just change the format, e.g. when going from
110 // RGB32 -> ARGB8888.
111 if (color.alpha() != 255 && !hasAlphaChannel()) {
112 m_blittable.reset(nullptr);
113 m_engine.reset(nullptr);
114 m_alpha = true;
115 }
116
117 blittable()->lock()->fill(color);
118 }
119
120}
121
126
128{
129 return blittable()->lock()->copy();
130}
131
136
138 Qt::ImageConversionFlags flags)
139{
140 m_alpha = image.hasAlphaChannel();
141 m_devicePixelRatio = image.devicePixelRatio();
142 resize(image.width(),image.height());
144 QImage *thisImg = buffer();
145
146 QImage correctFormatPic = image;
147 if (correctFormatPic.format() != thisImg->format())
148 correctFormatPic = correctFormatPic.convertToFormat(thisImg->format(), flags);
149
150 uchar *mem = thisImg->bits();
151 const uchar *bits = correctFormatPic.constBits();
152 qsizetype bytesCopied = 0;
153 while (bytesCopied < correctFormatPic.sizeInBytes()) {
154 memcpy(mem,bits,correctFormatPic.bytesPerLine());
155 mem += thisImg->bytesPerLine();
156 bits += correctFormatPic.bytesPerLine();
157 bytesCopied+=correctFormatPic.bytesPerLine();
158 }
159}
160
165
167{
168 m_devicePixelRatio = scaleFactor;
169}
170
172{
173 if (!m_engine) {
174 QBlittablePlatformPixmap *that = const_cast<QBlittablePlatformPixmap *>(this);
175 that->m_engine.reset(new QBlitterPaintEngine(that));
176 }
177 return m_engine.data();
178}
179
180#ifdef QT_BLITTER_RASTEROVERLAY
181
182static bool showRasterOverlay = !qEnvironmentVariableIsEmpty("QT_BLITTER_RASTEROVERLAY");
183
184void QBlittablePlatformPixmap::mergeOverlay()
185{
186 if (m_unmergedCopy || !showRasterOverlay)
187 return;
188 m_unmergedCopy = new QImage(buffer()->copy());
189 QPainter p(buffer());
190 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
191 p.drawImage(0,0,*overlay());
192 p.end();
193}
194
195void QBlittablePlatformPixmap::unmergeOverlay()
196{
197 if (!m_unmergedCopy || !showRasterOverlay)
198 return;
199 QPainter p(buffer());
200 p.setCompositionMode(QPainter::CompositionMode_Source);
201 p.drawImage(0,0,*m_unmergedCopy);
202 p.end();
203
204 delete m_unmergedCopy;
205 m_unmergedCopy = 0;
206}
207
208QImage *QBlittablePlatformPixmap::overlay()
209{
210 if (!m_rasterOverlay||
211 m_rasterOverlay->size() != QSize(w,h)){
212 m_rasterOverlay = new QImage(w,h,QImage::Format_ARGB32_Premultiplied);
213 m_rasterOverlay->fill(0x00000000);
214 uint color = QRandomGenerator::global()->bounded(11)+7;
215 m_overlayColor = QColor(Qt::GlobalColor(color));
216 m_overlayColor.setAlpha(0x88);
217
218 }
219 return m_rasterOverlay;
220}
221
222void QBlittablePlatformPixmap::markRasterOverlayImpl(const QRectF &rect)
223{
224 if (!showRasterOverlay)
225 return;
226 QRectF transformationRect = clipAndTransformRect(rect);
227 if (!transformationRect.isEmpty()) {
228 QPainter p(overlay());
229 p.setBrush(m_overlayColor);
230 p.setCompositionMode(QPainter::CompositionMode_Source);
231 p.fillRect(transformationRect,QBrush(m_overlayColor));
232 }
233}
234
235void QBlittablePlatformPixmap::unmarkRasterOverlayImpl(const QRectF &rect)
236{
237 if (!showRasterOverlay)
238 return;
239 QRectF transformationRect = clipAndTransformRect(rect);
240 if (!transformationRect.isEmpty()) {
241 QPainter p(overlay());
242 QColor color(0x00,0x00,0x00,0x00);
243 p.setBrush(color);
244 p.setCompositionMode(QPainter::CompositionMode_Source);
245 p.fillRect(transformationRect,QBrush(color));
246 }
247}
248
249QRectF QBlittablePlatformPixmap::clipAndTransformRect(const QRectF &rect) const
250{
251 QRectF transformationRect = rect;
252 paintEngine();
253 if (m_engine->state()) {
254 transformationRect = m_engine->state()->matrix.mapRect(rect);
255 const QClipData *clipData = m_engine->clip();
256 if (clipData) {
257 if (clipData->hasRectClip) {
258 transformationRect &= clipData->clipRect;
259 } else if (clipData->hasRegionClip) {
260 for (const QRect &rect : clipData->clipRegion)
261 transformationRect &= rect;
262 }
263 }
264 }
265 return transformationRect;
266}
267
268#endif //QT_BLITTER_RASTEROVERLAY
269
271
272#endif //QT_NO_BLITTABLE
virtual QBlittable * createBlittable(const QSize &size, bool alpha) const =0
void setBlittable(QBlittable *blittable)
void resize(int width, int height) override
QBlittable * blittable() const
bool hasAlphaChannel() const override
QImage toImage() const override
void markRasterOverlay(const QRectF &)
qreal devicePixelRatio() const override
void setDevicePixelRatio(qreal scaleFactor) override
void fromImage(const QImage &image, Qt::ImageConversionFlags flags) override
void fill(const QColor &color) override
int metric(QPaintDevice::PaintDeviceMetric metric) const override
QScopedPointer< QBlitterPaintEngine > m_engine
QPaintEngine * paintEngine() const override
QScopedPointer< QBlittable > m_blittable
QImage * buffer() override
QSize size() const
virtual void alphaFillRect(const QRectF &rect, const QColor &color, QPainter::CompositionMode cmode)
QImage * lock()
virtual void fillRect(const QRectF &rect, const QColor &color)=0
@ SolidRectCapability
@ AlphaFillRectCapability
void unlock()
\inmodule QtGui
Definition qbrush.h:30
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
QScreen * primaryScreen
the primary (or default) screen of the application.
\inmodule QtGui
Definition qimage.h:37
bool hasAlphaChannel() const
Returns true if the image has a format that respects the alpha channel, otherwise returns false.
Definition qimage.cpp:4589
QImage copy(const QRect &rect=QRect()) const
Returns a sub-area of the image as a new image.
@ Format_ARGB32_Premultiplied
Definition qimage.h:48
void fill(uint pixel)
Fills the entire image with the given pixelValue.
Definition qimage.cpp:1758
@ PdmDevicePixelRatioScaled
static qreal devicePixelRatioFScale()
\inmodule QtGui
QTransform matrix
Definition qpainter_p.h:130
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
@ CompositionMode_SourceOver
Definition qpainter.h:98
@ CompositionMode_Source
Definition qpainter.h:101
The QPlatformPixmap class provides an abstraction for native pixmaps.
int height() const
void setSerialNumber(int serNo)
virtual void copy(const QPlatformPixmap *data, const QRect &rect)
int width() const
static Q_DECL_CONST_FUNCTION QRandomGenerator * global()
\threadsafe
Definition qrandom.h:275
QRasterPaintEngineState * state()
void clip(const QVectorPath &path, Qt::ClipOperation op) override
\inmodule QtCore\reentrant
Definition qrect.h:484
\inmodule QtCore\reentrant
Definition qrect.h:30
T * data() const noexcept
Returns the value of the pointer referenced by this object.
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
int depth
the color depth of the screen
Definition qscreen.h:40
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
QRect mapRect(const QRect &) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
rect
[4]
Combined button and popup list for selecting options.
GlobalColor
Definition qnamespace.h:27
Definition image.cpp:4
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:327
Q_GUI_EXPORT int qt_defaultDpiX()
Definition qfont.cpp:110
Q_GUI_EXPORT int qt_defaultDpiY()
Definition qfont.cpp:125
#define qWarning
Definition qlogging.h:166
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLint GLsizei width
GLuint color
[2]
GLbitfield flags
GLfloat GLfloat GLfloat GLfloat h
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
GLfloat GLfloat p
[1]
static QT_BEGIN_NAMESPACE int global_ser_no
Q_CORE_EXPORT bool qEnvironmentVariableIsEmpty(const char *varName) noexcept
unsigned char uchar
Definition qtypes.h:32
ptrdiff_t qsizetype
Definition qtypes.h:165
unsigned int uint
Definition qtypes.h:34
double qreal
Definition qtypes.h:187