summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2013-08-09 11:14:36 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-08-09 17:36:15 +0200
commiteab5d78ef51a9a36414960714853341087bb8e99 (patch)
treeb40544dfcecf99d82fe28a406847e851651d98f8
parent6ba7d28706c770b0921de5a56cb24be85d8f179a (diff)
downloadqtwebkit-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.cpp34
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);