118void QBackingStore::beginPaint(
const QRegion ®ion)
120 const qreal toNativeFactor = d_ptr->deviceIndependentToNativeFactor();
122 if (d_ptr->nativeSize != QHighDpi::scale(size(), toNativeFactor))
125 QPlatformBackingStore *platformBackingStore = handle();
126 platformBackingStore->beginPaint(QHighDpi::scale(region, toNativeFactor));
134 QPaintDevice *device = platformBackingStore->paintDevice();
135 if (!qFuzzyCompare(toNativeFactor, qreal(1)) && device->devType() == QInternal::Image) {
136 QImage *source =
static_cast<QImage *>(device);
137 const bool needsNewImage = d_ptr->highDpiBackingstore.isNull()
138 || source->constBits() != d_ptr->highDpiBackingstore->constBits()
139 || source->size() != d_ptr->highDpiBackingstore->size()
140 || source->bytesPerLine() != d_ptr->highDpiBackingstore->bytesPerLine()
141 || source->format() != d_ptr->highDpiBackingstore->format();
143 d_ptr->highDpiBackingstore.reset(
144 new QImage(source->bits(), source->width(), source->height(), source->bytesPerLine(), source->format()));
146 d_ptr->highDpiBackingstore->setDevicePixelRatio(d_ptr->backingStoreDevicePixelRatio());
148 d_ptr->highDpiBackingstore.reset();
158QPaintDevice *QBackingStore::paintDevice()
160 QPaintDevice *device = handle()->paintDevice();
162 if (!qFuzzyCompare(d_ptr->deviceIndependentToNativeFactor(), qreal(1)) && device->devType() == QInternal::Image)
163 return d_ptr->highDpiBackingstore.data();
198void QBackingStore::flush(
const QRegion ®ion, QWindow *window,
const QPoint &offset)
200 QWindow *topLevelWindow =
this->window();
203 window = topLevelWindow;
204 if (!window->handle()) {
205 qWarning() <<
"QBackingStore::flush() called for "
206 << window <<
" which does not have a handle.";
210 Q_ASSERT(window == topLevelWindow || topLevelWindow->isAncestorOf(window, QWindow::ExcludeTransients));
212 const qreal toNativeFactor = d_ptr->deviceIndependentToNativeFactor();
214 QRegion nativeRegion = QHighDpi::scale(region, toNativeFactor);
216 if (!offset.isNull()) {
217 nativeOffset = QHighDpi::scale(offset, toNativeFactor);
219 QPoint topLeft = region.boundingRect().topLeft() + offset;
220 QPoint nativeTopLeft = QHighDpi::scale(topLeft, toNativeFactor);
221 QPoint diff = nativeTopLeft - (nativeRegion.boundingRect().topLeft() + nativeOffset);
222 Q_ASSERT(qMax(qAbs(diff.x()), qAbs(diff.y())) <= 1);
223 nativeRegion.translate(diff);
225 handle()->flush(window, nativeRegion, nativeOffset);
233void QBackingStore::resize(
const QSize &size)
235 const qreal factor = d_ptr->deviceIndependentToNativeFactor();
237 d_ptr->nativeSize = QHighDpi::scale(size, factor);
238 handle()->resize(d_ptr->nativeSize, QHighDpi::scale(d_ptr->staticContents, factor));
255bool QBackingStore::scroll(
const QRegion &area,
int dx,
int dy)
260 const qreal toNativeFactor = d_ptr->deviceIndependentToNativeFactor();
261 const qreal nativeDx = QHighDpi::scale(qreal(dx), toNativeFactor);
262 const qreal nativeDy = QHighDpi::scale(qreal(dy), toNativeFactor);
263 if (qFloor(nativeDx) != nativeDx || qFloor(nativeDy) != nativeDy)
266 return handle()->scroll(QHighDpi::scale(area, toNativeFactor), nativeDx, nativeDy);
272void QBackingStore::setStaticContents(
const QRegion ®ion)
274 [[maybe_unused]]
static const bool didCheckPlatformSupport = []{
275 const auto *integration = QGuiApplicationPrivate::platformIntegration();
276 if (!integration->hasCapability(QPlatformIntegration::BackingStoreStaticContents))
277 qWarning(
"QBackingStore::setStaticContents(): Platform does not support static contents");
281 d_ptr->staticContents = region;
301void Q_GUI_EXPORT qt_scrollRectInImage(QImage &img,
const QRect &rect,
const QPoint &offset)
304 uchar *mem =
const_cast<uchar*>(img.constBits());
306 qsizetype lineskip = img.bytesPerLine();
307 int depth = img.depth() >> 3;
309 const QRect imageRect(0, 0, img.width(), img.height());
310 const QRect sourceRect = rect.intersected(imageRect).intersected(imageRect.translated(-offset));
311 if (sourceRect.isEmpty())
314 const QRect destRect = sourceRect.translated(offset);
315 Q_ASSERT_X(imageRect.contains(destRect),
"qt_scrollRectInImage",
316 "The sourceRect should already account for clipping, both pre and post scroll");
321 if (sourceRect.top() < destRect.top()) {
322 src = mem + sourceRect.bottom() * lineskip + sourceRect.left() * depth;
323 dest = mem + (destRect.top() + sourceRect.height() - 1) * lineskip + destRect.left() * depth;
324 lineskip = -lineskip;
326 src = mem + sourceRect.top() * lineskip + sourceRect.left() * depth;
327 dest = mem + destRect.top() * lineskip + destRect.left() * depth;
330 const int w = sourceRect.width();
331 int h = sourceRect.height();
332 const int bytes = w * depth;
335 if (offset.y() == 0 && qAbs(offset.x()) < w) {
337 ::memmove(dest, src, bytes);
343 ::memcpy(dest, src, bytes);
353QPlatformBackingStore *QBackingStore::handle()
const
355 if (!d_ptr->platformBackingStore) {
356 d_ptr->platformBackingStore = QGuiApplicationPrivate::platformIntegration()->createPlatformBackingStore(d_ptr->window);
357 d_ptr->platformBackingStore->setBackingStore(
const_cast<QBackingStore*>(
this));
359 return d_ptr->platformBackingStore;