From a0c12d54b8eef537ab8051e48b6d04617a91d170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 6 Aug 2009 10:56:58 +0200 Subject: Fix wrong transform when applying multiple QGraphicsEffects. --- src/gui/graphicsview/qgraphicsitem.cpp | 33 +++++++++++++++++++-------------- src/gui/graphicsview/qgraphicsitem_p.h | 4 +++- src/gui/graphicsview/qgraphicsscene.cpp | 7 +++++-- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 47f8a90..7a53598 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -10021,10 +10021,11 @@ QRectF QGraphicsItemEffectSourcePrivate::boundingRect(Qt::CoordinateSystem syste if (!item->d_ptr->children.isEmpty()) rect |= item->childrenBoundingRect(); - if (info && deviceCoordinates) { - Q_ASSERT(info->transformPtr); - rect = info->transformPtr->mapRect(rect); + if (deviceCoordinates) { + Q_ASSERT(info->painter); + rect = info->painter->worldTransform().mapRect(rect); } + return rect; } @@ -10039,11 +10040,13 @@ void QGraphicsItemEffectSourcePrivate::draw(QPainter *painter) QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func(); if (painter == info->painter) { scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion, - info->widget, info->opacity, 0, info->wasDirtySceneTransform, + info->widget, info->opacity, info->effectTransform, info->wasDirtySceneTransform, info->drawItem); } else { QTransform effectTransform = painter->worldTransform(); - effectTransform *= info->transformPtr->inverted(); + effectTransform *= info->painter->worldTransform().inverted(); + if (info->effectTransform) + effectTransform *= *info->effectTransform; scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion, info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform, info->drawItem); @@ -10097,26 +10100,28 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP QPainter pixmapPainter(&pixmap); pixmapPainter.setRenderHints(info ? info->painter->renderHints() : QPainter::TextAntialiasing); - const QTransform translateTransform = QTransform::fromTranslate(-effectRect.x(), - -effectRect.y()); + QTransform effectTransform = QTransform::fromTranslate(-effectRect.x(), -effectRect.y()); + if (deviceCoordinates && info->effectTransform) + effectTransform *= *info->effectTransform; + if (!info) { // Logical coordinates without info. QTransform sceneTransform = item->sceneTransform(); - QTransform effectTransform = sceneTransform.inverted(); - effectTransform *= translateTransform; + QTransform newEffectTransform = sceneTransform.inverted(); + newEffectTransform *= effectTransform; scened->draw(item, &pixmapPainter, 0, &sceneTransform, 0, 0, qreal(1.0), - &effectTransform, false, true); + &newEffectTransform, false, true); } else if (deviceCoordinates) { // Device coordinates with info. scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, info->exposedRegion, - info->widget, info->opacity, &translateTransform, info->wasDirtySceneTransform, + info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform, info->drawItem); } else { // Item coordinates with info. - QTransform effectTransform = info->transformPtr->inverted(); - effectTransform *= translateTransform; + QTransform newEffectTransform = info->transformPtr->inverted(); + newEffectTransform *= effectTransform; scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, info->exposedRegion, - info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform, + info->widget, info->opacity, &newEffectTransform, info->wasDirtySceneTransform, info->drawItem); } return pixmap; diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 76c9dab..0d6946f 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -517,14 +517,16 @@ struct QGraphicsItemPrivate::TransformData { struct QGraphicsItemPaintInfo { inline QGraphicsItemPaintInfo(const QTransform *const xform1, const QTransform *const xform2, + const QTransform *const xform3, QRegion *r, QWidget *w, QStyleOptionGraphicsItem *opt, QPainter *p, qreal o, bool b1, bool b2) - : viewTransform(xform1), transformPtr(xform2), exposedRegion(r), widget(w), + : viewTransform(xform1), transformPtr(xform2), effectTransform(xform3), exposedRegion(r), widget(w), option(opt), painter(p), opacity(o), wasDirtySceneTransform(b1), drawItem(b2) {} const QTransform *viewTransform; const QTransform *transformPtr; + const QTransform *effectTransform; QRegion *exposedRegion; QWidget *widget; QStyleOptionGraphicsItem *option; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index c898a3e..5f214c9 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4348,14 +4348,17 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * if (item->d_ptr->graphicsEffect && item->d_ptr->graphicsEffect->isEnabled()) { ENSURE_TRANSFORM_PTR; - QGraphicsItemPaintInfo info(viewTransform, transformPtr, exposedRegion, widget, &styleOptionTmp, + QGraphicsItemPaintInfo info(viewTransform, transformPtr, effectTransform, exposedRegion, widget, &styleOptionTmp, painter, opacity, wasDirtyParentSceneTransform, drawItem); QGraphicsEffectSource *source = item->d_ptr->graphicsEffect->d_func()->source; QGraphicsItemEffectSourcePrivate *sourced = static_cast (source->d_func()); sourced->info = &info; const QTransform restoreTransform = painter->worldTransform(); - painter->setWorldTransform(*transformPtr); + if (effectTransform) + painter->setWorldTransform(*transformPtr * *effectTransform); + else + painter->setWorldTransform(*transformPtr); item->d_ptr->graphicsEffect->draw(painter, source); painter->setWorldTransform(restoreTransform); sourced->info = 0; -- cgit v0.12