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();
385 emit statusChanged(d->status);
387 if (sourceSize() != d->oldSourceSize) {
388 d->oldSourceSize = sourceSize();
389 emit sourceSizeChanged();
391 if (autoTransform() != d->oldAutoTransform) {
392 d->oldAutoTransform = autoTransform();
393 emitAutoTransformBaseChanged();
395 if (d->frameCount != d->currentPix->frameCount()) {
396 d->frameCount = d->currentPix->frameCount();
397 emit frameCountChanged();
399 if (d->colorSpace != d->currentPix->colorSpace()) {
400 d->colorSpace = d->currentPix->colorSpace();
401 emit colorSpaceChanged();
414void QQuickImageBase::itemChange(ItemChange change,
const ItemChangeData &value)
416 Q_D(QQuickImageBase);
418 if (change == ItemDevicePixelRatioHasChanged && value.realValue != d->devicePixelRatio) {
419 const auto oldDpr = d->devicePixelRatio;
425 if (qmlEngine(
this) && isComponentComplete()) {
428 if (d->devicePixelRatio == oldDpr)
429 d->updateDevicePixelRatio(value.realValue);
432 QQuickItem::itemChange(change, value);
449void QQuickImageBase::resolve2xLocalFile(
const QUrl &url, qreal targetDevicePixelRatio, QUrl *sourceUrl, qreal *sourceDevicePixelRatio)
452 Q_ASSERT(sourceDevicePixelRatio);
455 static const bool disable2xImageLoading = !qEnvironmentVariableIsEmpty(
"QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
456 if (disable2xImageLoading)
459 const QString localFile = QQmlFile::urlToLocalFileOrQrc(url);
462 if (localFile.isEmpty())
466 int atLocation = localFile.lastIndexOf(QLatin1Char(
'@'));
467 if (atLocation > 0 && atLocation + 3 < localFile.size()) {
468 if (localFile[atLocation + 1].isDigit()
469 && localFile[atLocation + 2] == QLatin1Char(
'x')
470 && localFile[atLocation + 3] == QLatin1Char(
'.')) {
471 *sourceDevicePixelRatio = localFile[atLocation + 1].digitValue();
477 QString localFileX = qt_findAtNxFile(localFile, targetDevicePixelRatio, sourceDevicePixelRatio);
478 if (localFileX != localFile)
479 *sourceUrl = QUrl::fromLocalFile(localFileX);
482bool QQuickImageBase::autoTransform()
const
484 Q_D(
const QQuickImageBase);
485 if (d->providerOptions.autoTransform() == QQuickImageProviderOptions::UsePluginDefaultTransform)
486 return d->currentPix->autoTransform() == QQuickImageProviderOptions::ApplyTransform;
487 return d->providerOptions.autoTransform() == QQuickImageProviderOptions::ApplyTransform;
490void QQuickImageBase::setAutoTransform(
bool transform)
492 Q_D(QQuickImageBase);
493 if (d->providerOptions.autoTransform() != QQuickImageProviderOptions::UsePluginDefaultTransform &&
494 transform == (d->providerOptions.autoTransform() == QQuickImageProviderOptions::ApplyTransform))
496 d->providerOptions.setAutoTransform(transform ? QQuickImageProviderOptions::ApplyTransform : QQuickImageProviderOptions::DoNotApplyTransform);
497 emitAutoTransformBaseChanged();
506void QQuickImageBase::setColorSpace(
const QColorSpace &colorSpace)
508 Q_D(QQuickImageBase);
509 if (d->colorSpace == colorSpace)
511 d->colorSpace = colorSpace;
512 d->providerOptions.setTargetColorSpace(colorSpace);
513 emit colorSpaceChanged();
522void QQuickImageBase::setRetainWhileLoading(
bool retainWhileLoading)
524 Q_D(QQuickImageBase);
525 if (d->retainWhileLoading == retainWhileLoading)
528 d->retainWhileLoading = retainWhileLoading;
529 if (d->retainWhileLoading) {
530 if (d->currentPix == &d->pix1)
531 d->pendingPix = &d->pix2;
533 d->pendingPix = &d->pix1;
535 d->pendingPix->clear();
536 d->pendingPix = d->currentPix;