Commit 5d199f83 authored by Ivan Yossi's avatar Ivan Yossi 👌

Allow loading multidimentional Gih images

Support all documented features of the format.
parent 517ad4ac
......@@ -57,7 +57,8 @@ public:
}
BrushType* currentBrush(const KisPaintInformation& info) {
return !m_brushes.isEmpty() ? m_brushes.at(chooseNextBrush(info)) : 0;
Q_UNUSED(info);
return !m_brushes.isEmpty() ? m_brushes.at(currentBrushIndex()) : 0;
}
int brushIndex(const KisPaintInformation& info) {
......@@ -155,15 +156,27 @@ protected:
m_brushes.append(brush);
}
int sizeBrush() {
return m_brushes.size();
}
/**
* Returns the index of the brush that corresponds to the current
* Returns the index of the next brush that corresponds to the current
* values of \p info. This method is called *before* the dab is
* actually painted.
*
*/
virtual int chooseNextBrush(const KisPaintInformation& info) = 0;
/**
* Returns the current index of the brush
* This method is called *before* the dab is
* actually painted.
*
* The method is const, so no internal counters of the brush should
* change during its execution
*/
virtual int chooseNextBrush(const KisPaintInformation& info) = 0;
virtual int currentBrushIndex() = 0;
/**
* Updates internal counters of the brush *after* a dab has been
......
......@@ -25,7 +25,8 @@ class KisImageBrushesPipe : public KisBrushesPipe<KisGbrBrush>
{
public:
KisImageBrushesPipe()
: m_isInitialized(false)
: m_currentBrushIndex(0)
, m_isInitialized(false)
{
}
......@@ -46,6 +47,8 @@ protected:
const KisPaintInformation& info) {
qreal angle;
qreal velocity;
qreal capSpeed = 3;
switch (mode) {
case KisParasite::Constant:
......@@ -56,8 +59,8 @@ protected:
index = static_cast<int>(info.pressure() * (rank - 1) + 0.5);
break;
case KisParasite::Angular:
// + m_d->PI_2 to be compatible with the gimp
angle = info.drawingAngle() + M_PI_2;
// + M_PI_2 + M_PI_4 to be compatible with the gimp
angle = info.drawingAngle() + M_PI_2 + M_PI_4;
angle = normalizeAngle(angle);
index = static_cast<int>(angle / (2.0 * M_PI) * rank);
......@@ -68,6 +71,16 @@ protected:
case KisParasite::TiltY:
index = qRound(info.yTilt() / 2.0 * rank) + rank / 2;
break;
case KisParasite::Velocity:
// log is slow, but allows for nicer dab transition
velocity = log(info.drawingSpeed() + 1);
if (velocity > capSpeed) {
velocity = capSpeed;
}
velocity /= capSpeed;
velocity *= (rank - 1) + 0.5;
index = qRound(velocity);
break;
default:
warnImage << "Parasite" << mode << "is not implemented";
index = 0;
......@@ -87,13 +100,14 @@ protected:
index = (seqNo >= 0 ? seqNo : (index + 1)) % rank;
break;
case KisParasite::Random:
index = info.randomSource()->generate(0, rank);
index = info.randomSource()->generate(0, rank-1);
break;
case KisParasite::Pressure:
case KisParasite::Angular:
break;
case KisParasite::TiltX:
case KisParasite::TiltY:
case KisParasite::Velocity:
break;
default:
warnImage << "Parasite" << mode << "is not implemented";
......@@ -125,10 +139,15 @@ protected:
brushIndex += m_parasite.brushesCount[i] * index;
}
brushIndex %= m_brushes.size();
brushIndex %= (quint32)m_brushes.size();
m_currentBrushIndex = brushIndex;
return brushIndex;
}
int currentBrushIndex() override {
return m_currentBrushIndex;
}
void updateBrushIndexes(const KisPaintInformation& info, int seqNo) override {
for (int i = 0; i < m_parasite.dim; i++) {
m_parasite.index[i] = selectPost(m_parasite.selection[i],
......@@ -141,6 +160,7 @@ protected:
public:
using KisBrushesPipe<KisGbrBrush>::addBrush;
using KisBrushesPipe<KisGbrBrush>::sizeBrush;
void setParasite(const KisPipeBrushParasite& parasite) {
m_parasite = parasite;
......@@ -177,6 +197,7 @@ public:
private:
KisPipeBrushParasite m_parasite;
int m_currentBrushIndex;
bool m_isInitialized;
};
......@@ -289,7 +310,7 @@ bool KisImagePipeBrush::initFromData(const QByteArray &data)
m_d->brushesPipe.setParasite(parasite);
i++; // Skip past the second newline
for (int brushIndex = 0;
for (int brushIndex = m_d->brushesPipe.sizeBrush();
brushIndex < numOfBrushes && i < data.size(); brushIndex++) {
KisGbrBrush* brush = new KisGbrBrush(name() + '_' + QString().setNum(brushIndex),
......@@ -325,7 +346,7 @@ bool KisImagePipeBrush::saveToDevice(QIODevice* dev) const
char const* name = utf8Name.data();
int len = qstrlen(name);
if (m_d->brushesPipe.parasite().dim != 1) {
if (m_d->brushesPipe.parasite().dim >= KisPipeBrushParasite::MaxDim) {
warnImage << "Save to file for pipe brushes with dim != not yet supported!";
return false;
}
......
......@@ -62,6 +62,9 @@ KisPipeBrushParasite::KisPipeBrushParasite(const QString& source)
else if (selectionMode == "ytilt") {
selection[selIndex] = KisParasite::TiltY;
}
else if (selectionMode == "velocity") {
selection[selIndex] = KisParasite::Velocity;
}
else {
selection[selIndex] = KisParasite::Constant;
}
......
......@@ -140,6 +140,11 @@ protected:
Q_UNUSED(info);
return m_currentBrushIndex;
}
int currentBrushIndex() override {
return m_currentBrushIndex;
}
void updateBrushIndexes(const KisPaintInformation& info, int seqNo) override {
Q_UNUSED(info);
......
......@@ -133,6 +133,7 @@ KisImportExportErrorCode KisBrushExport::convert(KisDocument *document, QIODevic
case 2: modes.push_back(KisParasite::Incremental); break;
case 3: modes.push_back(KisParasite::Pressure); break;
case 4: modes.push_back(KisParasite::Angular); break;
case 5: modes.push_back(KisParasite::Velocity); break;
default: modes.push_back(KisParasite::Incremental);
}
......
......@@ -161,6 +161,11 @@
<string>Angular</string>
</property>
</item>
<item>
<property name="text">
<string>Velocity</string>
</property>
</item>
</widget>
</item>
</layout>
......
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