Commit 64da3218 authored by Tusooa Zhu's avatar Tusooa Zhu 🔼

Make KoClipMask, KoClipPath, KoImageData implicitly sharable

parent 799f21d8
......@@ -21,13 +21,15 @@
#include <QRectF>
#include <QTransform>
#include <QPainter>
#include <QSharedData>
#include <KoShape.h>
#include "kis_algebra_2d.h"
#include <KoViewConverter.h>
#include <KoShapePainter.h>
struct Q_DECL_HIDDEN KoClipMask::Private {
struct Q_DECL_HIDDEN KoClipMask::Private : public QSharedData
{
Private() {}
Private(const Private &rhs)
: coordinates(rhs.coordinates),
......@@ -35,6 +37,7 @@ struct Q_DECL_HIDDEN KoClipMask::Private {
maskRect(rhs.maskRect),
extraShapeTransform(rhs.extraShapeTransform)
{
// XXX: Use KisDescendent<KoShape> instead of this
Q_FOREACH (KoShape *shape, rhs.shapes) {
KoShape *clonedShape = shape->cloneShape();
KIS_ASSERT_RECOVER(clonedShape) { continue; }
......@@ -68,11 +71,6 @@ KoClipMask::~KoClipMask()
{
}
KoClipMask::KoClipMask(const KoClipMask &rhs)
: m_d(new Private(*rhs.m_d))
{
}
KoClipMask *KoClipMask::clone() const
{
return new KoClipMask(*this);
......
......@@ -22,8 +22,8 @@
#include "kritaflake_export.h"
#include <KoFlakeCoordinateSystem.h>
#include <QScopedPointer>
#include <QList>
#include <QSharedDataPointer>
class KoShape;
class QRectF;
......@@ -59,10 +59,8 @@ public:
void drawMask(QPainter *painter, KoShape *shape);
private:
KoClipMask(const KoClipMask &rhs);
struct Private;
const QScopedPointer<Private> m_d;
QSharedDataPointer<Private> m_d;
};
#endif // KOCLIPMASK_H
......@@ -26,6 +26,7 @@
#include <QPainterPath>
#include <QPainter>
#include <QVarLengthArray>
#include <QSharedData>
#include <kis_algebra_2d.h>
......@@ -44,7 +45,7 @@ QTransform scaleFromPercent(const QSizeF &size)
return QTransform().scale(w/1.0, h/1.0);
}
class Q_DECL_HIDDEN KoClipPath::Private
class Q_DECL_HIDDEN KoClipPath::Private : public QSharedData
{
public:
Private()
......@@ -121,11 +122,6 @@ KoClipPath::KoClipPath(QList<KoShape*> clipShapes, KoFlake::CoordinateSystem coo
d->compileClipPath();
}
KoClipPath::KoClipPath(const KoClipPath &rhs)
: d(new Private(*rhs.d))
{
}
KoClipPath::~KoClipPath()
{
}
......
......@@ -24,6 +24,7 @@
#include <QScopedPointer>
#include <QList>
#include <QSharedDataPointer>
#include <qnamespace.h>
#include <KoFlakeCoordinateSystem.h>
......@@ -82,12 +83,9 @@ public:
/// Applies the clipping to the given painter
static void applyClipping(KoShape *clippedShape, QPainter &painter, const KoViewConverter &converter);
private:
KoClipPath(const KoClipPath &rhs);
private:
class Private;
const QScopedPointer<Private> d;
QSharedDataPointer<Private> d;
};
#endif // KOCLIPPATH_H
......@@ -41,28 +41,22 @@
#define MAX_MEMORY_IMAGESIZE 90000
KoImageData::KoImageData()
: d(0)
{
}
KoImageData::KoImageData(const KoImageData &imageData)
: KoShapeUserData(),
d(imageData.d)
d(imageData.d)
{
if (d)
d->refCount.ref();
}
KoImageData::KoImageData(KoImageDataPrivate *priv)
: d(priv)
{
d->refCount.ref();
}
KoImageData::~KoImageData()
{
if (d && !d->refCount.deref())
delete d;
}
QPixmap KoImageData::pixmap(const QSize &size)
......@@ -104,10 +98,10 @@ QPixmap KoImageData::pixmap(const QSize &size)
}
if (d->dataStoreState == KoImageDataPrivate::StateImageLoaded) {
if (d->cleanCacheTimer.isActive())
d->cleanCacheTimer.stop();
if (d->cleanCacheTimer->isActive())
d->cleanCacheTimer->stop();
// schedule an auto-unload of the big QImage in a second.
d->cleanCacheTimer.start();
d->cleanCacheTimer->start();
}
}
return d->pixmap;
......@@ -138,6 +132,7 @@ QSizeF KoImageData::imageSize()
return d->imageSize;
}
// XXX: why const here?
QImage KoImageData::image() const
{
if (d->dataStoreState == KoImageDataPrivate::StateNotLoaded) {
......@@ -183,8 +178,7 @@ void KoImageData::setImage(const QImage &image, KoImageCollection *collection)
delete other;
} else {
if (d == 0) {
d = new KoImageDataPrivate(this);
d->refCount.ref();
d = new KoImageDataPrivate();
}
delete d->temporaryFile;
d->temporaryFile = 0;
......@@ -235,8 +229,7 @@ void KoImageData::setImage(const QString &url, KoStore *store, KoImageCollection
delete other;
} else {
if (d == 0) {
d = new KoImageDataPrivate(this);
d->refCount.ref();
d = new KoImageDataPrivate();
} else {
d->clear();
}
......@@ -290,8 +283,7 @@ void KoImageData::setImage(const QByteArray &imageData, KoImageCollection *colle
}
else {
if (d == 0) {
d = new KoImageDataPrivate(this);
d->refCount.ref();
d = new KoImageDataPrivate();
}
d->suffix = "png"; // good default for non-lossy storage.
......@@ -335,6 +327,11 @@ bool KoImageData::isValid() const
&& d->errorCode == Success;
}
KoImageDataPrivate *KoImageData::priv()
{
return d.data();
}
bool KoImageData::operator==(const KoImageData &other) const
{
return other.d == d;
......@@ -342,10 +339,6 @@ bool KoImageData::operator==(const KoImageData &other) const
KoImageData &KoImageData::operator=(const KoImageData &other)
{
if (other.d)
other.d->refCount.ref();
if (d && !d->refCount.deref())
delete d;
d = other.d;
return *this;
}
......
......@@ -25,6 +25,7 @@
#include <QSize>
#include <QMetaType>
#include <QSharedDataPointer>
#include <KoShapeUserData.h>
......@@ -112,7 +113,7 @@ public:
bool isValid() const;
/// \internal
KoImageDataPrivate *priv() { return d; }
KoImageDataPrivate *priv();
private:
friend class KoImageCollection;
......@@ -132,8 +133,7 @@ private:
private:
KoImageDataPrivate *d;
Q_PRIVATE_SLOT(d, void cleanupImageCache())
QSharedDataPointer<KoImageDataPrivate> d;
};
Q_DECLARE_METATYPE(KoImageData*)
......
......@@ -31,17 +31,16 @@
#include <FlakeDebug.h>
#include <QBuffer>
KoImageDataPrivate::KoImageDataPrivate(KoImageData *q)
KoImageDataPrivate::KoImageDataPrivate()
: collection(0),
errorCode(KoImageData::Success),
key(0),
refCount(0),
dataStoreState(StateEmpty),
temporaryFile(0)
{
cleanCacheTimer.setSingleShot(true);
cleanCacheTimer.setInterval(1000);
QObject::connect(&cleanCacheTimer, SIGNAL(timeout()), q, SLOT(cleanupImageCache()));
cleanCacheTimer->setSingleShot(true);
cleanCacheTimer->setInterval(1000);
QObject::connect(cleanCacheTimer.data(), &QTimer::timeout, [&]() { cleanupImageCache(); });
}
KoImageDataPrivate::~KoImageDataPrivate()
......
......@@ -29,16 +29,19 @@
#include <QPixmap>
#include <QTimer>
#include <QDir>
#include <QSharedData>
#include <KisNewOnCopy.h>
#include "KoImageData.h"
class KoImageCollection;
class QTemporaryFile;
class KoImageDataPrivate
class KoImageDataPrivate : public QSharedData
{
public:
explicit KoImageDataPrivate(KoImageData *q);
KoImageDataPrivate();
virtual ~KoImageDataPrivate();
/**
......@@ -70,18 +73,17 @@ public:
};
KoImageCollection *collection;
KoImageData::ErrorCode errorCode;
mutable KoImageData::ErrorCode errorCode;
QSizeF imageSize;
qint64 key;
QString suffix; // the suffix of the picture e.g. png TODO use a QByteArray ?
QTimer cleanCacheTimer;
QAtomicInt refCount;
KisNewOnCopy<QTimer> cleanCacheTimer;
// Image data store.
DataStoreState dataStoreState;
mutable DataStoreState dataStoreState;
QUrl imageLocation;
QImage image;
// XXX this should not be needed
mutable QImage image;
/// screen optimized cached version.
QPixmap pixmap;
......
......@@ -86,6 +86,7 @@ public:
QList<KoShape::ShapeChangeListener*> listeners;
KoShapeShadow * shadow; ///< the current shape shadow
KoBorder *border; ///< the current shape border
// XXX: change this to instance instead of pointer
QScopedPointer<KoClipPath> clipPath; ///< the current clip path
QScopedPointer<KoClipMask> clipMask; ///< the current clip mask
QMap<QString, QString> additionalAttributes;
......
/*
* Copyright (c) 2019 Tusooa Zhu <tusooa@vista.aero>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KIS_NEW_ON_COPY_H_
#define KIS_NEW_ON_COPY_H_
/**
* This class wraps around some type T that is not copiable.
* When the copy-constructor or assignment of KisNewOnCopy<T> is called,
* it default-constructs an instance of T.
*/
template<typename T>
class KisNewOnCopy
{
public:
KisNewOnCopy() : instance() {}
KisNewOnCopy(const KisNewOnCopy &) : instance() {}
// KisNewOnCopy &operator=(const KisNewOnCopy &) { return *this; }
const T *data() const { return &instance; }
const T *constData() { return &instance; }
T *data() { return &instance; }
const T *operator->() const { return &instance; }
T *operator->() { return &instance; }
private:
T instance;
};
#endif
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