Commit 17cf4787 authored by Dmitry Kazakov's avatar Dmitry Kazakov

Let KisAslLayerStyleSerializer load multiple layer style from a single file

parent 61bce229
......@@ -34,8 +34,8 @@ struct KRITAIMAGE_EXPORT KisLayerStyleSerializer {
typedef QSharedPointer<KisLayerStyleSerializer> KisLayerStyleSerializerSP;
class KRITAIMAGE_EXPORT KisLayerStyleSerializerFactory
: public KisExternalFactoryBase<KisLayerStyleSerializerSP, KisPSDLayerStyle*,
KisLayerStyleSerializerFactory>
: public KisExternalFactoryBase<KisLayerStyleSerializerSP, KisPSDLayerStyle*,
KisLayerStyleSerializerFactory>
{
public:
static KisLayerStyleSerializerFactory* instance();
......
......@@ -78,6 +78,8 @@ struct KisAslCallbackObjectCatcher::Private
MapHashPattern mapPattern;
MapHashPatternRef mapPatternRef;
MapHashGradient mapGradient;
ASLCallbackNewStyle newStyleCallback;
};
......@@ -179,6 +181,13 @@ void KisAslCallbackObjectCatcher::addGradient(const QString &path, const KoAbstr
passToCallback(path, m_d->mapGradient, value);
}
void KisAslCallbackObjectCatcher::newStyleStarted()
{
if (m_d->newStyleCallback) {
m_d->newStyleCallback();
}
}
/*****************************************************************/
/* Subscription methods */
/*****************************************************************/
......@@ -242,3 +251,8 @@ void KisAslCallbackObjectCatcher::subscribeGradient(const QString &path, ASLCall
{
m_d->mapGradient.insert(path, callback);
}
void KisAslCallbackObjectCatcher::subscribeNewStyleStarted(ASLCallbackNewStyle callback)
{
m_d->newStyleCallback = callback;
}
......@@ -36,6 +36,7 @@ typedef boost::function<void (const QString &, const QVector<QPointF> &)> ASLCal
typedef boost::function<void (const KoPattern *)> ASLCallbackPattern;
typedef boost::function<void (const QString &, const QString &)> ASLCallbackPatternRef;
typedef boost::function<void (const KoAbstractGradient *)> ASLCallbackGradient;
typedef boost::function<void ()> ASLCallbackNewStyle;
class KRITAIMAGE_EXPORT KisAslCallbackObjectCatcher : public KisAslObjectCatcher
......@@ -56,6 +57,7 @@ public:
void addPattern(const QString &path, const KoPattern *pattern);
void addPatternRef(const QString &path, const QString &patternUuid, const QString &patternName);
void addGradient(const QString &path, const KoAbstractGradient *gradient);
void newStyleStarted();
void subscribeDouble(const QString &path, ASLCallbackDouble callback);
void subscribeInteger(const QString &path, ASLCallbackInteger callback);
......@@ -69,6 +71,7 @@ public:
void subscribePattern(const QString &path, ASLCallbackPattern callback);
void subscribePatternRef(const QString &path, ASLCallbackPatternRef callback);
void subscribeGradient(const QString &path, ASLCallbackGradient callback);
void subscribeNewStyleStarted(ASLCallbackNewStyle callback);
private:
struct Private;
......
......@@ -25,6 +25,9 @@
class KisPSDLayerStyle;
class KoPattern;
#include "kis_asl_callback_object_catcher.h"
class KRITAIMAGE_EXPORT KisAslLayerStyleSerializer : public KisLayerStyleSerializer
{
......@@ -38,6 +41,9 @@ public:
void saveToDevice(QIODevice *device);
void readFromDevice(QIODevice *device);
QVector<KisPSDLayerStyleSP> styles() const;
void setStyles(const QVector<KisPSDLayerStyleSP> &styles);
private:
void registerPatternObject(const KoPattern *pattern);
......@@ -47,9 +53,14 @@ private:
QVector<KoPattern*> fetchAllPatterns(KisPSDLayerStyle *style);
void newStyleStarted();
void connectCatcherToStyle(KisPSDLayerStyle *style);
private:
KisPSDLayerStyle *m_style;
QHash<QString, KoPattern*> m_patternsStore;
KisAslCallbackObjectCatcher m_catcher;
QVector<KisPSDLayerStyleSP> m_stylesVector;
};
#endif /* __KIS_ASL_LAYER_STYLE_SERIALIZER_H */
......@@ -85,6 +85,11 @@ void KisAslObjectCatcher::addGradient(const QString &path, const KoAbstractGradi
qDebug() << "Unhandled:" << (m_arrayMode ? "[A]" : "[ ]") << path << "gradient" << value;
}
void KisAslObjectCatcher::newStyleStarted()
{
qDebug() << "Unhandled:" << "new style started";
}
void KisAslObjectCatcher::setArrayMode(bool value) {
m_arrayMode = value;
}
......
......@@ -48,6 +48,8 @@ public:
virtual void addPatternRef(const QString &path, const QString &patternUuid, const QString &patternName);
virtual void addGradient(const QString &path, const KoAbstractGradient *gradient);
virtual void newStyleStarted();
void setArrayMode(bool value);
protected:
bool m_arrayMode;
......
......@@ -630,22 +630,27 @@ QDomDocument readFileImpl(QIODevice *device)
quint32 numStyles = GARBAGE_VALUE_MARK;
SAFE_READ_EX(device, numStyles);
quint32 bytesToRead = GARBAGE_VALUE_MARK;
SAFE_READ_EX(device, bytesToRead);
for (int i = 0; i < (int)numStyles; i++) {
{
quint32 stylesFormatVersion = GARBAGE_VALUE_MARK;
SAFE_READ_SIGNATURE_EX(device, stylesFormatVersion, 16);
}
quint32 bytesToRead = GARBAGE_VALUE_MARK;
SAFE_READ_EX(device, bytesToRead);
readDescriptor(device, "", &root, &doc);
SETUP_OFFSET_VERIFIER(singleStyleSectionVerifier, device, bytesToRead, 0);
{
quint32 stylesFormatVersion = GARBAGE_VALUE_MARK;
SAFE_READ_SIGNATURE_EX(device, stylesFormatVersion, 16);
}
{
quint32 stylesFormatVersion = GARBAGE_VALUE_MARK;
SAFE_READ_SIGNATURE_EX(device, stylesFormatVersion, 16);
}
readDescriptor(device, "", &root, &doc);
readDescriptor(device, "", &root, &doc);
{
quint32 stylesFormatVersion = GARBAGE_VALUE_MARK;
SAFE_READ_SIGNATURE_EX(device, stylesFormatVersion, 16);
}
readDescriptor(device, "", &root, &doc);
}
return doc;
}
......
......@@ -124,6 +124,25 @@ void parseElement(const QDomElement &el, QIODevice *device, bool forceTypeInfo =
}
}
int calculateNumStyles(const QDomElement &root)
{
int numStyles = 0;
QDomNode child = root.firstChild();
while (!child.isNull()) {
QDomElement el = child.toElement();
QString classId = el.attribute("classId", "");
if (classId == "null") {
numStyles++;
}
child = child.nextSibling();
}
return numStyles;
}
void writeFileImpl(QIODevice *device, const QDomDocument &doc)
{
{
......@@ -150,27 +169,29 @@ void writeFileImpl(QIODevice *device, const QDomDocument &doc)
patternsWriter.writePatterns();
}
QDomElement root = doc.documentElement();
KIS_ASSERT_RECOVER_RETURN(root.tagName() == "asl");
int numStyles = calculateNumStyles(root);
KIS_ASSERT_RECOVER_RETURN(numStyles > 0);
{
// FIXME: real number of styles
quint32 numStyles = 1;
SAFE_WRITE_EX(device, numStyles);
quint32 numStylesTag = numStyles;
SAFE_WRITE_EX(device, numStylesTag);
}
QDomNode child = root.firstChild();
{
// the only style section
for (int styleIndex = 0; styleIndex < numStyles; styleIndex++) {
KisAslWriterUtils::OffsetStreamPusher<quint32> theOnlyStyleSizeField(device);
KIS_ASSERT_RECOVER_RETURN(!child.isNull());
{
quint32 stylesFormatVersion = 16;
SAFE_WRITE_EX(device, stylesFormatVersion);
}
QDomElement root = doc.documentElement();
KIS_ASSERT_RECOVER_RETURN(root.tagName() == "asl");
QDomNode child = root.firstChild();
while (!child.isNull()) {
QDomElement el = child.toElement();
QString key = el.attribute("key", "");
......@@ -188,10 +209,8 @@ void writeFileImpl(QIODevice *device, const QDomDocument &doc)
SAFE_WRITE_EX(device, stylesFormatVersion);
}
while (!child.isNull()) {
parseElement(child.toElement(), device);
child = child.nextSibling();
}
parseElement(child.toElement(), device);
child = child.nextSibling();
// ASL files' size should be 4-bytes aligned
const qint64 paddingSize = 4 - (device->pos() & 0x3);
......@@ -199,7 +218,6 @@ void writeFileImpl(QIODevice *device, const QDomDocument &doc)
QByteArray padding(paddingSize, '\0');
device->write(padding);
}
}
}
......
......@@ -227,7 +227,12 @@ bool tryParseDescriptor(const QDomElement &el,
{
bool retval = true;
if (classId == "RGBC") {
if (classId == "null") {
catcher.newStyleStarted();
// here we just notify that a new style is started, we haven't
// processed the whole block yet, so return false.
retval = false;
} else if (classId == "RGBC") {
catcher.addColor(path, parseRGBColorObject(el));
} else if (classId == "ShpC") {
......
......@@ -283,4 +283,47 @@ void KisAslLayerStyleSerializerTest::testWritingGlobalPatterns()
}
void KisAslLayerStyleSerializerTest::testReadMultipleStyles()
{
KisPSDLayerStyleSP style(new KisPSDLayerStyle());
QVector<KisPSDLayerStyleSP> styles;
{
KisAslLayerStyleSerializer s(0);
QString srcFileName(TestUtil::fetchDataFileLazy("multiple_styles.asl"));
QFile aslFile(srcFileName);
aslFile.open(QIODevice::ReadOnly);
s.readFromDevice(&aslFile);
styles = s.styles();
}
{
KisAslLayerStyleSerializer s(0);
QString dstFileName("multiple_styles_out.asl");
QFile aslFile(dstFileName);
aslFile.open(QIODevice::WriteOnly);
s.setStyles(styles);
s.saveToDevice(&aslFile);
}
{
KisAslLayerStyleSerializer s(0);
QString srcFileName("multiple_styles_out.asl");
QFile aslFile(srcFileName);
aslFile.open(QIODevice::ReadOnly);
s.readFromDevice(&aslFile);
styles = s.styles();
qDebug() << ppVar(styles.size());
}
}
QTEST_KDEMAIN(KisAslLayerStyleSerializerTest, GUI)
......@@ -28,6 +28,7 @@ private slots:
void testReading();
void testWriting();
void testWritingGlobalPatterns();
void testReadMultipleStyles();
};
#endif /* __KIS_ASL_LAYER_STYLE_SERIALIZER_TEST_H */
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