From 16d2b97e03ff99583ab25977880affecc1c4463b Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Mon, 19 Apr 2010 14:47:11 +1000 Subject: QDeclarativeImage should stretch in one direction when tiling in the other. Task-number: QTBUG-6716 Reviewed-by: Michael Brasser --- .../graphicsitems/qdeclarativeimage.cpp | 25 +++++-- .../declarative/qdeclarativeimage/data/green.png | Bin 0 -> 314 bytes .../declarative/qdeclarativeimage/data/tiling.qml | 16 +++++ .../qdeclarativeimage/tst_qdeclarativeimage.cpp | 77 ++++++++++++++++++++- 4 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativeimage/data/green.png create mode 100644 tests/auto/declarative/qdeclarativeimage/data/tiling.qml diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp index 37b07bf..1ca8fe2 100644 --- a/src/declarative/graphicsitems/qdeclarativeimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp @@ -366,12 +366,27 @@ void QDeclarativeImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWi if (width() != d->pix.width() || height() != d->pix.height()) { if (d->fillMode >= Tile) { - if (d->fillMode == Tile) + if (d->fillMode == Tile) { p->drawTiledPixmap(QRectF(0,0,width(),height()), d->pix); - else if (d->fillMode == TileVertically) - p->drawTiledPixmap(QRectF(0,0,d->pix.width(),height()), d->pix); - else - p->drawTiledPixmap(QRectF(0,0,width(),d->pix.height()), d->pix); + } else { + qreal widthScale = width() / qreal(d->pix.width()); + qreal heightScale = height() / qreal(d->pix.height()); + + QTransform scale; + if (d->fillMode == TileVertically) { + scale.scale(widthScale, 1.0); + QTransform old = p->transform(); + p->setWorldTransform(scale * old); + p->drawTiledPixmap(QRectF(0,0,d->pix.width(),height()), d->pix); + p->setWorldTransform(old); + } else { + scale.scale(1.0, heightScale); + QTransform old = p->transform(); + p->setWorldTransform(scale * old); + p->drawTiledPixmap(QRectF(0,0,width(),d->pix.height()), d->pix); + p->setWorldTransform(old); + } + } } else { qreal widthScale = width() / qreal(d->pix.width()); qreal heightScale = height() / qreal(d->pix.height()); diff --git a/tests/auto/declarative/qdeclarativeimage/data/green.png b/tests/auto/declarative/qdeclarativeimage/data/green.png new file mode 100644 index 0000000..0a2e153 Binary files /dev/null and b/tests/auto/declarative/qdeclarativeimage/data/green.png differ diff --git a/tests/auto/declarative/qdeclarativeimage/data/tiling.qml b/tests/auto/declarative/qdeclarativeimage/data/tiling.qml new file mode 100644 index 0000000..32839bb --- /dev/null +++ b/tests/auto/declarative/qdeclarativeimage/data/tiling.qml @@ -0,0 +1,16 @@ +import Qt 4.7 + +Rectangle { + width: 800; height: 600 + + Image { + objectName: "vTiling"; height: 550; width: 200 + source: "green.png"; fillMode: Image.TileVertically + } + + Image { + objectName: "hTiling"; x: 225; height: 250; width: 550 + source: "green.png"; fillMode: Image.TileHorizontally + } +} + diff --git a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp index f94692b..73aefaf 100644 --- a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp +++ b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include "../shared/testhttpserver.h" @@ -86,8 +87,12 @@ private slots: void pixmap(); void svg(); void big(); + void tiling_QTBUG_6716(); private: + template + T *findItem(QGraphicsObject *parent, const QString &id, int index=-1); + QDeclarativeEngine engine; }; @@ -161,7 +166,7 @@ void tst_qdeclarativeimage::imageSource() if (async) QVERIFY(obj->asynchronous() == true); - + if (remote || async) TRY_WAIT(obj->status() == QDeclarativeImage::Loading); @@ -339,6 +344,76 @@ void tst_qdeclarativeimage::big() delete obj; } +void tst_qdeclarativeimage::tiling_QTBUG_6716() +{ + QDeclarativeView *canvas = new QDeclarativeView(0); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/tiling.qml")); + canvas->show(); + qApp->processEvents(); + + QDeclarativeImage *vTiling = findItem(canvas->rootObject(), "vTiling"); + QDeclarativeImage *hTiling = findItem(canvas->rootObject(), "hTiling"); + + QVERIFY(vTiling != 0); + QVERIFY(hTiling != 0); + + { + QPixmap pm(vTiling->width(), vTiling->height()); + QPainter p(&pm); + vTiling->paint(&p, 0, 0); + + QImage img = pm.toImage(); + for (int x = 0; x < vTiling->width(); ++x) { + for (int y = 0; y < vTiling->height(); ++y) { + QVERIFY(img.pixel(x, y) == qRgb(0, 255, 0)); + } + } + } + + { + QPixmap pm(hTiling->width(), hTiling->height()); + QPainter p(&pm); + hTiling->paint(&p, 0, 0); + + QImage img = pm.toImage(); + for (int x = 0; x < hTiling->width(); ++x) { + for (int y = 0; y < hTiling->height(); ++y) { + QVERIFY(img.pixel(x, y) == qRgb(0, 255, 0)); + } + } + } +} + +/* + Find an item with the specified objectName. If index is supplied then the + item must also evaluate the {index} expression equal to index +*/ +template +T *tst_qdeclarativeimage::findItem(QGraphicsObject *parent, const QString &objectName, int index) +{ + const QMetaObject &mo = T::staticMetaObject; + //qDebug() << parent->childItems().count() << "children"; + for (int i = 0; i < parent->childItems().count(); ++i) { + QDeclarativeItem *item = qobject_cast(parent->childItems().at(i)); + if(!item) + continue; + //qDebug() << "try" << item; + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { + if (index != -1) { + QDeclarativeExpression e(qmlContext(item), "index", item); + if (e.value().toInt() == index) + return static_cast(item); + } else { + return static_cast(item); + } + } + item = findItem(item, objectName, index); + if (item) + return static_cast(item); + } + + return 0; +} QTEST_MAIN(tst_qdeclarativeimage) -- cgit v0.12