}
/*!
+ Returns a pointer to the item if this source is a QGraphicsItem; otherwise
+ returns 0.
+
+ \sa widget()
+*/
+const QGraphicsItem *QGraphicsEffectSource::graphicsItem() const
+{
+ return d_func()->graphicsItem();
+}
+
+/*!
Returns a pointer to the widget if this source is a QWidget; otherwise
returns 0.
+
+ \sa graphicsItem()
*/
const QWidget *QGraphicsEffectSource::widget() const
{
}
/*!
+ Returns a pointer to the style options (used when drawing the source) if
+ available; otherwise returns 0.
+
+ \sa graphicsItem(), widget()
+*/
+const QStyleOption *QGraphicsEffectSource::styleOption() const
+{
+ return d_func()->styleOption();
+}
+
+/*!
Draws the source using the given \a painter.
This function should only be called from QGraphicsEffect::draw().
}
/*!
+ Returns true if the source effectively is a pixmap, e.g., a
+ QGraphicsPixmapItem.
+
+ This function is useful for optimization purposes. For instance, there's no
+ point in drawing the source in device coordinates to avoid pixmap scaling
+ if this function returns true - the source pixmap will be scaled anyways.
+*/
+bool QGraphicsEffectSource::isPixmap() const
+{
+ return d_func()->isPixmap();
+}
+
+/*!
+ Returns true if the source effectively is a pixmap, e.g., a
+ QGraphicsPixmapItem.
+
+ This function is useful for optimization purposes. For instance, there's no
+ point in drawing the source in device coordinates to avoid pixmap scaling
+ if this function returns true - the source pixmap will be scaled anyways.
+*/
+bool QGraphicsEffect::sourceIsPixmap() const
+{
+ return source() ? source()->isPixmap() : false;
+}
+
+/*!
Returns a pixmap with the source painted into it.
The \a system specifies which coordinate system to be used for the source.
{
Q_D(const QGraphicsEffectSource);
- QPixmap pm = d->pixmap(system, &d->m_cachedOffset, mode);
- d->m_cachedSystem = system;
- d->m_cachedMode = mode;
+ // Shortcut, no cache for childless pixmap items...
+ const QGraphicsItem *item = graphicsItem();
+ if (system == Qt::LogicalCoordinates && mode == QGraphicsEffect::NoPad && item && isPixmap()) {
+ const QGraphicsPixmapItem *pixmapItem = static_cast<const QGraphicsPixmapItem *>(item);
+ if (offset)
+ *offset = pixmapItem->offset().toPoint();
+ return pixmapItem->pixmap();
+ }
- d->invalidateCache();
- d->m_cacheKey = QPixmapCache::insert(pm);
+ if (system == Qt::DeviceCoordinates && item
+ && !static_cast<const QGraphicsItemEffectSourcePrivate *>(d_func())->info) {
+ qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
+ return QPixmap();
+ }
+
+ QPixmap pm;
+ if (item && d->m_cachedSystem == system && d->m_cachedMode == mode)
+ QPixmapCache::find(d->m_cacheKey, &pm);
+
+ if (pm.isNull()) {
+ pm = d->pixmap(system, &d->m_cachedOffset, mode);
+ d->m_cachedSystem = system;
+ d->m_cachedMode = mode;
+
+ d->invalidateCache();
+ d->m_cacheKey = QPixmapCache::insert(pm);
+ }
if (offset)
*offset = d->m_cachedOffset;
}
QPoint offset;
+ if (sourceIsPixmap()) {
+ // No point in drawing in device coordinates (pixmap will be scaled anyways).
+ const QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, NoPad);
+ if (!pixmap.isNull())
+ d->filter->draw(painter, offset, pixmap);
+
+ return;
+ }
+
// Draw pixmap in deviceCoordinates to avoid pixmap scaling.
const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset);
if (pixmap.isNull())
}
QPoint offset;
- QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, QGraphicsEffect::NoPad);
+ Qt::CoordinateSystem system = sourceIsPixmap() ? Qt::LogicalCoordinates : Qt::DeviceCoordinates;
+ QPixmap pixmap = sourcePixmap(system, &offset, QGraphicsEffect::NoPad);
if (pixmap.isNull())
return;
QPainter pixmapPainter(&pixmap);
pixmapPainter.setRenderHints(painter->renderHints());
pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
- QTransform worldTransform = painter->worldTransform();
- worldTransform *= QTransform::fromTranslate(-offset.x(), -offset.y());
- pixmapPainter.setWorldTransform(worldTransform);
- pixmapPainter.fillRect(sourceBoundingRect(), d->opacityMask);
+ if (system == Qt::DeviceCoordinates) {
+ QTransform worldTransform = painter->worldTransform();
+ worldTransform *= QTransform::fromTranslate(-offset.x(), -offset.y());
+ pixmapPainter.setWorldTransform(worldTransform);
+ pixmapPainter.fillRect(sourceBoundingRect(), d->opacityMask);
+ } else {
+ pixmapPainter.translate(-offset);
+ pixmapPainter.fillRect(pixmap.rect(), d->opacityMask);
+ }
}
- painter->setWorldTransform(QTransform());
+ if (system == Qt::DeviceCoordinates)
+ painter->setWorldTransform(QTransform());
painter->drawPixmap(offset, pixmap);
painter->restore();
Q_OBJECT
public:
~QGraphicsEffectSource();
+ const QGraphicsItem *graphicsItem() const;
const QWidget *widget() const;
+ const QStyleOption *styleOption() const;
+ bool isPixmap() const;
void draw(QPainter *painter);
void update();
virtual void detach() = 0;
virtual QRectF boundingRect(Qt::CoordinateSystem system) const = 0;
virtual QRect deviceRect() const = 0;
+ virtual const QGraphicsItem *graphicsItem() const = 0;
virtual const QWidget *widget() const = 0;
+ virtual const QStyleOption *styleOption() const = 0;
virtual void draw(QPainter *p) = 0;
virtual void update() = 0;
+ virtual bool isPixmap() const = 0;
virtual QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset = 0,
QGraphicsEffect::PixmapPadMode mode = QGraphicsEffect::PadToTransparentBorder) const = 0;
virtual void effectBoundingRectChanged() = 0;