117void QBackingStore::beginPaint(
const QRegion ®ion)
119 const qreal toNativeFactor = d_ptr->deviceIndependentToNativeFactor();
121 if (d_ptr->nativeSize != QHighDpi::scale(size(), toNativeFactor))
124 QPlatformBackingStore *platformBackingStore = handle();
125 platformBackingStore->beginPaint(QHighDpi::scale(region, toNativeFactor));
133 QPaintDevice *device = platformBackingStore->paintDevice();
134 if (!qFuzzyCompare(toNativeFactor, qreal(1)) && device->devType() == QInternal::Image) {
135 QImage *source =
static_cast<QImage *>(device);
136 const bool needsNewImage = d_ptr->highDpiBackingstore.isNull()
137 || source->constBits() != d_ptr->highDpiBackingstore->constBits()
138 || source->size() != d_ptr->highDpiBackingstore->size()
139 || source->bytesPerLine() != d_ptr->highDpiBackingstore->bytesPerLine()
140 || source->format() != d_ptr->highDpiBackingstore->format();
142 d_ptr->highDpiBackingstore.reset(
143 new QImage(source->bits(), source->width(), source->height(), source->bytesPerLine(), source->format()));
145 d_ptr->highDpiBackingstore->setDevicePixelRatio(d_ptr->backingStoreDevicePixelRatio());
147 d_ptr->highDpiBackingstore.reset();
157QPaintDevice *QBackingStore::paintDevice()
159 QPaintDevice *device = handle()->paintDevice();
161 if (!qFuzzyCompare(d_ptr->deviceIndependentToNativeFactor(), qreal(1)) && device->devType() == QInternal::Image)
162 return d_ptr->highDpiBackingstore.data();
197void QBackingStore::flush(
const QRegion ®ion, QWindow *window,
const QPoint &offset)
199 QWindow *topLevelWindow =
this->window();
202 window = topLevelWindow;
203 if (!window->handle()) {
204 qWarning() <<
"QBackingStore::flush() called for "
205 << window <<
" which does not have a handle.";
209 Q_ASSERT(window == topLevelWindow || topLevelWindow->isAncestorOf(window, QWindow::ExcludeTransients));
211 const qreal toNativeFactor = d_ptr->deviceIndependentToNativeFactor();
213 QRegion nativeRegion = QHighDpi::scale(region, toNativeFactor);
215 if (!offset.isNull()) {
216 nativeOffset = QHighDpi::scale(offset, toNativeFactor);
218 QPoint topLeft = region.boundingRect().topLeft() + offset;
219 QPoint nativeTopLeft = QHighDpi::scale(topLeft, toNativeFactor);
220 QPoint diff = nativeTopLeft - (nativeRegion.boundingRect().topLeft() + nativeOffset);
221 Q_ASSERT(qMax(qAbs(diff.x()), qAbs(diff.y())) <= 1);
222 nativeRegion.translate(diff);
224 handle()->flush(window, nativeRegion, nativeOffset);
232void QBackingStore::resize(
const QSize &size)
234 const qreal factor = d_ptr->deviceIndependentToNativeFactor();
236 d_ptr->nativeSize = QHighDpi::scale(size, factor);
237 handle()->resize(d_ptr->nativeSize, QHighDpi::scale(d_ptr->staticContents, factor));
254bool QBackingStore::scroll(
const QRegion &area,
int dx,
int dy)
259 const qreal toNativeFactor = d_ptr->deviceIndependentToNativeFactor();
260 const qreal nativeDx = QHighDpi::scale(qreal(dx), toNativeFactor);
261 const qreal nativeDy = QHighDpi::scale(qreal(dy), toNativeFactor);
262 if (qFloor(nativeDx) != nativeDx || qFloor(nativeDy) != nativeDy)
265 return handle()->scroll(QHighDpi::scale(area, toNativeFactor), nativeDx, nativeDy);
271void QBackingStore::setStaticContents(
const QRegion ®ion)
273 [[maybe_unused]]
static const bool didCheckPlatformSupport = []{
274 const auto *integration = QGuiApplicationPrivate::platformIntegration();
275 if (!integration->hasCapability(QPlatformIntegration::BackingStoreStaticContents))
276 qWarning(
"QBackingStore::setStaticContents(): Platform does not support static contents");
280 d_ptr->staticContents = region;
300void Q_GUI_EXPORT qt_scrollRectInImage(QImage &img,
const QRect &rect,
const QPoint &offset)
303 uchar *mem =
const_cast<uchar*>(img.constBits());
305 qsizetype lineskip = img.bytesPerLine();
306 int depth = img.depth() >> 3;
308 const QRect imageRect(0, 0, img.width(), img.height());
309 const QRect sourceRect = rect.intersected(imageRect).intersected(imageRect.translated(-offset));
310 if (sourceRect.isEmpty())
313 const QRect destRect = sourceRect.translated(offset);
314 Q_ASSERT_X(imageRect.contains(destRect),
"qt_scrollRectInImage",
315 "The sourceRect should already account for clipping, both pre and post scroll");
320 if (sourceRect.top() < destRect.top()) {
321 src = mem + sourceRect.bottom() * lineskip + sourceRect.left() * depth;
322 dest = mem + (destRect.top() + sourceRect.height() - 1) * lineskip + destRect.left() * depth;
323 lineskip = -lineskip;
325 src = mem + sourceRect.top() * lineskip + sourceRect.left() * depth;
326 dest = mem + destRect.top() * lineskip + destRect.left() * depth;
329 const int w = sourceRect.width();
330 int h = sourceRect.height();
331 const int bytes = w * depth;
334 if (offset.y() == 0 && qAbs(offset.x()) < w) {
336 ::memmove(dest, src, bytes);
342 ::memcpy(dest, src, bytes);
352QPlatformBackingStore *QBackingStore::handle()
const
354 if (!d_ptr->platformBackingStore) {
355 d_ptr->platformBackingStore = QGuiApplicationPrivate::platformIntegration()->createPlatformBackingStore(d_ptr->window);
356 d_ptr->platformBackingStore->setBackingStore(
const_cast<QBackingStore*>(
this));
358 return d_ptr->platformBackingStore;