Commit 4c54bfc5 authored by Jan Hambrecht's avatar Jan Hambrecht

refactor to have a dedicated class to manage the stack of filter effects


svn path=/trunk/koffice/; revision=1005663
parent 70ad844c
......@@ -101,6 +101,7 @@ set(flake_SRCS
KoZoomMode.cpp
KoDpi.cpp
KoFilterEffect.cpp
KoFilterEffectStack.cpp
KoFilterEffectFactory.cpp
KoFilterEffectRegistry.cpp
KoFilterEffectConfigWidgetBase.cpp
......
......@@ -26,14 +26,12 @@
struct KoFilterEffect::Private {
Private()
: clipRect(-0.1, -0.1, 1.2, 1.2)
, filterRect(0, 0, 1, 1)
: filterRect(0, 0, 1, 1)
, requiredInputCount(1), maximalInputCount(1)
{}
QString id;
QString name;
QRectF clipRect;
QRectF filterRect;
QList<QString> inputs;
QString output;
......@@ -63,25 +61,6 @@ QString KoFilterEffect::id() const
return d->id;
}
void KoFilterEffect::setClipRect(const QRectF &clipRect)
{
d->clipRect = clipRect;
}
QRectF KoFilterEffect::clipRect() const
{
return d->clipRect;
}
QRectF KoFilterEffect::clipRectForBoundingRect(const QRectF &boundingRect) const
{
qreal x = boundingRect.x() + d->clipRect.x() * boundingRect.width();
qreal y = boundingRect.y() + d->clipRect.y() * boundingRect.height();
qreal w = d->clipRect.width() * boundingRect.width();
qreal h = d->clipRect.height() * boundingRect.height();
return QRectF(x, y, w, h);
}
void KoFilterEffect::setFilterRect(const QRectF &filterRect)
{
d->filterRect = filterRect;
......
......@@ -49,15 +49,6 @@ public:
/// Returns the unique id of the filter
QString id() const;
/// Sets the clipping rectangle used for this filter in bounding box units
void setClipRect(const QRectF &clipRect);
/// Returns the clipping rectangle used for this filter in bounding box units
QRectF clipRect() const;
/// Returns the clipping rectangle for the given bounding rect
QRectF clipRectForBoundingRect(const QRectF &boundingRect) const;
/// Sets the region the filter is applied to in bounding box units
void setFilterRect(const QRectF &filterRect);
......
/* This file is part of the KDE project
* Copyright (c) 2009 Jan Hambrecht <jaham@gmx.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "KoFilterEffectStack.h"
#include "KoFilterEffect.h"
#include <QtCore/QAtomicInt>
class KoFilterEffectStack::Private
{
public:
Private()
: clipRect(-0.1, -0.1, 1.2, 1.2)
{
}
~Private()
{
qDeleteAll(filterEffects);
}
QList<KoFilterEffect*> filterEffects;
QRectF clipRect;
QAtomicInt refCount;
};
KoFilterEffectStack::KoFilterEffectStack()
: d(new Private())
{
}
KoFilterEffectStack::~KoFilterEffectStack()
{
delete d;
}
QList<KoFilterEffect*> KoFilterEffectStack::filterEffects() const
{
return d->filterEffects;
}
void KoFilterEffectStack::insertFilterEffect(int index, KoFilterEffect * filter)
{
if (filter)
d->filterEffects.insert(index, filter);
}
void KoFilterEffectStack::appendFilterEffect(KoFilterEffect *filter)
{
if (filter)
d->filterEffects.append(filter);
}
void KoFilterEffectStack::removeFilterEffect(int index)
{
d->filterEffects.removeAt(index);
}
void KoFilterEffectStack::setClipRect(const QRectF &clipRect)
{
d->clipRect = clipRect;
}
QRectF KoFilterEffectStack::clipRect() const
{
return d->clipRect;
}
QRectF KoFilterEffectStack::clipRectForBoundingRect(const QRectF &boundingRect) const
{
qreal x = boundingRect.x() + d->clipRect.x() * boundingRect.width();
qreal y = boundingRect.y() + d->clipRect.y() * boundingRect.height();
qreal w = d->clipRect.width() * boundingRect.width();
qreal h = d->clipRect.height() * boundingRect.height();
return QRectF(x, y, w, h);
}
void KoFilterEffectStack::addUser()
{
d->refCount.ref();
}
bool KoFilterEffectStack::removeUser()
{
return d->refCount.deref();
}
int KoFilterEffectStack::useCount() const
{
return d->refCount;
}
/* This file is part of the KDE project
* Copyright (c) 2009 Jan Hambrecht <jaham@gmx.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KOFILTEREFFECTSTACK
#define KOFILTEREFFECTSTACK
#include "flake_export.h"
#include <QtCore/QList>
#include <QtCore/QRectF>
class KoFilterEffect;
class FLAKE_EXPORT KoFilterEffectStack
{
public:
KoFilterEffectStack();
~KoFilterEffectStack();
/**
* The first filter of the list is the first to be applied.
*
* @return the list of filter effects applied on the shape when rendering.
*/
QList<KoFilterEffect*> filterEffects() const;
/**
* Inserts a new filter at the given position in the filter list.
* @param index the list index to insert the new filter at
* @param filter the new filter to insert
*/
void insertFilterEffect(int index, KoFilterEffect *filter);
/**
* Appends a new filter at the end of the filter list.
* @param filter the new filter to append
*/
void appendFilterEffect(KoFilterEffect *filter);
/**
* Removes the filter with the given index from the filter list.
* @param index the index of the filter to remove
*/
void removeFilterEffect(int index);
/// Sets the clipping rectangle used for this filter in bounding box units
void setClipRect(const QRectF &clipRect);
/// Returns the clipping rectangle used for this filter in bounding box units
QRectF clipRect() const;
/// Returns the clipping rectangle for the given bounding rect
QRectF clipRectForBoundingRect(const QRectF &boundingRect) const;
/// Increase reference counter
void addUser();
/// Decrease reference counter
bool removeUser();
/// Return reference counter
int useCount() const;
private:
class Private;
Private * const d;
};
#endif // KOFILTEREFFECTSTACK
......@@ -45,7 +45,7 @@
#include "KoEventAction.h"
#include "KoEventActionRegistry.h"
#include "KoOdfWorkaround.h"
#include "KoFilterEffect.h"
#include "KoFilterEffectStack.h"
#include <KoXmlReader.h>
#include <KoXmlWriter.h>
......@@ -77,6 +77,7 @@ KoShapePrivate::KoShapePrivate(KoShape *shape)
border(0),
q(shape),
shadow(0),
filterEffectStack(0),
zIndex(0),
visible(true),
printable(true),
......@@ -108,8 +109,9 @@ KoShapePrivate::~KoShapePrivate()
delete shadow;
if (fill && ! fill->removeUser())
delete fill;
if (filterEffectStack && ! filterEffectStack->removeUser())
delete filterEffectStack;
qDeleteAll(eventActions);
qDeleteAll(filterEffects);
}
void KoShapePrivate::shapeChanged(KoShape::ChangeType type)
......@@ -1387,20 +1389,20 @@ void KoShape::removeAdditionalStyleAttribute(const char * name)
d->additionalStyleAttributes.remove(name);
}
QList<KoFilterEffect*> KoShape::filterEffectStack() const
KoFilterEffectStack * KoShape::filterEffectStack() const
{
Q_D(const KoShape);
return d->filterEffects;
return d->filterEffectStack;
}
void KoShape::insertFilterEffect(int index, KoFilterEffect * filter)
void KoShape::setFilterEffectStack(KoFilterEffectStack * filterEffectStack)
{
Q_D(KoShape);
d->filterEffects.insert(index, filter);
}
void KoShape::removeFilterEffect(int index)
{
Q_D(KoShape);
d->filterEffects.removeAt(index);
if (d->filterEffectStack)
d->filterEffectStack->removeUser();
d->filterEffectStack = filterEffectStack;
if (d->filterEffectStack) {
d->filterEffectStack->addUser();
}
notifyChanged();
}
......@@ -58,7 +58,7 @@ class KoDataCenter;
class KoShapeShadow;
class KoEventAction;
class KoShapePrivate;
class KoFilterEffect;
class KoFilterEffectStack;
/**
*
......@@ -797,25 +797,15 @@ public:
void removeAdditionalStyleAttribute(const char * name);
/**
* The first filter of the list is the first to be applied.
* Returns the filter effect stack of the shape
*
* @return the list of filter effects applied on the shape when rendering.
*/
QList<KoFilterEffect*> filterEffectStack() const;
/**
* Inserts a new filter at the given position in the filter list.
* @param index the list index to insert the new filter at
* @param filter the new filter to insert
*/
void insertFilterEffect(int index, KoFilterEffect * filter);
/**
* Removes the filter with the given index from the filter list.
* @param index the index of the filter to remove
*/
void removeFilterEffect(int index);
KoFilterEffectStack * filterEffectStack() const;
/// Sets the new filter effect stack, removing the old one
void setFilterEffectStack(KoFilterEffectStack * filterEffectStack);
protected:
/// constructor
KoShape(KoShapePrivate &);
......
......@@ -34,6 +34,7 @@
#include "KoShapeShadow.h"
#include "KoShapeLayer.h"
#include "KoFilterEffect.h"
#include "KoFilterEffectStack.h"
#include <KoRTree.h>
......@@ -222,7 +223,7 @@ void KoShapeManager::paintShape(KoShape * shape, QPainter &painter, const KoView
shape->shadow()->paint(shape, painter, converter);
painter.restore();
}
if(shape->filterEffectStack().empty()) {
if(!shape->filterEffectStack() || shape->filterEffectStack()->filterEffects().isEmpty()) {
painter.save();
shape->paint(painter, converter);
painter.restore();
......@@ -235,10 +236,8 @@ void KoShapeManager::paintShape(KoShape * shape, QPainter &painter, const KoView
// There are filter effets, then we need to prerender the shape on an image, to filter it
QRectF shapeBound(QPointF(), shape->size());
// First step, compute the rectangle used for the image
QRectF clipRegion;
foreach(KoFilterEffect* filterEffect, shape->filterEffectStack()) {
clipRegion |= filterEffect->clipRectForBoundingRect(shapeBound);
}
QRectF clipRegion = shape->filterEffectStack()->clipRectForBoundingRect(shapeBound);
// convert clip region to view coordinates
QRectF zoomedClipRegion = converter.documentToView(clipRegion);
// determine the offset of the clipping rect from the shapes origin
QPointF clippingOffset = zoomedClipRegion.topLeft();
......@@ -274,8 +273,9 @@ void KoShapeManager::paintShape(KoShape * shape, QPainter &painter, const KoView
imageBuffers.insert(QString(), sourceGraphic);
imageBuffers.insert("SourceAlpha", sourceAlpha);
QList<KoFilterEffect*> filterEffects = shape->filterEffectStack()->filterEffects();
// Filter
foreach(KoFilterEffect* filterEffect, shape->filterEffectStack()) {
foreach(KoFilterEffect* filterEffect, filterEffects) {
QRectF filterRegion = filterEffect->filterRectForBoundingRect(clipRegion);
filterRegion = converter.documentToView(filterRegion);
QPointF filterOffset = filterRegion.topLeft()-2*clippingOffset;
......@@ -302,7 +302,7 @@ void KoShapeManager::paintShape(KoShape * shape, QPainter &painter, const KoView
}
}
KoFilterEffect * lastEffect = shape->filterEffectStack().last();
KoFilterEffect * lastEffect = filterEffects.last();
// Paint the result
painter.save();
......
......@@ -55,7 +55,7 @@ public:
QMap<QByteArray, QString> additionalAttributes;
QMap<QByteArray, QString> additionalStyleAttributes;
QList<KoEventAction *> eventActions; ///< list of event actions the shape has
QList<KoFilterEffect*> filterEffects; ///< list of filter effects applied to the shape
KoFilterEffectStack *filterEffectStack; ///< stack of filter effects applied to the shape
int zIndex : 14; // should be enough ;)
int visible : 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment