diff options
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 5 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 10 | ||||
-rw-r--r-- | tests/manual/highdpi/main.cpp | 54 |
3 files changed, 68 insertions, 1 deletions
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) diff --git a/tests/manual/highdpi/main.cpp b/tests/manual/highdpi/main.cpp index bd6af75b16..6f854a68d4 100644 --- a/tests/manual/highdpi/main.cpp +++ b/tests/manual/highdpi/main.cpp @@ -334,6 +334,59 @@ void PixmapPainter::paintEvent(QPaintEvent *) x+=dx * 2; p.drawImage(QRect(x, y, pixmapPointSize * 2, pixmapPointSize * 2), imageLarge); } +class TiledPixmapPainter : public QWidget +{ +public: + QPixmap pixmap1X; + QPixmap pixmap2X; + QPixmap pixmapLarge; + + TiledPixmapPainter(); + void paintEvent(QPaintEvent *event); +}; + +TiledPixmapPainter::TiledPixmapPainter() +{ + pixmap1X = QPixmap(":/qticon32.png"); + pixmap2X = QPixmap(":/qticon32@2x.png"); + pixmapLarge = QPixmap(":/qticon64.png"); +} + +void TiledPixmapPainter::paintEvent(QPaintEvent *event) +{ + QPainter p(this); + + int xoff = 10; + int yoff = 10; + int tiles = 4; + int pixmapEdge = 32; + int tileAreaEdge = pixmapEdge * tiles; + + // Expected behavior for both 1x and 2x dislays: + // 1x pixmap : 4 x 4 tiles + // large pixmap: 2 x 2 tiles + // 2x pixmap : 4 x 4 tiles + // + // On a 2x display the 2x pimxap tiles + // will be drawn in high resolution. + p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmap1X); + yoff += tiles * pixmapEdge + 10; + p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmapLarge); + yoff += tiles * pixmapEdge + 10; + p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmap2X); + + // Again, with an offset. The offset is in + // device-independent pixels. + QPoint offset(40, 40); // larger than the pixmap edge size to exercise that code path + yoff = 10; + xoff = 20 + tiles * pixmapEdge ; + p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmap1X, offset); + yoff += tiles * pixmapEdge + 10; + p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmapLarge, offset); + yoff += tiles * pixmapEdge + 10; + p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmap2X, offset); +} + class Labels : public QWidget { public: @@ -1119,6 +1172,7 @@ int main(int argc, char **argv) DemoContainerList demoList; demoList << new DemoContainer<PixmapPainter>("pixmap", "Test pixmap painter"); + demoList << new DemoContainer<TiledPixmapPainter>("tiledpixmap", "Test tiled pixmap painter"); demoList << new DemoContainer<Labels>("label", "Test Labels"); demoList << new DemoContainer<MainWindow>("mainwindow", "Test QMainWindow"); demoList << new DemoContainer<StandardIcons>("standard-icons", "Test standard icons"); |