58QQuickImageBase::QQuickImageBase(QQuickItem *parent)
59: QQuickImplicitSizeItem(*(
new QQuickImageBasePrivate), parent)
61 setFlag(ItemHasContents);
133QSize QQuickImageBase::sourceSize()
const
135 Q_D(
const QQuickImageBase);
137 int width = d->sourcesize.width();
138 int height = d->sourcesize.height();
139 return QSize(width != -1 ? width : d->currentPix->width(), height != -1 ? height : d->currentPix->height());
265void QQuickImageBase::loadEmptyUrl()
267 Q_D(QQuickImageBase);
268 d->currentPix->clear(
this);
269 d->pendingPix->clear(
this);
272 setImplicitSize(0, 0);
275 emit statusChanged(d->status);
276 if (sourceSize() != d->oldSourceSize) {
277 d->oldSourceSize = sourceSize();
278 emit sourceSizeChanged();
280 if (autoTransform() != d->oldAutoTransform) {
281 d->oldAutoTransform = autoTransform();
282 emitAutoTransformBaseChanged();
287void QQuickImageBase::loadPixmap(
const QUrl &url, LoadPixmapOptions loadOptions)
289 Q_D(QQuickImageBase);
290 QQuickPixmap::Options options;
292 options |= QQuickPixmap::Asynchronous;
294 options |= QQuickPixmap::Cache;
295 d->pendingPix->clear(
this);
297 const QQmlContext *context = qmlContext(
this);
299 loadUrl = context->resolvedUrl(url);
301 if (loadOptions & HandleDPR) {
302 const qreal targetDevicePixelRatio = d->effectiveDevicePixelRatio();
303 d->devicePixelRatio = 1.0;
304 bool updatedDevicePixelRatio =
false;
305 if (d->sourcesize.isValid()
306 || (QQuickPixmap::isScalableImageFormat(d->url) && d->url.scheme() !=
"image"_L1)) {
307 updatedDevicePixelRatio = d->updateDevicePixelRatio(targetDevicePixelRatio);
310 if (!updatedDevicePixelRatio) {
313 resolve2xLocalFile(context ? context->resolvedUrl(d->url) : d->url,
314 targetDevicePixelRatio, &loadUrl, &d->devicePixelRatio);
320 auto engine = qmlEngine(
this);
322 d->pendingPix->load(engine,
324 d->sourceClipRect.toRect(),
325 (loadOptions & HandleDPR) ? d->sourcesize * d->devicePixelRatio : QSize(),
327 (loadOptions & UseProviderOptions) ? d->providerOptions : QQuickImageProviderOptions(),
328 d->currentFrame, d->frameCount,
329 d->devicePixelRatio);
331 if (d->pendingPix->isLoading()) {
333 d->setStatus(Loading);
335 static int thisRequestProgress = -1;
336 static int thisRequestFinished = -1;
337 if (thisRequestProgress == -1) {
338 thisRequestProgress =
339 QQuickImageBase::staticMetaObject.indexOfSlot(
"requestProgress(qint64,qint64)");
340 thisRequestFinished =
341 QQuickImageBase::staticMetaObject.indexOfSlot(
"requestFinished()");
344 d->pendingPix->connectFinished(
this, thisRequestFinished);
345 d->pendingPix->connectDownloadProgress(
this, thisRequestProgress);
346 if (!d->retainWhileLoading)
365void QQuickImageBase::requestFinished()
367 Q_D(QQuickImageBase);
368 if (d->pendingPix != d->currentPix
369 && d->pendingPix->status() != QQuickPixmap::Null
370 && d->pendingPix->status() != QQuickPixmap::Loading) {
371 std::swap(d->pendingPix, d->currentPix);
372 d->pendingPix->clear(
this);
375 if (d->currentPix->isError()) {
376 qmlWarning(
this) << d->currentPix->error();
383 if (d->url.scheme() == QQuickPixmap::itemGrabberScheme)
384 d->devicePixelRatio = d->currentPix->devicePixelRatio();
390 emit statusChanged(d->status);
392 if (sourceSize() != d->oldSourceSize) {
393 d->oldSourceSize = sourceSize();
394 emit sourceSizeChanged();
396 if (autoTransform() != d->oldAutoTransform) {
397 d->oldAutoTransform = autoTransform();
398 emitAutoTransformBaseChanged();
400 if (d->frameCount != d->currentPix->frameCount()) {
401 d->frameCount = d->currentPix->frameCount();
402 emit frameCountChanged();
404 if (d->colorSpace != d->currentPix->colorSpace()) {
405 d->colorSpace = d->currentPix->colorSpace();
406 emit colorSpaceChanged();
419void QQuickImageBase::itemChange(ItemChange change,
const ItemChangeData &value)
421 Q_D(QQuickImageBase);
423 if (change == ItemDevicePixelRatioHasChanged && value.realValue != d->devicePixelRatio) {
424 const auto oldDpr = d->devicePixelRatio;
430 if (qmlEngine(
this) && isComponentComplete()) {
433 if (d->devicePixelRatio == oldDpr)
434 d->updateDevicePixelRatio(value.realValue);
436 }
else if (change == ItemSceneChange && value.window
437 && value.window->effectiveDevicePixelRatio() != d->devicePixelRatio) {
442 if (qmlEngine(
this) && isComponentComplete())
445 QQuickItem::itemChange(change, value);
462void QQuickImageBase::resolve2xLocalFile(
const QUrl &url, qreal targetDevicePixelRatio, QUrl *sourceUrl, qreal *sourceDevicePixelRatio)
465 Q_ASSERT(sourceDevicePixelRatio);
468 static const bool disable2xImageLoading = !qEnvironmentVariableIsEmpty(
"QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
469 if (disable2xImageLoading)
472 const QString localFile = QQmlFile::urlToLocalFileOrQrc(url);
475 if (localFile.isEmpty())
479 int atLocation = localFile.lastIndexOf(QLatin1Char(
'@'));
480 if (atLocation > 0 && atLocation + 3 < localFile.size()) {
481 if (localFile[atLocation + 1].isDigit()
482 && localFile[atLocation + 2] == QLatin1Char(
'x')
483 && localFile[atLocation + 3] == QLatin1Char(
'.')) {
484 *sourceDevicePixelRatio = localFile[atLocation + 1].digitValue();
490 QString localFileX = qt_findAtNxFile(localFile, targetDevicePixelRatio, sourceDevicePixelRatio);
491 if (localFileX != localFile)
492 *sourceUrl = QUrl::fromLocalFile(localFileX);
495bool QQuickImageBase::autoTransform()
const
497 Q_D(
const QQuickImageBase);
498 if (d->providerOptions.autoTransform() == QQuickImageProviderOptions::UsePluginDefaultTransform)
499 return d->currentPix->autoTransform() == QQuickImageProviderOptions::ApplyTransform;
500 return d->providerOptions.autoTransform() == QQuickImageProviderOptions::ApplyTransform;
503void QQuickImageBase::setAutoTransform(
bool transform)
505 Q_D(QQuickImageBase);
506 if (d->providerOptions.autoTransform() != QQuickImageProviderOptions::UsePluginDefaultTransform &&
507 transform == (d->providerOptions.autoTransform() == QQuickImageProviderOptions::ApplyTransform))
509 d->providerOptions.setAutoTransform(transform ? QQuickImageProviderOptions::ApplyTransform : QQuickImageProviderOptions::DoNotApplyTransform);
510 emitAutoTransformBaseChanged();
519void QQuickImageBase::setColorSpace(
const QColorSpace &colorSpace)
521 Q_D(QQuickImageBase);
522 if (d->colorSpace == colorSpace)
524 d->colorSpace = colorSpace;
525 d->providerOptions.setTargetColorSpace(colorSpace);
526 emit colorSpaceChanged();
535void QQuickImageBase::setRetainWhileLoading(
bool retainWhileLoading)
537 Q_D(QQuickImageBase);
538 if (d->retainWhileLoading == retainWhileLoading)
541 d->retainWhileLoading = retainWhileLoading;
542 if (d->retainWhileLoading) {
543 if (d->currentPix == &d->pix1)
544 d->pendingPix = &d->pix2;
546 d->pendingPix = &d->pix1;
548 d->pendingPix->clear();
549 d->pendingPix = d->currentPix;