Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qgraphicseffect.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
69#include "qgraphicseffect_p.h"
70#include "private/qgraphicsitem_p.h"
71
72#include <QtWidgets/qgraphicsitem.h>
73
74#include <QtGui/qimage.h>
75#include <QtGui/qpainter.h>
76#include <QtGui/qpaintengine.h>
77#include <QtCore/qrect.h>
78#include <QtCore/qdebug.h>
79#include <private/qdrawhelper_p.h>
80
82
86
109
115
122{
123 return d_func()->boundingRect(system);
124}
125
136{
137 Q_D(const QGraphicsEffect);
138 if (d->source)
139 return d->source->boundingRect(system);
140 return QRectF();
141}
142
150{
151 return d_func()->graphicsItem();
152}
153
161{
162 return d_func()->widget();
163}
164
172{
173 return d_func()->styleOption();
174}
175
184{
185 Q_D(const QGraphicsEffectSource);
186
187 QPixmap pm;
188 if (QPixmapCache::find(d->m_cacheKey, &pm)) {
189 QTransform restoreTransform;
190 if (d->m_cachedSystem == Qt::DeviceCoordinates) {
191 restoreTransform = painter->worldTransform();
193 }
194
195 painter->drawPixmap(d->m_cachedOffset, pm);
196
197 if (d->m_cachedSystem == Qt::DeviceCoordinates)
198 painter->setWorldTransform(restoreTransform);
199 } else {
200 d_func()->draw(painter);
201 }
202}
203
216{
217 Q_D(const QGraphicsEffect);
218 if (d->source)
219 d->source->draw(painter);
220}
221
230{
231 d_func()->update();
232}
233
243{
244 return d_func()->isPixmap();
245}
246
256{
257 return source() ? source()->isPixmap() : false;
258}
259
276{
277 Q_D(const QGraphicsEffectSource);
278
279 // Shortcut, no cache for childless pixmap items...
281 if (system == Qt::LogicalCoordinates && mode == QGraphicsEffect::NoPad && item && isPixmap()) {
282 const QGraphicsPixmapItem *pixmapItem = static_cast<const QGraphicsPixmapItem *>(item);
283 if (offset)
284 *offset = pixmapItem->offset().toPoint();
285 return pixmapItem->pixmap();
286 }
287
288 if (Q_UNLIKELY(system == Qt::DeviceCoordinates && item &&
289 !static_cast<const QGraphicsItemEffectSourcePrivate *>(d_func())->info)) {
290 qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
291 return QPixmap();
292 }
293
294 QPixmap pm;
295 if (item && d->m_cachedSystem == system && d->m_cachedMode == mode)
296 QPixmapCache::find(d->m_cacheKey, &pm);
297
298 if (pm.isNull()) {
299 pm = d->pixmap(system, &d->m_cachedOffset, mode);
300 d->m_cachedSystem = system;
301 d->m_cachedMode = mode;
302
303 d->invalidateCache();
304 d->m_cacheKey = QPixmapCache::insert(pm);
305 }
306
307 if (offset)
308 *offset = d->m_cachedOffset;
309
310 return pm;
311}
312
331{
332 Q_D(const QGraphicsEffect);
333 if (d->source)
334 return d->source->pixmap(system, offset, mode);
335 return QPixmap();
336}
337
342
344{
345 m_cachedOffset = offset;
346}
347
349{
351 && (reason == EffectRectChanged
352 || (reason == TransformChanged && m_cachedSystem == Qt::LogicalCoordinates))) {
353 return;
354 }
355
356 QPixmapCache::remove(m_cacheKey);
357}
358
367
375
380{
381 Q_D(QGraphicsEffect);
382 d->setGraphicsEffectSource(nullptr);
383}
384
393{
394 Q_D(const QGraphicsEffect);
395 if (d->source)
396 return boundingRectFor(d->source->boundingRect());
397 return QRectF();
398}
399
410{
411 return rect;
412}
413
428{
429 Q_D(const QGraphicsEffect);
430 return d->isEnabled;
431}
432
434{
435 Q_D(QGraphicsEffect);
436 if (d->isEnabled == enable)
437 return;
438
439 d->isEnabled = enable;
440 if (d->source) {
441 d->source->d_func()->effectBoundingRectChanged();
442 d->source->d_func()->invalidateCache();
443 }
445}
446
463{
464 Q_D(QGraphicsEffect);
465 if (d->source)
466 d->source->update();
467}
468
478{
479 Q_D(const QGraphicsEffect);
480 return d->source;
481}
482
494{
495 Q_D(QGraphicsEffect);
496 if (d->source) {
497 d->source->d_func()->effectBoundingRectChanged();
498 d->source->d_func()->invalidateCache(QGraphicsEffectSourcePrivate::EffectRectChanged);
499 }
500}
501
553{
555}
556
581
588
596{
597 Q_D(const QGraphicsColorizeEffect);
598 return d->filter->color();
599}
600
602{
604 if (d->filter->color() == color)
605 return;
606
607 d->filter->setColor(color);
608 update();
610}
611
620{
621 Q_D(const QGraphicsColorizeEffect);
622 return d->filter->strength();
623}
624
626{
628 if (qFuzzyCompare(d->filter->strength(), strength))
629 return;
630
631 d->filter->setStrength(strength);
632 d->opaque = !qFuzzyIsNull(strength);
633 update();
635}
636
654{
656
657 if (!d->opaque) {
659 return;
660 }
661
663 if (sourceIsPixmap()) {
664 // No point in drawing in device coordinates (pixmap will be scaled anyways).
666 if (!pixmap.isNull())
667 d->filter->draw(painter, offset, pixmap);
668
669 return;
670 }
671
672 // Draw pixmap in deviceCoordinates to avoid pixmap scaling.
674 if (pixmap.isNull())
675 return;
676
677 QTransform restoreTransform = painter->worldTransform();
679 d->filter->draw(painter, offset, pixmap);
680 painter->setWorldTransform(restoreTransform);
681}
682
734
741
755{
756 Q_D(const QGraphicsBlurEffect);
757 return d->filter->radius();
758}
759
761{
763 if (qFuzzyCompare(d->filter->radius(), radius))
764 return;
765
766 d->filter->setRadius(radius);
768 emit blurRadiusChanged(radius);
769}
770
788QGraphicsBlurEffect::BlurHints QGraphicsBlurEffect::blurHints() const
789{
790 Q_D(const QGraphicsBlurEffect);
791 return d->filter->blurHints();
792}
793
794void QGraphicsBlurEffect::setBlurHints(QGraphicsBlurEffect::BlurHints hints)
795{
797 if (d->filter->blurHints() == hints)
798 return;
799
800 d->filter->setBlurHints(hints);
801 emit blurHintsChanged(hints);
802}
803
815{
816 Q_D(const QGraphicsBlurEffect);
817 return d->filter->boundingRectFor(rect);
818}
819
824{
826 if (d->filter->radius() < 1) {
828 return;
829 }
830
832
835 if (pixmap.isNull())
836 return;
837
838 d->filter->draw(painter, offset, pixmap);
839}
840
871
878
891{
892 Q_D(const QGraphicsDropShadowEffect);
893 return d->filter->offset();
894}
895
897{
899 if (d->filter->offset() == offset)
900 return;
901
902 d->filter->setOffset(offset);
905}
906
946{
947 Q_D(const QGraphicsDropShadowEffect);
948 return d->filter->blurRadius();
949}
950
952{
954 if (qFuzzyCompare(d->filter->blurRadius(), blurRadius))
955 return;
956
957 d->filter->setBlurRadius(blurRadius);
960}
961
979{
980 Q_D(const QGraphicsDropShadowEffect);
981 return d->filter->color();
982}
983
985{
987 if (d->filter->color() == color)
988 return;
989
990 d->filter->setColor(color);
991 update();
993}
994
1006{
1007 Q_D(const QGraphicsDropShadowEffect);
1008 return d->filter->boundingRectFor(rect);
1009}
1010
1015{
1017 if (d->filter->blurRadius() <= 0 && d->filter->offset().isNull()) {
1019 return;
1020 }
1021
1023
1024 // Draw pixmap in device coordinates to avoid pixmap scaling.
1025 QPoint offset;
1027 if (pixmap.isNull())
1028 return;
1029
1030 QTransform restoreTransform = painter->worldTransform();
1032 d->filter->draw(painter, offset, pixmap);
1033 painter->setWorldTransform(restoreTransform);
1034}
1035
1061
1068
1081{
1082 Q_D(const QGraphicsOpacityEffect);
1083 return d->opacity;
1084}
1085
1087{
1089 opacity = qBound(qreal(0.0), opacity, qreal(1.0));
1090
1091 if (qFuzzyCompare(d->opacity, opacity))
1092 return;
1093
1094 d->opacity = opacity;
1095 if ((d->isFullyTransparent = qFuzzyIsNull(d->opacity)))
1096 d->isFullyOpaque = 0;
1097 else
1098 d->isFullyOpaque = qFuzzyIsNull(d->opacity - 1);
1099 update();
1101}
1102
1125{
1126 Q_D(const QGraphicsOpacityEffect);
1127 return d->opacityMask;
1128}
1129
1131{
1133 if (d->opacityMask == mask)
1134 return;
1135
1136 d->opacityMask = mask;
1137 d->hasOpacityMask = (mask.style() != Qt::NoBrush);
1138 update();
1139
1141}
1142
1154{
1156
1157 // Transparent; nothing to draw.
1158 if (d->isFullyTransparent)
1159 return;
1160
1161 // Opaque; draw directly without going through a pixmap.
1162 if (d->isFullyOpaque && !d->hasOpacityMask) {
1164 return;
1165 }
1166
1167 QPoint offset;
1170 if (pixmap.isNull())
1171 return;
1172
1173 painter->save();
1174 painter->setOpacity(d->opacity);
1175
1176 if (d->hasOpacityMask) {
1177 QPainter pixmapPainter(&pixmap);
1178 pixmapPainter.setRenderHints(painter->renderHints());
1179 pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
1180 if (system == Qt::DeviceCoordinates) {
1181 QTransform worldTransform = painter->worldTransform();
1182 worldTransform *= QTransform::fromTranslate(-offset.x(), -offset.y());
1183 pixmapPainter.setWorldTransform(worldTransform);
1184 pixmapPainter.fillRect(sourceBoundingRect(), d->opacityMask);
1185 } else {
1186 pixmapPainter.translate(-offset);
1187 pixmapPainter.fillRect(pixmap.rect(), d->opacityMask);
1188 }
1189 }
1190
1191 if (system == Qt::DeviceCoordinates)
1193
1195 painter->restore();
1196}
1197
1198
1200
1201#include "moc_qgraphicseffect.cpp"
1202#include "moc_qgraphicseffect_p.cpp"
\inmodule QtGui
Definition qbrush.h:30
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
The QGraphicsBlurEffect class provides a blur effect.
~QGraphicsBlurEffect()
Destroys the effect.
void draw(QPainter *painter) override
\reimp
void blurHintsChanged(BlurHints hints)
This signal is emitted whenever the effect's blur hints changes.
QGraphicsBlurEffect(QObject *parent=nullptr)
Constructs a new QGraphicsBlurEffect instance.
void blurRadiusChanged(qreal blurRadius)
This signal is emitted whenever the effect's blur radius changes.
void setBlurRadius(qreal blurRadius)
qreal blurRadius
the blur radius of the effect.
QRectF boundingRectFor(const QRectF &rect) const override
\reimp
void setBlurHints(BlurHints hints)
BlurHints blurHints
the blur hint of the effect.
The QGraphicsColorizeEffect class provides a colorize effect.
void draw(QPainter *painter) override
\reimp
void setStrength(qreal strength)
QColor color
the color of the effect.
void setColor(const QColor &c)
qreal strength
the strength of the effect.
~QGraphicsColorizeEffect()
Destroys the effect.
QGraphicsColorizeEffect(QObject *parent=nullptr)
Constructs a new QGraphicsColorizeEffect instance.
void strengthChanged(qreal strength)
This signal is emitted whenever setStrength() changes the colorize strength property.
The QGraphicsDropShadowEffect class provides a drop shadow effect.
void draw(QPainter *painter) override
\reimp
void blurRadiusChanged(qreal blurRadius)
This signal is emitted whenever the effect's blur radius changes.
QGraphicsDropShadowEffect(QObject *parent=nullptr)
Constructs a new QGraphicsDropShadowEffect instance.
void setColor(const QColor &color)
void offsetChanged(const QPointF &offset)
This signal is emitted whenever the effect's shadow offset changes.
QRectF boundingRectFor(const QRectF &rect) const override
\reimp
void setBlurRadius(qreal blurRadius)
QColor color
the color of the drop shadow.
void setOffset(const QPointF &ofs)
QPointF offset
the shadow offset in pixels.
qreal blurRadius
the blur radius in pixels of the drop shadow.
~QGraphicsDropShadowEffect()
Destroys the effect.
void setCachedOffset(const QPoint &offset)
void invalidateCache(InvalidateReason reason=SourceChanged) const
The QGraphicsEffectSource class represents the source on which a QGraphicsEffect is installed on.
const QGraphicsItem * graphicsItem() const
Returns a pointer to the item if this source is a QGraphicsItem; otherwise returns \nullptr.
QRectF boundingRect(Qt::CoordinateSystem coordinateSystem=Qt::LogicalCoordinates) const
Returns the bounding rectangle of the source mapped to the given system.
bool isPixmap() const
Returns true if the source effectively is a pixmap, e.g., a QGraphicsPixmapItem.
const QStyleOption * styleOption() const
Returns a pointer to the style options (used when drawing the source) if available; otherwise returns...
void update()
Schedules a redraw of the source.
QPixmap pixmap(Qt::CoordinateSystem system=Qt::LogicalCoordinates, QPoint *offset=nullptr, QGraphicsEffect::PixmapPadMode mode=QGraphicsEffect::PadToEffectiveBoundingRect) const
Returns a pixmap with the source painted into it.
~QGraphicsEffectSource()
Destroys the effect source.
QGraphicsEffectSource(QGraphicsEffectSourcePrivate &dd, QObject *parent=nullptr)
void draw(QPainter *painter)
Draws the source using the given painter.
const QWidget * widget() const
Returns a pointer to the widget if this source is a QWidget; otherwise returns \nullptr.
The QGraphicsEffect class is the base class for all graphics effects.
void drawSource(QPainter *painter)
Draws the source directly using the given painter.
QRectF boundingRect() const
Returns the effective bounding rectangle for this effect, i.e., the bounding rectangle of the source ...
QPixmap sourcePixmap(Qt::CoordinateSystem system=Qt::LogicalCoordinates, QPoint *offset=nullptr, PixmapPadMode mode=PadToEffectiveBoundingRect) const
Returns a pixmap with the source painted into it.
void updateBoundingRect()
This function notifies the effect framework when the effect's bounding rectangle has changed.
virtual ~QGraphicsEffect()
Removes the effect from the source, and destroys the graphics effect.
bool sourceIsPixmap() const
Returns true if the source effectively is a pixmap, e.g., a QGraphicsPixmapItem.
void update()
Schedules a redraw of the effect.
void setEnabled(bool enable)
void enabledChanged(bool enabled)
This signal is emitted whenever the effect is enabled or disabled.
PixmapPadMode
This enum describes how the pixmap returned from sourcePixmap should be padded.
QGraphicsEffectSource * source() const
virtual void sourceChanged(ChangeFlags flags)
This virtual function is called by QGraphicsEffect to notify the effect that the source has changed.
bool isEnabled() const
virtual QRectF boundingRectFor(const QRectF &sourceRect) const
Returns the effective bounding rectangle for this effect, given the provided rect in the device coord...
QGraphicsEffect(QObject *parent=nullptr)
Constructs a new QGraphicsEffect instance having the specified parent.
QRectF sourceBoundingRect(Qt::CoordinateSystem system=Qt::LogicalCoordinates) const
Returns the bounding rectangle of the source mapped to the given system.
The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene.
The QGraphicsOpacityEffect class provides an opacity effect.
qreal opacity
the opacity of the effect.
void opacityMaskChanged(const QBrush &mask)
This signal is emitted whenever the effect's opacity mask changes.
void setOpacityMask(const QBrush &mask)
QBrush opacityMask
the opacity mask of the effect.
void setOpacity(qreal opacity)
QGraphicsOpacityEffect(QObject *parent=nullptr)
Constructs a new QGraphicsOpacityEffect instance.
void draw(QPainter *painter) override
\reimp
~QGraphicsOpacityEffect()
Destroys the effect.
void opacityChanged(qreal opacity)
This signal is emitted whenever the effect's opacity changes.
The QGraphicsPixmapItem class provides a pixmap item that you can add to a QGraphicsScene.
QPointF offset() const
Returns the pixmap item's offset, which defines the point of the top-left corner of the pixmap,...
\inmodule QtCore
Definition qobject.h:103
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
RenderHints renderHints() const
Returns a flag that specifies the rendering hints that are set for this painter.
void restore()
Restores the current painter state (pops a saved state off the stack).
const QTransform & worldTransform() const
Returns the world transformation matrix.
void setOpacity(qreal opacity)
void save()
Saves the current painter state (pushes the state onto a stack).
void setWorldTransform(const QTransform &matrix, bool combine=false)
Sets the world transformation matrix.
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Draws the rectangular portion source of the given pixmap into the given target in the paint device.
@ CompositionMode_DestinationIn
Definition qpainter.h:104
static bool find(const QString &key, QPixmap *pixmap)
Looks for a cached pixmap associated with the given key in the cache.
static void remove(const QString &key)
Removes the pixmap associated with key from the cache.
static bool insert(const QString &key, const QPixmap &pixmap)
Inserts a copy of the pixmap pixmap associated with the key into the cache.
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
bool isNull() const
Returns true if this is a null pixmap; otherwise returns false.
Definition qpixmap.cpp:456
\inmodule QtCore\reentrant
Definition qpoint.h:217
constexpr QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
Definition qpoint.h:404
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:484
The QStyleOption class stores the parameters used by QStyle functions.
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
static QTransform fromTranslate(qreal dx, qreal dy)
Creates a matrix which corresponds to a translation of dx along the x axis and dy along the y axis.
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void colorChanged()
rect
[4]
Combined button and popup list for selecting options.
@ NoBrush
CoordinateSystem
@ DeviceCoordinates
@ LogicalCoordinates
#define Q_UNLIKELY(x)
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:333
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:349
#define qWarning
Definition qlogging.h:166
constexpr const T & qBound(const T &min, const T &val, const T &max)
Definition qminmax.h:44
GLenum mode
GLuint color
[2]
GLbitfield flags
GLboolean enable
GLenum GLuint GLintptr offset
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
#define emit
#define Q_UNUSED(x)
double qreal
Definition qtypes.h:187
QGraphicsItem * item
widget render & pixmap
QPainter painter(this)
[7]
QHostInfo info
[0]