From 7160df3a15637acbb6548878d3a0afe294e64a6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 24 Feb 2015 11:13:31 +0100 Subject: High-dpi drawTiledPixmap (raster paint engine) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement more consistent behavior for drawTiledPixmap(), which should produce the same visual tiling pattern independent of display devicePixelRatio Consider the following pixmaps and draw calls: QPixmap px32; // 32x32 QPixmap px64; // 64x64 drawTiledPixmap(QRect(0, 0, 128, 128), px32); drawTiledPixmap(QRect(0, 0, 128, 128), px64); On 1x displays this will produce 4x4 and 2x2 tiles, respectively. On 2x displays this would previously produce a different tiling pattern, where the paint engine would tile in the device pixel coordinate system. Change this to tile in the device independent coordinate system, producing the same visual tiling pattern as the 1x case. It is possible to produce a 4x4 tiling pattern with high-resolution output from the 64x64 pixmap by setting the devicePixelRatio: QPixmap px64; px64.setDevicePixelRatio(2); drawTiledPixmap(QRect(0, 0, 128, 128), px64); This change adds an inverse scale to the image filler transform that accounts for the pixmap devicePixelRatio. [ChangeLog][QtGui] QPainter::drawTiledPixmap() now tiles in the device independent coordinate system. Change-Id: I4918d274192967f222f181b374571c7c597dcd76 Reviewed-by: Jonathan Courtois Reviewed-by: Timur Pocheptsov Reviewed-by: 石博文 Reviewed-by: Eirik Aavitsland --- src/gui/painting/qpaintengine_raster.cpp | 5 ++++- src/gui/painting/qpainter.cpp | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'src/gui') diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 6336b2943e..e0dd789dfd 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -2502,10 +2502,13 @@ void QRasterPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, if (image.depth() == 1) image = d->rasterBuffer->colorizeBitmap(image, s->pen.color()); - if (s->matrix.type() > QTransform::TxTranslate) { + const qreal pixmapDevicePixelRatio = pixmap.devicePixelRatio(); + if (s->matrix.type() > QTransform::TxTranslate || pixmapDevicePixelRatio > qreal(1.0)) { QTransform copy = s->matrix; copy.translate(r.x(), r.y()); copy.translate(-sr.x(), -sr.y()); + const qreal inverseDpr = qreal(1.0) / pixmapDevicePixelRatio; + copy.scale(inverseDpr, inverseDpr); d->image_filler_xform.clip = d->clip(); d->image_filler_xform.initTexture(&image, s->intOpacity, QTextureData::Tiled); if (!d->image_filler_xform.blend) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index a0a58cc157..a37511ff0a 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6664,6 +6664,16 @@ QRectF QPainter::boundingRect(const QRectF &r, const QString &text, const QTextO potentially much more efficient depending on the underlying window system. + drawTiledPixmap() will produce the same visual tiling pattern on + high-dpi displays (with devicePixelRatio > 1), compared to normal- + dpi displays. Set the devicePixelRatio on the \a pixmap to control + the tile size. For example, setting it to 2 halves the tile width + and height (on both 1x and 2x displays), and produces high-resolution + output on 2x displays. + + The \a position offset is always in the painter coordinate system, + indepentent of display devicePixelRatio. + \sa drawPixmap() */ void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &sp) -- cgit v1.2.3