diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2013-08-09 11:14:36 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-08-09 17:36:15 +0200 |
commit | eab5d78ef51a9a36414960714853341087bb8e99 (patch) | |
tree | b40544dfcecf99d82fe28a406847e851651d98f8 | |
parent | 6ba7d28706c770b0921de5a56cb24be85d8f179a (diff) | |
download | qtwebkit-eab5d78ef51a9a36414960714853341087bb8e99.tar.gz |
[Qt] Images are down-scaled badly
https://bugs.webkit.org/show_bug.cgi?id=119263
Reviewed by Jocelyn Turcotte.
QPainter only does bilinear filtering, which means it will downscaling beyond
0.5x will start skipping pixel and start to degrade the end result. Scaling in
QImage and QPixmap however uses a better but much more expensive sampling that
counts all pixels.
To get the high quality downscaling we must therefore prescale the images before
painting them. To avoid a performance impact on repeated paints the prescaled
image are saved in the QPixmapCache.
* platform/graphics/qt/ImageQt.cpp:
(WebCore::BitmapImage::draw):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153522 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Task-number: QTBUG-30155
Change-Id: I8b07de1d7415bc4e2dea565df92739e3ff2014b4
Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
-rw-r--r-- | Source/WebCore/platform/graphics/qt/ImageQt.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/Source/WebCore/platform/graphics/qt/ImageQt.cpp b/Source/WebCore/platform/graphics/qt/ImageQt.cpp index 83692fdae..0c66fe5fb 100644 --- a/Source/WebCore/platform/graphics/qt/ImageQt.cpp +++ b/Source/WebCore/platform/graphics/qt/ImageQt.cpp @@ -47,7 +47,9 @@ #include <QImageReader> #include <QPainter> #include <QPixmap> +#include <QPixmapCache> #include <QTransform> +#include <private/qhexstring_p.h> #include <math.h> @@ -245,6 +247,7 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, QPixmap* image = nativeImageForCurrentFrame(); if (!image) return; + QPixmap prescaled; if (mayFillWithSolidColor()) { fillWithSolidColor(ctxt, normalizedDst, solidColor(), styleColorSpace, op); @@ -255,6 +258,37 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, normalizedSrc = adjustSourceRectForDownSampling(normalizedSrc, image->size()); #endif + QPainter* painter = ctxt->platformContext(); + // The quality of down scaling at 0.5x and below in QPainter is not very good + // due only using bilinear sampling, so for high quality scaling we need to + // perform scaling ourselves. +#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) + const float pixelRatio = painter->device()->devicePixelRatio(); +#else + const float pixelRatio = 1; +#endif + if (painter->renderHints() & QPainter::SmoothPixmapTransform + && (normalizedDst.width() * 2 * pixelRatio < normalizedSrc.width() + || normalizedDst.height() * 2 * pixelRatio < normalizedSrc.height())) { + // This may not work right with subpixel positions, but that can not currently happen. + QRect pixelSrc = normalizedSrc.toRect(); + QSize scaledSize(normalizedDst.width() * pixelRatio, normalizedDst.height() * pixelRatio); + QString key = QStringLiteral("qtwebkit_prescaled_") + % HexString<qint64>(image->cacheKey()) + % HexString<int>(pixelSrc.x()) % HexString<int>(pixelSrc.y()) + % HexString<int>(pixelSrc.width()) % HexString<int>(pixelSrc.height()) + % HexString<int>(scaledSize.width()) % HexString<int>(scaledSize.height()); + if (!QPixmapCache::find(key, &prescaled)) { + if (pixelSrc != image->rect()) + prescaled = image->copy(pixelSrc).scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + else + prescaled = image->scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + QPixmapCache::insert(key, prescaled); + } + normalizedSrc = QRectF(QPointF(), prescaled.size()); + image = &prescaled; + } + CompositeOperator previousOperator = ctxt->compositeOperation(); ctxt->setCompositeOperation(!image->hasAlpha() && op == CompositeSourceOver ? CompositeCopy : op); |