File indexing completed on 2024-05-19 04:24:16

0001 /*
0002  *  SPDX-FileCopyrightText: 2004 Boudewijn Rempt <boud@valdyas.org>
0003  *  SPDX-FileCopyrightText: 2005 Bart Coppens <kde@bartcoppens.be>
0004  *
0005  *  SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 #include "kis_pipebrush_parasite.h"
0008 
0009 KisPipeBrushParasite::KisPipeBrushParasite(const QString& source)
0010 {
0011     init();
0012     needsMovement = false;
0013     QRegExp basicSplitter(" ");
0014     QRegExp parasiteSplitter(":");
0015 
0016 #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
0017     QStringList parasites = source.split(basicSplitter, Qt::SkipEmptyParts);
0018 #else
0019     QStringList parasites = source.split(basicSplitter, QString::SkipEmptyParts);
0020 #endif
0021 
0022     for (int i = 0; i < parasites.count(); i++) {
0023 
0024 #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
0025         QStringList split = parasites.at(i).split(parasiteSplitter, Qt::SkipEmptyParts);
0026 #else
0027         QStringList split = parasites.at(i).split(parasiteSplitter, QString::SkipEmptyParts);
0028 #endif
0029 
0030         if (split.count() != 2) {
0031             warnImage << "Wrong count for this parasite key/value:" << parasites.at(i);
0032             continue;
0033         }
0034         QString index = split.at(0);
0035         if (index == "dim") {
0036             dim = (split.at(1)).toInt();
0037             if (dim < 1 || dim > MaxDim) {
0038                 dim = 1;
0039             }
0040         } else if (index.startsWith(QString("sel"))) {
0041             int selIndex = index.mid(strlen("sel")).toInt();
0042 
0043             if (selIndex >= 0 && selIndex < dim) {
0044                 selectionMode = split.at(1);
0045 
0046                 if (selectionMode == "incremental") {
0047                     selection[selIndex] = KisParasite::Incremental;                    
0048                 }
0049                 else if (selectionMode == "angular") {
0050                     selection[selIndex] = KisParasite::Angular;
0051                     needsMovement = true;
0052                 }
0053                 else if (selectionMode == "random") {
0054                     selection[selIndex] = KisParasite::Random;
0055                 }
0056                 else if (selectionMode == "pressure") {
0057                     selection[selIndex] = KisParasite::Pressure;
0058                 }
0059                 else if (selectionMode == "xtilt") {
0060                     selection[selIndex] = KisParasite::TiltX;
0061                 }
0062                 else if (selectionMode == "ytilt") {
0063                     selection[selIndex] = KisParasite::TiltY;
0064                 }
0065                 else if (selectionMode == "velocity") {
0066                     selection[selIndex] = KisParasite::Velocity;
0067                 }
0068                 else {
0069                     selection[selIndex] = KisParasite::Constant;
0070                 }
0071             }
0072             else {
0073                 warnImage << "Sel: wrong index: " << selIndex << "(dim = " << dim << ")";
0074             }
0075         }
0076         else if (index.startsWith(QString("rank"))) {
0077             int rankIndex = index.mid(strlen("rank")).toInt();
0078             if (rankIndex < 0 || rankIndex > dim) {
0079                 warnImage << "Rankindex out of range: " << rankIndex;
0080                 continue;
0081             }
0082             rank[rankIndex] = (split.at(1)).toInt();
0083         }
0084         else if (index == "ncells") {
0085             ncells = (split.at(1)).toInt();
0086             if (ncells < 1) {
0087                 warnImage << "ncells out of range: " << ncells;
0088                 ncells = 1;
0089             }
0090         }
0091     }
0092 
0093     for (int i = 0; i < dim; i++) {
0094         index[i] = 0;
0095     }
0096 
0097     setBrushesCount();
0098 }
0099 
0100 void KisPipeBrushParasite::init()
0101 {
0102     for (int i = 0; i < MaxDim; i++) {
0103         rank[i] = index[i] = brushesCount[i] = 0;
0104         selection[i] = KisParasite::Constant;
0105     }
0106 }
0107 
0108 void KisPipeBrushParasite::sanitize()
0109 {
0110     for (int i = 0; i < dim; i++) {
0111         // In the 2 listed cases, we'd divide by 0!
0112         if (rank[i] == 0 &&
0113                 (selection[i] == KisParasite::Incremental
0114                  || selection[i] == KisParasite::Angular)) {
0115 
0116             warnImage << "PIPE brush has a wrong rank for its selection mode!";
0117             selection[i] = KisParasite::Constant;
0118         }
0119     }
0120 }
0121 
0122 void KisPipeBrushParasite::setBrushesCount()
0123 {
0124     // I assume ncells is correct. If it isn't, complain to the parasite header.
0125     if (rank[0] != 0) {
0126         brushesCount[0] = ncells / rank[0];
0127     }
0128     else {
0129         brushesCount[0] = ncells;
0130     }
0131     
0132     for (int i = 1; i < dim; i++) {
0133         if (rank[i] == 0) {
0134             brushesCount[i] = brushesCount[i - 1];
0135         }
0136         else {
0137             brushesCount[i] = brushesCount[i - 1] / rank[i];
0138         }
0139     }
0140 }
0141 
0142 bool KisPipeBrushParasite::saveToDevice(QIODevice* dev) const
0143 {
0144     // write out something like
0145     // <count> ncells:<count> dim:<dim> rank0:<rank0> sel0:<sel0> <...>
0146 
0147     QTextStream stream(dev);
0148     stream.setCodec("UTF-8");
0149 
0150     // XXX: FIXME things like step, placement and so are not added (nor loaded, as a matter of fact)"
0151     stream << ncells << " ncells:" << ncells << " dim:" << dim;
0152 
0153     for (int i = 0; i < dim; i++) {
0154         stream << " rank" << i << ":" << rank[i] << " sel" << i << ":";
0155         switch (selection[i]) {
0156         case KisParasite::Constant:
0157             stream << "constant"; break;
0158         case KisParasite::Incremental:
0159             stream << "incremental"; break;
0160         case KisParasite::Angular:
0161             stream << "angular"; break;
0162         case KisParasite::Velocity:
0163             stream << "velocity"; break;
0164         case KisParasite::Random:
0165             stream << "random"; break;
0166         case KisParasite::Pressure:
0167             stream << "pressure"; break;
0168         case KisParasite::TiltX:
0169             stream << "xtilt"; break;
0170         case KisParasite::TiltY:
0171             stream << "ytilt"; break;
0172         }
0173     }
0174 
0175     return true;
0176 }
0177 
0178 bool loadFromDevice(QIODevice */*dev*/)
0179 {
0180     // XXX: implement...
0181     return true;
0182 }