11#include <private/qguiapplication_p.h>
12#include <private/qblittable_p.h>
14#include <private/qdrawhelper_p.h>
15#include <private/qfont_p.h>
17#ifndef QT_NO_BLITTABLE
22QBlittablePlatformPixmap::QBlittablePlatformPixmap()
23 : QPlatformPixmap(QPlatformPixmap::PixmapType,BlitterClass)
25 , m_devicePixelRatio(1.0)
26#ifdef QT_BLITTER_RASTEROVERLAY
27 ,m_rasterOverlay(0), m_unmergedCopy(0)
30 setSerialNumber(++global_ser_no);
33QBlittablePlatformPixmap::~QBlittablePlatformPixmap()
35#ifdef QT_BLITTER_RASTEROVERLAY
36 delete m_rasterOverlay;
37 delete m_unmergedCopy;
41QBlittable *QBlittablePlatformPixmap::blittable()
const
44 QBlittablePlatformPixmap *that =
const_cast<QBlittablePlatformPixmap *>(
this);
45 that->m_blittable.reset(
this->createBlittable(QSize(w, h), m_alpha));
48 return m_blittable.data();
51void QBlittablePlatformPixmap::setBlittable(QBlittable *blittable)
53 resize(blittable->size().width(),blittable->size().height());
54 m_blittable.reset(blittable);
57void QBlittablePlatformPixmap::resize(
int width,
int height)
59 m_blittable.reset(
nullptr);
60 m_engine.reset(
nullptr);
61 d = QGuiApplication::primaryScreen()->depth();
64 is_null = (w <= 0 || h <= 0);
65 setSerialNumber(++global_ser_no);
68int QBlittablePlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric)
const
71 case QPaintDevice::PdmWidth:
73 case QPaintDevice::PdmHeight:
75 case QPaintDevice::PdmWidthMM:
76 return qRound(w * 25.4 / qt_defaultDpiX());
77 case QPaintDevice::PdmHeightMM:
78 return qRound(h * 25.4 / qt_defaultDpiY());
79 case QPaintDevice::PdmDepth:
81 case QPaintDevice::PdmDpiX:
82 case QPaintDevice::PdmPhysicalDpiX:
83 return qt_defaultDpiX();
84 case QPaintDevice::PdmDpiY:
85 case QPaintDevice::PdmPhysicalDpiY:
86 return qt_defaultDpiY();
87 case QPaintDevice::PdmDevicePixelRatio:
88 return devicePixelRatio();
89 case QPaintDevice::PdmDevicePixelRatioScaled:
90 return devicePixelRatio() * QPaintDevice::devicePixelRatioFScale();
91 case QPaintDevice::PdmDevicePixelRatioF_EncodedA:
93 case QPaintDevice::PdmDevicePixelRatioF_EncodedB:
94 return QPaintDevice::encodeMetricF(metric, devicePixelRatio());
96 qWarning(
"QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric);
103void QBlittablePlatformPixmap::fill(
const QColor &color)
105 if (blittable()->capabilities() & QBlittable::AlphaFillRectCapability) {
106 blittable()->unlock();
107 blittable()->alphaFillRect(QRectF(0,0,w,h),color,QPainter::CompositionMode_Source);
108 }
else if (color.alpha() == 255 && blittable()->capabilities() & QBlittable::SolidRectCapability) {
109 blittable()->unlock();
110 blittable()->fillRect(QRectF(0,0,w,h),color);
115 if (color.alpha() != 255 && !hasAlphaChannel()) {
116 m_blittable.reset(
nullptr);
117 m_engine.reset(
nullptr);
121 blittable()->lock()->fill(color);
126QImage *QBlittablePlatformPixmap::buffer()
128 return blittable()->lock();
131QImage QBlittablePlatformPixmap::toImage()
const
133 return blittable()->lock()->copy();
136bool QBlittablePlatformPixmap::hasAlphaChannel()
const
138 return blittable()->lock()->hasAlphaChannel();
141void QBlittablePlatformPixmap::fromImage(
const QImage &image,
142 Qt::ImageConversionFlags flags)
144 m_alpha = image.hasAlphaChannel();
145 m_devicePixelRatio = image.devicePixelRatio();
146 resize(image.width(),image.height());
147 markRasterOverlay(QRect(0,0,w,h));
148 QImage *thisImg = buffer();
150 QImage correctFormatPic = image;
151 if (correctFormatPic.format() != thisImg->format())
152 correctFormatPic = correctFormatPic.convertToFormat(thisImg->format(), flags);
154 uchar *mem = thisImg->bits();
155 const uchar *bits = correctFormatPic.constBits();
156 qsizetype bytesCopied = 0;
157 while (bytesCopied < correctFormatPic.sizeInBytes()) {
158 memcpy(mem,bits,correctFormatPic.bytesPerLine());
159 mem += thisImg->bytesPerLine();
160 bits += correctFormatPic.bytesPerLine();
161 bytesCopied+=correctFormatPic.bytesPerLine();
165qreal QBlittablePlatformPixmap::devicePixelRatio()
const
167 return m_devicePixelRatio;
170void QBlittablePlatformPixmap::setDevicePixelRatio(qreal scaleFactor)
172 m_devicePixelRatio = scaleFactor;
175QPaintEngine *QBlittablePlatformPixmap::paintEngine()
const
178 QBlittablePlatformPixmap *that =
const_cast<QBlittablePlatformPixmap *>(
this);
179 that->m_engine.reset(
new QBlitterPaintEngine(that));
181 return m_engine.data();
184#ifdef QT_BLITTER_RASTEROVERLAY
186static bool showRasterOverlay = !qEnvironmentVariableIsEmpty(
"QT_BLITTER_RASTEROVERLAY");
188void QBlittablePlatformPixmap::mergeOverlay()
190 if (m_unmergedCopy || !showRasterOverlay)
192 m_unmergedCopy =
new QImage(buffer()->copy());
193 QPainter p(buffer());
194 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
195 p.drawImage(0,0,*overlay());
199void QBlittablePlatformPixmap::unmergeOverlay()
201 if (!m_unmergedCopy || !showRasterOverlay)
203 QPainter p(buffer());
204 p.setCompositionMode(QPainter::CompositionMode_Source);
205 p.drawImage(0,0,*m_unmergedCopy);
208 delete m_unmergedCopy;
212QImage *QBlittablePlatformPixmap::overlay()
214 if (!m_rasterOverlay||
215 m_rasterOverlay->size() != QSize(w,h)){
216 m_rasterOverlay =
new QImage(w,h,QImage::Format_ARGB32_Premultiplied);
217 m_rasterOverlay->fill(0x00000000);
218 uint color = QRandomGenerator::global()->bounded(11)+7;
219 m_overlayColor = QColor(Qt::GlobalColor(color));
220 m_overlayColor.setAlpha(0x88);
223 return m_rasterOverlay;
226void QBlittablePlatformPixmap::markRasterOverlayImpl(
const QRectF &rect)
228 if (!showRasterOverlay)
230 QRectF transformationRect = clipAndTransformRect(rect);
231 if (!transformationRect.isEmpty()) {
232 QPainter p(overlay());
233 p.setBrush(m_overlayColor);
234 p.setCompositionMode(QPainter::CompositionMode_Source);
235 p.fillRect(transformationRect,QBrush(m_overlayColor));
239void QBlittablePlatformPixmap::unmarkRasterOverlayImpl(
const QRectF &rect)
241 if (!showRasterOverlay)
243 QRectF transformationRect = clipAndTransformRect(rect);
244 if (!transformationRect.isEmpty()) {
245 QPainter p(overlay());
246 QColor color(0x00,0x00,0x00,0x00);
248 p.setCompositionMode(QPainter::CompositionMode_Source);
249 p.fillRect(transformationRect,QBrush(color));
253QRectF QBlittablePlatformPixmap::clipAndTransformRect(
const QRectF &rect)
const
255 QRectF transformationRect = rect;
257 if (m_engine->state()) {
258 transformationRect = m_engine->state()->matrix.mapRect(rect);
259 const QClipData *clipData = m_engine->clip();
261 if (clipData->hasRectClip) {
262 transformationRect &= clipData->clipRect;
263 }
else if (clipData->hasRegionClip) {
264 for (
const QRect &rect : clipData->clipRegion)
265 transformationRect &= rect;
269 return transformationRect;
static QT_BEGIN_NAMESPACE int global_ser_no