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 const int roundedDx = qRound(nativeDx);
264 const int roundedDy = qRound(nativeDy);
266 if (!qFuzzyCompare(nativeDx, qreal(roundedDx)) ||
267 !qFuzzyCompare(nativeDy, qreal(roundedDy)))
270 return handle()->scroll(QHighDpi::scale(area, toNativeFactor), roundedDx, roundedDy);
276void QBackingStore::setStaticContents(
const QRegion ®ion)
278 [[maybe_unused]]
static const bool didCheckPlatformSupport = []{
279 const auto *integration = QGuiApplicationPrivate::platformIntegration();
280 if (!integration->hasCapability(QPlatformIntegration::BackingStoreStaticContents))
281 qWarning(
"QBackingStore::setStaticContents(): Platform does not support static contents");
285 d_ptr->staticContents = region;
305void Q_GUI_EXPORT qt_scrollRectInImage(QImage &img,
const QRect &rect,
const QPoint &offset)
308 uchar *mem =
const_cast<uchar*>(img.constBits());
310 qsizetype lineskip = img.bytesPerLine();
311 int depth = img.depth() >> 3;
313 const QRect imageRect(0, 0, img.width(), img.height());
314 const QRect sourceRect = rect.intersected(imageRect).intersected(imageRect.translated(-offset));
315 if (sourceRect.isEmpty())
318 const QRect destRect = sourceRect.translated(offset);
319 Q_ASSERT_X(imageRect.contains(destRect),
"qt_scrollRectInImage",
320 "The sourceRect should already account for clipping, both pre and post scroll");
325 if (sourceRect.top() < destRect.top()) {
326 src = mem + sourceRect.bottom() * lineskip + sourceRect.left() * depth;
327 dest = mem + (destRect.top() + sourceRect.height() - 1) * lineskip + destRect.left() * depth;
328 lineskip = -lineskip;
330 src = mem + sourceRect.top() * lineskip + sourceRect.left() * depth;
331 dest = mem + destRect.top() * lineskip + destRect.left() * depth;
334 const int w = sourceRect.width();
335 int h = sourceRect.height();
336 const int bytes = w * depth;
339 if (offset.y() == 0 && qAbs(offset.x()) < w) {
341 ::memmove(dest, src, bytes);
347 ::memcpy(dest, src, bytes);
357QPlatformBackingStore *QBackingStore::handle()
const
359 if (!d_ptr->platformBackingStore) {
360 d_ptr->platformBackingStore = QGuiApplicationPrivate::platformIntegration()->createPlatformBackingStore(d_ptr->window);
361 d_ptr->platformBackingStore->setBackingStore(
const_cast<QBackingStore*>(
this));
363 return d_ptr->platformBackingStore;