19 #include <QDomDocument>
20 #include <QTextStream>
21 #include <QProgressDialog>
22 #include <QApplication>
31 #include "layerbitmap.h"
32 #include "layervector.h"
33 #include "layersound.h"
34 #include "layercamera.h"
38 #include "bitmapimage.h"
39 #include "vectorimage.h"
40 #include "fileformat.h"
41 #include "activeframepool.h"
52 mActiveFramePool->clear();
54 for (
Layer* layer : mLayers)
75 for (
int i = 0; i < getLayerCount(); i++)
77 Layer* layer = getLayer(i);
78 QDomElement layerTag = layer->createDomElement(doc);
84 bool Object::loadXML(
QDomElement docElem, ProgressCallback progressForward)
91 const QString dataDirPath = mDataDirPath;
96 if (element.
tagName() ==
"layer")
113 default: Q_ASSERT(
false);
continue;
115 mLayers.append(newLayer);
116 newLayer->loadDomElement(element, dataDirPath, progressForward);
125 mLayers.append(layerBitmap);
127 layerBitmap->addNewKeyFrameAt(1);
135 mLayers.append(layerVector);
137 layerVector->addNewKeyFrameAt(1);
145 mLayers.append(layerSound);
155 mLayers.append(layerCamera);
157 layerCamera->addNewKeyFrameAt(1);
159 connect(layerCamera, &LayerCamera::resolutionChanged,
this, &Object::layerViewChanged);
164 void Object::createWorkingDir()
169 projectName =
"Default";
174 projectName = fileInfo.completeBaseName();
181 strWorkingDir =
QString(
"%1/Pencil2D/%2_%3_%4/")
184 .
arg(PFF_TMP_DECOMPRESS_EXT)
185 .
arg(uniqueString(8));
187 while(dir.exists(strWorkingDir));
189 dir.mkpath(strWorkingDir);
190 mWorkingDirPath = strWorkingDir;
192 QDir dataDir(strWorkingDir + PFF_DATA_DIR);
195 mDataDirPath = dataDir.absolutePath();
198 void Object::deleteWorkingDir()
const
200 if (!mWorkingDirPath.
isEmpty())
202 QDir dir(mWorkingDirPath);
203 bool ok = dir.removeRecursively();
208 void Object::setWorkingDir(
const QString& path)
211 Q_ASSERT(dir.exists());
212 mWorkingDirPath = path;
215 void Object::createDefaultLayers()
223 int Object::getMaxLayerID()
226 for (
Layer* iLayer : mLayers)
228 if (iLayer->id() > maxId)
230 maxId = iLayer->id();
236 int Object::getUniqueLayerID()
238 return 1 + getMaxLayerID();
241 Layer* Object::getLayer(
int i)
const
243 if (i < 0 || i >= getLayerCount())
248 return mLayers.at(i);
251 Layer* Object::findLayerByName(
QString strName, Layer::LAYER_TYPE type)
const
253 bool bCheckType = (type != Layer::UNDEFINED);
254 for (
Layer* layer : mLayers)
256 bool isTypeMatch = (bCheckType) ? (type == layer->type()) :
true;
257 if (isTypeMatch && layer->name() == strName)
265 Layer* Object::takeLayer(
int layerId)
270 for (
int i = 0; i< mLayers.length(); ++i)
272 Layer* layer = mLayers[i];
273 if (layer->id() == layerId)
280 if (index == -1) {
return nullptr; }
282 Layer* layer = mLayers.takeAt(index);
287 bool Object::swapLayers(
int i,
int j)
289 if (i < 0 || i >= mLayers.size())
294 if (j < 0 || j >= mLayers.size())
301 Layer* tmp = mLayers.at(i);
302 mLayers[i] = mLayers.at(j);
308 void Object::deleteLayer(
int i)
310 if (i > -1 && i < mLayers.size())
312 delete mLayers.takeAt(i);
316 void Object::deleteLayer(
Layer* layer)
318 auto it = std::find(mLayers.begin(), mLayers.end(), layer);
320 if (it != mLayers.end())
327 bool Object::addLayer(
Layer* layer)
329 if (layer ==
nullptr)
333 if (mLayers.contains(layer))
337 layer->setObject(
this);
338 mLayers.append(layer);
342 ColorRef Object::getColor(
int index)
const
345 if (index > -1 && index < mPalette.
size())
347 result = mPalette.
at(index);
352 void Object::setColor(
int index,
QColor newColor)
354 Q_ASSERT(index >= 0);
356 mPalette[index].color = newColor;
359 void Object::setColorRef(
int index,
ColorRef newColorRef)
361 mPalette[index] = newColorRef;
364 void Object::addColor(
QColor color)
369 void Object::movePaletteColor(
int start,
int end)
371 mPalette.
move(start, end);
374 void Object::moveVectorColor(
int start,
int end)
376 for (
int i = 0; i < getLayerCount(); i++)
378 Layer* layer = getLayer(i);
379 if (layer->type() == Layer::VECTOR)
381 static_cast<LayerVector*
>(layer)->moveColor(start, end);
386 void Object::addColorAtIndex(
int index,
ColorRef newColor)
388 mPalette.
insert(index, newColor);
391 bool Object::isColorInUse(
int index)
393 for (
int i = 0; i < getLayerCount(); i++)
395 Layer* layer = getLayer(i);
396 if (layer->type() == Layer::VECTOR)
400 if (layerVector->usesColor(index))
410 void Object::removeColor(
int index)
412 for (
int i = 0; i < getLayerCount(); i++)
414 Layer* layer = getLayer(i);
415 if (layer->type() == Layer::VECTOR)
418 layerVector->removeColor(index);
427 void Object::renameColor(
int i,
QString text)
429 mPalette[i].name = text;
435 bool ok = exportPalette(fullPath);
441 void Object::exportPaletteGPL(
QFile& file)
const
446 out <<
"GIMP Palette" <<
"\n";
447 out <<
"Name: " << fileName <<
"\n";
454 out <<
" " << ref.name <<
"\n";
458 void Object::exportPalettePencil(
QFile& file)
const
465 for (
int i = 0; i < mPalette.size(); i++)
477 doc.
save(out, IndentSize);
480 bool Object::exportPalette(
const QString& filePath)
const
482 QFile file(filePath);
485 qDebug(
"Error: cannot export palette");
490 exportPaletteGPL(file);
492 exportPalettePencil(file);
506 void Object::importPaletteGPL(
QFile& file)
513 in.readLineInto(&line);
516 in.readLineInto(&line);
521 in.readLineInto(&line);
526 in.readLineInto(&line);
554 green = snip.toInt();
569 if (countInLine < 2) green = prevColor.green();
570 if (countInLine < 3) blue = prevColor.blue();
577 QColor color(red, green, blue);
580 mPalette.append(
ColorRef(color, name));
583 }
while (in.readLineInto(&line));
586 void Object::importPalettePencil(
QFile& file)
609 void Object::openPalette(
QString filePath)
617 importPalette(filePath);
623 bool Object::importPalette(
QString filePath)
625 QFile file(filePath);
634 importPaletteGPL(file);
636 importPalettePencil(file);
643 void Object::loadDefaultPalette()
672 void Object::paintImage(
QPainter& painter,
int frameNumber,
674 bool antialiasing)
const
676 updateActiveFrames(frameNumber);
692 for (
int i = 0; i < getLayerCount(); i++)
694 Layer* layer = getLayer(i);
695 if (layer->visible())
700 if (layer->type() == Layer::BITMAP)
704 BitmapImage* bitmap = layerBitmap->getLastBitmapImageAtFrame(frameNumber);
705 if (bitmap !=
nullptr)
707 bitmap->paintImage(painter);
712 if (layer->type() == Layer::VECTOR)
715 VectorImage* vec = layerVector->getLastVectorImageAtFrame(frameNumber, 0);
718 vec->
paintImage(painter,
false,
false, antialiasing);
729 qDebug() <<
"[Object] sound file doesn't exist: " << strFilePath;
733 QString sNewFileName =
"sound_";
748 qDebug() <<
"[Object] couldn't copy sound file to data folder: " << strFilePath;
755 bool Object::exportFrames(
int frameStart,
int frameEnd,
761 bool exportKeyframesOnly,
765 int progressMax = 50)
const
767 Q_ASSERT(cameraLayer);
773 if (formatStr ==
"PNG" || formatStr ==
"png")
778 if (formatStr ==
"JPG" || formatStr ==
"jpg" || formatStr ==
"JPEG" || formatStr ==
"jpeg")
782 transparency =
false;
784 if (formatStr ==
"TIFF" || formatStr ==
"tiff" || formatStr ==
"TIF" || formatStr ==
"tif")
789 if (formatStr ==
"BMP" || formatStr ==
"bmp")
793 transparency =
false;
800 qDebug() <<
"Exporting frames from "
801 << frameStart <<
"to"
803 <<
"at size " << exportSize;
805 for (
int currentFrame = frameStart; currentFrame <= frameEnd; currentFrame++)
807 if (progress !=
nullptr)
809 int totalFramesToExport = (frameEnd - frameStart) + 1;
810 if (totalFramesToExport != 0)
812 progress->setValue((currentFrame - frameStart + 1) * progressMax / totalFramesToExport);
816 if (progress->wasCanceled())
822 QTransform view = cameraLayer->getViewAtFrame(currentFrame);
823 QSize camSize = cameraLayer->getViewSize();
826 while (frameNumberString.
length() < 4)
828 frameNumberString.
prepend(
"0");
830 QString sFileName = filePath + frameNumberString + extension;
831 Layer* layer = findLayerByName(layerName);
832 if (exportKeyframesOnly)
834 if (layer->keyExists(currentFrame))
835 exportIm(currentFrame, view, camSize, exportSize, sFileName, format, antialiasing, transparency);
839 exportIm(currentFrame, view, camSize, exportSize, sFileName, format, antialiasing, transparency);
846 bool Object::exportX(
int frameStart,
int frameEnd,
QTransform view,
QSize exportSize,
QString filePath,
bool antialiasing)
852 for (
int j = frameStart; j <= frameEnd; j = j + 15)
856 xPainter.fillRect(0, 0, 2300, 3400,
Qt::white);
858 for (
int i = j; i < 15 + page * 15 && i <= frameEnd; i++)
862 QTransform thumbView = view * RectMapTransform(source, target);
863 xPainter.setWorldTransform(thumbView);
865 paintImage(xPainter, i,
false, antialiasing);
866 xPainter.resetTransform();
867 xPainter.setClipping(
false);
869 xPainter.drawRect(target);
895 imageToExport.fill(bgColor);
904 paintImage(painter, frame,
false, antialiasing);
906 return imageToExport.save(filePath, format.
toStdString().c_str());
909 int Object::getLayerCount()
const
911 return mLayers.size();
916 Q_ASSERT(mData !=
nullptr);
922 Q_ASSERT(d !=
nullptr);
926 int Object::totalKeyFrameCount()
const
929 for (
const Layer* layer : mLayers)
931 sum += layer->keyFrameCount();
936 void Object::updateActiveFrames(
int frame)
const
938 int beginFrame = std::max(frame - 3, 1);
939 int endFrame = frame + 4;
940 for (
int i = 0; i < getLayerCount(); ++i)
942 Layer* layer = getLayer(i);
943 for (
int k = beginFrame; k < endFrame; ++k)
945 KeyFrame* key = layer->getKeyFrameAt(k);
946 mActiveFramePool->put(key);
951 void Object::setActiveFramePoolSize(
int sizeInMB)
954 mActiveFramePool->resize(qint64(sizeInMB) * 1024 * 1024);
std::string toStdString() const const
QString toString(Qt::DateFormat format) const const
void setOpacity(qreal opacity)
void paintImage(QPainter &painter, bool simplified, bool showThinCurves, bool antialiasing)
VectorImage::paintImage.
void setCompositionMode(QPainter::CompositionMode mode)
void setRenderHint(QPainter::RenderHint hint, bool on)
QDomNode appendChild(const QDomNode &newChild)
QString attribute(const QString &name, const QString &defValue) const const
QString & prepend(QChar ch)
const T & at(int i) const const
virtual QString fileName() const const override
QString filePath(const QString &fileName) const const
void move(int from, int to)
QDomElement documentElement() const const
bool exists() const const
QString tr(const char *sourceText, const char *disambiguation, int n)
bool copy(const QString &newName)
QDomNode nextSibling() const const
QDomElement toElement() const const
void setWindow(const QRect &rectangle)
void drawRect(const QRectF &rectangle)
QColor toRgb() const const
QString number(int n, int base)
void processEvents(QEventLoop::ProcessEventsFlags flags)
void setPen(const QColor &color)
void setAttribute(const QString &name, const QString &value)
int toInt(bool *ok, int base) const const
bool isEmpty() const const
QString trimmed() const const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QPaintDevice * device() const const
void setBrush(const QBrush &brush)
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const const
virtual bool open(QIODevice::OpenMode mode) override
CompositionMode_SourceOver
void setParent(QObject *parent)
bool isNull() const const
QDateTime currentDateTime()
void save(QTextStream &stream, int indent, QDomNode::EncodingPolicy encodingPolicy) const const
QDomNode firstChild() const const
QString suffix() const const
void insert(int i, const T &value)
virtual void close() override
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
void setWorldMatrixEnabled(bool enable)
QString tagName() const const
ActiveFramePool implemented a LRU cache to keep tracking the most recent accessed key frames A key fr...
QDomElement createElement(const QString &tagName)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString baseName() const const
bool isValid() const const
bool setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)