diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2017-04-07 14:48:56 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2017-04-07 12:53:23 +0000 |
commit | 017350a8a9b4ac866c9b79186bf5a1dd6f6f06ec (patch) | |
tree | f98070d9bf0bd5659d34355b5eb9647637874187 /src/quick/util | |
parent | b361a59c699fca02379c149cf0b9c59490a1ba62 (diff) | |
parent | 67d1d7843ab5e1c904c8f0f76eadb9fc3f1bbb17 (diff) |
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts:
src/qml/jit/qv4assembler.cpp
src/qml/jit/qv4assembler_p.h
src/qml/jit/qv4isel_masm.cpp
src/qml/jsruntime/qv4vme_moth.cpp
Change-Id: I865d794e550a263387a39ca8d051ebf48b70cbc0
Diffstat (limited to 'src/quick/util')
-rw-r--r-- | src/quick/util/qquickimageprovider.cpp | 45 | ||||
-rw-r--r-- | src/quick/util/qquickimageprovider.h | 1 | ||||
-rw-r--r-- | src/quick/util/qquickpixmapcache.cpp | 59 | ||||
-rw-r--r-- | src/quick/util/qquickpixmapcache_p.h | 3 |
4 files changed, 67 insertions, 41 deletions
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp index 0ceed7f681..c4a98c69f9 100644 --- a/src/quick/util/qquickimageprovider.cpp +++ b/src/quick/util/qquickimageprovider.cpp @@ -613,7 +613,6 @@ void QQuickImageProviderOptions::setPreserveAspectRatioFit(bool preserveAspectRa d->preserveAspectRatioFit = preserveAspectRatioFit; } - QQuickImageProviderWithOptions::QQuickImageProviderWithOptions(ImageType type, Flags flags) : QQuickAsyncImageProvider() { @@ -670,5 +669,49 @@ QQuickImageResponse *QQuickImageProviderWithOptions::requestImageResponse(const return requestImageResponse(id, requestedSize); } +/*! + Returns the recommended scaled image size for loading and storage. This is + calculated according to the native pixel size of the image \a originalSize, + the requested sourceSize \a requestedSize, the image file format \a format, + and \a options. If the calculation otherwise concludes that scaled loading + is not recommended, an invalid size is returned. +*/ +QSize QQuickImageProviderWithOptions::loadSize(const QSize &originalSize, const QSize &requestedSize, const QByteArray &format, const QQuickImageProviderOptions &options) +{ + QSize res; + if ((requestedSize.width() <= 0 && requestedSize.height() <= 0) || originalSize.isEmpty()) + return res; + + const bool preserveAspectCropOrFit = options.preserveAspectRatioCrop() || options.preserveAspectRatioFit(); + const bool force_scale = (format == "svg" || format == "svgz"); + + qreal ratio = 0.0; + if (requestedSize.width() && (preserveAspectCropOrFit || force_scale || requestedSize.width() < originalSize.width())) { + ratio = qreal(requestedSize.width()) / originalSize.width(); + } + if (requestedSize.height() && (preserveAspectCropOrFit || force_scale || requestedSize.height() < originalSize.height())) { + qreal hr = qreal(requestedSize.height()) / originalSize.height(); + if (ratio == 0.0) + ratio = hr; + else if (!preserveAspectCropOrFit && (hr < ratio)) + ratio = hr; + else if (preserveAspectCropOrFit && (hr > ratio)) + ratio = hr; + } + if (ratio > 0.0) { + res.setHeight(qRound(originalSize.height() * ratio)); + res.setWidth(qRound(originalSize.width() * ratio)); + } + return res; +} + +QQuickImageProviderWithOptions *QQuickImageProviderWithOptions::checkedCast(QQuickImageProvider *provider) +{ + if (provider && provider->d && provider->d->isProviderWithOptions) + return static_cast<QQuickImageProviderWithOptions *>(provider); + + return nullptr; +} + QT_END_NAMESPACE diff --git a/src/quick/util/qquickimageprovider.h b/src/quick/util/qquickimageprovider.h index c77ff95f32..681de4b6c2 100644 --- a/src/quick/util/qquickimageprovider.h +++ b/src/quick/util/qquickimageprovider.h @@ -88,7 +88,6 @@ Q_SIGNALS: class Q_QUICK_EXPORT QQuickImageProvider : public QQmlImageProviderBase { friend class QQuickImageProviderWithOptions; // ### Qt 6 Remove - friend class QQuickPixmapReader; // ### Qt 6 Remove public: QQuickImageProvider(ImageType type, Flags flags = Flags()); virtual ~QQuickImageProvider(); diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index 395b89c784..7d88935402 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -141,6 +141,7 @@ public: QUrl url; bool loading; + QQuickImageProviderOptions providerOptions; int redirectCount; class Event : public QEvent { @@ -204,7 +205,7 @@ protected: private: friend class QQuickPixmapReaderThreadObject; void processJobs(); - void processJob(QQuickPixmapReply *, const QUrl &, const QString &, const QQuickImageProviderOptions &, QQuickImageProvider::ImageType, QQuickImageProvider *); + void processJob(QQuickPixmapReply *, const QUrl &, const QString &, QQuickImageProvider::ImageType, QQuickImageProvider *); #if QT_CONFIG(qml_network) void networkRequestDone(QNetworkReply *); #endif @@ -386,37 +387,15 @@ static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *e const QSize &requestSize, const QQuickImageProviderOptions &providerOptions, QQuickImageProviderOptions::AutoTransform *appliedTransform = nullptr) { - const bool preserveAspectCropOrFit = providerOptions.preserveAspectRatioCrop() || providerOptions.preserveAspectRatioFit(); - QImageReader imgio(dev); if (providerOptions.autoTransform() != QQuickImageProviderOptions::UsePluginDefaultTransform) imgio.setAutoTransform(providerOptions.autoTransform() == QQuickImageProviderOptions::ApplyTransform); else if (appliedTransform) *appliedTransform = imgio.autoTransform() ? QQuickImageProviderOptions::ApplyTransform : QQuickImageProviderOptions::DoNotApplyTransform; - const bool force_scale = imgio.format() == "svg" || imgio.format() == "svgz"; - - if (requestSize.width() > 0 || requestSize.height() > 0) { - QSize s = imgio.size(); - qreal ratio = 0.0; - if (requestSize.width() && (preserveAspectCropOrFit || force_scale || requestSize.width() < s.width())) { - ratio = qreal(requestSize.width())/s.width(); - } - if (requestSize.height() && (preserveAspectCropOrFit || force_scale || requestSize.height() < s.height())) { - qreal hr = qreal(requestSize.height())/s.height(); - if (ratio == 0.0) - ratio = hr; - else if (!preserveAspectCropOrFit && (hr < ratio)) - ratio = hr; - else if (preserveAspectCropOrFit && (hr > ratio)) - ratio = hr; - } - if (ratio > 0.0) { - s.setHeight(qRound(s.height() * ratio)); - s.setWidth(qRound(s.width() * ratio)); - imgio.setScaledSize(s); - } - } + QSize scSize = QQuickImageProviderWithOptions::loadSize(imgio.size(), requestSize, imgio.format(), providerOptions); + if (scSize.isValid()) + imgio.setScaledSize(scSize); if (impsize) *impsize = imgio.size(); @@ -664,7 +643,7 @@ void QQuickPixmapReader::processJobs() PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(url)); locker.unlock(); - processJob(job, url, localFile, job->data->providerOptions, imageType, provider); + processJob(job, url, localFile, imageType, provider); locker.relock(); } } @@ -676,7 +655,6 @@ void QQuickPixmapReader::processJobs() } void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &url, const QString &localFile, - const QQuickImageProviderOptions &providerOptions, QQuickImageProvider::ImageType imageType, QQuickImageProvider *provider) { // fetch @@ -693,8 +671,7 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u return; } - QQuickImageProviderWithOptions *providerV2 = provider->d->isProviderWithOptions ? static_cast<QQuickImageProviderWithOptions *>(provider) - : nullptr; + QQuickImageProviderWithOptions *providerV2 = QQuickImageProviderWithOptions::checkedCast(provider); switch (imageType) { case QQuickImageProvider::Invalid: @@ -707,7 +684,7 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u { QImage image; if (providerV2) { - image = providerV2->requestImage(imageId(url), &readSize, runningJob->requestSize, providerOptions); + image = providerV2->requestImage(imageId(url), &readSize, runningJob->requestSize, runningJob->providerOptions); } else { image = provider->requestImage(imageId(url), &readSize, runningJob->requestSize); } @@ -728,7 +705,7 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u { QPixmap pixmap; if (providerV2) { - pixmap = providerV2->requestPixmap(imageId(url), &readSize, runningJob->requestSize, providerOptions); + pixmap = providerV2->requestPixmap(imageId(url), &readSize, runningJob->requestSize, runningJob->providerOptions); } else { pixmap = provider->requestPixmap(imageId(url), &readSize, runningJob->requestSize); } @@ -749,7 +726,7 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u { QQuickTextureFactory *t; if (providerV2) { - t = providerV2->requestTexture(imageId(url), &readSize, runningJob->requestSize, providerOptions); + t = providerV2->requestTexture(imageId(url), &readSize, runningJob->requestSize, runningJob->providerOptions); } else { t = provider->requestTexture(imageId(url), &readSize, runningJob->requestSize); } @@ -772,7 +749,7 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u { QQuickImageResponse *response; if (providerV2) { - response = providerV2->requestImageResponse(imageId(url), runningJob->requestSize, providerOptions); + response = providerV2->requestImageResponse(imageId(url), runningJob->requestSize, runningJob->providerOptions); } else { QQuickAsyncImageProvider *asyncProvider = static_cast<QQuickAsyncImageProvider*>(provider); response = asyncProvider->requestImageResponse(imageId(url), runningJob->requestSize); @@ -794,7 +771,7 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u QFile f(localFile); QSize readSize; if (f.open(QIODevice::ReadOnly)) { - if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->requestSize, providerOptions)) + if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->requestSize, runningJob->providerOptions)) errorCode = QQuickPixmapReply::Loading; } else { errorStr = QQuickPixmap::tr("Cannot open: %1").arg(url.toString()); @@ -1075,7 +1052,7 @@ void QQuickPixmap::purgeCache() } QQuickPixmapReply::QQuickPixmapReply(QQuickPixmapData *d) -: data(d), engineForReader(0), requestSize(d->requestSize), url(d->url), loading(false), redirectCount(0) +: data(d), engineForReader(0), requestSize(d->requestSize), url(d->url), loading(false), providerOptions(d->providerOptions), redirectCount(0) { if (finishedIndex == -1) { finishedIndex = QMetaMethod::fromSignal(&QQuickPixmapReply::finished).methodIndex(); @@ -1196,6 +1173,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q QQuickImageProvider::ImageType imageType = QQuickImageProvider::Invalid; QQuickImageProvider *provider = static_cast<QQuickImageProvider *>(engine->imageProvider(imageProviderId(url))); + QQuickImageProviderWithOptions *providerV2 = QQuickImageProviderWithOptions::checkedCast(provider); if (provider) imageType = provider->imageType(); @@ -1205,7 +1183,8 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q QQuickPixmap::tr("Invalid image provider: %1").arg(url.toString())); case QQuickImageProvider::Texture: { - QQuickTextureFactory *texture = provider->requestTexture(imageId(url), &readSize, requestSize); + QQuickTextureFactory *texture = providerV2 ? providerV2->requestTexture(imageId(url), &readSize, requestSize, providerOptions) + : provider->requestTexture(imageId(url), &readSize, requestSize); if (texture) { *ok = true; return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform); @@ -1215,7 +1194,8 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q case QQuickImageProvider::Image: { - QImage image = provider->requestImage(imageId(url), &readSize, requestSize); + QImage image = providerV2 ? providerV2->requestImage(imageId(url), &readSize, requestSize, providerOptions) + : provider->requestImage(imageId(url), &readSize, requestSize); if (!image.isNull()) { *ok = true; return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform); @@ -1224,7 +1204,8 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q } case QQuickImageProvider::Pixmap: { - QPixmap pixmap = provider->requestPixmap(imageId(url), &readSize, requestSize); + QPixmap pixmap = providerV2 ? providerV2->requestPixmap(imageId(url), &readSize, requestSize, providerOptions) + : provider->requestPixmap(imageId(url), &readSize, requestSize); if (!pixmap.isNull()) { *ok = true; return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()), readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform); diff --git a/src/quick/util/qquickpixmapcache_p.h b/src/quick/util/qquickpixmapcache_p.h index 93d5a1cf56..91fb1ed3bb 100644 --- a/src/quick/util/qquickpixmapcache_p.h +++ b/src/quick/util/qquickpixmapcache_p.h @@ -204,6 +204,9 @@ public: virtual QPixmap requestPixmap(const QString &id, QSize *size, const QSize& requestedSize, const QQuickImageProviderOptions &options); virtual QQuickTextureFactory *requestTexture(const QString &id, QSize *size, const QSize &requestedSize, const QQuickImageProviderOptions &options); virtual QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize, const QQuickImageProviderOptions &options); + + static QSize loadSize(const QSize &originalSize, const QSize &requestedSize, const QByteArray &format, const QQuickImageProviderOptions &options); + static QQuickImageProviderWithOptions *checkedCast(QQuickImageProvider *provider); }; QT_END_NAMESPACE |