diff options
author | Yoann Lopes <yoann.lopes@nokia.com> | 2010-03-17 13:28:50 (GMT) |
---|---|---|
committer | Yoann Lopes <yoann.lopes@nokia.com> | 2010-03-17 13:33:34 (GMT) |
commit | 6aba7215a0ac2092a7f00015df0d7a80681ef6bc (patch) | |
tree | ba486c3999713bbe73d3acb78a7ec117cdfe124f /tests/auto | |
parent | c950a2594f7c3102930541800edac5384827846d (diff) | |
download | Qt-6aba7215a0ac2092a7f00015df0d7a80681ef6bc.zip Qt-6aba7215a0ac2092a7f00015df0d7a80681ef6bc.tar.gz Qt-6aba7215a0ac2092a7f00015df0d7a80681ef6bc.tar.bz2 |
Fixes blending problem when paiting non-opaque items with cache enabled.
In most cases when partially updating an item, the old content of the
cache needs to be replaced with the new content
(CompositionMode_Source). But in a specific case when using
DeviceCoordinateCache and when the item is transformed, the new content
needs to be blended (CompositionMode_SourceAtop) with the old one to
avoid incorrect fully transparent background.
Autotest included.
Task-number: QTBUG-7863
Reviewed-by: bnilsen
Diffstat (limited to 'tests/auto')
-rw-r--r-- | tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 132 |
1 files changed, 130 insertions, 2 deletions
diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 9d437d6..9cd86a6 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -283,6 +283,7 @@ private slots: void task250680_childClip(); void taskQTBUG_5904_crashWithDeviceCoordinateCache(); void taskQT657_paintIntoCacheWithTransparentParts(); + void taskQTBUG_7863_paintIntoCacheWithTransparentParts(); }; void tst_QGraphicsScene::initTestCase() @@ -4348,8 +4349,9 @@ void tst_QGraphicsScene::taskQTBUG_5904_crashWithDeviceCoordinateCache() void tst_QGraphicsScene::taskQT657_paintIntoCacheWithTransparentParts() { + // Test using DeviceCoordinateCache and opaque item QWidget *w = new QWidget(); - w->setPalette(Qt::blue); + w->setPalette(QColor(0, 0, 255)); w->setGeometry(0, 0, 50, 50); QGraphicsScene *scene = new QGraphicsScene(); @@ -4361,7 +4363,7 @@ void tst_QGraphicsScene::taskQT657_paintIntoCacheWithTransparentParts() view->show(); QTest::qWaitForWindowShown(view); - w->update(10,10,10,10); + w->update(10, 10, 10, 10); QTest::qWait(50); QPixmap pix; @@ -4382,6 +4384,132 @@ void tst_QGraphicsScene::taskQT657_paintIntoCacheWithTransparentParts() for(int j = 0; j < im.height(); j++) QCOMPARE(qAlpha(im.pixel(i, j)), 255); } + + delete w; +} + +void tst_QGraphicsScene::taskQTBUG_7863_paintIntoCacheWithTransparentParts() +{ + // Test using DeviceCoordinateCache and semi-transparent item + { + QGraphicsRectItem *backItem = new QGraphicsRectItem(0, 0, 100, 100); + backItem->setBrush(QColor(255, 255, 0)); + QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 50, 50); + rectItem->setBrush(QColor(0, 0, 255, 125)); + rectItem->setParentItem(backItem); + + QGraphicsScene *scene = new QGraphicsScene(); + QGraphicsView *view = new QGraphicsView(scene); + + scene->addItem(backItem); + rectItem->setCacheMode(QGraphicsItem::DeviceCoordinateCache); + backItem->rotate(15); + + view->show(); + QTest::qWaitForWindowShown(view); + rectItem->update(10, 10, 10, 10); + QTest::qWait(50); + + QPixmap pix; + QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(rectItem); + QPixmapCache::Key key = itemp->extraItemCache()->deviceData.value(view->viewport()).key; + QVERIFY(QPixmapCache::find(key, &pix)); + + QTransform t = rectItem->sceneTransform(); + // Map from scene coordinates to pixmap coordinates. + // X origin in the pixmap is the most-left point + // of the item's boundingRect in the scene. + qreal adjust = t.mapRect(rectItem->boundingRect().toRect()).left(); + QRect rect = t.mapRect(QRect(10, 10, 10, 10)).adjusted(-adjust, 0, -adjust + 1, 1); + QPixmap subpix = pix.copy(rect); + + QImage im = subpix.toImage(); + for(int i = 0; i < im.width(); i++) { + for(int j = 0; j < im.height(); j++) { + QCOMPARE(qAlpha(im.pixel(i, j)), 125); + } + } + + delete view; + } + + // Test using ItemCoordinateCache and opaque item + { + QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 50, 50); + rectItem->setBrush(QColor(0, 0, 255)); + + QGraphicsScene *scene = new QGraphicsScene(); + QGraphicsView *view = new QGraphicsView(scene); + + scene->addItem(rectItem); + rectItem->setCacheMode(QGraphicsItem::ItemCoordinateCache); + rectItem->rotate(15); + + view->show(); + QTest::qWaitForWindowShown(view); + rectItem->update(10, 10, 10, 10); + QTest::qWait(50); + + QPixmap pix; + QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(rectItem); + QPixmapCache::Key key = itemp->extraItemCache()->key; + QVERIFY(QPixmapCache::find(key, &pix)); + + QTransform t = rectItem->sceneTransform(); + // Map from scene coordinates to pixmap coordinates. + // X origin in the pixmap is the most-left point + // of the item's boundingRect in the scene. + qreal adjust = t.mapRect(rectItem->boundingRect().toRect()).left(); + QRect rect = t.mapRect(QRect(10, 10, 10, 10)).adjusted(-adjust, 0, -adjust + 1, 1); + QPixmap subpix = pix.copy(rect); + + QImage im = subpix.toImage(); + for(int i = 0; i < im.width(); i++) { + for(int j = 0; j < im.height(); j++) + QCOMPARE(qAlpha(im.pixel(i, j)), 255); + } + + delete view; + } + + // Test using ItemCoordinateCache and semi-transparent item + { + QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 50, 50); + rectItem->setBrush(QColor(0, 0, 255, 125)); + + QGraphicsScene *scene = new QGraphicsScene(); + QGraphicsView *view = new QGraphicsView(scene); + + scene->addItem(rectItem); + rectItem->setCacheMode(QGraphicsItem::ItemCoordinateCache); + rectItem->rotate(15); + + view->show(); + QTest::qWaitForWindowShown(view); + rectItem->update(10, 10, 10, 10); + QTest::qWait(50); + + QPixmap pix; + QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(rectItem); + QPixmapCache::Key key = itemp->extraItemCache()->key; + QVERIFY(QPixmapCache::find(key, &pix)); + + QTransform t = rectItem->sceneTransform(); + // Map from scene coordinates to pixmap coordinates. + // X origin in the pixmap is the most-left point + // of the item's boundingRect in the scene. + qreal adjust = t.mapRect(rectItem->boundingRect().toRect()).left(); + QRect rect = t.mapRect(QRect(10, 10, 10, 10)).adjusted(-adjust, 0, -adjust + 1, 1); + QPixmap subpix = pix.copy(rect); + + QImage im = subpix.toImage(); + for(int i = 0; i < im.width(); i++) { + for(int j = 0; j < im.height(); j++) + QCOMPARE(qAlpha(im.pixel(i, j)), 125); + } + + delete view; + } } QTEST_MAIN(tst_QGraphicsScene) |