Commit d8ee0554 authored by Halla Rempt's avatar Halla Rempt
Browse files

Merge origin/calligra-resource_md5-rempt into master

This makes it possible to id resources by an md5 sum.

It also prepares for deferred resource loading by splitting
the image() method of some resources into the image used
for icons, and the actual resource data used as e.g. brush
or pattern.

Squashed commit of the following:

commit aaf181254f8fe3800c589687566e6036ed100f5d
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu May 1 14:06:57 2014 +0200

    Make saving/loading tags work again

    Tags now work primarily with md5, then with the filename without the
    path. In some places, Krita was already adapted to work with just the
    file names, in others not yet.

    Also: reinstate the KoResourceTaggingTest and make it actually work
    without depending on a given user setting.

commit 4cdc4e1e11a8ae550e1104108d929d4052ba3411
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu May 1 11:31:49 2014 +0200

    Add methods to get a resource by filename or md5

    The filename is stripped of the path; the tagstore stores the full
    path for compatibility with gimp, but we won't find any resource by
    using the full path since we use only the filename.

commit ecfbdfe1ee4c65ac3254ca63f2097d905e690a47
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu May 1 10:29:01 2014 +0200

    Add some debug

commit ea1738f1497f6e5252b860cc2ed4d31f8e5d03b0
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu May 1 10:10:41 2014 +0200

    Try to find the tagged resource using both md5 and filename

commit 971b55530f60561b16b76dd741e9b2657efe1a96
Merge: e760836 e0a2654
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu May 1 09:13:26 2014 +0200

    Merge branch 'master' into calligra-resource_md5-rempt

commit e760836a20c25ff8d6be71d01e00b5179164db99
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Wed Apr 30 20:18:14 2014 +0200

    Use the actual resource in the tagging database

    (intermediate, needs fixing)

commit 39a780fbba3c5a736245ba8b34408a5a2927321d
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Wed Apr 30 11:47:25 2014 +0200

    Remove unused conversion method

    The tag store now keeps pointers to the resources

commit c6b23d8eb01c18d9aa3a083345c03b89771c4259
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Wed Apr 30 10:41:38 2014 +0200

    Remove the resourcetagging test altogether

    It was broken by design because it depends on the tag store in the local
    user's .kde directory.

commit 5ffd7c7f0bdb8f5c0e2a3ddc67445fddb0b2276d
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Wed Apr 30 10:31:43 2014 +0200

    Add hash function using the md5 sum for KoResource

commit edceb9e3e59ff887333d37ac68b136ab1a53373b
Merge: b502624 93475d4
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Tue Apr 29 11:49:31 2014 +0200

    Merge remote-tracking branch 'origin/master' into calligra-resource_md5-rempt

commit b502624e453a64d880ed346977b67a3807128228
Merge: fcc7adf 6871ea1
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Tue Apr 29 10:11:36 2014 +0200

    Merge branch 'master' into calligra-resource_md5-rempt

commit fcc7adf61a26c570b86c1aad847dca8ebae83f61
Merge: 7e892ab 6942088
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Mon Apr 28 09:12:39 2014 +0200

    Merge branch 'master' into calligra-resource_md5-rempt

commit 7e892ab6ee5437253ad6d37a66563e767f5b05f8
Merge: 931fc5e aeeef4b
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Fri Apr 25 09:07:59 2014 +0200

    Merge branch 'master' into calligra-resource_md5-rempt

    Conflicts:
    	libs/widgets/KoResourceFiltering.cpp

commit 931fc5ee1bd82db5d64d9371e87e7adcd16fd9cf
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Fri Apr 18 20:10:53 2014 +0200

    Warnings--

commit 9e0be15ca6fdcf5c54986cd4ed98a0a27d1eff2a
Merge: 9044045 a51c97c
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Wed Apr 16 10:29:03 2014 +0200

    Merge branch 'master' into calligra-resource_md5-rempt

    Conflicts:
    	libs/widgets/KoFileDialog.cpp

commit 9044045b5a606ef040c70af871e5bfc5ac7586a0
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Wed Apr 16 09:38:10 2014 +0200

    Move to using md5 in the tagstore

commit 050007c30216534863a7b9d5a633d1291fb50ada
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Tue Apr 15 15:52:43 2014 +0200

    more tagObject -> tagStore renaming

commit ffd1a0cc68d75d9b87948eef1dd846ac14b4f1a1
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Tue Apr 15 15:44:10 2014 +0200

    Also store the md5sum in the tag repository.

commit 7a319b1234fe6d42abf5a4c625d6e0a25724ac87
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Tue Apr 15 15:13:07 2014 +0200

    skip resources without md5 sum

commit 3dba36cd21e70f8e39a7f38d15fe33aee7ca8ae7
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Tue Apr 15 14:52:26 2014 +0200

    Calculate MD5 sum as soon as possible

commit 13838d84e83f54ddac31954975d14dbf1b7b3891
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Tue Apr 15 14:26:38 2014 +0200

    initialize KoAbstractGradient properly

commit 855d18073deb68ac816ced0d7b7c7a03de7f4299
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Tue Apr 15 12:52:35 2014 +0200

    index resources also by md5

commit 0481ea8b6fbc2e88bf83ed428de7fdb5de2881a2
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Tue Apr 15 11:33:31 2014 +0200

    Add dummy implementation for md5 summing resource bundles

commit 9870cdc3c30cbf072ddb2d91bfee36c7baba59b1
Merge: f4bf3ac ff5e141
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Tue Apr 15 11:20:52 2014 +0200

    Merge branch 'master' into calligra-resource_md5-rempt

    Conflicts:
    	krita/plugins/paintops/resourcemanager/KoResourceBundle.cpp
    	krita/plugins/paintops/resourcemanager/KoResourceBundle.h

commit f4bf3aca5155df5f83d72c4de0febc48aa7f8332
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Tue Apr 15 11:19:04 2014 +0200

    Rename tabObject to tagStore

commit 32d353d1e695b4ca1edb569cc927599fea2137ec
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Tue Apr 15 11:18:41 2014 +0200

    Tagstore: Read md5 sum if present

commit 8d1e900544671464054dc8c5df3e77e5fedc2642
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Tue Apr 15 11:01:53 2014 +0200

    Add md5 sum calculation for the various brush tip types

commit 68461e8135d570982f072e7f22e7febf484cb34a
Merge: 4faa11b 516b07d
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Tue Apr 15 10:08:21 2014 +0200

    Merge branch 'master' into calligra-resource_md5-rempt

commit 4faa11bab8b6dcb7a56eae19ed8d26f4b0839d41
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Mon Apr 14 12:51:04 2014 +0200

    Remove protected m_image variable from KisBrush

commit e2a4590fd15e5dcf493f5e5c78269579e74118c2
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Mon Apr 14 11:49:38 2014 +0200

    Cleanup KisBrush implementations

    The empty saveToDevice implementations aren't necessary at all, it's
    not part of the KisBrush api.

commit 1c15374839c3b438a24736fee18ba0ce69f0c432
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Mon Apr 14 11:29:25 2014 +0200

    Fix setting the icon for png patterns

commit 9b51e01492d4e6349b1b6412771fe1914ed9c23a
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Mon Apr 14 11:00:08 2014 +0200

    Show the gradient previews again.

commit 8733300e85057506614346ee9bb7fadee13c1df2
Merge: be373dc b7b85ae
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Mon Apr 14 10:13:53 2014 +0200

    Merge remote-tracking branch 'origin/master' into calligra-resource_md5-rempt

commit be373dcd4ac8ca6896cf31f7e3d15b8717ec00c9
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Fri Apr 11 15:49:47 2014 +0200

    Start implementing the md5sum generators for all kinds of resources.

commit d924d5ef13b2c790064606cb296ba9fafb370246
Merge: 2e08dfe c93b2d5
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Fri Apr 11 11:46:07 2014 +0200

    Merge branch 'master' into calligra-resource_md5-rempt

commit 2e08dfe57ccbfff797b42267c63d0a9f84d36d27
Merge: 50a8ceb 1b3508d
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Fri Apr 11 11:33:00 2014 +0200

    Merge branch 'master' into calligra-resource_md5-rempt

commit 50a8ceb8a2954cec91d15e5d3144d92592f2a493
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Fri Apr 11 11:21:54 2014 +0200

    Delete some more d-pointers

commit 7e731d3dbcf7b81ccd5006f92a9daf19b47d936c
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Fri Apr 11 10:22:39 2014 +0200

    remove obsolete comment. save _is_ implemented.

commit 72562746d80748c410d444b4242e5fa14efbc329
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Fri Apr 11 10:07:20 2014 +0200

    Move the KoCachedGradient into KisGradientPainter

    It's only used in one place, so let's not clutter up pigment with it.

    (Also, it hasn't got a d-pointer to leak anymore.)

commit f2a68ee8cf5fc4a74aabf6013cfd6832430b80ac
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu Apr 10 16:38:27 2014 +0200

    remove unused include

commit bfdd7d822b6493bb2f7e03e1e33c95d5762d7764
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu Apr 10 16:34:35 2014 +0200

    Remove image() overload from KoResourceBundle

commit d35d3a54d0c42dd9a28ed0dd4a283c9c06dc6ed6
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu Apr 10 16:33:24 2014 +0200

    fix coding style: m_ prefix for class members

commit 20cc841932b6a6edef3ba413e833fcbe0c862b70
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu Apr 10 16:31:31 2014 +0200

    Remove image() overload from the mypaint brush resource

commit 7930fa780c9e3bfaa66138abbc5a1205dc761bf6
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu Apr 10 16:27:29 2014 +0200

    Remove useless image() override from the taskset resource

commit 8967f4d072f2ab194bb154b8ca70be885bddd4ef
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu Apr 10 16:26:21 2014 +0200

    Move the md5sum functionality from KoPattern to KoResource

    So we can start implementing it in all resources

commit f8ed4ac3777f7044592778cae96cd907adbb4942
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu Apr 10 16:17:34 2014 +0200

    Fix warning

commit 02ede1c630cb59a37736e6981b29e87d40e5de6f
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu Apr 10 15:50:53 2014 +0200

    Coding style: remove superfluous semicolon

commit 9dacc59e326184e673f3e924cf1661c4cbc10161
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu Apr 10 14:24:06 2014 +0200

    Add KisBrush::brushTipImage() to access the image to paint with

commit b0ef67a458ce2f7b6698f244db6dd21b3673f0b3
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu Apr 10 13:52:31 2014 +0200

    rename KisBrush::setImage to KisBrush::setBrushTipImage

    Since that's what it does -- it sets the QImage that we'll use as a
    mask when painting.

commit 7cefc667c5ed6bdbe4b66485bcb0d8147ea67ba3
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu Apr 10 12:37:12 2014 +0200

    Use KisPattern::pattern() where that is needed, and image() for icons

commit 83a32df13463bc419a93e5bf609e8bde1b25e035
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Thu Apr 10 12:29:12 2014 +0200

    Add a pattern() method to KoPattern to return the actual pattern

    Because using image() for both the thumbnail as well as the pattern
    is something we need to change if we want to make all resources lazy
    loading.
parent 51c45910
......@@ -26,6 +26,7 @@
#include <QImageReader>
#include <QDomDocument>
#include <QBuffer>
#include <QCryptographicHash>
#include <KoInputDevice.h>
......@@ -166,29 +167,14 @@ bool KisPaintOpPreset::save()
return false;
QString paintopid = m_d->settings->getString("paintop", "");
if (paintopid.isEmpty())
return false;
QImageWriter writer(filename(), "PNG");
QDomDocument doc;
QDomElement root = doc.createElement("Preset");
toXML(doc, root);
doc.appendChild(root);
writer.setText("version", "2.2");
writer.setText("preset", doc.toString());
QImage img;
if(m_d->image.isNull())
{
img = QImage(1,1, QImage::Format_RGB32);
} else {
img = m_d->image;
}
QFile f(filename());
f.open(QFile::WriteOnly);
return writer.write(img);
return save(&f);
}
void KisPaintOpPreset::toXML(QDomDocument& doc, QDomElement& elt) const
......@@ -243,3 +229,43 @@ void KisPaintOpPreset::setImage(QImage image)
m_d->image = image;
}
QByteArray KisPaintOpPreset::generateMD5() const
{
QByteArray ba;
QBuffer buf(&ba);
save(&buf);
if (!ba.isEmpty()) {
QCryptographicHash md5(QCryptographicHash::Md5);
md5.addData(ba);
return md5.result();
}
return ba;
}
bool KisPaintOpPreset::save(QIODevice *io) const
{
QImageWriter writer(io, "PNG");
QDomDocument doc;
QDomElement root = doc.createElement("Preset");
toXML(doc, root);
doc.appendChild(root);
writer.setText("version", "2.2");
writer.setText("preset", doc.toString());
QImage img;
if (m_d->image.isNull()) {
img = QImage(1,1, QImage::Format_RGB32);
}
else {
img = m_d->image;
}
return writer.write(img);
}
......@@ -77,8 +77,14 @@ public:
return ".kpp";
}
protected:
virtual QByteArray generateMD5() const;
private:
bool save(QIODevice *io) const;
struct Private;
Private * const m_d;
};
......
......@@ -41,7 +41,7 @@ public:
private:
friend class KisScanlineFillTest;
Q_DISABLE_COPY(KisScanlineFill);
Q_DISABLE_COPY(KisScanlineFill)
template <class T>
void processLine(KisFillInterval interval, const int rowIncrement, T &pixelPolicy);
......
......@@ -123,7 +123,7 @@ void KisFillPainter::fillRect(qint32 x1, qint32 y1, qint32 w, qint32 h, const Ko
if (h < 1) return;
KisPaintDeviceSP patternLayer = new KisPaintDevice(device()->compositionSourceColorSpace(), pattern->name());
patternLayer->convertFromQImage(pattern->image(), 0);
patternLayer->convertFromQImage(pattern->pattern(), 0);
fillRect(x1, y1, w, h, patternLayer, QRect(0, 0, pattern->width(), pattern->height()));
}
......
......@@ -22,7 +22,6 @@
#include <KoColorSpace.h>
#include <KoAbstractGradient.h>
#include <KoCachedGradient.h>
#include <KoProgressUpdater.h>
#include <KoUpdater.h>
......@@ -35,6 +34,64 @@
#include "kis_random_accessor_ng.h"
#include "kis_progress_update_helper.h"
class PIGMENTCMS_EXPORT CachedGradient : public KoAbstractGradient
{
public:
explicit CachedGradient(const KoAbstractGradient *gradient, qint32 steps, const KoColorSpace *cs)
: KoAbstractGradient(gradient->filename())
{
m_subject = gradient;
m_max = steps - 1;
m_colorSpace = cs;
m_black = KoColor(cs);
KoColor tmpColor(m_colorSpace);
for(qint32 i = 0; i < steps; i++) {
m_subject->colorAt(tmpColor, qreal(i) / m_max);
m_colors << tmpColor;
}
}
virtual ~CachedGradient() {}
/**
* Creates a QGradient from the gradient.
* The resulting QGradient might differ from original gradient
*/
virtual QGradient* toQGradient() const
{
return m_subject->toQGradient();
}
/// gets the color data at position 0 <= t <= 1
const quint8 *cachedAt(qreal t) const
{
qint32 tInt = t * m_max + 0.5;
if (m_colors.size() > tInt) {
return m_colors[tInt].data();
}
else {
return m_black.data();
}
}
void setColorSpace(KoColorSpace* colorSpace) { m_colorSpace = colorSpace; }
const KoColorSpace * colorSpace() const { return m_colorSpace; }
virtual QByteArray generateMD5() const { return QByteArray(); }
private:
const KoAbstractGradient *m_subject;
const KoColorSpace *m_colorSpace;
qint32 m_max;
QVector<KoColor> m_colors;
KoColor m_black;
};
namespace
{
......@@ -550,7 +607,7 @@ bool KisGradientPainter::paintGradient(const QPointF& gradientVectorStart,
KisHLineIteratorSP hit = dev->createHLineIteratorNG(startx, starty, width);
KisProgressUpdateHelper progressHelper(progressUpdater(), 100, height);
KoCachedGradient cachedGradient(gradient(), qMax(endy-starty, endx - startx), colorSpace);
CachedGradient cachedGradient(gradient(), qMax(endy-starty, endx - startx), colorSpace);
for (int y = starty; y <= endy; y++) {
for (int x = startx; x <= endx; x++) {
......
......@@ -46,10 +46,10 @@ void KoPatternTest::testRoundTripMd5()
qDebug() << "PAT Name:" << patPattern.name();
qDebug() << "PAT Filename:" << patPattern.filename();
qDebug() << pngPattern.image().format();
qDebug() << patPattern.image().format();
qDebug() << pngPattern.pattern().format();
qDebug() << patPattern.pattern().format();
QCOMPARE(pngPattern.image().convertToFormat(QImage::Format_ARGB32), patPattern.image().convertToFormat(QImage::Format_ARGB32));
QCOMPARE(pngPattern.pattern().convertToFormat(QImage::Format_ARGB32), patPattern.pattern().convertToFormat(QImage::Format_ARGB32));
QCOMPARE(pngPattern.md5(), patPattern.md5());
}
......
......@@ -20,6 +20,9 @@
#include <QFile>
#include <QDomDocument>
#include <QTextStream>
#include <QBuffer>
#include <QByteArray>
#include <QCryptographicHash>
#define TASKSET_VERSION 1
......@@ -38,20 +41,7 @@ bool TasksetResource::save()
QFile file(filename());
file.open(QIODevice::WriteOnly);
QDomDocument doc;
QDomElement root = doc.createElement("Taskset");
root.setAttribute("name", name() );
root.setAttribute("version", TASKSET_VERSION);
foreach(const QString& action, m_actions) {
QDomElement element = doc.createElement("action");
element.appendChild(doc.createTextNode(action));
root.appendChild(element);
}
doc.appendChild(root);
QTextStream textStream(&file);
doc.save(textStream, 4);
save(&file);
file.close();
return true;
}
......@@ -87,11 +77,6 @@ bool TasksetResource::load()
return true;
}
QImage TasksetResource::image() const
{
return KoResource::image();
}
QString TasksetResource::defaultFileExtension() const
{
return QString(".kts");
......@@ -107,4 +92,38 @@ QStringList TasksetResource::actionList()
return m_actions;
}
QByteArray TasksetResource::generateMD5() const
{
QByteArray ba;
QBuffer buf(&ba);
save(&buf);
if (!ba.isEmpty()) {
QCryptographicHash md5(QCryptographicHash::Md5);
md5.addData(ba);
return md5.result();
}
return ba;
}
void TasksetResource::save(QIODevice *io) const
{
QDomDocument doc;
QDomElement root = doc.createElement("Taskset");
root.setAttribute("name", name() );
root.setAttribute("version", TASKSET_VERSION);
foreach(const QString& action, m_actions) {
QDomElement element = doc.createElement("action");
element.appendChild(doc.createTextNode(action));
root.appendChild(element);
}
doc.appendChild(root);
QTextStream textStream(io);
doc.save(textStream, 4);
}
......@@ -32,13 +32,14 @@ public:
virtual bool save();
virtual bool load();
virtual QImage image() const;
virtual QString defaultFileExtension() const;
void setActionList(const QStringList actions);
QStringList actionList();
protected:
virtual QByteArray generateMD5() const;
private:
void save(QIODevice *io) const;
QStringList m_actions;
};
......
......@@ -24,6 +24,9 @@
#include <QFile>
#include <QImage>
#include <QPoint>
#include <QByteArray>
#include <QBuffer>
#include <QCryptographicHash>
#include <kis_debug.h>
#include <klocale.h>
......@@ -37,8 +40,9 @@
#define DEFAULT_SPACING 0.25
KisAbrBrush::KisAbrBrush(const QString& filename)
KisAbrBrush::KisAbrBrush(const QString& filename, const QByteArray &parentMD5)
: KisBrush(filename)
, m_parentMD5(parentMD5)
{
setBrushType(INVALID);
setHasColor(false);
......@@ -52,23 +56,17 @@ bool KisAbrBrush::load()
bool KisAbrBrush::save()
{
//Return true, otherwise the brush won't be add to the
//Return true, otherwise the brush won't be added to the
//resource server if the brush is loaded via import
return true;
}
bool KisAbrBrush::saveToDevice(QIODevice* dev) const
{
Q_UNUSED(dev);
return false;
}
void KisAbrBrush::setImage(const QImage& image)
void KisAbrBrush::setBrushTipImage(const QImage& image)
{
setValid(true);
setBrushType(MASK);
setHasColor(false);
KisBrush::setImage(image);
KisBrush::setBrushTipImage(image);
}
void KisAbrBrush::toXML(QDomDocument& d, QDomElement& e) const
......@@ -82,3 +80,22 @@ QString KisAbrBrush::defaultFileExtension() const
{
return QString();
}
QByteArray KisAbrBrush::generateMD5() const
{
if (!brushTipImage().isNull()) {
#if QT_VERSION >= 0x040700
QByteArray ba = QByteArray::fromRawData((const char*)brushTipImage().constBits(), brushTipImage().byteCount());
#else
QByteArray ba = QByteArray::fromRawData((const char*)brushTipImage().bits(), brushTipImage().byteCount());
#endif
QCryptographicHash md5(QCryptographicHash::Md5);
md5.addData(ba);
md5.addData(m_parentMD5);
return md5.result();
}
return QByteArray();
}
......@@ -44,17 +44,12 @@ class BRUSH_EXPORT KisAbrBrush : public KisBrush
public:
/// Construct brush to load filename later as brush
KisAbrBrush(const QString& filename);
KisAbrBrush(const QString& filename, const QByteArray &parentMD5);
virtual bool load();
virtual bool save();
/**
* save the content of this brush to an IO device
*/
virtual bool saveToDevice(QIODevice* dev) const;
/**
* @return default file extension for saving the brush
*/
......@@ -64,12 +59,13 @@ protected:
friend class KisAbrBrushCollection;
virtual void setImage(const QImage& image);
virtual QByteArray generateMD5() const;
virtual void setBrushTipImage(const QImage& image);
void toXML(QDomDocument& d, QDomElement& e) const;
private:
QByteArray m_parentMD5;
};
......
......@@ -31,6 +31,8 @@
#include <QByteArray>
#include <QDebug>
#include <QString>
#include <QBuffer>
#include <QCryptographicHash>
#include <kis_debug.h>
#include <klocale.h>
......@@ -360,9 +362,9 @@ quint32 KisAbrBrushCollection::abr_brush_load_v6(QDataStream & abr, AbrInfo *abr
// filename - filename of the file , e.g. test.abr
// name - test_number_of_the_brush, e.g test_1, test_2
KisAbrBrush* abrBrush = new KisAbrBrush(name);
KisAbrBrush* abrBrush = new KisAbrBrush(name, md5());
abrBrush->setImage(convertToQImage(buffer, width, height));
abrBrush->setBrushTipImage(convertToQImage(buffer, width, height));
// XXX: call extra setters on abrBrush for other options of ABR brushes
abrBrush->setValid(true);
abrBrush->setName(name);
......@@ -450,8 +452,8 @@ qint32 KisAbrBrushCollection::abr_brush_load_v12(QDataStream & abr, AbrInfo *abr
rle_decode(abr, buffer, height);
}
KisAbrBrush* abrBrush = new KisAbrBrush(name);
abrBrush->setImage(convertToQImage(buffer, width, height));
KisAbrBrush* abrBrush = new KisAbrBrush(name, md5());
abrBrush->setBrushTipImage(convertToQImage(buffer, width, height));
// XXX: call extra setters on abrBrush for other options of ABR brushes free (buffer);
abrBrush->setValid(true);
abrBrush->setName(name);
......@@ -504,7 +506,13 @@ bool KisAbrBrushCollection::load()
warnKrita << "Can't open file " << filename();
return false;
}
QDataStream abr(&file);
QByteArray ba = file.readAll();
QCryptographicHash md5(QCryptographicHash::Md5);
md5.addData(ba);
setMD5(md5.result());
QBuffer buf(&ba);
QDataStream abr(&buf);
if (!abr_read_content(abr, &abr_hdr)) {
warnKrita << "Error: cannot parse ABR file: " << filename();
......@@ -540,12 +548,6 @@ bool KisAbrBrushCollection::save()
return false;
}
bool KisAbrBrushCollection::saveToDevice(QIODevice* dev) const
{
Q_UNUSED(dev);
return false;
}
QImage KisAbrBrushCollection::image() const
{
return QImage();
......
......@@ -62,11 +62,6 @@ public:
*/
virtual QImage image() const;
/**
* save the content of this brush to an IO device
*/
virtual bool saveToDevice(QIODevice* dev) const;
/**
* @return default file extension for saving the brush
*/
......
......@@ -26,6 +26,9 @@
#include <QRect>
#include <QDomElement>
#include <QtConcurrentMap>
#include <QByteArray>
#include <QBuffer>
#include <QCryptographicHash>
#include <KoColor.h>
#include <KoColorSpace.h>
......@@ -68,6 +71,7 @@ KisAutoBrush::KisAutoBrush(KisMaskGenerator* as, qreal angle, qreal randomness,
setAngle(angle);
QImage image = createBrushPreview();
setImage(image);
setBrushTipImage(image);
}
KisAutoBrush::~KisAutoBrush()
......@@ -307,15 +311,32 @@ qreal KisAutoBrush::density() const
return d->density;
}
qreal KisAutoBrush::randomness() const
QByteArray KisAutoBrush::generateMD5() const
{
return d->randomness;
QByteArray ba;
if (!brushTipImage().isNull()) {
#if QT_VERSION >= 0x040700
ba = QByteArray::fromRawData((const char*)brushTipImage().constBits(), brushTipImage().byteCount());
#else
ba = QByteArray::fromRawData((const char*)brushTipImage().bits(), brushTipImage().byteCount());
#endif
}
QCryptographicHash md5(QCryptographicHash::Md5);
md5.addData(ba);
QDomDocument doc;
QDomElement root = doc.createElement("autobrush");
toXML(doc, root);
doc.appendChild(root);
md5.addData(doc.toByteArray());
return md5.result();
}
void KisAutoBrush::setImage(const QImage& image)
qreal KisAutoBrush::randomness() const
{
m_image = image;
clearBrushPyramid();
return d->randomness;
}
QPainterPath KisAutoBrush::outline() const
......
......@@ -54,10 +54,6 @@ public:
virtual QPainterPath outline() const;
protected:
virtual void setImage(const QImage& image);
public:
bool load() {
......@@ -68,11 +64,15 @@ public:
const KisMaskGenerator* maskGenerator() const;
qreal randomness() const;
qreal density() const;
private:
QImage createBrushPreview();
protected:
virtual QByteArray generateMD5() const;
private:
QImage createBrushPreview();
struct Private;
Private* const d;
};
......
......@@ -26,6 +26,9 @@
#include <QDomElement>
#include <QFile>
#include <QPoint>
#include <QFileInfo>
#include <QCryptographicHash>
#include <QBuffer>
#include <kis_debug.h>
#include <klocale.h>
......@@ -122,6 +125,8 @@ struct KisBrush::Private {
QPointF hotSpot;
mutable KisQImagePyramid *brushPyramid;