1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtWidgets module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QGRAPHICSEFFECT_P_H
41 #define QGRAPHICSEFFECT_P_H
42 
43 //
44 //  W A R N I N G
45 //  -------------
46 //
47 // This file is not part of the Qt API.  It exists for the convenience
48 // of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp.  This header
49 // file may change from version to version without notice, or even be removed.
50 //
51 // We mean it.
52 //
53 
54 #include <QtWidgets/private/qtwidgetsglobal_p.h>
55 #include "qgraphicseffect.h"
56 
57 #include <QPixmapCache>
58 
59 #include <private/qobject_p.h>
60 #include <private/qpixmapfilter_p.h>
61 
62 QT_REQUIRE_CONFIG(graphicseffect);
63 
64 QT_BEGIN_NAMESPACE
65 
66 class QGraphicsEffectSourcePrivate;
67 class Q_WIDGETS_EXPORT QGraphicsEffectSource : public QObject
68 {
69     Q_OBJECT
70 public:
71     ~QGraphicsEffectSource();
72     const QGraphicsItem *graphicsItem() const;
73     const QWidget *widget() const;
74     const QStyleOption *styleOption() const;
75 
76     bool isPixmap() const;
77     void draw(QPainter *painter);
78     void update();
79 
80     QRectF boundingRect(Qt::CoordinateSystem coordinateSystem = Qt::LogicalCoordinates) const;
81     QRect deviceRect() const;
82     QPixmap pixmap(Qt::CoordinateSystem system = Qt::LogicalCoordinates,
83                    QPoint *offset = nullptr,
84                    QGraphicsEffect::PixmapPadMode mode = QGraphicsEffect::PadToEffectiveBoundingRect) const;
85 
86 protected:
87     QGraphicsEffectSource(QGraphicsEffectSourcePrivate &dd, QObject *parent = nullptr);
88 
89 private:
90     Q_DECLARE_PRIVATE(QGraphicsEffectSource)
91     Q_DISABLE_COPY_MOVE(QGraphicsEffectSource)
92     friend class QGraphicsEffect;
93     friend class QGraphicsEffectPrivate;
94     friend class QGraphicsScenePrivate;
95     friend class QGraphicsItem;
96     friend class QGraphicsItemPrivate;
97     friend class QWidget;
98     friend class QWidgetPrivate;
99 };
100 
101 class QGraphicsEffectSourcePrivate : public QObjectPrivate
102 {
Q_DECLARE_PUBLIC(QGraphicsEffectSource)103     Q_DECLARE_PUBLIC(QGraphicsEffectSource)
104 public:
105     QGraphicsEffectSourcePrivate()
106         : QObjectPrivate()
107         , m_cachedSystem(Qt::DeviceCoordinates)
108         , m_cachedMode(QGraphicsEffect::PadToTransparentBorder)
109     {}
110 
111     enum InvalidateReason
112     {
113         TransformChanged,
114         EffectRectChanged,
115         SourceChanged
116     };
117 
118     virtual ~QGraphicsEffectSourcePrivate();
119     virtual void detach() = 0;
120     virtual QRectF boundingRect(Qt::CoordinateSystem system) const = 0;
121     virtual QRect deviceRect() const = 0;
122     virtual const QGraphicsItem *graphicsItem() const = 0;
123     virtual const QWidget *widget() const = 0;
124     virtual const QStyleOption *styleOption() const = 0;
125     virtual void draw(QPainter *p) = 0;
126     virtual void update() = 0;
127     virtual bool isPixmap() const = 0;
128     virtual QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset = nullptr,
129                            QGraphicsEffect::PixmapPadMode mode = QGraphicsEffect::PadToTransparentBorder) const = 0;
130     virtual void effectBoundingRectChanged() = 0;
131 
132     void setCachedOffset(const QPoint &offset);
133     void invalidateCache(InvalidateReason reason = SourceChanged) const;
currentCachedSystem()134     Qt::CoordinateSystem currentCachedSystem() const { return m_cachedSystem; }
currentCachedMode()135     QGraphicsEffect::PixmapPadMode currentCachedMode() const { return m_cachedMode; }
136 
137     friend class QGraphicsScenePrivate;
138     friend class QGraphicsItem;
139     friend class QGraphicsItemPrivate;
140 
141 private:
142     mutable Qt::CoordinateSystem m_cachedSystem;
143     mutable QGraphicsEffect::PixmapPadMode m_cachedMode;
144     mutable QPoint m_cachedOffset;
145     mutable QPixmapCache::Key m_cacheKey;
146 };
147 
148 class Q_WIDGETS_EXPORT QGraphicsEffectPrivate : public QObjectPrivate
149 {
Q_DECLARE_PUBLIC(QGraphicsEffect)150     Q_DECLARE_PUBLIC(QGraphicsEffect)
151 public:
152     QGraphicsEffectPrivate() : source(nullptr), isEnabled(1) {}
153     ~QGraphicsEffectPrivate();
154 
setGraphicsEffectSource(QGraphicsEffectSource * newSource)155     inline void setGraphicsEffectSource(QGraphicsEffectSource *newSource)
156     {
157         QGraphicsEffect::ChangeFlags flags;
158         if (source) {
159             flags |= QGraphicsEffect::SourceDetached;
160             source->d_func()->invalidateCache();
161             source->d_func()->detach();
162             delete source;
163         }
164         source = newSource;
165         if (newSource)
166             flags |= QGraphicsEffect::SourceAttached;
167         q_func()->sourceChanged(flags);
168     }
169 
170     QGraphicsEffectSource *source;
171     QRectF boundingRect;
172     quint32 isEnabled : 1;
173     quint32 padding : 31; // feel free to use
174 };
175 
176 
177 class QGraphicsColorizeEffectPrivate : public QGraphicsEffectPrivate
178 {
Q_DECLARE_PUBLIC(QGraphicsColorizeEffect)179     Q_DECLARE_PUBLIC(QGraphicsColorizeEffect)
180 public:
181     QGraphicsColorizeEffectPrivate()
182         : opaque(true)
183     {
184         filter = new QPixmapColorizeFilter;
185     }
~QGraphicsColorizeEffectPrivate()186     ~QGraphicsColorizeEffectPrivate() { delete filter; }
187 
188     QPixmapColorizeFilter *filter;
189     quint32 opaque : 1;
190     quint32 padding : 31;
191 };
192 
193 class QGraphicsBlurEffectPrivate : public QGraphicsEffectPrivate
194 {
Q_DECLARE_PUBLIC(QGraphicsBlurEffect)195     Q_DECLARE_PUBLIC(QGraphicsBlurEffect)
196 public:
197     QGraphicsBlurEffectPrivate() : filter(new QPixmapBlurFilter) {}
~QGraphicsBlurEffectPrivate()198     ~QGraphicsBlurEffectPrivate() { delete filter; }
199 
200     QPixmapBlurFilter *filter;
201 };
202 
203 class QGraphicsDropShadowEffectPrivate : public QGraphicsEffectPrivate
204 {
Q_DECLARE_PUBLIC(QGraphicsDropShadowEffect)205     Q_DECLARE_PUBLIC(QGraphicsDropShadowEffect)
206 public:
207     QGraphicsDropShadowEffectPrivate() : filter(new QPixmapDropShadowFilter) {}
~QGraphicsDropShadowEffectPrivate()208     ~QGraphicsDropShadowEffectPrivate() { delete filter; }
209 
210     QPixmapDropShadowFilter *filter;
211 };
212 
213 class QGraphicsOpacityEffectPrivate : public QGraphicsEffectPrivate
214 {
Q_DECLARE_PUBLIC(QGraphicsOpacityEffect)215     Q_DECLARE_PUBLIC(QGraphicsOpacityEffect)
216 public:
217     QGraphicsOpacityEffectPrivate()
218         : opacity(qreal(0.7)), isFullyTransparent(0), isFullyOpaque(0), hasOpacityMask(0) {}
~QGraphicsOpacityEffectPrivate()219     ~QGraphicsOpacityEffectPrivate() {}
220 
221     qreal opacity;
222     QBrush opacityMask;
223     uint isFullyTransparent : 1;
224     uint isFullyOpaque : 1;
225     uint hasOpacityMask : 1;
226 };
227 
228 QT_END_NAMESPACE
229 
230 #endif // QGRAPHICSEFFECT_P_H
231