remove unused graphics effects feature

doubles as performance optimzation

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2022-11-22 00:42:26 +02:00
parent edfe07176e
commit 427396074d
30 changed files with 59 additions and 4504 deletions

View file

@ -549,14 +549,10 @@ katie_generate_obsolete(QGradient QtGui qbrush.h)
katie_generate_obsolete(QGradientStop QtGui qbrush.h)
katie_generate_obsolete(QGradientStops QtGui qbrush.h)
katie_generate_obsolete(QGraphicsAnchor QtGui qgraphicsanchorlayout.h)
katie_generate_obsolete(QGraphicsBlurEffect QtGui qgraphicseffect.h)
katie_generate_obsolete(QGraphicsColorizeEffect QtGui qgraphicseffect.h)
katie_generate_obsolete(QGraphicsDropShadowEffect QtGui qgraphicseffect.h)
katie_generate_obsolete(QGraphicsEllipseItem QtGui qgraphicsitem.h)
katie_generate_obsolete(QGraphicsItemGroup QtGui qgraphicsitem.h)
katie_generate_obsolete(QGraphicsLineItem QtGui qgraphicsitem.h)
katie_generate_obsolete(QGraphicsObject QtGui qgraphicsitem.h)
katie_generate_obsolete(QGraphicsOpacityEffect QtGui qgraphicseffect.h)
katie_generate_obsolete(QGraphicsPathItem QtGui qgraphicsitem.h)
katie_generate_obsolete(QGraphicsPixmapItem QtGui qgraphicsitem.h)
katie_generate_obsolete(QGraphicsPolygonItem QtGui qgraphicsitem.h)

View file

@ -3,7 +3,7 @@
# https://wiki.archlinux.org/index.php/Arch_package_guidelines
pkgname=katie-git
pkgver=4.12.0.r7809.51bb04664
pkgver=4.12.0.r7833.a324f5a0a
pkgrel=1
pkgdesc='C++ toolkit derived from the Qt 4.8 framework'
arch=('i486' 'i686' 'pentium4' 'x86_64' 'arm')

View file

@ -418,10 +418,6 @@ include/katie/QtGui/QGradientStop
include/katie/QtGui/QGradientStops
include/katie/QtGui/QGraphicsAnchor
include/katie/QtGui/QGraphicsAnchorLayout
include/katie/QtGui/QGraphicsBlurEffect
include/katie/QtGui/QGraphicsColorizeEffect
include/katie/QtGui/QGraphicsDropShadowEffect
include/katie/QtGui/QGraphicsEffect
include/katie/QtGui/QGraphicsEllipseItem
include/katie/QtGui/QGraphicsGridLayout
include/katie/QtGui/QGraphicsItem
@ -432,7 +428,6 @@ include/katie/QtGui/QGraphicsLayoutItem
include/katie/QtGui/QGraphicsLineItem
include/katie/QtGui/QGraphicsLinearLayout
include/katie/QtGui/QGraphicsObject
include/katie/QtGui/QGraphicsOpacityEffect
include/katie/QtGui/QGraphicsPathItem
include/katie/QtGui/QGraphicsPixmapItem
include/katie/QtGui/QGraphicsPolygonItem
@ -757,7 +752,6 @@ include/katie/QtGui/qformlayout.h
include/katie/QtGui/qframe.h
include/katie/QtGui/qgenericmatrix.h
include/katie/QtGui/qgraphicsanchorlayout.h
include/katie/QtGui/qgraphicseffect.h
include/katie/QtGui/qgraphicsgridlayout.h
include/katie/QtGui/qgraphicsitem.h
include/katie/QtGui/qgraphicsitemanimation.h

View file

@ -129,14 +129,10 @@ incmap = {
'QGradientStop': 'qbrush.h',
'QGradientStops': 'qbrush.h',
'QGraphicsAnchor': 'qgraphicsanchorlayout.h',
'QGraphicsBlurEffect': 'qgraphicseffect.h',
'QGraphicsColorizeEffect': 'qgraphicseffect.h',
'QGraphicsDropShadowEffect': 'qgraphicseffect.h',
'QGraphicsEllipseItem': 'qgraphicsitem.h',
'QGraphicsItemGroup': 'qgraphicsitem.h',
'QGraphicsLineItem': 'qgraphicsitem.h',
'QGraphicsObject': 'qgraphicsitem.h',
'QGraphicsOpacityEffect': 'qgraphicseffect.h',
'QGraphicsPathItem': 'qgraphicsitem.h',
'QGraphicsPixmapItem': 'qgraphicsitem.h',
'QGraphicsPolygonItem': 'qgraphicsitem.h',

View file

@ -183,10 +183,6 @@ classlist = [
"QGradientStops",
"QGraphicsAnchor",
"QGraphicsAnchorLayout",
"QGraphicsBlurEffect",
"QGraphicsColorizeEffect",
"QGraphicsDropShadowEffect",
"QGraphicsEffect",
"QGraphicsEllipseItem",
"QGraphicsGridLayout",
"QGraphicsItem",
@ -197,7 +193,6 @@ classlist = [
"QGraphicsLineItem",
"QGraphicsLinearLayout",
"QGraphicsObject",
"QGraphicsOpacityEffect",
"QGraphicsPathItem",
"QGraphicsPixmapItem",
"QGraphicsPolygonItem",

View file

@ -174,7 +174,6 @@
#cmakedefine QT_NO_FORMLAYOUT
#cmakedefine QT_NO_FRAME
#cmakedefine QT_NO_FSCOMPLETER
#cmakedefine QT_NO_GRAPHICSEFFECT
#cmakedefine QT_NO_IDENTITYPROXYMODEL
#cmakedefine QT_NO_IMAGEFORMAT_KAT
#cmakedefine QT_NO_IMAGEFORMAT_PPM
@ -350,11 +349,6 @@
# define QT_NO_COLORDIALOG
#endif
// QGraphicsEffect
#if !defined(QT_NO_GRAPHICSEFFECT) && defined(QT_NO_GRAPHICSVIEW)
# define QT_NO_GRAPHICSEFFECT
#endif
// The Model/View Framework
#if !defined(QT_NO_ITEMVIEWS) && (defined(QT_NO_RUBBERBAND) || defined(QT_NO_SCROLLAREA))
# define QT_NO_ITEMVIEWS

View file

@ -23,7 +23,6 @@
#include <QtGui/qaction.h>
#include <QtGui/qvalidator.h>
#include <QtGui/qgraphicseffect.h>
#include "qdeclarativeevents_p_p.h"
#include "qdeclarativescalegrid_p_p.h"
@ -147,9 +146,6 @@ void QDeclarativeItemModule::defineModule()
#endif
qmlRegisterType<QDeclarativePen>();
qmlRegisterType<QDeclarativeFlickableVisibleArea>();
#ifndef QT_NO_GRAPHICSEFFECT
qmlRegisterType<QGraphicsEffect>();
#endif
qmlRegisterUncreatableType<QDeclarativeKeyNavigationAttached>("QtQuick",1,0,"KeyNavigation",QDeclarativeKeyNavigationAttached::tr("KeyNavigation is only available via attached properties"));
qmlRegisterUncreatableType<QDeclarativeKeysAttached>("QtQuick",1,0,"Keys",QDeclarativeKeysAttached::tr("Keys is only available via attached properties"));

View file

@ -66,7 +66,6 @@ set(GUI_PUBLIC_HEADERS
QFrame
QGenericMatrix
QGraphicsAnchorLayout
QGraphicsEffect
QGraphicsGridLayout
QGraphicsItem
QGraphicsItemAnimation
@ -251,8 +250,6 @@ set(GUI_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/dialogs/qfileinfogatherer_p.h
${CMAKE_CURRENT_SOURCE_DIR}/dialogs/qwizard.h
${CMAKE_CURRENT_SOURCE_DIR}/dialogs/qprintpreviewdialog.h
${CMAKE_CURRENT_SOURCE_DIR}/effects/qgraphicseffect.h
${CMAKE_CURRENT_SOURCE_DIR}/effects/qgraphicseffect_p.h
${CMAKE_CURRENT_SOURCE_DIR}/graphicsview/qgraphicsgridlayout.h
${CMAKE_CURRENT_SOURCE_DIR}/graphicsview/qgraphicsitem.h
${CMAKE_CURRENT_SOURCE_DIR}/graphicsview/qgraphicsitem_p.h
@ -297,7 +294,6 @@ set(GUI_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/image/qpixmap.h
${CMAKE_CURRENT_SOURCE_DIR}/image/qpixmapcache.h
${CMAKE_CURRENT_SOURCE_DIR}/image/qpixmapdata_p.h
${CMAKE_CURRENT_SOURCE_DIR}/image/qpixmapfilter_p.h
${CMAKE_CURRENT_SOURCE_DIR}/image/qppmhandler_p.h
${CMAKE_CURRENT_SOURCE_DIR}/image/qxpmhandler_p.h
${CMAKE_CURRENT_SOURCE_DIR}/image/qpnghandler_p.h
@ -610,7 +606,6 @@ set(GUI_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/dialogs/qprintsettingsoutput.ui
${CMAKE_CURRENT_SOURCE_DIR}/dialogs/qprintwidget.ui
${CMAKE_CURRENT_SOURCE_DIR}/dialogs/qprintpropertieswidget.ui
${CMAKE_CURRENT_SOURCE_DIR}/effects/qgraphicseffect.cpp
${CMAKE_CURRENT_SOURCE_DIR}/graphicsview/qgraphicsgridlayout.cpp
${CMAKE_CURRENT_SOURCE_DIR}/graphicsview/qgraphicsitem.cpp
${CMAKE_CURRENT_SOURCE_DIR}/graphicsview/qgraphicsitemanimation.cpp
@ -643,7 +638,6 @@ set(GUI_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/image/qpixmap.cpp
${CMAKE_CURRENT_SOURCE_DIR}/image/qpixmapcache.cpp
${CMAKE_CURRENT_SOURCE_DIR}/image/qpixmapdata.cpp
${CMAKE_CURRENT_SOURCE_DIR}/image/qpixmapfilter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/image/qiconengine.cpp
${CMAKE_CURRENT_SOURCE_DIR}/image/qiconengineplugin.cpp
${CMAKE_CURRENT_SOURCE_DIR}/image/qmovie.cpp
@ -931,7 +925,6 @@ katie_unity_exclude(
${CMAKE_CURRENT_SOURCE_DIR}/graphicsview/qgraphicsscene.cpp
${CMAKE_CURRENT_SOURCE_DIR}/graphicsview/qgraphicsview.cpp
${CMAKE_CURRENT_SOURCE_DIR}/image/qpixmap.cpp
${CMAKE_CURRENT_SOURCE_DIR}/image/qpixmapfilter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/itemviews/qitemeditorfactory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/kernel/qapplication.cpp
${CMAKE_CURRENT_SOURCE_DIR}/kernel/qapplication_x11.cpp

File diff suppressed because it is too large Load diff

View file

@ -1,266 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtGui module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QGRAPHICSEFFECT_H
#define QGRAPHICSEFFECT_H
#include <QtCore/qobject.h>
#include <QtCore/qpoint.h>
#include <QtCore/qrect.h>
#include <QtGui/qcolor.h>
#include <QtGui/qbrush.h>
#ifndef QT_NO_GRAPHICSEFFECT
QT_BEGIN_NAMESPACE
class QGraphicsItem;
class QStyleOption;
class QPainter;
class QPixmap;
class QGraphicsEffectSource;
class QGraphicsEffectPrivate;
class Q_GUI_EXPORT QGraphicsEffect : public QObject
{
Q_OBJECT
Q_FLAGS(ChangeFlags)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
public:
enum ChangeFlag {
SourceAttached = 0x1,
SourceDetached = 0x2,
SourceBoundingRectChanged = 0x4,
SourceInvalidated = 0x8
};
Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag)
enum PixmapPadMode {
NoPad,
PadToTransparentBorder,
PadToEffectiveBoundingRect
};
QGraphicsEffect(QObject *parent = nullptr);
virtual ~QGraphicsEffect();
virtual QRectF boundingRectFor(const QRectF &sourceRect) const;
QRectF boundingRect() const;
bool isEnabled() const;
public Q_SLOTS:
void setEnabled(bool enable);
void update();
Q_SIGNALS:
void enabledChanged(bool enabled);
protected:
QGraphicsEffect(QGraphicsEffectPrivate &d, QObject *parent = nullptr);
virtual void draw(QPainter *painter) = 0;
virtual void sourceChanged(ChangeFlags flags);
void updateBoundingRect();
bool sourceIsPixmap() const;
QRectF sourceBoundingRect(Qt::CoordinateSystem system = Qt::LogicalCoordinates) const;
void drawSource(QPainter *painter);
QPixmap sourcePixmap(Qt::CoordinateSystem system = Qt::LogicalCoordinates,
QPoint *offset = nullptr,
PixmapPadMode mode = PadToEffectiveBoundingRect) const;
private:
Q_DECLARE_PRIVATE(QGraphicsEffect)
Q_DISABLE_COPY(QGraphicsEffect)
friend class QGraphicsItem;
friend class QGraphicsItemPrivate;
friend class QGraphicsScenePrivate;
friend class QWidget;
friend class QWidgetPrivate;
public:
QGraphicsEffectSource *source() const; // internal
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsEffect::ChangeFlags)
class QGraphicsColorizeEffectPrivate;
class Q_GUI_EXPORT QGraphicsColorizeEffect: public QGraphicsEffect
{
Q_OBJECT
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged)
public:
QGraphicsColorizeEffect(QObject *parent = nullptr);
~QGraphicsColorizeEffect();
QColor color() const;
qreal strength() const;
public Q_SLOTS:
void setColor(const QColor &c);
void setStrength(qreal strength);
Q_SIGNALS:
void colorChanged(const QColor &color);
void strengthChanged(qreal strength);
protected:
void draw(QPainter *painter);
private:
Q_DECLARE_PRIVATE(QGraphicsColorizeEffect)
Q_DISABLE_COPY(QGraphicsColorizeEffect)
};
class QGraphicsBlurEffectPrivate;
class Q_GUI_EXPORT QGraphicsBlurEffect: public QGraphicsEffect
{
Q_OBJECT
Q_FLAGS(BlurHint BlurHints)
Q_PROPERTY(qreal blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged)
Q_PROPERTY(BlurHints blurHints READ blurHints WRITE setBlurHints NOTIFY blurHintsChanged)
public:
enum BlurHint {
PerformanceHint = 0x00,
QualityHint = 0x01,
AnimationHint = 0x02
};
Q_DECLARE_FLAGS(BlurHints, BlurHint)
QGraphicsBlurEffect(QObject *parent = nullptr);
~QGraphicsBlurEffect();
QRectF boundingRectFor(const QRectF &rect) const;
qreal blurRadius() const;
BlurHints blurHints() const;
public Q_SLOTS:
void setBlurRadius(qreal blurRadius);
void setBlurHints(BlurHints hints);
Q_SIGNALS:
void blurRadiusChanged(qreal blurRadius);
void blurHintsChanged(BlurHints hints);
protected:
void draw(QPainter *painter);
private:
Q_DECLARE_PRIVATE(QGraphicsBlurEffect)
Q_DISABLE_COPY(QGraphicsBlurEffect)
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsBlurEffect::BlurHints)
class QGraphicsDropShadowEffectPrivate;
class Q_GUI_EXPORT QGraphicsDropShadowEffect: public QGraphicsEffect
{
Q_OBJECT
Q_PROPERTY(QPointF offset READ offset WRITE setOffset NOTIFY offsetChanged)
Q_PROPERTY(qreal xOffset READ xOffset WRITE setXOffset NOTIFY offsetChanged)
Q_PROPERTY(qreal yOffset READ yOffset WRITE setYOffset NOTIFY offsetChanged)
Q_PROPERTY(qreal blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
public:
QGraphicsDropShadowEffect(QObject *parent = nullptr);
~QGraphicsDropShadowEffect();
QRectF boundingRectFor(const QRectF &rect) const;
QPointF offset() const;
inline qreal xOffset() const
{ return offset().x(); }
inline qreal yOffset() const
{ return offset().y(); }
qreal blurRadius() const;
QColor color() const;
public Q_SLOTS:
void setOffset(const QPointF &ofs);
inline void setOffset(qreal dx, qreal dy)
{ setOffset(QPointF(dx, dy)); }
inline void setOffset(qreal d)
{ setOffset(QPointF(d, d)); }
inline void setXOffset(qreal dx)
{ setOffset(QPointF(dx, yOffset())); }
inline void setYOffset(qreal dy)
{ setOffset(QPointF(xOffset(), dy)); }
void setBlurRadius(qreal blurRadius);
void setColor(const QColor &color);
Q_SIGNALS:
void offsetChanged(const QPointF &offset);
void blurRadiusChanged(qreal blurRadius);
void colorChanged(const QColor &color);
protected:
void draw(QPainter *painter);
private:
Q_DECLARE_PRIVATE(QGraphicsDropShadowEffect)
Q_DISABLE_COPY(QGraphicsDropShadowEffect)
};
class QGraphicsOpacityEffectPrivate;
class Q_GUI_EXPORT QGraphicsOpacityEffect: public QGraphicsEffect
{
Q_OBJECT
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged)
Q_PROPERTY(QBrush opacityMask READ opacityMask WRITE setOpacityMask NOTIFY opacityMaskChanged)
public:
QGraphicsOpacityEffect(QObject *parent = nullptr);
~QGraphicsOpacityEffect();
qreal opacity() const;
QBrush opacityMask() const;
public Q_SLOTS:
void setOpacity(qreal opacity);
void setOpacityMask(const QBrush &mask);
Q_SIGNALS:
void opacityChanged(qreal opacity);
void opacityMaskChanged(const QBrush &mask);
protected:
void draw(QPainter *painter);
private:
Q_DECLARE_PRIVATE(QGraphicsOpacityEffect)
Q_DISABLE_COPY(QGraphicsOpacityEffect)
};
QT_END_NAMESPACE
#endif //QT_NO_GRAPHICSEFFECT
#endif // QGRAPHICSEFFECT_H

View file

@ -1,224 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtGui module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QGRAPHICSEFFECT_P_H
#define QGRAPHICSEFFECT_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Katie API. It exists for the convenience
// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
// file may change from version to version without notice, or even be removed.
//
// We mean it.
//
#include "qgraphicseffect.h"
#include <QPixmapCache>
#include "qobject_p.h"
#include "qpixmapfilter_p.h"
#ifndef QT_NO_GRAPHICSEFFECT
QT_BEGIN_NAMESPACE
class QGraphicsEffectSourcePrivate;
class Q_AUTOTEST_EXPORT QGraphicsEffectSource : public QObject
{
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();
QRectF boundingRect(Qt::CoordinateSystem coordinateSystem = Qt::LogicalCoordinates) const;
QRect deviceRect() const;
QPixmap pixmap(Qt::CoordinateSystem system = Qt::LogicalCoordinates,
QPoint *offset = 0,
QGraphicsEffect::PixmapPadMode mode = QGraphicsEffect::PadToEffectiveBoundingRect) const;
protected:
QGraphicsEffectSource(QGraphicsEffectSourcePrivate &dd, QObject *parent = nullptr);
private:
Q_DECLARE_PRIVATE(QGraphicsEffectSource)
Q_DISABLE_COPY(QGraphicsEffectSource)
friend class QGraphicsEffect;
friend class QGraphicsEffectPrivate;
friend class QGraphicsScenePrivate;
friend class QGraphicsItem;
friend class QGraphicsItemPrivate;
friend class QWidget;
friend class QWidgetPrivate;
};
class QGraphicsEffectSourcePrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QGraphicsEffectSource)
public:
QGraphicsEffectSourcePrivate()
: QObjectPrivate(),
m_cachedSystem(Qt::DeviceCoordinates),
m_cachedMode(QGraphicsEffect::PadToTransparentBorder)
{
}
enum InvalidateReason {
TransformChanged,
EffectRectChanged,
SourceChanged
};
virtual ~QGraphicsEffectSourcePrivate();
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;
void setCachedOffset(const QPoint &offset);
void invalidateCache(InvalidateReason reason = SourceChanged) const;
Qt::CoordinateSystem currentCachedSystem() const { return m_cachedSystem; }
QGraphicsEffect::PixmapPadMode currentCachedMode() const { return m_cachedMode; }
friend class QGraphicsScenePrivate;
friend class QGraphicsItem;
friend class QGraphicsItemPrivate;
private:
mutable Qt::CoordinateSystem m_cachedSystem;
mutable QGraphicsEffect::PixmapPadMode m_cachedMode;
mutable QPoint m_cachedOffset;
mutable QPixmapCache::Key m_cacheKey;
};
class QGraphicsEffectPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QGraphicsEffect)
public:
QGraphicsEffectPrivate()
: source(nullptr),
isEnabled(true)
{
}
inline void setGraphicsEffectSource(QGraphicsEffectSource *newSource)
{
QGraphicsEffect::ChangeFlags flags;
if (source) {
flags |= QGraphicsEffect::SourceDetached;
source->d_func()->invalidateCache();
source->d_func()->detach();
delete source;
}
source = newSource;
if (newSource)
flags |= QGraphicsEffect::SourceAttached;
q_func()->sourceChanged(flags);
}
QGraphicsEffectSource *source;
QRectF boundingRect;
bool isEnabled;
};
class QGraphicsColorizeEffectPrivate : public QGraphicsEffectPrivate
{
Q_DECLARE_PUBLIC(QGraphicsColorizeEffect)
public:
QGraphicsColorizeEffectPrivate()
: filter(new QPixmapColorizeFilter()),
opaque(true)
{
}
~QGraphicsColorizeEffectPrivate() { delete filter; }
QPixmapColorizeFilter *filter;
bool opaque;
};
class QGraphicsBlurEffectPrivate : public QGraphicsEffectPrivate
{
Q_DECLARE_PUBLIC(QGraphicsBlurEffect)
public:
QGraphicsBlurEffectPrivate()
: filter(new QPixmapBlurFilter())
{
}
~QGraphicsBlurEffectPrivate() { delete filter; }
QPixmapBlurFilter *filter;
};
class QGraphicsDropShadowEffectPrivate : public QGraphicsEffectPrivate
{
Q_DECLARE_PUBLIC(QGraphicsDropShadowEffect)
public:
QGraphicsDropShadowEffectPrivate()
: filter(new QPixmapDropShadowFilter())
{
}
~QGraphicsDropShadowEffectPrivate() { delete filter; }
QPixmapDropShadowFilter *filter;
};
class QGraphicsOpacityEffectPrivate : public QGraphicsEffectPrivate
{
Q_DECLARE_PUBLIC(QGraphicsOpacityEffect)
public:
QGraphicsOpacityEffectPrivate()
: opacity(qreal(0.7)),
isFullyTransparent(false),
isFullyOpaque(false),
hasOpacityMask(false)
{
}
~QGraphicsOpacityEffectPrivate() {}
qreal opacity;
QBrush opacityMask;
bool isFullyTransparent;
bool isFullyOpaque;
bool hasOpacityMask;
};
QT_END_NAMESPACE
#endif //QT_NO_GRAPHICSEFFECT
#endif // QGRAPHICSEFFECT_P_H

View file

@ -708,7 +708,6 @@
#include <QtGui/qpixmapcache.h>
#include <QtGui/qstyleoption.h>
#include <QtGui/qevent.h>
#include <QtGui/qgraphicseffect.h>
#include "qgraphicsitem_p.h"
#include "qgraphicswidget_p.h"
#include "qtextcontrol_p.h"
@ -1094,10 +1093,6 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const Q
p = p->d_ptr->parent;
}
// Update graphics effect optimization flag
if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect))
newParent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
// Update focus scope item ptr in new scope.
QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
if (newFocusScopeItem && newParent) {
@ -1235,14 +1230,14 @@ void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rec
QTransform matrix = childd->transformToParent();
if (x)
matrix *= *x;
*rect |= matrix.mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
*rect |= matrix.mapRect(child->boundingRect());
if (!childd->children.isEmpty())
childd->childrenBoundingRectHelper(&matrix, rect, topMostEffectItem);
} else {
if (x)
*rect |= x->mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
*rect |= x->mapRect(child->boundingRect());
else
*rect |= child->d_ptr->effectiveBoundingRect(topMostEffectItem);
*rect |= child->boundingRect();
if (!childd->children.isEmpty())
childd->childrenBoundingRectHelper(x, rect, topMostEffectItem);
}
@ -1417,9 +1412,6 @@ QGraphicsItem::~QGraphicsItem()
setParentItem(0);
}
#ifndef QT_NO_GRAPHICSEFFECT
delete d_ptr->graphicsEffect;
#endif //QT_NO_GRAPHICSEFFECT
if (d_ptr->transformData) {
for(int i = 0; i < d_ptr->transformData->graphicsTransforms.size(); ++i) {
QGraphicsTransform *t = d_ptr->transformData->graphicsTransforms.at(i);
@ -2172,9 +2164,6 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
if (c)
c->purge();
if (scene) {
#ifndef QT_NO_GRAPHICSEFFECT
invalidateParentGraphicsEffectsRecursively();
#endif //QT_NO_GRAPHICSEFFECT
scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true);
}
}
@ -2610,11 +2599,6 @@ void QGraphicsItem::setOpacity(qreal opacity)
// Update.
if (d_ptr->scene) {
#ifndef QT_NO_GRAPHICSEFFECT
d_ptr->invalidateParentGraphicsEffectsRecursively();
if (!(d_ptr->flags & ItemDoesntPropagateOpacityToChildren))
d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged);
#endif //QT_NO_GRAPHICSEFFECT
d_ptr->scene->d_func()->markDirty(this, QRectF(),
/*invalidateChildren=*/true,
/*force=*/false,
@ -2627,138 +2611,6 @@ void QGraphicsItem::setOpacity(qreal opacity)
emit static_cast<QGraphicsObject *>(this)->opacityChanged();
}
/*!
Returns a pointer to this item's effect if it has one; otherwise 0.
\since 4.6
*/
#ifndef QT_NO_GRAPHICSEFFECT
QGraphicsEffect *QGraphicsItem::graphicsEffect() const
{
return d_ptr->graphicsEffect;
}
/*!
Sets \a effect as the item's effect. If there already is an effect installed
on this item, QGraphicsItem will delete the existing effect before installing
the new \a effect.
If \a effect is the installed on a different item, setGraphicsEffect() will remove
the effect from the item and install it on this item.
QGraphicsItem takes ownership of \a effect.
\note This function will apply the effect on itself and all its children.
\since 4.6
*/
void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
{
if (d_ptr->graphicsEffect == effect)
return;
if (d_ptr->graphicsEffect) {
delete d_ptr->graphicsEffect;
d_ptr->graphicsEffect = 0;
} else if (d_ptr->parent) {
d_ptr->parent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
}
if (effect) {
// Set new effect.
QGraphicsEffectSourcePrivate *sourced = new QGraphicsItemEffectSourcePrivate(this);
QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
d_ptr->graphicsEffect = effect;
effect->d_func()->setGraphicsEffectSource(source);
prepareGeometryChange();
}
}
#endif //QT_NO_GRAPHICSEFFECT
void QGraphicsItemPrivate::updateChildWithGraphicsEffectFlagRecursively()
{
#ifndef QT_NO_GRAPHICSEFFECT
QGraphicsItemPrivate *itemPrivate = this;
do {
// parent chain already notified?
if (itemPrivate->mayHaveChildWithGraphicsEffect)
return;
itemPrivate->mayHaveChildWithGraphicsEffect = true;
} while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
#endif
}
/*!
\internal
\since 4.6
Returns the effective bounding rect of the given item space rect.
If the item has no effect, the rect is returned unmodified.
If the item has an effect, the effective rect can be extend beyond the
item's bounding rect, depending on the effect.
\sa boundingRect()
*/
QRectF QGraphicsItemPrivate::effectiveBoundingRect(const QRectF &rect) const
{
#ifndef QT_NO_GRAPHICSEFFECT
Q_Q(const QGraphicsItem);
QGraphicsEffect *effect = graphicsEffect;
if (scene && effect && effect->isEnabled()) {
if (scene->d_func()->views.isEmpty())
return effect->boundingRectFor(rect);
QRectF sceneRect = q->mapRectToScene(rect);
QRectF sceneEffectRect;
foreach (QGraphicsView *view, scene->views()) {
QRectF deviceRect = view->d_func()->mapRectFromScene(sceneRect);
QRect deviceEffectRect = effect->boundingRectFor(deviceRect).toAlignedRect();
sceneEffectRect |= view->d_func()->mapRectToScene(deviceEffectRect);
}
return q->mapRectFromScene(sceneEffectRect);
}
#endif //QT_NO_GRAPHICSEFFECT
return rect;
}
/*!
\internal
\since 4.6
Returns the effective bounding rect of the item.
If the item has no effect, this is the same as the item's bounding rect.
If the item has an effect, the effective rect can be larger than the item's
bouding rect, depending on the effect.
\sa boundingRect()
*/
QRectF QGraphicsItemPrivate::effectiveBoundingRect(QGraphicsItem *topMostEffectItem) const
{
#ifndef QT_NO_GRAPHICSEFFECT
Q_Q(const QGraphicsItem);
QRectF brect = effectiveBoundingRect(q_ptr->boundingRect());
if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren || topMostEffectItem == q)
return brect;
const QGraphicsItem *effectParent = parent;
while (effectParent) {
QGraphicsEffect *effect = effectParent->d_ptr->graphicsEffect;
if (scene && effect && effect->isEnabled()) {
const QRectF brectInParentSpace = q->mapRectToItem(effectParent, brect);
const QRectF effectRectInParentSpace = effectParent->d_ptr->effectiveBoundingRect(brectInParentSpace);
brect = effectParent->mapRectToItem(q, effectRectInParentSpace);
}
if (effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
|| topMostEffectItem == effectParent) {
return brect;
}
effectParent = effectParent->d_ptr->parent;
}
return brect;
#else //QT_NO_GRAPHICSEFFECT
return q_ptr->boundingRect();
#endif //QT_NO_GRAPHICSEFFECT
}
/*!
\internal
\since 4.6
@ -2784,7 +2636,7 @@ QRectF QGraphicsItemPrivate::sceneEffectiveBoundingRect() const
offset += itemd->pos;
} while ((parentItem = itemd->parent));
QRectF br = effectiveBoundingRect();
QRectF br = q_ptr->boundingRect();
br.translate(offset);
return !parentItem ? br : parentItem->sceneTransform().mapRect(br);
}
@ -5197,40 +5049,6 @@ int QGraphicsItemPrivate::depth() const
return itemDepth;
}
/*!
\internal
*/
#ifndef QT_NO_GRAPHICSEFFECT
void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively()
{
QGraphicsItemPrivate *itemPrivate = this;
do {
if (itemPrivate->graphicsEffect && !itemPrivate->updateDueToGraphicsEffect) {
itemPrivate->notifyInvalidated = true;
static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
}
} while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
}
void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason)
{
if (!mayHaveChildWithGraphicsEffect)
return;
for (int i = 0; i < children.size(); ++i) {
QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data();
if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity))
continue;
if (childPrivate->graphicsEffect) {
childPrivate->notifyInvalidated = true;
static_cast<QGraphicsItemEffectSourcePrivate *>(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
}
childPrivate->invalidateChildGraphicsEffectsRecursively(reason);
}
}
#endif //QT_NO_GRAPHICSEFFECT
/*!
\internal
*/
@ -5488,32 +5306,21 @@ void QGraphicsItem::update(const QRectF &rect)
if (rect.isEmpty() && !rect.isNull())
return;
// Make sure we notify effects about invalidated source.
#ifndef QT_NO_GRAPHICSEFFECT
d_ptr->invalidateParentGraphicsEffectsRecursively();
#endif //QT_NO_GRAPHICSEFFECT
#ifndef QT_NO_GRAPHICSEFFECT
if (!d_ptr->updateDueToGraphicsEffect) {
#endif
if (d_ptr->cacheMode != NoCache) {
// Invalidate cache.
QGraphicsItemCache *cache = d_ptr->extraItemCache();
if (!cache->allExposed) {
if (rect.isNull()) {
cache->allExposed = true;
cache->exposed.clear();
} else {
cache->exposed.append(rect);
}
if (d_ptr->cacheMode != NoCache) {
// Invalidate cache.
QGraphicsItemCache *cache = d_ptr->extraItemCache();
if (!cache->allExposed) {
if (rect.isNull()) {
cache->allExposed = true;
cache->exposed.clear();
} else {
cache->exposed.append(rect);
}
// Only invalidate cache; item is already dirty.
if (d_ptr->fullUpdatePending)
return;
}
#ifndef QT_NO_GRAPHICSEFFECT
// Only invalidate cache; item is already dirty.
if (d_ptr->fullUpdatePending)
return;
}
#endif
if (d_ptr->scene)
d_ptr->scene->d_func()->markDirty(this, rect);
@ -10328,149 +10135,6 @@ int QGraphicsItemGroup::type() const
return Type;
}
#ifndef QT_NO_GRAPHICSEFFECT
QRectF QGraphicsItemEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
{
const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
if (!info && deviceCoordinates) {
// Device coordinates without info not yet supported.
qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
return QRectF();
}
QRectF rect = item->boundingRect();
if (!item->d_ptr->children.isEmpty())
rect |= item->childrenBoundingRect();
if (deviceCoordinates) {
Q_ASSERT(info->painter);
rect = info->painter->worldTransform().mapRect(rect);
}
return rect;
}
void QGraphicsItemEffectSourcePrivate::draw(QPainter *painter)
{
if (!info) {
qWarning("QGraphicsEffectSource::draw: Can only begin as a result of QGraphicsEffect::draw");
return;
}
Q_ASSERT(item->d_ptr->scene);
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, info->effectTransform, info->wasDirtySceneTransform,
info->drawItem);
} else {
QTransform effectTransform = info->painter->worldTransform().inverted();
effectTransform *= painter->worldTransform();
scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
info->drawItem);
}
}
// sourceRect must be in the given coordinate system
QRect QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const
{
QRectF effectRectF;
if (unpadded)
*unpadded = false;
if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) {
if (info) {
QRectF deviceRect = system == Qt::DeviceCoordinates ? sourceRect : info->painter->worldTransform().mapRect(sourceRect);
effectRectF = item->graphicsEffect()->boundingRectFor(deviceRect);
if (unpadded)
*unpadded = (effectRectF.size() == sourceRect.size());
if (info && system == Qt::LogicalCoordinates)
effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF);
} else {
// no choice but to send a logical coordinate bounding rect to boundingRectFor
effectRectF = item->graphicsEffect()->boundingRectFor(sourceRect);
}
} else if (mode == QGraphicsEffect::PadToTransparentBorder) {
// adjust by 1.5 to account for cosmetic pens
effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5);
} else {
effectRectF = sourceRect;
if (unpadded)
*unpadded = true;
}
return effectRectF.toAlignedRect();
}
QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
QGraphicsEffect::PixmapPadMode mode) const
{
const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
if (!info && deviceCoordinates) {
// Device coordinates without info not yet supported.
qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
return QPixmap();
}
if (!item->d_ptr->scene)
return QPixmap();
QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
bool unpadded;
const QRectF sourceRect = boundingRect(system);
QRect effectRect = paddedEffectRect(system, mode, sourceRect, &unpadded);
if (offset)
*offset = effectRect.topLeft();
bool untransformed = !deviceCoordinates
|| info->painter->worldTransform().type() <= QTransform::TxTranslate;
if (untransformed && unpadded && isPixmap()) {
if (offset)
*offset = boundingRect(system).topLeft().toPoint();
return static_cast<QGraphicsPixmapItem *>(item)->pixmap();
}
if (effectRect.isEmpty())
return QPixmap();
QPixmap pixmap(effectRect.size());
pixmap.fill(Qt::transparent);
QPainter pixmapPainter(&pixmap);
pixmapPainter.setRenderHints(info ? info->painter->renderHints() : QPainter::TextAntialiasing);
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 newEffectTransform = sceneTransform.inverted();
newEffectTransform *= effectTransform;
scened->draw(item, &pixmapPainter, 0, &sceneTransform, 0, 0, qreal(1.0),
&newEffectTransform, false, true);
} else if (deviceCoordinates) {
// Device coordinates with info.
scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0,
info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
info->drawItem);
} else {
// Item coordinates with info.
QTransform newEffectTransform = info->transformPtr->inverted();
newEffectTransform *= effectTransform;
scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0,
info->widget, info->opacity, &newEffectTransform, info->wasDirtySceneTransform,
info->drawItem);
}
pixmapPainter.end();
return pixmap;
}
#endif //QT_NO_GRAPHICSEFFECT
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, QGraphicsItem *item)
{

View file

@ -40,7 +40,6 @@ QT_BEGIN_NAMESPACE
class QBrush;
class QCursor;
class QFocusEvent;
class QGraphicsEffect;
class QGraphicsItemGroup;
class QGraphicsObject;
class QGraphicsSceneContextMenuEvent;
@ -205,12 +204,6 @@ public:
qreal effectiveOpacity() const;
void setOpacity(qreal opacity);
#ifndef QT_NO_GRAPHICSEFFECT
// Effect
QGraphicsEffect *graphicsEffect() const;
void setGraphicsEffect(QGraphicsEffect *effect);
#endif //QT_NO_GRAPHICSEFFECT
Qt::MouseButtons acceptedMouseButtons() const;
void setAcceptedMouseButtons(Qt::MouseButtons buttons);
@ -510,9 +503,6 @@ class Q_GUI_EXPORT QGraphicsObject : public QObject, public QGraphicsItem
Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged)
Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged)
Q_PROPERTY(QPointF transformOriginPoint READ transformOriginPoint WRITE setTransformOriginPoint)
#ifndef QT_NO_GRAPHICSEFFECT
Q_PROPERTY(QGraphicsEffect *effect READ graphicsEffect WRITE setGraphicsEffect)
#endif
Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), QDeclarativeListProperty<QGraphicsObject> children READ childrenList DESIGNABLE false NOTIFY childrenChanged)
Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), qreal width READ width WRITE setWidth NOTIFY widthChanged RESET resetWidth FINAL)
Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), qreal height READ height WRITE setHeight NOTIFY heightChanged RESET resetHeight FINAL)

View file

@ -39,11 +39,7 @@
#include "qgraphicsview_p.h"
#include "qgraphicstransform.h"
#include "qgraphicstransform_p.h"
#include "qgraphicseffect_p.h"
#include "qgraphicseffect.h"
#include <QtCore/qpoint.h>
#include "qpoint.h"
#ifndef QT_NO_GRAPHICSVIEW
@ -157,7 +153,6 @@ public:
scene(0),
parent(0),
transformData(0),
graphicsEffect(0),
index(-1),
siblingIndex(-1),
itemDepth(-1),
@ -202,10 +197,8 @@ public:
wantsActive(false),
holesInSiblingIndex(false),
sequentialOrdering(true),
updateDueToGraphicsEffect(false),
scenePosDescendants(false),
pendingPolish(false),
mayHaveChildWithGraphicsEffect(false),
isDeclarativeItem(false),
sendParentChangeNotification(false),
cacheMode(QGraphicsItem::NoCache),
@ -229,7 +222,6 @@ public:
return item->d_ptr.data();
}
void updateChildWithGraphicsEffectFlagRecursively();
void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag,
AncestorFlag flag = NoFlag, bool enabled = false, bool root = true);
void updateAncestorFlags();
@ -258,13 +250,6 @@ public:
bool ignoreDirtyBit = false, bool ignoreOpacity = false) const;
virtual void transformChanged() {}
int depth() const;
#ifndef QT_NO_GRAPHICSEFFECT
enum InvalidateReason {
OpacityChanged
};
void invalidateParentGraphicsEffectsRecursively();
void invalidateChildGraphicsEffectsRecursively(InvalidateReason reason);
#endif //QT_NO_GRAPHICSEFFECT
void invalidateDepthRecursively();
void resolveDepth();
void addChild(QGraphicsItem *child);
@ -275,11 +260,8 @@ public:
void childrenBoundingRectHelper(QTransform *x, QRectF *rect, QGraphicsItem *topMostEffectItem);
void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
const QRegion &exposedRegion, bool allItems = false) const;
QRectF effectiveBoundingRect(QGraphicsItem *topMostEffectItem = 0) const;
QRectF sceneEffectiveBoundingRect() const;
QRectF effectiveBoundingRect(const QRectF &rect) const;
virtual void resolveFont(uint inheritedMask)
{
for (int i = 0; i < children.size(); ++i)
@ -481,7 +463,6 @@ public:
QList<QGraphicsItem *> children;
struct TransformData;
TransformData *transformData;
QGraphicsEffect *graphicsEffect;
QTransform sceneTransform;
int index;
int siblingIndex;
@ -529,10 +510,8 @@ public:
bool wantsActive;
bool holesInSiblingIndex;
bool sequentialOrdering;
bool updateDueToGraphicsEffect;
bool scenePosDescendants;
bool pendingPolish;
bool mayHaveChildWithGraphicsEffect;
bool isDeclarativeItem ;
bool sendParentChangeNotification;
@ -613,68 +592,6 @@ struct QGraphicsItemPaintInfo
bool drawItem;
};
#ifndef QT_NO_GRAPHICSEFFECT
class QGraphicsItemEffectSourcePrivate : public QGraphicsEffectSourcePrivate
{
public:
QGraphicsItemEffectSourcePrivate(QGraphicsItem *i)
: QGraphicsEffectSourcePrivate(), item(i), info(0)
{}
inline void detach()
{
item->d_ptr->graphicsEffect = 0;
item->prepareGeometryChange();
}
inline const QGraphicsItem *graphicsItem() const
{ return item; }
inline const QWidget *widget() const
{ return nullptr; }
inline void update() {
item->d_ptr->updateDueToGraphicsEffect = true;
item->update();
item->d_ptr->updateDueToGraphicsEffect = false;
}
inline void effectBoundingRectChanged()
{ item->prepareGeometryChange(); }
inline bool isPixmap() const
{
return item->type() == QGraphicsPixmapItem::Type
&& !(item->flags() & QGraphicsItem::ItemIsSelectable)
&& item->d_ptr->children.size() == 0;
//|| (item->d_ptr->isObject && qobject_cast<QDeclarativeImage *>(q_func()));
}
inline const QStyleOption *styleOption() const
{ return info ? info->option : 0; }
inline QRect deviceRect() const
{
if (!info || !info->widget) {
qWarning("QGraphicsEffectSource::deviceRect: Not yet implemented, lacking device context");
return QRect();
}
return info->widget->rect();
}
QRectF boundingRect(Qt::CoordinateSystem system) const;
void draw(QPainter *);
QPixmap pixmap(Qt::CoordinateSystem system,
QPoint *offset,
QGraphicsEffect::PixmapPadMode mode) const;
QRect paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded = 0) const;
QGraphicsItem *item;
QGraphicsItemPaintInfo *info;
QTransform lastEffectTransform;
};
#endif //QT_NO_GRAPHICSEFFECT
/*!
Returns true if \a item1 is on top of \a item2.
The items don't need to be siblings.
@ -807,13 +724,6 @@ inline bool QGraphicsItemPrivate::insertionOrder(QGraphicsItem *a, QGraphicsItem
inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect)
{
QGraphicsItemPrivate *parentp = this;
#ifndef QT_NO_GRAPHICSEFFECT
if (updateBoundingRect && parentp->graphicsEffect && !parentp->inSetPosHelper) {
parentp->notifyInvalidated = true;
static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()
->source->d_func())->invalidateCache();
}
#endif
while (parentp->parent) {
parentp = parentp->parent->d_ptr.data();
parentp->dirtyChildren = 1;
@ -823,19 +733,6 @@ inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect)
// ### Only do this if the parent's effect applies to the entire subtree.
parentp->notifyBoundingRectChanged = true;
}
#ifndef QT_NO_GRAPHICSEFFECT
if (parentp->graphicsEffect) {
if (updateBoundingRect) {
static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()
->source->d_func())->invalidateCache();
parentp->notifyInvalidated = true;
}
if (parentp->scene && parentp->graphicsEffect->isEnabled()) {
parentp->dirty = true;
parentp->fullUpdatePending = true;
}
}
#endif
}
}

View file

@ -222,14 +222,12 @@
#include <QtGui/qstyleoption.h>
#include <QtGui/qtooltip.h>
#include <QtGui/qtransform.h>
#include <QtGui/qgraphicseffect.h>
#include "qapplication_p.h"
#include "qobject_p.h"
#ifdef Q_WS_X11
#include "qt_x11_p.h"
#endif
#include "qgraphicseffect_p.h"
#include "qpathclipper_p.h"
// #define GESTURE_DEBUG
@ -4564,7 +4562,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
bool drawItem = itemHasContents && !itemIsFullyTransparent;
if (drawItem) {
const QRectF brect = adjustedItemEffectiveBoundingRect(item);
const QRectF brect = adjustedItemBoundingRect(item);
ENSURE_TRANSFORM_PTR
QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toAlignedRect()
: transformPtr->mapRect(brect).toAlignedRect();
@ -4587,48 +4585,8 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
if (itemHasChildren && itemClipsChildrenToShape)
ENSURE_TRANSFORM_PTR;
#ifndef QT_NO_GRAPHICSEFFECT
if (item->d_ptr->graphicsEffect && item->d_ptr->graphicsEffect->isEnabled()) {
ENSURE_TRANSFORM_PTR;
QGraphicsItemPaintInfo info(viewTransform, transformPtr, effectTransform, exposedRegion, widget, &styleOptionTmp,
painter, opacity, wasDirtyParentSceneTransform, itemHasContents && !itemIsFullyTransparent);
QGraphicsEffectSource *source = item->d_ptr->graphicsEffect->d_func()->source;
QGraphicsItemEffectSourcePrivate *sourced = static_cast<QGraphicsItemEffectSourcePrivate *>
(source->d_func());
sourced->info = &info;
const QTransform restoreTransform = painter->worldTransform();
if (effectTransform)
painter->setWorldTransform(*transformPtr * *effectTransform);
else
painter->setWorldTransform(*transformPtr);
painter->setOpacity(opacity);
if (sourced->currentCachedSystem() != Qt::LogicalCoordinates
&& sourced->lastEffectTransform != painter->worldTransform())
{
if (sourced->lastEffectTransform.type() <= QTransform::TxTranslate
&& painter->worldTransform().type() <= QTransform::TxTranslate)
{
QRectF sourceRect = sourced->boundingRect(Qt::DeviceCoordinates);
QRect effectRect = sourced->paddedEffectRect(Qt::DeviceCoordinates, sourced->currentCachedMode(), sourceRect);
sourced->setCachedOffset(effectRect.topLeft());
} else {
sourced->invalidateCache(QGraphicsEffectSourcePrivate::TransformChanged);
}
sourced->lastEffectTransform = painter->worldTransform();
}
item->d_ptr->graphicsEffect->draw(painter);
painter->setWorldTransform(restoreTransform);
sourced->info = 0;
} else
#endif //QT_NO_GRAPHICSEFFECT
{
draw(item, painter, viewTransform, transformPtr, exposedRegion, widget, opacity,
effectTransform, wasDirtyParentSceneTransform, drawItem);
}
draw(item, painter, viewTransform, transformPtr, exposedRegion, widget, opacity,
effectTransform, wasDirtyParentSceneTransform, drawItem);
}
static inline void setClip(QPainter *painter, QGraphicsItem *item)
@ -4855,8 +4813,6 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b
item->d_ptr->fullUpdatePending = 1;
else if (!item->d_ptr->fullUpdatePending)
item->d_ptr->needsRepaint |= rect;
} else if (item->d_ptr->graphicsEffect) {
invalidateChildren = true;
}
if (invalidateChildren) {
@ -4935,8 +4891,6 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
resetDirtyItem(item);
return; // Item has neither contents nor children!(?)
}
if (item->d_ptr->graphicsEffect)
itemHasContents = true;
}
const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
@ -4977,7 +4931,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
// Process item.
if (item->d_ptr->dirty || item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
const bool useCompatUpdate = views.isEmpty() || isSignalConnected(changedSignalIndex);
const QRectF itemBoundingRect = adjustedItemEffectiveBoundingRect(item);
const QRectF itemBoundingRect = adjustedItemBoundingRect(item);
if (useCompatUpdate && !itemIsUntransformable && qFuzzyIsNull(item->boundingRegionGranularity())) {
// This block of code is kept for compatibility. Since 4.5, by default

View file

@ -278,7 +278,6 @@ private:
friend class QGraphicsViewPrivate;
friend class QGraphicsWidget;
friend class QGraphicsWidgetPrivate;
friend class QGraphicsEffect;
friend class QGraphicsSceneIndex;
friend class QGraphicsSceneIndexPrivate;
friend class QGraphicsSceneBspTreeIndex;

View file

@ -224,25 +224,10 @@ public:
item->d_ptr->fullUpdatePending = 0;
item->d_ptr->ignoreVisible = 0;
item->d_ptr->ignoreOpacity = 0;
#ifndef QT_NO_GRAPHICSEFFECT
QGraphicsEffect::ChangeFlags flags;
if (item->d_ptr->notifyBoundingRectChanged) {
flags |= QGraphicsEffect::SourceBoundingRectChanged;
item->d_ptr->notifyBoundingRectChanged = 0;
}
if (item->d_ptr->notifyInvalidated) {
flags |= QGraphicsEffect::SourceInvalidated;
item->d_ptr->notifyInvalidated = 0;
}
#endif //QT_NO_GRAPHICSEFFECT
if (recursive) {
for (int i = 0; i < item->d_ptr->children.size(); ++i)
resetDirtyItem(item->d_ptr->children.at(i), recursive);
}
#ifndef QT_NO_GRAPHICSEFFECT
if (flags && item->d_ptr->graphicsEffect)
item->d_ptr->graphicsEffect->sourceChanged(flags);
#endif //QT_NO_GRAPHICSEFFECT
}
inline void ensureSortedTopLevelItems()
@ -295,14 +280,6 @@ static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item)
return boundingRect;
}
static inline QRectF adjustedItemEffectiveBoundingRect(const QGraphicsItem *item)
{
Q_ASSERT(item);
QRectF boundingRect(QGraphicsItemPrivate::get(item)->effectiveBoundingRect());
_q_adjustRect(&boundingRect);
return boundingRect;
}
QT_END_NAMESPACE
#endif // QT_NO_GRAPHICSVIEW

View file

@ -3348,7 +3348,7 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
// (QGraphicsScene::drawItems) is not called. If it is, we'll do this
// operation twice, but that's the price one has to pay for using indirect
// painting :-/.
const QRectF brect = adjustedItemEffectiveBoundingRect(item);
const QRectF brect = adjustedItemBoundingRect(item);
if (!itemd->itemIsUntransformable()) {
transform = item->sceneTransform();
if (viewTransformed)

View file

@ -1,901 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtGui module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qpainter.h"
#include "qpixmap.h"
#include "qpixmapfilter_p.h"
#include "qapplication_p.h"
#include "qpaintengineex_p.h"
#include "qpaintengine_raster_p.h"
#include "qmath.h"
#include "qmemrotate_p.h"
#include "qdrawhelper_p.h"
#include "qdebug.h"
QT_BEGIN_NAMESPACE
// grayscales the image to dest (could be same). If rect isn't defined
// destination image size is used to determine the dimension of grayscaling
// process.
Q_GUI_EXPORT void qt_grayscale(const QImage &image, QImage &dest)
{
Q_ASSERT(image.depth() == 32 && dest.depth() == 32);
QRect srcRect = image.rect();
if (srcRect.isNull()) {
srcRect = dest.rect();
}
QRect destRect = srcRect;
if (&image != &dest) {
destRect.moveTo(QPoint(0, 0));
}
unsigned int *outData = (unsigned int *)dest.bits();
if (dest.size() == image.size() && image.rect() == srcRect) {
const unsigned int *data = (const unsigned int *)image.constBits();
// a bit faster loop for grayscaling everything
int pixels = dest.width() * dest.height();
for (int i = 0; i < pixels; ++i) {
int val = qGray(data[i]);
outData[i] = qRgba(val, val, val, qAlpha(data[i]));
}
} else {
int yd = destRect.top();
for (int y = srcRect.top(); y <= srcRect.bottom() && y < image.height(); y++) {
const unsigned int *data = (const unsigned int*)image.constScanLine(y);
outData = (unsigned int*)dest.scanLine(yd++);
int xd = destRect.left();
for (int x = srcRect.left(); x <= srcRect.right() && x < image.width(); x++) {
int val = qGray(data[x]);
outData[xd++] = qRgba(val, val, val, qAlpha(data[x]));
}
}
}
}
QT_END_NAMESPACE
#ifndef QT_NO_GRAPHICSEFFECT
QT_BEGIN_NAMESPACE
class QPixmapFilterPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QPixmapFilter)
public:
QPixmapFilter::FilterType type;
};
/*!
\class QPixmapFilter
\since 4.5
\ingroup painting
\brief The QPixmapFilter class provides the basic functionality for
pixmap filter classes. Pixmap filter can be for example colorize or blur.
QPixmapFilter is the base class for every pixmap filter. QPixmapFilter is
an abstract class and cannot itself be instantiated. It provides a standard
interface for filter processing.
\internal
*/
/*!
\enum QPixmapFilter::FilterType
\internal
This enum describes the types of filter that can be applied to pixmaps.
\value ColorizeFilter A filter that is used to change the overall color
of an image. See QPixmapColorizeFilter for more
information.
\value DropShadowFilter A filter that is used to add a drop shadow to an
image. See QPixmapDropShadowFilter for more
information.
\value BlurFilter A filter that is used to blur an image using
a simple blur radius. See QPixmapBlurFilter
for more information.
*/
/*!
Constructs a default QPixmapFilter with the given \a type.
This constructor should be used when subclassing QPixmapFilter to
create custom user filters.
\internal
*/
QPixmapFilter::QPixmapFilter(FilterType type, QObject *parent)
: QObject(*new QPixmapFilterPrivate, parent)
{
d_func()->type = type;
}
/*!
\internal
*/
QPixmapFilter::QPixmapFilter(QPixmapFilterPrivate&d, QPixmapFilter::FilterType type, QObject *parent)
: QObject(d, parent)
{
d_func()->type = type;
}
/*!
Destroys the pixmap filter.
\internal
*/
QPixmapFilter::~QPixmapFilter()
{
}
/*!
Returns the type of the filter. All standard pixmap filter classes
are associated with a unique value.
\internal
*/
QPixmapFilter::FilterType QPixmapFilter::type() const
{
Q_D(const QPixmapFilter);
return d->type;
}
/*!
Returns the bounding rectangle that is affected by the pixmap
filter if the filter is applied to the specified \a rect.
\internal
*/
QRectF QPixmapFilter::boundingRectFor(const QRectF &rect) const
{
return rect;
}
/*!
\fn void QPixmapFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF& srcRect) const
Uses \a painter to draw filtered result of \a src at the point
specified by \a p. If \a srcRect is specified the it will
be used as a source rectangle to only draw a part of the source.
draw() will affect the area which boundingRectFor() returns.
\internal
*/
/*!
\class QPixmapBlurFilter
\since 4.6
\ingroup multimedia
\brief The QPixmapBlurFilter class provides blur filtering
for pixmaps.
QPixmapBlurFilter implements a blur pixmap filter,
which is applied when \l{QPixmapFilter::}{draw()} is called.
The filter lets you specialize the radius of the blur as well
as hints as to whether to prefer performance or quality.
By default, the blur effect is produced by applying an exponential
filter generated from the specified blurRadius(). Paint engines
may override this with a custom blur that is faster on the
underlying hardware.
\sa {Pixmap Filters Example}, QPixmapDropShadowFilter
\internal
*/
class QPixmapBlurFilterPrivate : public QPixmapFilterPrivate
{
public:
QPixmapBlurFilterPrivate() : radius(5), hints(QGraphicsBlurEffect::PerformanceHint) {}
qreal radius;
QGraphicsBlurEffect::BlurHints hints;
};
/*!
Constructs a pixmap blur filter.
\internal
*/
QPixmapBlurFilter::QPixmapBlurFilter(QObject *parent)
: QPixmapFilter(*new QPixmapBlurFilterPrivate, BlurFilter, parent)
{
}
/*!
Destructor of pixmap blur filter.
\internal
*/
QPixmapBlurFilter::~QPixmapBlurFilter()
{
}
/*!
Sets the radius of the blur filter. Higher radius produces increased blurriness.
\internal
*/
void QPixmapBlurFilter::setRadius(qreal radius)
{
Q_D(QPixmapBlurFilter);
d->radius = radius;
}
/*!
Gets the radius of the blur filter.
\internal
*/
qreal QPixmapBlurFilter::radius() const
{
Q_D(const QPixmapBlurFilter);
return d->radius;
}
/*!
Setting the blur hints to PerformanceHint causes the implementation
to trade off visual quality to blur the image faster. Setting the
blur hints to QualityHint causes the implementation to improve
visual quality at the expense of speed.
AnimationHint causes the implementation to optimize for animating
the blur radius, possibly by caching blurred versions of the source
pixmap.
The implementation is free to ignore this value if it only has a single
blur algorithm.
\internal
*/
void QPixmapBlurFilter::setBlurHints(QGraphicsBlurEffect::BlurHints hints)
{
Q_D(QPixmapBlurFilter);
d->hints = hints;
}
/*!
Gets the blur hints of the blur filter.
\internal
*/
QGraphicsBlurEffect::BlurHints QPixmapBlurFilter::blurHints() const
{
Q_D(const QPixmapBlurFilter);
return d->hints;
}
const qreal radiusScale = qreal(2.5);
/*!
\internal
*/
QRectF QPixmapBlurFilter::boundingRectFor(const QRectF &rect) const
{
Q_D(const QPixmapBlurFilter);
const qreal delta = radiusScale * d->radius + 1;
return rect.adjusted(-delta, -delta, delta, delta);
}
static inline int qt_static_shift(int shift, int value)
{
if (shift == 0)
return value;
else if (shift > 0)
return value << (uint(shift) & 0x1f);
else
return value >> (uint(-shift) & 0x1f);
}
static const int aprec = 12;
static const int zprec = 10;
static inline void qt_blurinner(uchar *bptr, int &zR, int &zG, int &zB, int &zA, int alpha)
{
QRgb *pixel = (QRgb *)bptr;
#define Z_MASK (0xff << zprec)
const int A_zprec = qt_static_shift(zprec - 24, *pixel) & Z_MASK;
const int R_zprec = qt_static_shift(zprec - 16, *pixel) & Z_MASK;
const int G_zprec = qt_static_shift(zprec - 8, *pixel) & Z_MASK;
const int B_zprec = qt_static_shift(zprec, *pixel) & Z_MASK;
#undef Z_MASK
const int zR_zprec = zR >> aprec;
const int zG_zprec = zG >> aprec;
const int zB_zprec = zB >> aprec;
const int zA_zprec = zA >> aprec;
zR += alpha * (R_zprec - zR_zprec);
zG += alpha * (G_zprec - zG_zprec);
zB += alpha * (B_zprec - zB_zprec);
zA += alpha * (A_zprec - zA_zprec);
#define ZA_MASK (0xff << (zprec + aprec))
*pixel =
qt_static_shift(24 - zprec - aprec, zA & ZA_MASK)
| qt_static_shift(16 - zprec - aprec, zR & ZA_MASK)
| qt_static_shift(8 - zprec - aprec, zG & ZA_MASK)
| qt_static_shift(-zprec - aprec, zB & ZA_MASK);
#undef ZA_MASK
}
static inline void qt_blurinner_alphaOnly(uchar *bptr, int &z, int alpha)
{
const int A_zprec = int(*(bptr)) << zprec;
const int z_zprec = z >> aprec;
z += alpha * (A_zprec - z_zprec);
*(bptr) = z >> (zprec + aprec);
}
static inline void qt_blurrow(QImage & im, int line, int alpha, bool alphaOnly)
{
uchar *bptr = im.scanLine(line);
int zR = 0, zG = 0, zB = 0, zA = 0;
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
if (alphaOnly)
bptr += 3;
#endif
const int stride = im.depth() >> 3;
const int im_width = im.width();
for (int index = 0; index < im_width; ++index) {
if (alphaOnly)
qt_blurinner_alphaOnly(bptr, zA, alpha);
else
qt_blurinner(bptr, zR, zG, zB, zA, alpha);
bptr += stride;
}
bptr -= stride;
for (int index = im_width - 2; index >= 0; --index) {
bptr -= stride;
if (alphaOnly)
qt_blurinner_alphaOnly(bptr, zA, alpha);
else
qt_blurinner(bptr, zR, zG, zB, zA, alpha);
}
}
/*
* expblur(QImage &img, int radius)
*
* Based on exponential blur algorithm by Jani Huhtanen
*
* In-place blur of image 'img' with kernel
* of approximate radius 'radius'.
*
* Blurs with two sided exponential impulse
* response.
*
* aprec = precision of alpha parameter
* in fixed-point format 0.aprec
*
* zprec = precision of state parameters
* zR,zG,zB and zA in fp format 8.zprec
*/
static void expblur(QImage &img, qreal radius, bool improvedQuality, bool alphaOnly)
{
// halve the radius if we're using two passes
if (improvedQuality)
radius *= qreal(0.5);
Q_ASSERT(img.format() == QImage::Format_ARGB32_Premultiplied
|| img.format() == QImage::Format_RGB32);
// choose the alpha such that pixels at radius distance from a fully
// saturated pixel will have an alpha component of no greater than
// the cutOffIntensity
const qreal cutOffIntensity = 2;
int alpha = radius <= qreal(1e-5)
? ((1 << aprec)-1)
: qRound((1<<aprec)*(1 - qPow(cutOffIntensity * (1 / qreal(255)), 1 / radius)));
int img_height = img.height();
for (int row = 0; row < img_height; ++row) {
for (int i = 0; i <= int(improvedQuality); ++i)
qt_blurrow(img, row, alpha, alphaOnly);
}
QImage temp(img.height(), img.width(), img.format());
qt_memrotate270(reinterpret_cast<const quint32*>(img.constBits()),
img.width(), img.height(), img.bytesPerLine(),
reinterpret_cast<quint32*>(temp.bits()),
temp.bytesPerLine());
img_height = temp.height();
for (int row = 0; row < img_height; ++row) {
for (int i = 0; i <= int(improvedQuality); ++i)
qt_blurrow(temp, row, alpha, alphaOnly);
}
qt_memrotate90(reinterpret_cast<const quint32*>(temp.constBits()),
temp.width(), temp.height(), temp.bytesPerLine(),
reinterpret_cast<quint32*>(img.bits()),
img.bytesPerLine());
}
#define AVG(a,b) ( ((((a)^(b)) & 0xfefefefeUL) >> 1) + ((a)&(b)) )
static QImage qt_halfScaled(const QImage &source)
{
Q_ASSERT(source.format() == QImage::Format_ARGB32_Premultiplied
|| source.format() == QImage::Format_RGB32);
if (source.width() < 2 || source.height() < 2)
return QImage();
QImage dest(source.width() / 2, source.height() / 2, source.format());
const quint32 *src = reinterpret_cast<const quint32*>(source.constBits());
int sx = source.bytesPerLine() >> 2;
int sx2 = sx << 1;
quint32 *dst = reinterpret_cast<quint32*>(dest.bits());
int dx = dest.bytesPerLine() >> 2;
int ww = dest.width();
int hh = dest.height();
for (int y = hh; y; --y, dst += dx, src += sx2) {
const quint32 *p1 = src;
const quint32 *p2 = src + sx;
quint32 *q = dst;
for (int x = ww; x; --x, q++, p1 += 2, p2 += 2)
*q = AVG(AVG(p1[0], p1[1]), AVG(p2[0], p2[1]));
}
return dest;
}
static void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly)
{
if (blurImage.format() != QImage::Format_ARGB32_Premultiplied
&& blurImage.format() != QImage::Format_RGB32)
{
blurImage = blurImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
}
qreal scale = 1;
if (radius >= 4 && blurImage.width() >= 2 && blurImage.height() >= 2) {
blurImage = qt_halfScaled(blurImage);
scale = 2;
radius *= qreal(0.5);
}
expblur(blurImage, radius, quality, alphaOnly);
Q_ASSERT(p);
p->scale(scale, scale);
p->drawImage(QRect(0, 0, blurImage.width(), blurImage.height()), blurImage);
}
Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
/*!
\internal
*/
void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF &rect) const
{
Q_D(const QPixmapBlurFilter);
if (!painter->isActive())
return;
if (src.isNull())
return;
QRectF srcRect = rect;
if (srcRect.isNull())
srcRect = src.rect();
if (d->radius <= 1) {
painter->drawPixmap(srcRect.translated(p), src, srcRect);
return;
}
qreal scaledRadius = radiusScale * d->radius;
qreal scale;
if (qt_scaleForTransform(painter->transform(), &scale))
scaledRadius /= scale;
QImage srcImage;
if (srcRect == src.rect()) {
srcImage = src.toImage();
} else {
QRect rect = srcRect.toAlignedRect().intersected(src.rect());
srcImage = src.copy(rect).toImage();
}
QTransform transform = painter->worldTransform();
painter->translate(p);
qt_blurImage(painter, srcImage, scaledRadius, (d->hints & QGraphicsBlurEffect::QualityHint), false);
painter->setWorldTransform(transform);
}
/*!
\class QPixmapColorizeFilter
\since 4.5
\ingroup painting
\brief The QPixmapColorizeFilter class provides colorizing
filtering for pixmaps.
A colorize filter gives the pixmap a tint of its color(). The
filter first grayscales the pixmap and then converts those to
colorized values using QPainter::CompositionMode_Screen with the
chosen color. The alpha-channel is not changed.
Example:
\snippet doc/src/snippets/code/src_gui_image_qpixmapfilter.cpp 0
\sa QPainter::CompositionMode
\internal
*/
class QPixmapColorizeFilterPrivate : public QPixmapFilterPrivate
{
Q_DECLARE_PUBLIC(QPixmapColorizeFilter)
public:
QPixmapColorizeFilterPrivate()
: color(0, 0, 192), strength(1), opaque(true), alphaBlend(false) {}
QColor color;
qreal strength;
bool opaque;
bool alphaBlend;
};
/*!
Constructs an pixmap colorize filter.
Default color value for colorizing is QColor(0, 0, 192).
\internal
*/
QPixmapColorizeFilter::QPixmapColorizeFilter(QObject *parent)
: QPixmapFilter(*new QPixmapColorizeFilterPrivate, ColorizeFilter, parent)
{
}
/*!
Gets the color of the colorize filter.
\internal
*/
QColor QPixmapColorizeFilter::color() const
{
Q_D(const QPixmapColorizeFilter);
return d->color;
}
/*!
Sets the color of the colorize filter to the \a color specified.
\internal
*/
void QPixmapColorizeFilter::setColor(const QColor &color)
{
Q_D(QPixmapColorizeFilter);
d->color = color;
}
/*!
Gets the strength of the colorize filter, 1.0 means full colorized while
0.0 equals to no filtering at all.
\internal
*/
qreal QPixmapColorizeFilter::strength() const
{
Q_D(const QPixmapColorizeFilter);
return d->strength;
}
/*!
Sets the strength of the colorize filter to \a strength.
\internal
*/
void QPixmapColorizeFilter::setStrength(qreal strength)
{
Q_D(QPixmapColorizeFilter);
d->strength = qBound(qreal(0), strength, qreal(1));
d->opaque = !qFuzzyIsNull(d->strength);
d->alphaBlend = !qFuzzyIsNull(d->strength - 1);
}
/*!
\internal
*/
void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
{
Q_D(const QPixmapColorizeFilter);
if (src.isNull())
return;
// raster implementation
if (!d->opaque) {
painter->drawPixmap(dest, src, srcRect);
return;
}
QImage srcImage;
QImage destImage;
if (srcRect.isNull()) {
srcImage = src.toImage();
srcImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ? QImage::Format_ARGB32_Premultiplied : QImage::systemFormat());
destImage = QImage(srcImage.size(), srcImage.format());
} else {
QRect rect = srcRect.toAlignedRect().intersected(src.rect());
srcImage = src.copy(rect).toImage();
srcImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ? QImage::Format_ARGB32_Premultiplied : QImage::systemFormat());
destImage = QImage(rect.size(), srcImage.format());
}
// do colorizing
QPainter destPainter(&destImage);
qt_grayscale(srcImage, destImage);
destPainter.setCompositionMode(QPainter::CompositionMode_Screen);
destPainter.fillRect(srcImage.rect(), d->color);
destPainter.end();
if (d->alphaBlend) {
// alpha blending srcImage and destImage
QImage buffer = srcImage;
QPainter bufPainter(&buffer);
bufPainter.setOpacity(d->strength);
bufPainter.drawImage(0, 0, destImage);
bufPainter.end();
destImage = buffer;
}
if (srcImage.hasAlphaChannel())
destImage.setAlphaChannel(srcImage.alphaChannel());
painter->drawImage(dest, destImage);
}
class QPixmapDropShadowFilterPrivate : public QPixmapFilterPrivate
{
public:
QPixmapDropShadowFilterPrivate()
: offset(8, 8), color(63, 63, 63, 180), radius(1) {}
QPointF offset;
QColor color;
qreal radius;
};
/*!
\class QPixmapDropShadowFilter
\since 4.5
\ingroup painting
\brief The QPixmapDropShadowFilter class is a convenience class
for drawing pixmaps with drop shadows.
The drop shadow is produced by taking a copy of the source pixmap
and applying a color to the copy using a
QPainter::CompositionMode_DestinationIn operation. The original
pixmap is drawn on top.
The QPixmapDropShadowFilter class provides some customization
options to specify how the drop shadow should appear. The color of
the drop shadow can be modified using the setColor() function, the
drop shadow offset can be modified using the setOffset() function,
and the blur radius of the drop shadow can be changed through the
setBlurRadius() function.
By default, the drop shadow is a dark gray shadow, blurred with a
radius of 1 at an offset of 8 pixels towards the lower right.
Example:
\snippet doc/src/snippets/code/src_gui_image_qpixmapfilter.cpp 2
\sa QPixmapColorizeFilter
\internal
*/
/*!
Constructs drop shadow filter.
\internal
*/
QPixmapDropShadowFilter::QPixmapDropShadowFilter(QObject *parent)
: QPixmapFilter(*new QPixmapDropShadowFilterPrivate, DropShadowFilter, parent)
{
}
/*!
Destroys drop shadow filter.
\internal
*/
QPixmapDropShadowFilter::~QPixmapDropShadowFilter()
{
}
/*!
Returns the radius in pixels of the blur on the drop shadow.
A smaller radius results in a sharper shadow.
\sa color(), offset()
\internal
*/
qreal QPixmapDropShadowFilter::blurRadius() const
{
Q_D(const QPixmapDropShadowFilter);
return d->radius;
}
/*!
Sets the radius in pixels of the blur on the drop shadow to the \a radius specified.
Using a smaller radius results in a sharper shadow.
\sa setColor(), setOffset()
\internal
*/
void QPixmapDropShadowFilter::setBlurRadius(qreal radius)
{
Q_D(QPixmapDropShadowFilter);
d->radius = radius;
}
/*!
Returns the color of the drop shadow.
\sa blurRadius(), offset()
\internal
*/
QColor QPixmapDropShadowFilter::color() const
{
Q_D(const QPixmapDropShadowFilter);
return d->color;
}
/*!
Sets the color of the drop shadow to the \a color specified.
\sa setBlurRadius(), setOffset()
\internal
*/
void QPixmapDropShadowFilter::setColor(const QColor &color)
{
Q_D(QPixmapDropShadowFilter);
d->color = color;
}
/*!
Returns the shadow offset in pixels.
\sa blurRadius(), color()
\internal
*/
QPointF QPixmapDropShadowFilter::offset() const
{
Q_D(const QPixmapDropShadowFilter);
return d->offset;
}
/*!
Sets the shadow offset in pixels to the \a offset specified.
\sa setBlurRadius(), setColor()
\internal
*/
void QPixmapDropShadowFilter::setOffset(const QPointF &offset)
{
Q_D(QPixmapDropShadowFilter);
d->offset = offset;
}
/*!
\fn void QPixmapDropShadowFilter::setOffset(qreal dx, qreal dy)
\overload
Sets the shadow offset in pixels to be the displacement specified by the
horizontal \a dx and vertical \a dy coordinates.
\sa setBlurRadius(), setColor()
\internal
*/
/*!
\internal
*/
QRectF QPixmapDropShadowFilter::boundingRectFor(const QRectF &rect) const
{
Q_D(const QPixmapDropShadowFilter);
return rect.united(rect.translated(d->offset).adjusted(-d->radius, -d->radius, d->radius, d->radius));
}
/*!
\internal
*/
void QPixmapDropShadowFilter::draw(QPainter *p,
const QPointF &pos,
const QPixmap &px,
const QRectF &src) const
{
Q_D(const QPixmapDropShadowFilter);
if (px.isNull())
return;
QImage tmp(px.size(), QImage::Format_ARGB32_Premultiplied);
tmp.fill(0);
QPainter tmpPainter(&tmp);
tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
tmpPainter.drawPixmap(d->offset, px);
tmpPainter.end();
// blur the alpha channel
QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied);
blurred.fill(0);
QPainter blurPainter(&blurred);
qt_blurImage(&blurPainter, tmp, d->radius, false, true);
blurPainter.end();
// blacken the image...
QPainter blackenPainter(&blurred);
blackenPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
blackenPainter.fillRect(blurred.rect(), d->color);
blackenPainter.end();
// draw the blurred drop shadow...
p->drawImage(pos, blurred);
// Draw the actual pixmap...
p->drawPixmap(pos, px, src);
}
QT_END_NAMESPACE
#include "moc_qpixmapfilter_p.h"
#endif // QT_NO_GRAPHICSEFFECT

View file

@ -1,141 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the QtGui module of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QPIXMAPFILTER_H
#define QPIXMAPFILTER_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Katie API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/qnamespace.h>
#include <QtGui/qpixmap.h>
#include <QtGui/qgraphicseffect.h>
#ifndef QT_NO_GRAPHICSEFFECT
QT_BEGIN_NAMESPACE
class QPainter;
class QPixmapFilterPrivate;
class Q_GUI_EXPORT QPixmapFilter : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(QPixmapFilter)
public:
virtual ~QPixmapFilter() = 0;
enum FilterType {
ColorizeFilter,
DropShadowFilter,
BlurFilter,
};
FilterType type() const;
virtual QRectF boundingRectFor(const QRectF &rect) const;
virtual void draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF &srcRect = QRectF()) const = 0;
protected:
QPixmapFilter(QPixmapFilterPrivate &d, FilterType type, QObject *parent);
QPixmapFilter(FilterType type, QObject *parent);
};
class QPixmapBlurFilterPrivate;
class Q_GUI_EXPORT QPixmapBlurFilter : public QPixmapFilter
{
Q_OBJECT
Q_DECLARE_PRIVATE(QPixmapBlurFilter)
public:
QPixmapBlurFilter(QObject *parent = nullptr);
~QPixmapBlurFilter();
void setRadius(qreal radius);
void setBlurHints(QGraphicsBlurEffect::BlurHints hints);
qreal radius() const;
QGraphicsBlurEffect::BlurHints blurHints() const;
QRectF boundingRectFor(const QRectF &rect) const;
void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const;
};
class QPixmapColorizeFilterPrivate;
class Q_GUI_EXPORT QPixmapColorizeFilter : public QPixmapFilter
{
Q_OBJECT
Q_DECLARE_PRIVATE(QPixmapColorizeFilter)
public:
QPixmapColorizeFilter(QObject *parent = nullptr);
void setColor(const QColor& color);
QColor color() const;
void setStrength(qreal strength);
qreal strength() const;
void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const;
};
class QPixmapDropShadowFilterPrivate;
class Q_GUI_EXPORT QPixmapDropShadowFilter : public QPixmapFilter
{
Q_OBJECT
Q_DECLARE_PRIVATE(QPixmapDropShadowFilter)
public:
QPixmapDropShadowFilter(QObject *parent = nullptr);
~QPixmapDropShadowFilter();
QRectF boundingRectFor(const QRectF &rect) const;
void draw(QPainter *p, const QPointF &pos, const QPixmap &px, const QRectF &src = QRectF()) const;
qreal blurRadius() const;
void setBlurRadius(qreal radius);
QColor color() const;
void setColor(const QColor &color);
QPointF offset() const;
void setOffset(const QPointF &offset);
inline void setOffset(qreal dx, qreal dy) { setOffset(QPointF(dx, dy)); }
};
QT_END_NAMESPACE
#endif //QT_NO_GRAPHICSEFFECT
#endif // QPIXMAPFILTER_H

View file

@ -43,7 +43,6 @@
#include "qdebug.h"
#include "qstylesheetstyle_p.h"
#include "qstyle_p.h"
#include "qgraphicseffect_p.h"
#include "qwindowsurface_p.h"
#include "qbackingstore_p.h"
#include "qpaintengine_raster_p.h"
@ -174,7 +173,6 @@ QWidgetPrivate::QWidgetPrivate()
, widgetItem(0)
, extraPaintEngine(0)
, polished(0)
, graphicsEffect(0)
, inheritedFontResolveMask(0)
, inheritedPaletteResolveMask(0)
, leftmargin(0)
@ -221,10 +219,6 @@ QWidgetPrivate::~QWidgetPrivate()
if (extra)
deleteExtra();
#ifndef QT_NO_GRAPHICSEFFECT
delete graphicsEffect;
#endif //QT_NO_GRAPHICSEFFECT
}
QWindowSurface *QWidgetPrivate::createDefaultWindowSurface()
@ -1324,9 +1318,9 @@ bool QWidgetPrivate::isOverlapped(const QRect &rect) const
continue;
}
if (qRectIntersects(sibling->d_func()->effectiveRectFor(sibling->data->crect), r)) {
if (qRectIntersects(sibling->data->crect, r)) {
const QWExtra *siblingExtra = sibling->d_func()->extra;
if (siblingExtra && siblingExtra->hasMask && !sibling->d_func()->graphicsEffect
if (siblingExtra && siblingExtra->hasMask
&& !siblingExtra->mask.translated(sibling->data->crect.topLeft()).intersects(r)) {
continue;
}
@ -1424,7 +1418,7 @@ QRect QWidgetPrivate::clipRect() const
const QWidget * w = q;
if (!w->isVisible())
return QRect();
QRect r = effectiveRectFor(q->rect());
QRect r = q->rect();
int ox = 0;
int oy = 0;
while (w
@ -1479,33 +1473,12 @@ QRegion QWidgetPrivate::clipRegion() const
return r;
}
#ifndef QT_NO_GRAPHICSEFFECT
void QWidgetPrivate::invalidateGraphicsEffectsRecursively()
{
Q_Q(QWidget);
QWidget *w = q;
do {
if (w->graphicsEffect()) {
QWidgetEffectSourcePrivate *sourced =
static_cast<QWidgetEffectSourcePrivate *>(w->graphicsEffect()->source()->d_func());
if (!sourced->updateDueToGraphicsEffect)
w->graphicsEffect()->source()->d_func()->invalidateCache();
}
w = w->parentWidget();
} while (w);
}
#endif //QT_NO_GRAPHICSEFFECT
void QWidgetPrivate::setDirtyOpaqueRegion()
{
Q_Q(QWidget);
dirtyOpaqueChildren = true;
#ifndef QT_NO_GRAPHICSEFFECT
invalidateGraphicsEffectsRecursively();
#endif //QT_NO_GRAPHICSEFFECT
if (q->isWindow())
return;
@ -1583,13 +1556,13 @@ void QWidgetPrivate::subtractOpaqueSiblings(QRegion &sourceRegion, bool *hasDirt
break;
QWidgetPrivate *pd = w->parentWidget()->d_func();
const int myIndex = pd->children.indexOf(const_cast<QWidget *>(w));
const QRect widgetGeometry = w->d_func()->effectiveRectFor(w->data->crect);
const QRect widgetGeometry = w->data->crect;
for (int i = myIndex + 1; i < pd->children.size(); ++i) {
QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i));
if (!sibling || !sibling->isVisible() || sibling->isWindow())
continue;
const QRect siblingGeometry = sibling->d_func()->effectiveRectFor(sibling->data->crect);
const QRect siblingGeometry = sibling->data->crect;
if (!qRectIntersects(siblingGeometry, widgetGeometry))
continue;
@ -1610,8 +1583,7 @@ void QWidgetPrivate::subtractOpaqueSiblings(QRegion &sourceRegion, bool *hasDirt
const QRect siblingClipRect(sibling->d_func()->clipRect());
QRegion siblingDirty(parentClip);
siblingDirty &= (siblingClipRect.translated(siblingPos));
const bool hasMask = sibling->d_func()->extra && sibling->d_func()->extra->hasMask
&& !sibling->d_func()->graphicsEffect;
const bool hasMask = sibling->d_func()->extra && sibling->d_func()->extra->hasMask;
if (hasMask)
siblingDirty &= sibling->d_func()->extra->mask.translated(siblingPos);
if (siblingDirty.isEmpty())
@ -1653,13 +1625,6 @@ void QWidgetPrivate::clipToEffectiveMask(QRegion &region) const
const QWidget *w = q;
QPoint offset;
#ifndef QT_NO_GRAPHICSEFFECT
if (graphicsEffect) {
w = q->parentWidget();
offset -= data.crect.topLeft();
}
#endif //QT_NO_GRAPHICSEFFECT
while (w) {
const QWidgetPrivate *wd = w->d_func();
if (wd->extra && wd->extra->hasMask)
@ -1691,17 +1656,8 @@ void QWidgetPrivate::updateIsOpaque()
// hw: todo: only needed if opacity actually changed
setDirtyOpaqueRegion();
#ifndef QT_NO_GRAPHICSEFFECT
if (graphicsEffect) {
// ### We should probably add QGraphicsEffect::isOpaque at some point.
setOpaque(false);
return;
}
#endif //QT_NO_GRAPHICSEFFECT
Q_Q(QWidget);
if (q->testAttribute(Qt::WA_OpaquePaintEvent) || q->testAttribute(Qt::WA_PaintOnScreen)) {
setOpaque(true);
return;
@ -4315,72 +4271,6 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
d->extra->inRenderWithPainter = false;
}
/*!
\brief The graphicsEffect function returns a pointer to the
widget's graphics effect.
If the widget has no graphics effect, 0 is returned.
\since 4.6
\sa setGraphicsEffect()
*/
#ifndef QT_NO_GRAPHICSEFFECT
QGraphicsEffect *QWidget::graphicsEffect() const
{
Q_D(const QWidget);
return d->graphicsEffect;
}
#endif //QT_NO_GRAPHICSEFFECT
/*!
\brief The setGraphicsEffect function is for setting the widget's graphics effect.
Sets \a effect as the widget's effect. If there already is an effect installed
on this widget, QWidget will delete the existing effect before installing
the new \a effect.
If \a effect is the installed on a different widget, setGraphicsEffect() will remove
the effect from the widget and install it on this widget.
QWidget takes ownership of \a effect.
\note This function will apply the effect on itself and all its children.
\note Graphics effects are not supported on Mac, so they will not cause any difference
to the rendering of the widget.
\since 4.6
\sa graphicsEffect()
*/
#ifndef QT_NO_GRAPHICSEFFECT
void QWidget::setGraphicsEffect(QGraphicsEffect *effect)
{
Q_D(QWidget);
if (d->graphicsEffect == effect)
return;
if (d->graphicsEffect) {
d->invalidateBuffer(rect());
delete d->graphicsEffect;
d->graphicsEffect = 0;
}
if (effect) {
// Set new effect.
QGraphicsEffectSourcePrivate *sourced = new QWidgetEffectSourcePrivate(this);
QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
d->graphicsEffect = effect;
effect->d_func()->setGraphicsEffectSource(source);
update();
}
d->updateIsOpaque();
}
#endif //QT_NO_GRAPHICSEFFECT
bool QWidgetPrivate::isAboutToShow() const
{
if (data.in_show)
@ -4514,38 +4404,6 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
return;
Q_Q(QWidget);
#if !defined(QT_NO_GRAPHICSEFFECT)
if (graphicsEffect && graphicsEffect->isEnabled()) {
QGraphicsEffectSource *source = graphicsEffect->d_func()->source;
QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *>
(source->d_func());
if (!sourced->context) {
QWidgetPaintContext context(pdev, rgn, offset, flags, sharedPainter, backingStore);
sourced->context = &context;
if (!sharedPainter) {
QPaintEngine *paintEngine = pdev->paintEngine();
paintEngine->d_func()->systemClip = rgn.translated(offset);
QPainter p(pdev);
p.translate(offset);
context.painter = &p;
graphicsEffect->draw(&p);
paintEngine->d_func()->systemClip = QRegion();
} else {
context.painter = sharedPainter;
if (sharedPainter->worldTransform() != sourced->lastEffectTransform) {
sourced->invalidateCache();
sourced->lastEffectTransform = sharedPainter->worldTransform();
}
sharedPainter->save();
sharedPainter->translate(offset);
graphicsEffect->draw(sharedPainter);
sharedPainter->restore();
}
sourced->context = 0;
return;
}
}
#endif //QT_NO_GRAFFICSEFFECT
const bool asRoot = flags & DrawAsRoot;
const bool alsoOnScreen = flags & DrawPaintOnScreen;
@ -4735,7 +4593,7 @@ void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectLis
dirtyBoundingRect = false;
}
if (qRectIntersects(boundingRect, x->d_func()->effectiveRectFor(x->data->crect))) {
if (qRectIntersects(boundingRect, x->data->crect)) {
w = x;
break;
}
@ -4748,7 +4606,7 @@ void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectLis
QWidgetPrivate *wd = w->d_func();
const QPoint widgetPos(w->data->crect.topLeft());
const bool hasMask = wd->extra && wd->extra->hasMask && !wd->graphicsEffect;
const bool hasMask = wd->extra && wd->extra->hasMask;
if (index > 0) {
QRegion wr(rgn);
if (wd->isOpaque)
@ -4763,7 +4621,7 @@ void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectLis
#endif //QT_NO_GRAPHICSVIEW
) {
QRegion wRegion(rgn);
wRegion &= wd->effectiveRectFor(w->data->crect);
wRegion &= w->data->crect;
wRegion.translate(-widgetPos);
if (hasMask)
wRegion &= wd->extra->mask;
@ -4771,80 +4629,6 @@ void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectLis
}
}
#ifndef QT_NO_GRAPHICSEFFECT
QRectF QWidgetEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
{
if (system != Qt::DeviceCoordinates)
return m_widget->rect();
if (Q_UNLIKELY(!context)) {
// Device coordinates without context not yet supported.
qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
return QRectF();
}
return context->painter->worldTransform().mapRect(m_widget->rect());
}
void QWidgetEffectSourcePrivate::draw(QPainter *painter)
{
if (!context || context->painter != painter) {
m_widget->render(painter);
return;
}
// The region saved in the context is neither clipped to the rect
// nor the mask, so we have to clip it here before calling drawWidget.
QRegion toBePainted = context->rgn;
toBePainted &= m_widget->rect();
QWidgetPrivate *wd = qt_widget_private(m_widget);
if (wd->extra && wd->extra->hasMask)
toBePainted &= wd->extra->mask;
wd->drawWidget(context->pdev, toBePainted, context->offset, context->flags,
context->sharedPainter, context->backingStore);
}
QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
QGraphicsEffect::PixmapPadMode mode) const
{
const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
if (Q_UNLIKELY(!context && deviceCoordinates)) {
// Device coordinates without context not yet supported.
qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
return QPixmap();
}
QPoint pixmapOffset;
QRectF sourceRect = m_widget->rect();
if (deviceCoordinates) {
const QTransform &painterTransform = context->painter->worldTransform();
sourceRect = painterTransform.mapRect(sourceRect);
pixmapOffset = painterTransform.map(pixmapOffset);
}
QRect effectRect;
if (mode == QGraphicsEffect::PadToEffectiveBoundingRect)
effectRect = m_widget->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect();
else if (mode == QGraphicsEffect::PadToTransparentBorder)
effectRect = sourceRect.adjusted(-1, -1, 1, 1).toAlignedRect();
else
effectRect = sourceRect.toAlignedRect();
if (offset)
*offset = effectRect.topLeft();
pixmapOffset -= effectRect.topLeft();
QPixmap pixmap(effectRect.size());
pixmap.fill(Qt::transparent);
m_widget->render(&pixmap, pixmapOffset, QRegion(), QWidget::DrawChildren);
return pixmap;
}
#endif //QT_NO_GRAPHICSEFFECT
#ifndef QT_NO_GRAPHICSVIEW
/*!
\internal

View file

@ -60,7 +60,6 @@ class QIcon;
class QWindowSurface;
class QLocale;
class QGraphicsProxyWidget;
class QGraphicsEffect;
#if defined(Q_WS_X11)
class QX11Info;
#endif
@ -288,11 +287,6 @@ public:
const QRegion &sourceRegion = QRegion(),
RenderFlags renderFlags = RenderFlags(DrawWindowBackground | DrawChildren));
#ifndef QT_NO_GRAPHICSEFFECT
QGraphicsEffect *graphicsEffect() const;
void setGraphicsEffect(QGraphicsEffect *effect);
#endif //QT_NO_GRAPHICSEFFECT
public Q_SLOTS:
void setWindowTitle(const QString &);
#ifndef QT_NO_STYLE_STYLESHEET
@ -599,7 +593,6 @@ private:
friend class QX11EmbedWidgetPrivate;
friend class QX11EmbedContainerPrivate;
friend struct QWidgetExceptionCleaner;
friend class QWidgetEffectSourcePrivate;
#ifdef Q_WS_X11
friend void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp);

View file

@ -42,7 +42,6 @@
#include "QtGui/qsizepolicy.h"
#include "QtGui/qstyle.h"
#include "QtGui/qapplication.h"
#include "qgraphicseffect_p.h"
#include "QtGui/qgraphicsproxywidget.h"
#include "QtGui/qgraphicsscene.h"
#include "QtGui/qgraphicsview.h"
@ -321,9 +320,6 @@ public:
void setOpaque(bool opaque);
void updateIsTranslucent();
bool paintOnScreen() const;
#ifndef QT_NO_GRAPHICSEFFECT
void invalidateGraphicsEffectsRecursively();
#endif //QT_NO_GRAPHICSEFFECT
const QRegion &getOpaqueChildren() const;
void setDirtyOpaqueRegion();
@ -466,15 +462,6 @@ public:
return extra ? extra->nativeChildrenForced : false;
}
inline QRect effectiveRectFor(const QRect &rect) const
{
#ifndef QT_NO_GRAPHICSEFFECT
if (graphicsEffect && graphicsEffect->isEnabled())
return graphicsEffect->boundingRectFor(rect).toAlignedRect();
#endif //QT_NO_GRAPHICSEFFECT
return rect;
}
QSize adjustedSize() const;
inline void handleSoftwareInputPanel(Qt::MouseButton button, bool clickCausedFocus)
@ -517,7 +504,6 @@ public:
QWidgetItemV2 *widgetItem;
QPaintEngine *extraPaintEngine;
mutable const QMetaObject *polished;
QGraphicsEffect *graphicsEffect;
// All widgets are added into the allWidgets set. Once
// they receive a window id they are also added to the mapper.
// This should just ensure that all widgets are deleted by QApplication
@ -602,61 +588,6 @@ struct QWidgetPaintContext
QPainter *painter;
};
#ifndef QT_NO_GRAPHICSEFFECT
class QWidgetEffectSourcePrivate : public QGraphicsEffectSourcePrivate
{
public:
QWidgetEffectSourcePrivate(QWidget *widget)
: QGraphicsEffectSourcePrivate(), m_widget(widget), context(0), updateDueToGraphicsEffect(false)
{}
inline void detach()
{ m_widget->d_func()->graphicsEffect = 0; }
inline const QGraphicsItem *graphicsItem() const
{ return nullptr; }
inline const QWidget *widget() const
{ return m_widget; }
inline void update()
{
updateDueToGraphicsEffect = true;
m_widget->update();
updateDueToGraphicsEffect = false;
}
inline bool isPixmap() const
{ return false; }
inline void effectBoundingRectChanged()
{
// ### This function should take a rect parameter; then we can avoid
// updating too much on the parent widget.
if (QWidget *parent = m_widget->parentWidget())
parent->update();
else
update();
}
inline const QStyleOption *styleOption() const
{ return nullptr; }
inline QRect deviceRect() const
{ return m_widget->window()->rect(); }
QRectF boundingRect(Qt::CoordinateSystem system) const;
void draw(QPainter *p);
QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset,
QGraphicsEffect::PixmapPadMode mode) const;
QWidget *m_widget;
QWidgetPaintContext *context;
QTransform lastEffectTransform;
bool updateDueToGraphicsEffect;
};
#endif //QT_NO_GRAPHICSEFFECT
inline QWExtra *QWidgetPrivate::extraData() const
{
return extra;

View file

@ -960,7 +960,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
{
Q_D(QWidget);
if (!isWindow() && parentWidget())
parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
parentWidget()->d_func()->invalidateBuffer(geometry());
d->deactivateWidgetCleanup();
if (testAttribute(Qt::WA_WState_Created)) {
setAttribute(Qt::WA_WState_Created, false);
@ -1032,7 +1032,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
QTLWExtra *topData = maybeTopData();
bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
q->parentWidget()->d_func()->invalidateBuffer(q->geometry());
#ifndef QT_NO_CURSOR
QCursor oldcurs;
#endif

View file

@ -33,7 +33,6 @@
#include "qwindowsurface_p.h"
#include "qapplication_p.h"
#include "qpaintengine_raster_p.h"
#include "qgraphicseffect_p.h"
QT_BEGIN_NAMESPACE
@ -197,10 +196,6 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool up
Q_ASSERT(widget->window() == tlw);
Q_ASSERT(!rgn.isEmpty());
#ifndef QT_NO_GRAPHICSEFFECT
widget->d_func()->invalidateGraphicsEffectsRecursively();
#endif //QT_NO_GRAPHICSEFFECT
if (widget->d_func()->paintOnScreen()) {
if (widget->d_func()->dirty.isEmpty()) {
widget->d_func()->dirty = rgn;
@ -220,7 +215,7 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool up
}
const QPoint offset = widget->mapTo(tlw, QPoint());
const QRect widgetRect = widget->d_func()->effectiveRectFor(widget->rect());
const QRect widgetRect = widget->rect();
if (qt_region_strictContains(dirty, widgetRect.translated(offset))) {
if (updateImmediately)
sendUpdateRequest(tlw, updateImmediately);
@ -229,12 +224,7 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool up
if (invalidateBuffer) {
const bool eventAlreadyPosted = !dirty.isEmpty();
#ifndef QT_NO_GRAPHICSEFFECT
if (widget->d_func()->graphicsEffect)
dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect()).translated(offset);
else
#endif //QT_NO_GRAPHICSEFFECT
dirty += rgn.translated(offset);
dirty += rgn.translated(offset);
if (!eventAlreadyPosted || updateImmediately)
sendUpdateRequest(tlw, updateImmediately);
return;
@ -248,12 +238,7 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool up
if (widget->d_func()->inDirtyList) {
if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect)) {
#ifndef QT_NO_GRAPHICSEFFECT
if (widget->d_func()->graphicsEffect)
widget->d_func()->dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect());
else
#endif //QT_NO_GRAPHICSEFFECT
widget->d_func()->dirty += rgn;
widget->d_func()->dirty += rgn;
}
} else {
addDirtyWidget(widget, rgn);
@ -278,10 +263,6 @@ void QWidgetBackingStore::markDirty(const QRect &rect, QWidget *widget, bool upd
Q_ASSERT(widget->window() == tlw);
Q_ASSERT(!rect.isEmpty());
#ifndef QT_NO_GRAPHICSEFFECT
widget->d_func()->invalidateGraphicsEffectsRecursively();
#endif //QT_NO_GRAPHICSEFFECT
if (widget->d_func()->paintOnScreen()) {
if (widget->d_func()->dirty.isEmpty()) {
widget->d_func()->dirty = QRegion(rect);
@ -300,7 +281,7 @@ void QWidgetBackingStore::markDirty(const QRect &rect, QWidget *widget, bool upd
return;
}
const QRect widgetRect = widget->d_func()->effectiveRectFor(rect);
const QRect widgetRect = rect;
const QRect translatedRect(widgetRect.translated(widget->mapTo(tlw, QPoint())));
if (qt_region_strictContains(dirty, translatedRect)) {
if (updateImmediately)
@ -451,7 +432,7 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
&& !isOverlapped(sourceRect) && !isOverlapped(destRect);
if (!accelerateMove) {
QRegion parentR(effectiveRectFor(parentRect));
QRegion parentR(parentRect);
if (!extra || !extra->hasMask) {
parentR -= newRect;
} else {
@ -834,12 +815,12 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q
return;
// Invalidate newly exposed area of the parent.
if (!graphicsEffect && extra && extra->hasMask) {
if (extra && extra->hasMask) {
QRegion parentExpose(extra->mask.translated(oldPos));
parentExpose &= QRect(oldPos, oldSize);
q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
} else {
q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(QRect(oldPos, oldSize)));
q->parentWidget()->d_func()->invalidateBuffer(QRect(oldPos, oldSize));
}
}
@ -858,7 +839,7 @@ void QWidgetPrivate::invalidateBuffer(const QRegion &rgn)
QRegion wrgn(rgn);
wrgn &= clipRect();
if (!graphicsEffect && extra && extra->hasMask)
if (extra && extra->hasMask)
wrgn &= extra->mask;
if (wrgn.isEmpty())
return;
@ -884,7 +865,7 @@ void QWidgetPrivate::invalidateBuffer(const QRect &rect)
if (wRect.isEmpty())
return;
if (graphicsEffect || !extra || !extra->hasMask) {
if (!extra || !extra->hasMask) {
tlwExtra->backingStore->markDirty(wRect, q, false, true);
return;
}

View file

@ -95,12 +95,7 @@ private:
{
if (widget && !widget->d_func()->inDirtyList && !widget->data->in_destructor) {
QWidgetPrivate *widgetPrivate = widget->d_func();
#ifndef QT_NO_GRAPHICSEFFECT
if (widgetPrivate->graphicsEffect)
widgetPrivate->dirty = widgetPrivate->effectiveRectFor(rgn.boundingRect());
else
#endif //QT_NO_GRAPHICSEFFECT
widgetPrivate->dirty = rgn;
widgetPrivate->dirty = rgn;
dirtyWidgets.append(widget);
widgetPrivate->inDirtyList = true;
}

View file

@ -5342,8 +5342,21 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardicon, const QStyleOption
return icon;
}
// in qpixmapfilter.cpp
extern Q_GUI_EXPORT void qt_grayscale(const QImage &image, QImage &dest);
// grayscales the image to dest (same as source).
static void qt_grayscale(const QImage &image, QImage &dest)
{
Q_ASSERT(image.depth() == 32 && dest.depth() == 32);
unsigned int *outData = (unsigned int *)dest.bits();
const unsigned int *data = (const unsigned int *)image.constBits();
// grayscaling everything
const int pixels = dest.width() * dest.height();
for (int i = 0; i < pixels; ++i) {
int val = qGray(data[i]);
outData[i] = qRgba(val, val, val, qAlpha(data[i]));
}
}
/*! \reimp */
QPixmap QCommonStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,

View file

@ -210,10 +210,6 @@ static const struct ClassTblData {
{ QLatin1String("QGradient"), QLatin1String("QtGui/qbrush.h") },
{ QLatin1String("QGraphicsAnchor"), QLatin1String("QtGui/qgraphicsanchorlayout.h") },
{ QLatin1String("QGraphicsAnchorLayout"), QLatin1String("QtGui/qgraphicsanchorlayout.h") },
{ QLatin1String("QGraphicsBlurEffect"), QLatin1String("QtGui/qgraphicseffect.h") },
{ QLatin1String("QGraphicsColorizeEffect"), QLatin1String("QtGui/qgraphicseffect.h") },
{ QLatin1String("QGraphicsDropShadowEffect"), QLatin1String("QtGui/qgraphicseffect.h") },
{ QLatin1String("QGraphicsEffect"), QLatin1String("QtGui/qgraphicseffect.h") },
{ QLatin1String("QGraphicsEllipseItem"), QLatin1String("QtGui/qgraphicsitem.h") },
{ QLatin1String("QGraphicsGridLayout"), QLatin1String("QtGui/qgraphicsgridlayout.h") },
{ QLatin1String("QGraphicsItem"), QLatin1String("QtGui/qgraphicsitem.h") },
@ -224,7 +220,6 @@ static const struct ClassTblData {
{ QLatin1String("QGraphicsLineItem"), QLatin1String("QtGui/qgraphicsitem.h") },
{ QLatin1String("QGraphicsLinearLayout"), QLatin1String("QtGui/qgraphicslinearlayout.h") },
{ QLatin1String("QGraphicsObject"), QLatin1String("QtGui/qgraphicsitem.h") },
{ QLatin1String("QGraphicsOpacityEffect"), QLatin1String("QtGui/qgraphicseffect.h") },
{ QLatin1String("QGraphicsPathItem"), QLatin1String("QtGui/qgraphicsitem.h") },
{ QLatin1String("QGraphicsPixmapItem"), QLatin1String("QtGui/qgraphicsitem.h") },
{ QLatin1String("QGraphicsPolygonItem"), QLatin1String("QtGui/qgraphicsitem.h") },

View file

@ -1,3 +0,0 @@
katie_gui_test(tst_qgraphicseffect
${CMAKE_CURRENT_SOURCE_DIR}/tst_qgraphicseffect.cpp
)

View file

@ -1,834 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2016 Ivailo Monev
**
** This file is part of the test suite of the Katie Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <QtGui/qdesktopwidget.h>
#include <QtGui/qgraphicseffect.h>
#include <QtGui/qgraphicsview.h>
#include <QtGui/qgraphicsscene.h>
#include <QtGui/qgraphicsitem.h>
#include <QtGui/qgraphicswidget.h>
#include <QtGui/qstyleoption.h>
#include "../../shared/util.h"
#include "qgraphicseffect_p.h"
//TESTED_CLASS=
//TESTED_FILES=
#ifndef QT_NO_GRAPHICSEFFECT
class tst_QGraphicsEffect : public QObject
{
Q_OBJECT
public slots:
void initTestCase();
private slots:
void setEnabled();
void source();
void boundingRectFor();
void boundingRect();
void boundingRect2();
void draw();
void opacity();
void grayscale();
void colorize();
void drawPixmapItem();
void deviceCoordinateTranslateCaching();
void inheritOpacity();
void dropShadowClipping();
void childrenVisibilityShouldInvalidateCache();
void prepareGeometryChangeInvalidateCache();
void graphicsEffectUpdateShouldNotInvalidateGraphicsItemCache();
void graphicsEffectUpdateShouldInvalidateParentGraphicsEffect();
void itemHasNoContents();
};
void tst_QGraphicsEffect::initTestCase()
{}
class CustomItem : public QGraphicsRectItem
{
public:
CustomItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = 0)
: QGraphicsRectItem(x, y, width, height, parent), numRepaints(0),
m_painter(0)
{}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
m_painter = painter;
++numRepaints;
QGraphicsRectItem::paint(painter, option, widget);
}
void reset()
{
numRepaints = 0;
m_painter = 0;
}
int numRepaints;
QPainter *m_painter;
};
class CustomEffect : public QGraphicsEffect
{
public:
CustomEffect()
: QGraphicsEffect(), numRepaints(0), m_margin(10),
doNothingInDraw(false), m_painter(0), m_source(0), m_opacity(1.0)
{}
QRectF boundingRectFor(const QRectF &rect) const
{ return rect.adjusted(-m_margin, -m_margin, m_margin, m_margin); }
void reset()
{
numRepaints = 0;
m_sourceChangedFlags = QGraphicsEffect::ChangeFlags();
m_painter = 0;
m_source = 0;
m_opacity = 1.0;
}
void setMargin(int margin)
{
m_margin = margin;
updateBoundingRect();
}
int margin() const
{ return m_margin; }
void draw(QPainter *painter)
{
++numRepaints;
if (doNothingInDraw)
return;
m_source = source();
m_painter = painter;
m_opacity = painter->opacity();
drawSource(painter);
}
void sourceChanged(QGraphicsEffect::ChangeFlags flags)
{ m_sourceChangedFlags |= flags; }
int numRepaints;
int m_margin;
QGraphicsEffect::ChangeFlags m_sourceChangedFlags;
bool doNothingInDraw;
QPainter *m_painter;
QGraphicsEffectSource *m_source;
qreal m_opacity;
};
void tst_QGraphicsEffect::setEnabled()
{
CustomEffect effect;
QVERIFY(effect.isEnabled());
effect.setEnabled(false);
QVERIFY(!effect.isEnabled());
}
void tst_QGraphicsEffect::source()
{
QPointer<CustomEffect> effect = new CustomEffect;
QVERIFY(!effect->source());
QVERIFY(!effect->m_sourceChangedFlags);
// Install effect on QGraphicsItem.
QGraphicsItem *item = new QGraphicsRectItem(0, 0, 10, 10);
item->setGraphicsEffect(effect);
QVERIFY(effect->source());
QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceAttached);
effect->reset();
// Make sure disabling/enabling the effect doesn't change the source.
effect->setEnabled(false);
QVERIFY(effect->source());
QVERIFY(!effect->m_sourceChangedFlags);
effect->reset();
effect->setEnabled(true);
QVERIFY(effect->source());
QVERIFY(!effect->m_sourceChangedFlags);
effect->reset();
// Uninstall effect on QGraphicsItem.
effect->reset();
item->setGraphicsEffect(0);
QVERIFY(!effect);
effect = new CustomEffect;
// The item takes ownership and should delete the effect when destroyed.
item->setGraphicsEffect(effect);
QPointer<QGraphicsEffectSource> source = effect->source();
QVERIFY(source);
delete item;
QVERIFY(!effect);
QVERIFY(!source);
}
void tst_QGraphicsEffect::boundingRectFor()
{
CustomEffect effect;
int margin = effect.margin();
const QRectF source(0, 0, 100, 100);
QCOMPARE(effect.boundingRectFor(source), source.adjusted(-margin, -margin, margin, margin));
effect.setMargin(margin = 20);
QCOMPARE(effect.boundingRectFor(source), source.adjusted(-margin, -margin, margin, margin));
}
void tst_QGraphicsEffect::boundingRect()
{
// No source; empty bounding rect.
CustomEffect *effect = new CustomEffect;
QCOMPARE(effect->boundingRect(), QRectF());
// Install effect on QGraphicsItem.
QRectF itemRect(0, 0, 100, 100);
QGraphicsRectItem *item = new QGraphicsRectItem;
item->setRect(itemRect);
item->setGraphicsEffect(effect);
int margin = effect->margin();
QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
// Make sure disabling/enabling the effect doesn't change the bounding rect.
effect->setEnabled(false);
QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
effect->setEnabled(true);
QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
// Change effect margins.
effect->setMargin(margin = 20);
QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
// Uninstall effect on QGraphicsItem.
QPointer<CustomEffect> ptr = effect;
item->setGraphicsEffect(0);
QVERIFY(!ptr);
delete item;
}
void tst_QGraphicsEffect::boundingRect2()
{
CustomEffect *effect = new CustomEffect;
QGraphicsRectItem *root = new QGraphicsRectItem;
root->setGraphicsEffect(effect);
QGraphicsRectItem *child = new QGraphicsRectItem;
QRectF childRect(0, 0, 100, 100);
child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
child->setRect(childRect);
child->setParentItem(root);
QGraphicsRectItem *grandChild = new QGraphicsRectItem;
QRectF grandChildRect(0, 0, 200, 200);
grandChild->setRect(grandChildRect);
grandChild->setParentItem(child);
// Make sure the effect's bounding rect is clipped to the child's bounding rect.
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
// Disable ItemClipsChildrenToShape; effect's bounding rect is no longer clipped.
child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
// Add root item to a scene, do the same tests as above. Results should be the same.
QGraphicsScene scene;
scene.addItem(root);
child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
// Now add the scene to a view, results should be the same.
QGraphicsView view(&scene);
child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
CustomEffect *childEffect = new CustomEffect;
child->setGraphicsEffect(childEffect);
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childEffect->boundingRectFor(childRect | grandChildRect)));
child->setGraphicsEffect(0);
QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
}
void tst_QGraphicsEffect::draw()
{
QGraphicsScene scene;
CustomItem *item = new CustomItem(0, 0, 100, 100);
scene.addItem(item);
QGraphicsView view(&scene);
view.show();
QTest::qWaitForWindowShown(&view);
QTRY_VERIFY(item->numRepaints > 0);
item->reset();
// Make sure installing the effect triggers a repaint.
CustomEffect *effect = new CustomEffect;
item->setGraphicsEffect(effect);
QTRY_COMPARE(effect->numRepaints, 1);
QTRY_COMPARE(item->numRepaints, 1);
// Make sure QPainter* and QStyleOptionGraphicsItem* stays persistent
// during QGraphicsEffect::draw/QGraphicsItem::paint.
QVERIFY(effect->m_painter);
QCOMPARE(effect->m_painter, item->m_painter);
// Make sure QGraphicsEffect::source is persistent.
QCOMPARE(effect->m_source, effect->source());
effect->reset();
item->reset();
// Make sure updating the source triggers a repaint.
item->update();
QTRY_COMPARE(effect->numRepaints, 1);
QTRY_COMPARE(item->numRepaints, 1);
QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceInvalidated);
effect->reset();
item->reset();
// Make sure changing the effect's bounding rect triggers a repaint.
effect->setMargin(20);
QTRY_COMPARE(effect->numRepaints, 1);
QTRY_COMPARE(item->numRepaints, 1);
effect->reset();
item->reset();
// Make sure change the item's bounding rect triggers a repaint.
item->setRect(0, 0, 50, 50);
QTRY_COMPARE(effect->numRepaints, 1);
QTRY_COMPARE(item->numRepaints, 1);
QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceBoundingRectChanged);
effect->reset();
item->reset();
// Make sure the effect is the one to issue a repaint of the item.
effect->doNothingInDraw = true;
item->update();
QTRY_COMPARE(effect->numRepaints, 1);
QCOMPARE(item->numRepaints, 0);
effect->doNothingInDraw = false;
effect->reset();
item->reset();
// Make sure we update the source when disabling/enabling the effect.
effect->setEnabled(false);
QTest::qWait(50);
QCOMPARE(effect->numRepaints, 0);
QCOMPARE(item->numRepaints, 1);
effect->reset();
item->reset();
effect->setEnabled(true);
QTRY_COMPARE(effect->numRepaints, 1);
QTRY_COMPARE(item->numRepaints, 1);
effect->reset();
item->reset();
// Effect is already enabled; nothing should happen.
effect->setEnabled(true);
QTest::qWait(50);
QCOMPARE(effect->numRepaints, 0);
QCOMPARE(item->numRepaints, 0);
// Make sure uninstalling an effect triggers a repaint.
QPointer<CustomEffect> ptr = effect;
item->setGraphicsEffect(0);
QVERIFY(!ptr);
QTRY_COMPARE(item->numRepaints, 1);
}
void tst_QGraphicsEffect::opacity()
{
// Make sure the painter's opacity is correct in QGraphicsEffect::draw.
QGraphicsScene scene;
CustomItem *item = new CustomItem(0, 0, 100, 100);
item->setOpacity(0.5);
CustomEffect *effect = new CustomEffect;
item->setGraphicsEffect(effect);
scene.addItem(item);
QGraphicsView view(&scene);
view.show();
QTest::qWaitForWindowShown(&view);
QTRY_VERIFY(effect->numRepaints > 0);
QCOMPARE(effect->m_opacity, qreal(0.5));
}
void tst_QGraphicsEffect::grayscale()
{
if (qApp->desktop()->depth() < 24) {
QSKIP("Test only works on 32 bit displays", SkipAll);
return;
}
QGraphicsScene scene(0, 0, 100, 100);
QGraphicsRectItem *item = scene.addRect(0, 0, 50, 50);
item->setPen(Qt::NoPen);
item->setBrush(QColor(122, 193, 66)); // Qt light green
QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect;
effect->setColor(Qt::black);
item->setGraphicsEffect(effect);
QPainter painter;
QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
image.fill(0);
painter.begin(&image);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
painter.end();
QCOMPARE(image.pixel(10, 10), qRgb(148, 148, 148));
effect->setStrength(0.5);
image.fill(0);
painter.begin(&image);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
painter.end();
QCOMPARE(image.pixel(10, 10), qRgb(135, 171, 107));
effect->setStrength(0.0);
image.fill(0);
painter.begin(&image);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
painter.end();
QCOMPARE(image.pixel(10, 10), qRgb(122, 193, 66));
}
void tst_QGraphicsEffect::colorize()
{
if (qApp->desktop()->depth() < 24) {
QSKIP("Test only works on 32 bit displays", SkipAll);
return;
}
QGraphicsScene scene(0, 0, 100, 100);
QGraphicsRectItem *item = scene.addRect(0, 0, 50, 50);
item->setPen(Qt::NoPen);
item->setBrush(QColor(122, 193, 66)); // Qt light green
QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect;
effect->setColor(QColor(102, 153, 51)); // Qt dark green
item->setGraphicsEffect(effect);
QPainter painter;
QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
image.fill(0);
painter.begin(&image);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
painter.end();
QCOMPARE(image.pixel(10, 10), qRgb(191, 212, 169));
effect->setStrength(0.5);
image.fill(0);
painter.begin(&image);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
painter.end();
QCOMPARE(image.pixel(10, 10), qRgb(156, 203, 117));
effect->setStrength(0.0);
image.fill(0);
painter.begin(&image);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
painter.end();
QCOMPARE(image.pixel(10, 10), qRgb(122, 193, 66));
}
class PixmapItemEffect : public QGraphicsEffect
{
public:
PixmapItemEffect(const QPixmap &source)
: QGraphicsEffect()
, pixmap(source)
, repaints(0)
{}
QRectF boundingRectFor(const QRectF &rect) const
{ return rect; }
void draw(QPainter *painter)
{
QVERIFY(sourcePixmap(Qt::LogicalCoordinates).cacheKey() == pixmap.cacheKey());
QVERIFY((painter->worldTransform().type() <= QTransform::TxTranslate) == (sourcePixmap(Qt::DeviceCoordinates).cacheKey() == pixmap.cacheKey()));
++repaints;
}
QPixmap pixmap;
int repaints;
};
void tst_QGraphicsEffect::drawPixmapItem()
{
QImage image(32, 32, QImage::Format_RGB32);
QPainter p(&image);
p.fillRect(0, 0, 32, 16, Qt::blue);
p.fillRect(0, 16, 32, 16, Qt::red);
p.end();
QGraphicsScene scene;
QGraphicsPixmapItem *item = new QGraphicsPixmapItem(QPixmap::fromImage(image));
scene.addItem(item);
PixmapItemEffect *effect = new PixmapItemEffect(item->pixmap());
item->setGraphicsEffect(effect);
QGraphicsView view(&scene);
view.show();
QTest::qWaitForWindowShown(&view);
QTRY_VERIFY(effect->repaints >= 1);
item->rotate(180);
QTRY_VERIFY(effect->repaints >= 2);
}
class DeviceEffect : public QGraphicsEffect
{
public:
QRectF boundingRectFor(const QRectF &rect) const
{ return rect; }
void draw(QPainter *painter)
{
QPoint offset;
QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, QGraphicsEffect::NoPad);
if (pixmap.isNull())
return;
painter->save();
painter->setWorldTransform(QTransform());
painter->drawPixmap(offset, pixmap);
painter->restore();
}
};
void tst_QGraphicsEffect::deviceCoordinateTranslateCaching()
{
QGraphicsScene scene;
CustomItem *item = new CustomItem(0, 0, 10, 10);
scene.addItem(item);
scene.setSceneRect(0, 0, 50, 0);
item->setGraphicsEffect(new DeviceEffect);
item->setPen(Qt::NoPen);
item->setBrush(Qt::red);
QGraphicsView view(&scene);
view.show();
QTest::qWaitForWindowShown(&view);
QTRY_VERIFY(item->numRepaints >= 1);
int numRepaints = item->numRepaints;
item->translate(10, 0);
QTRY_VERIFY(item->numRepaints == numRepaints);
}
void tst_QGraphicsEffect::inheritOpacity()
{
QGraphicsScene scene;
QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 10, 10);
CustomItem *item = new CustomItem(0, 0, 10, 10, rectItem);
scene.addItem(rectItem);
item->setGraphicsEffect(new DeviceEffect);
item->setPen(Qt::NoPen);
item->setBrush(Qt::red);
rectItem->setOpacity(0.5);
QGraphicsView view(&scene);
view.show();
QTest::qWaitForWindowShown(&view);
QTRY_VERIFY(item->numRepaints >= 1);
int numRepaints = item->numRepaints;
rectItem->setOpacity(1);
// item should have been rerendered due to opacity changing
QTRY_VERIFY(item->numRepaints > numRepaints);
}
void tst_QGraphicsEffect::dropShadowClipping()
{
QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
img.fill(0xffffffff);
QGraphicsScene scene;
QGraphicsRectItem *item = new QGraphicsRectItem(-5, -500, 10, 1000);
item->setGraphicsEffect(new QGraphicsDropShadowEffect);
item->setPen(Qt::NoPen);
item->setBrush(Qt::red);
scene.addItem(item);
QPainter p(&img);
scene.render(&p, img.rect(), QRect(-64, -64, 128, 128));
p.end();
for (int y = 1; y < img.height(); ++y)
for (int x = 0; x < img.width(); ++x)
QCOMPARE(img.pixel(x, y), img.pixel(x, y-1));
}
class MyGraphicsItem : public QGraphicsWidget
{
public:
MyGraphicsItem(QGraphicsItem *parent = 0) :
QGraphicsWidget(parent), nbPaint(0)
{}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
nbPaint++;
QGraphicsWidget::paint(painter, option, widget);
}
int nbPaint;
};
void tst_QGraphicsEffect::childrenVisibilityShouldInvalidateCache()
{
QGraphicsScene scene;
MyGraphicsItem parent;
parent.resize(200, 200);
QGraphicsWidget child(&parent);
child.resize(200, 200);
child.setVisible(false);
scene.addItem(&parent);
QGraphicsView view(&scene);
view.show();
QApplication::setActiveWindow(&view);
QTest::qWaitForWindowShown(&view);
QTRY_VERIFY(parent.nbPaint >= 1);
//we set an effect on the parent
parent.setGraphicsEffect(new QGraphicsDropShadowEffect(&parent));
//flush the events
QApplication::processEvents();
//new effect applied->repaint
QVERIFY(parent.nbPaint >= 2);
child.setVisible(true);
//flush the events
QApplication::processEvents();
//a new child appears we need to redraw the effect.
QVERIFY(parent.nbPaint >= 3);
}
void tst_QGraphicsEffect::prepareGeometryChangeInvalidateCache()
{
MyGraphicsItem *item = new MyGraphicsItem;
item->resize(200, 200);
QGraphicsScene scene;
scene.addItem(item);
QGraphicsView view(&scene);
view.show();
QTest::qWaitForWindowShown(&view);
QTRY_VERIFY(item->nbPaint >= 1);
item->nbPaint = 0;
item->setGraphicsEffect(new QGraphicsDropShadowEffect);
QTRY_COMPARE(item->nbPaint, 1);
item->nbPaint = 0;
item->resize(300, 300);
QTRY_COMPARE(item->nbPaint, 1);
item->nbPaint = 0;
item->setPos(item->pos() + QPointF(10, 10));
QTest::qWait(50);
QCOMPARE(item->nbPaint, 0);
}
class MyGraphicsEffect : public QGraphicsEffect
{
public:
MyGraphicsEffect(QObject *parent = 0) :
QGraphicsEffect(parent), nbSourceInvalidations(0)
{}
int nbSourceInvalidations;
protected:
void draw(QPainter *painter)
{
drawSource(painter);
}
void sourceChanged(ChangeFlags flags)
{
if (flags == SourceInvalidated)
nbSourceInvalidations++;
}
};
void tst_QGraphicsEffect::graphicsEffectUpdateShouldNotInvalidateGraphicsItemCache()
{
QGraphicsScene scene;
MyGraphicsItem parent;
parent.resize(200, 200);
parent.setCacheMode(QGraphicsItem::ItemCoordinateCache);
scene.addItem(&parent);
QGraphicsView view(&scene);
view.show();
QApplication::setActiveWindow(&view);
QTest::qWaitForWindowShown(&view);
QTRY_COMPARE(parent.nbPaint, 1);
//we set an effect on the parent
MyGraphicsEffect* opacityEffect = new MyGraphicsEffect(&parent);
opacityEffect->update();
parent.setGraphicsEffect(opacityEffect);
//flush the events
QApplication::processEvents();
//new effect applied->repaint
QCOMPARE(parent.nbPaint, 1);
opacityEffect->update();
//flush the events
QApplication::processEvents();
//A change to the effect shouldn't invalidate the graphicsitem's cache
// => it shouldn't trigger a paint
QCOMPARE(parent.nbPaint, 1);
}
void tst_QGraphicsEffect::graphicsEffectUpdateShouldInvalidateParentGraphicsEffect()
{
QGraphicsScene scene;
// Add the parent
MyGraphicsItem parent;
parent.resize(200, 200);
scene.addItem(&parent);
// Add a child to the parent
MyGraphicsItem child(&parent);
child.resize(100, 100);
QGraphicsView view(&scene);
view.show();
QApplication::setActiveWindow(&view);
QTest::qWaitForWindowShown(&view);
//flush the events
QApplication::processEvents();
QTRY_COMPARE(parent.nbPaint, 1);
QTRY_COMPARE(child.nbPaint, 1);
//we set an effect on the parent and the child
MyGraphicsEffect* effectForParent = new MyGraphicsEffect(&parent);
parent.setGraphicsEffect(effectForParent);
MyGraphicsEffect* effectForChild = new MyGraphicsEffect(&child);
child.setGraphicsEffect(effectForChild);
//flush the events
QApplication::processEvents();
// Both effects should start with no source invalidations
QCOMPARE(effectForParent->nbSourceInvalidations, 0);
QCOMPARE(effectForChild->nbSourceInvalidations, 0);
// Trigger an update of the child graphics effect
effectForChild->update();
//flush the events
QApplication::processEvents();
// An update of the effect on the child shouldn't tell that effect that its source has been invalidated
QCOMPARE(effectForChild->nbSourceInvalidations, 0);
// The effect on the parent should however be notified of an invalidated source
QCOMPARE(effectForParent->nbSourceInvalidations, 1);
}
void tst_QGraphicsEffect::itemHasNoContents()
{
QGraphicsRectItem *parent = new QGraphicsRectItem;
parent->setFlag(QGraphicsItem::ItemHasNoContents);
MyGraphicsItem *child = new MyGraphicsItem;
child->setParentItem(parent);
child->resize(200, 200);
QGraphicsScene scene;
scene.addItem(parent);
QGraphicsView view(&scene);
view.show();
QTest::qWaitForWindowShown(&view);
QTRY_VERIFY(child->nbPaint >= 1);
CustomEffect *effect = new CustomEffect;
parent->setGraphicsEffect(effect);
QTRY_COMPARE(effect->numRepaints, 1);
for (int i = 0; i < 3; ++i) {
effect->reset();
effect->update();
QTRY_COMPARE(effect->numRepaints, 1);
}
}
QTEST_MAIN(tst_QGraphicsEffect)
#include "moc_tst_qgraphicseffect.cpp"
#else // QT_NO_GRAPHICSEFFECT
QTEST_NOOP_MAIN
#endif // QT_NO_GRAPHICSEFFECT