Krita Source Code Documentation
Loading...
Searching...
No Matches
KisSpriterExport Class Reference

#include <kis_spriter_export.h>

+ Inheritance diagram for KisSpriterExport:

Public Member Functions

KisImportExportErrorCode convert (KisDocument *document, QIODevice *io, KisPropertiesConfigurationSP configuration=0) override
 
void initializeCapabilities () override
 
 KisSpriterExport (QObject *parent, const QVariantList &)
 
bool supportsIO () const override
 Override and return false for the filters that use a library that cannot handle file handles, only file names.
 
 ~KisSpriterExport () override
 
- Public Member Functions inherited from KisImportExportFilter
virtual KisConfigWidgetcreateConfigurationWidget (QWidget *parent, const QByteArray &from="", const QByteArray &to="") const
 createConfigurationWidget creates a widget that can be used to define the settings for a given import/export filter
 
virtual KisPropertiesConfigurationSP defaultConfiguration (const QByteArray &from="", const QByteArray &to="") const
 defaultConfiguration defines the default settings for the given import export filter
 
virtual QMap< QString, KisExportCheckBase * > exportChecks ()
 generate and return the list of capabilities of this export filter. The list
 
virtual bool exportSupportsGuides () const
 exportSupportsGuides Because guides are in the document and not the image, checking for guides cannot be made an exportCheck.
 
KisPropertiesConfigurationSP lastSavedConfiguration (const QByteArray &from="", const QByteArray &to="") const
 lastSavedConfiguration return the last saved configuration for this filter
 
 Private ()
 
void setBatchMode (bool batchmode)
 
void setFilename (const QString &filename)
 
void setImportUserFeedBackInterface (KisImportUserFeedbackInterface *interface)
 
void setMimeType (const QString &mime)
 
void setRealFilename (const QString &filename)
 
void setUpdater (QPointer< KoUpdater > updater)
 
QPointer< KoUpdaterupdater ()
 
virtual QString verify (const QString &fileName) const
 Verify whether the given file is correct and readable.
 
 ~KisImportExportFilter () override
 
 ~Private ()
 

Private Member Functions

void fillScml (QDomDocument &scml, const QString &entityName)
 
void fixBone (Bone *bone)
 
BoneparseBone (const Bone *parent, KisGroupLayerSP groupLayer)
 
KisImportExportErrorCode parseFolder (KisGroupLayerSP parentGroup, const QString &folderName, const QString &basePath, int *folderId=0)
 
KisImportExportErrorCode savePaintDevice (KisPaintDeviceSP dev, const QString &fileName)
 
void writeBone (const Bone *bone, QDomElement &timeline, QDomDocument &scml)
 
void writeBoneRef (const Bone *bone, QDomElement &mainline, QDomDocument &scml)
 

Private Attributes

KisLayerSP m_boneLayer
 
QList< Folderm_folders
 
KisImageSP m_image
 
QList< SpriterObjectm_objects
 
Bonem_rootBone {nullptr}
 
KisGroupLayerSP m_rootLayer
 
qreal m_timelineid {0.0}
 

Additional Inherited Members

- Public Attributes inherited from KisImportExportFilter
bool batchmode
 
QMap< QString, KisExportCheckBase * > capabilities
 
QString filename
 
KisImportUserFeedbackInterfaceimportUserFeedBackInterface {nullptr}
 
QByteArray mime
 
QString realFilename
 
QPointer< KoUpdaterupdater
 
- Static Public Attributes inherited from KisImportExportFilter
static const QString CICPPrimariesTag = "CICPCompatiblePrimaries"
 
static const QString CICPTransferCharacteristicsTag = "CICPCompatibleTransferFunction"
 
static const QString ColorDepthIDTag = "ColorDepthID"
 
static const QString ColorModelIDTag = "ColorModelID"
 
static const QString HDRTag = "HDRSupported"
 
static const QString ImageContainsTransparencyTag = "ImageContainsTransparency"
 
static const QString sRGBTag = "sRGB"
 
- Protected Member Functions inherited from KisImportExportFilter
void addCapability (KisExportCheckBase *capability)
 
void addSupportedColorModels (QList< QPair< KoID, KoID > > supportedColorModels, const QString &name, KisExportCheckBase::Level level=KisExportCheckBase::PARTIALLY)
 
bool batchMode () const
 
QString filename () const
 
KisImportUserFeedbackInterfaceimportUserFeedBackInterface () const
 
 KisImportExportFilter (QObject *parent=0)
 
QByteArray mimeType () const
 
QString realFilename () const
 
void setProgress (int value)
 
QString verifyZiPBasedFiles (const QString &fileName, const QStringList &filesToCheck) const
 

Detailed Description

Definition at line 93 of file kis_spriter_export.h.

Constructor & Destructor Documentation

◆ KisSpriterExport()

KisSpriterExport::KisSpriterExport ( QObject * parent,
const QVariantList &  )

Definition at line 47 of file kis_spriter_export.cpp.

47 : KisImportExportFilter(parent)
48{
49}
KisImportExportFilter(QObject *parent=0)

◆ ~KisSpriterExport()

KisSpriterExport::~KisSpriterExport ( )
override

Definition at line 51 of file kis_spriter_export.cpp.

52{
53}

Member Function Documentation

◆ convert()

KisImportExportErrorCode KisSpriterExport::convert ( KisDocument * document,
QIODevice * io,
KisPropertiesConfigurationSP configuration = 0 )
overridevirtual

The filter chain calls this method to perform the actual conversion. The passed mimetypes should be a pair of those you specified in your .desktop file. You have to implement this method to make the filter work.

Returns
The error status, see the #ConversionStatus enum. KisImportExportFilter::OK means that everything is alright.

Implements KisImportExportFilter.

Definition at line 469 of file kis_spriter_export.cpp.

470{
471 QFileInfo fi(filename());
472
473 m_image = document->savingImage();
474
475 if (m_image->rootLayer()->childCount() == 0) {
477 }
478
480
481 m_boneLayer = qobject_cast<KisLayer*>(KisLayerUtils::findNodeByName(root,"bone").data());
482 //qDebug() << "Found boneLayer" << m_boneLayer;
483
484 m_rootLayer= qobject_cast<KisGroupLayer*>(KisLayerUtils::findNodeByName(root,"root").data());
485 //qDebug() << "Fond rootLayer" << m_rootLayer;
486
487 KisImportExportErrorCode result = parseFolder(m_image->rootLayer(), "", fi.absolutePath());
488 if (!result.isOk()) {
489 dbgFile << "There were errors encountered while using the spriter exporter.";
490 return result;
491 }
492
493 m_rootBone = 0;
494
495 if (m_rootLayer) {
497 }
498 // Generate objects
499 int objectId = 0;
500 for (int folderIndex = 0, folderCount = m_folders.size(); folderIndex < folderCount; ++folderIndex) {
501 Folder folder = m_folders[folderCount - 1 - folderIndex];
502 for (int fileIndex = 0, fileCount = folder.files.size(); fileIndex < fileCount; ++ fileIndex) {
503 SpriterFile file = folder.files[fileCount - 1 - fileIndex];
504 SpriterObject spriterObject;
505 spriterObject.id = objectId++;
506 spriterObject.folderId = folder.id;
507 spriterObject.fileId = file.id;
508 spriterObject.x = file.x;
509 spriterObject.y = -file.y;
510 Bone *bone = 0;
511
512 //qDebug() << "file layername" << file.layerName;
513 // layer.name format: "base_name bone(bone_name) slot(slot_name)"
514 if (file.layerName.contains("bone(")) {
515 int start = file.layerName.indexOf("bone(") + 5;
516 int end = file.layerName.indexOf(')', start);
517 QString boneName = file.layerName.mid(start, end - start);
518 bone = findBoneByName(m_rootBone, boneName);
519 }
520
521
522 // layer.name format: "base_name"
523 if (!bone && m_rootBone) {
524 bone = findBoneByName(m_rootBone, file.layerName);
525 }
526 // group.name format: "base_name bone(bone_name)"
527 if (!bone && m_rootBone) {
528 if (folder.groupName.contains("bone(")) {
529 int start = folder.groupName.indexOf("bone(") + 5;
530 int end = folder.groupName.indexOf(')', start);
531 QString boneName = folder.groupName.mid(start, end - start);
532 bone = findBoneByName(m_rootBone, boneName);
533 }
534
535 // group.name format: "base_name"
536 if (!bone) {
537 bone = findBoneByName(m_rootBone, folder.groupName);
538 }
539 }
540
541 if (!bone) {
542 bone = m_rootBone;
543 }
544
545 if (bone) {
546 spriterObject.bone = bone;
547 spriterObject.localX = spriterObject.x - bone->x;
548 spriterObject.localY = spriterObject.y - bone->y;
549 }
550 else {
551 spriterObject.bone = 0;
552 spriterObject.localX = spriterObject.x;
553 spriterObject.localY = spriterObject.y;
554 }
555
556 spriterObject.localAngle = 0;
557 spriterObject.localScaleX = 1.0;
558 spriterObject.localScaleY = 1.0;
559
560 SpriterSlot *slot = 0;
561
562 // layer.name format: "base_name bone(bone_name) slot(slot_name)"
563 if (file.layerName.contains("slot(")) {
564 int start = file.layerName.indexOf("slot(") + 5;
565 int end = file.layerName.indexOf(')', start);
566 slot = new SpriterSlot();
567 slot->name = file.layerName.mid(start, end - start);
568 slot->defaultAttachmentFlag = file.layerName.contains("*");
569 }
570
571 spriterObject.slot = slot;
572
573// qDebug() << "Created object" << spriterObject.id << spriterObject.folderId
574// << spriterObject.fileId << spriterObject.x << spriterObject.y
575// << spriterObject.localX << spriterObject.localY;
576
577 m_objects.append(spriterObject);
578 }
579 }
580
581 // Copy object transforms
582 for (int i = 0; i < m_objects.size(); ++i) {
583 m_objects[i].fixLocalX = m_objects[i].localX;
584 m_objects[i].fixLocalY = m_objects[i].localY;
585 m_objects[i].fixLocalAngle = m_objects[i].localAngle;
586 m_objects[i].fixLocalScaleX = m_objects[i].localScaleX;
587 m_objects[i].fixLocalScaleY = m_objects[i].localScaleY;
588 }
589
590 // Calculate bone angles
591 if (m_rootBone) {
594 }
595
596 // Generate scml
597 QDomDocument scml;
598 fillScml(scml, fi.completeBaseName());
599
600 bool openedHere = false;
601 if (!io->isOpen()) {
602 openedHere = io->open(QIODevice::WriteOnly);
603 if (!openedHere) {
604 // unsuccessful open
606 }
607 }
608
609 QString towrite = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
610 if (io->write(towrite.toUtf8()) != towrite.length()) {
612 }
613 towrite = scml.toString(4).toUtf8();
614 if (io->write(towrite.toUtf8()) != towrite.length()) {
616 }
617
618 delete m_rootBone;
619
620 if (openedHere) {
621 // FIXME: causes crash...
622 //io->close();
623 }
624
626}
KisGroupLayerSP rootLayer() const
KisImportExportErrorCode parseFolder(KisGroupLayerSP parentGroup, const QString &folderName, const QString &basePath, int *folderId=0)
Bone * parseBone(const Bone *parent, KisGroupLayerSP groupLayer)
void fixBone(Bone *bone)
KisGroupLayerSP m_rootLayer
QList< SpriterObject > m_objects
void fillScml(QDomDocument &scml, const QString &entityName)
QList< Folder > m_folders
#define dbgFile
Definition kis_debug.h:53
void copyBone(Bone *startBone)
Bone * findBoneByName(Bone *startBone, const QString &name)
KisNodeSP findNodeByName(KisNodeSP root, const QString &name)
QString groupName
QList< SpriterFile > files
quint32 childCount() const
Definition kis_node.cpp:414
SpriterSlot * slot

References SpriterObject::bone, KisNode::childCount(), copyBone(), dbgFile, SpriterSlot::defaultAttachmentFlag, ImportExportCodes::ErrorWhileWriting, ImportExportCodes::Failure, SpriterObject::fileId, KisImportExportFilter::filename, Folder::files, fillScml(), findBoneByName(), KisLayerUtils::findNodeByName(), fixBone(), SpriterObject::folderId, Folder::groupName, Folder::id, SpriterObject::id, KisImportExportErrorCode::isOk(), SpriterObject::localAngle, SpriterObject::localScaleX, SpriterObject::localScaleY, SpriterObject::localX, SpriterObject::localY, m_boneLayer, m_folders, m_image, m_objects, m_rootBone, m_rootLayer, SpriterSlot::name, ImportExportCodes::NoAccessToWrite, ImportExportCodes::OK, parseBone(), parseFolder(), KisImage::rootLayer(), SpriterObject::slot, Bone::x, SpriterObject::x, Bone::y, and SpriterObject::y.

◆ fillScml()

void KisSpriterExport::fillScml ( QDomDocument & scml,
const QString & entityName )
private

Definition at line 326 of file kis_spriter_export.cpp.

327{
328 //qDebug() << "Creating scml" << entityName;
329
330 QDomElement root = scml.createElement("spriter_data");
331 scml.appendChild(root);
332 root.setAttribute("scml_version", 1);
333 root.setAttribute("generator", "krita");
334 root.setAttribute("generator_version", qApp->applicationVersion());
335
336 Q_FOREACH(const Folder &folder, m_folders) {
337 QDomElement fe = scml.createElement("folder");
338 root.appendChild(fe);
339 fe.setAttribute("id", folder.id);
340 fe.setAttribute("name", folder.name);
341 Q_FOREACH(const SpriterFile &file, folder.files) {
342 QDomElement fileElement = scml.createElement("file");
343 fe.appendChild(fileElement);
344 fileElement.setAttribute("id", file.id);
345 fileElement.setAttribute("name", file.name);
346 fileElement.setAttribute("width", QString::number(file.width, 'f', 2));
347 fileElement.setAttribute("height", QString::number(file.height, 'f', 2));
348 // qreal pivotX=0;
349 // qreal pivotY=1;
350 // Q_FOREACH(const SpriterObject &object, m_objects) {
351 // if(file.id == object.fileId)
352 // {
353 // pivotX = (0.0 -(object.fixLocalX / file.width));
354 // pivotY = (1.0 -(object.fixLocalY / file.height));
355 // break;
356 // }
357 // }
358 // fileElement.setAttribute("pivot_x", QString::number(pivotX, 'f', 2));
359 // fileElement.setAttribute("pivot_y", QString::number(pivotY, 'f', 2));
360 }
361 }
362
363 // entity
364 QDomElement entity = scml.createElement("entity");
365 root.appendChild(entity);
366 entity.setAttribute("id", "0");
367 entity.setAttribute("name", entityName);
368
369 // entity/animation
370 QDomElement animation = scml.createElement("animation");
371 entity.appendChild(animation);
372 animation.setAttribute("id", "0");
373 animation.setAttribute("name", "default");
374 animation.setAttribute("length", "1000");
375 animation.setAttribute("looping", "false");
376
377 // entity/animation/mainline
378 QDomElement mainline = scml.createElement("mainline");
379 animation.appendChild(mainline);
380
381 QDomElement key = scml.createElement("key");
382 mainline.appendChild(key);
383 key.setAttribute("id", "0");
384
385 m_timelineid = 0;
386 writeBoneRef(m_rootBone, key, scml);
387
388 Q_FOREACH(const SpriterObject &object, m_objects) {
389 QDomElement oe = scml.createElement("object_ref");
390 key.appendChild(oe);
391 oe.setAttribute("id", object.id);
392 if (object.bone) {
393 oe.setAttribute("parent", object.bone->id);
394 }
395 oe.setAttribute("timeline", m_timelineid++);
396 oe.setAttribute("key", "0");
397 oe.setAttribute("z_index", object.id);
398 }
399
400 // entity/animation/timeline
401 m_timelineid = 0;
402 if (m_rootBone) {
403 writeBone(m_rootBone, animation, scml);
404 }
405
406 Q_FOREACH(const SpriterObject &object, m_objects) {
407 Folder folder;
408 Q_FOREACH(const Folder & f, m_folders) {
409 if (f.id == object.folderId) {
410 folder = f;
411 break;
412 }
413 }
415 file.id = -1;
416 Q_FOREACH(const SpriterFile &f, folder.files) {
417 if (f.id == object.fileId) {
418 file = f;
419 break;
420 }
421 }
422 Q_ASSERT(file.id >= 0);
423
424 QString objectName = "object-" + file.baseName;
425
426 QDomElement timeline = scml.createElement("timeline");
427 animation.appendChild(timeline);
428 timeline.setAttribute("id", m_timelineid++);
429 timeline.setAttribute("name", objectName);
430
431 QDomElement key = scml.createElement("key");
432 timeline.appendChild(key);
433 key.setAttribute("id", "0");
434 key.setAttribute("spin", "0");
435
436 QDomElement objectEl = scml.createElement("object");
437 key.appendChild(objectEl);
438 objectEl.setAttribute("folder", object.folderId);
439 objectEl.setAttribute("file", object.fileId);
440 objectEl.setAttribute("x", object.fixLocalX);
441 objectEl.setAttribute("y", object.fixLocalY);
442 objectEl.setAttribute("angle", QString::number(kisRadiansToDegrees(object.fixLocalAngle), 'f', 2));
443 objectEl.setAttribute("scale_x", QString::number(object.fixLocalScaleX, 'f', 2));
444 objectEl.setAttribute("scale_y", QString::number(object.fixLocalScaleY, 'f', 2));
445 }
446}
void writeBone(const Bone *bone, QDomElement &timeline, QDomDocument &scml)
void writeBoneRef(const Bone *bone, QDomElement &mainline, QDomDocument &scml)
T kisRadiansToDegrees(T radians)
Definition kis_global.h:181

References Folder::files, Folder::id, kisRadiansToDegrees(), m_folders, m_objects, m_rootBone, m_timelineid, Folder::name, writeBone(), and writeBoneRef().

◆ fixBone()

void KisSpriterExport::fixBone ( Bone * bone)
private

Definition at line 224 of file kis_spriter_export.cpp.

225{
226 qreal boneLocalAngle = 0;
227 qreal boneLocalScaleX = 1;
228
229 if (bone->bones.length() >= 1) {
230 // if a bone has one or more children, point at first child
231 Bone *childBone = bone->bones[0];
232 qreal dx = childBone->x - bone->x;
233 qreal dy = childBone->y - bone->y;
234 if (qAbs(dx) > 0 || qAbs(dy) > 0) {
235 boneLocalAngle = KisFastMath::atan2(dy, dx);
236 boneLocalScaleX = sqrt(dx * dx + dy * dy) / 200;
237 }
238 }
239 else if (bone->parentBone) {
240 // else, if bone has parent, point away from parent
241 qreal dx = bone->x - bone->parentBone->x;
242 qreal dy = bone->y - bone->parentBone->y;
243 if (qAbs(dx) > 0 || qAbs(dy) > 0) {
244 boneLocalAngle = KisFastMath::atan2(dy, dx);
245 boneLocalScaleX = sqrt(dx * dx + dy * dy) / 200;
246 }
247 }
248 // adjust bone angle
249 bone->fixLocalAngle += boneLocalAngle;
250 bone->fixLocalScaleX *= boneLocalScaleX;
251
252 // rotate all the child bones back to world position
253 for (int i = 0; i < bone->bones.length(); ++i) {
254 Bone *childBone = bone->bones[i];
255
256 qreal tx = childBone->fixLocalX;
257 qreal ty = childBone->fixLocalY;
258
259 childBone->fixLocalX = tx * cos(-boneLocalAngle) - ty * sin(-boneLocalAngle);
260 childBone->fixLocalY = tx * sin(-boneLocalAngle) + ty * cos(-boneLocalAngle);
261
262 childBone->fixLocalX /= boneLocalScaleX;
263 childBone->fixLocalAngle -= boneLocalAngle;
264 childBone->fixLocalScaleX /= boneLocalScaleX;
265 }
266
267 // rotate all the child objects back to world position
268 for (int i = 0; i < m_objects.length(); ++i) {
269 if (m_objects[i].bone == bone) {
270 m_objects[i].fixLocalAngle -= boneLocalAngle;
271 m_objects[i].fixLocalScaleX /= boneLocalScaleX;
272 }
273 }
274
275 // process all child bones
276 for (int i = 0; i < bone->bones.length(); ++i) {
277 fixBone(bone->bones[i]);
278 }
279}
KRITAIMAGE_EXPORT qreal atan2(qreal y, qreal x)
atan2 replacement
const Bone * parentBone
qreal fixLocalScaleX
qreal fixLocalAngle
QList< Bone * > bones
qreal fixLocalY
qreal fixLocalX

References KisFastMath::atan2(), Bone::bones, fixBone(), Bone::fixLocalAngle, Bone::fixLocalScaleX, Bone::fixLocalX, Bone::fixLocalY, m_objects, Bone::parentBone, Bone::x, and Bone::y.

◆ initializeCapabilities()

void KisSpriterExport::initializeCapabilities ( )
overridevirtual

Reimplemented from KisImportExportFilter.

Definition at line 628 of file kis_spriter_export.cpp.

629{
632 QList<QPair<KoID, KoID> > supportedColorModels;
633 supportedColorModels << QPair<KoID, KoID>()
634 << QPair<KoID, KoID>(RGBAColorModelID, Integer8BitsColorDepthID);
635 addSupportedColorModels(supportedColorModels, "Spriter");
636}
VertexDescriptor get(PredecessorMap const &m, VertexDescriptor v)
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
static KisExportCheckRegistry * instance()
void addSupportedColorModels(QList< QPair< KoID, KoID > > supportedColorModels, const QString &name, KisExportCheckBase::Level level=KisExportCheckBase::PARTIALLY)
void addCapability(KisExportCheckBase *capability)
QPainterPath create(const char32_t codepoint, double height)
Creates a tofu missing glyph indicator representing the provided Unicode codepoint.

References KisImportExportFilter::addCapability(), KisImportExportFilter::addSupportedColorModels(), get(), KisExportCheckRegistry::instance(), Integer8BitsColorDepthID, KisExportCheckBase::PARTIALLY, RGBAColorModelID, and KisExportCheckBase::SUPPORTED.

◆ parseBone()

Bone * KisSpriterExport::parseBone ( const Bone * parent,
KisGroupLayerSP groupLayer )
private

Definition at line 157 of file kis_spriter_export.cpp.

158{
159 static int boneId = 0;
160 QString groupBaseName = groupLayer->name().split(" ").first();
161 Bone *bone = new Bone;
162 bone->id = boneId++;
163 bone->parentBone = parent;
164 bone->name = groupBaseName;
165
166 if (m_boneLayer) {
167 QRectF rc = m_image->bounds().intersected(m_boneLayer->exactBounds());
168
169 qreal xmin = rc.left();
170 qreal ymin = rc.top();
171 qreal xmax = rc.right();
172 qreal ymax = rc.bottom();
173
174 bone->x = (xmin + xmax) / 2;
175 bone->y = -(ymin + ymax) / 2;
176 bone->width = xmax - xmin;
177 bone->height = ymax - ymin;
178 }
179 else {
180 bone->x = 0.0;
181 bone->y = 0.0;
182 bone->width = 0.0;
183 bone->height = 0.0;
184 }
185
186 if (parent) {
187 bone->localX = bone->x - parent->x;
188 bone->localY = bone->y - parent->y;
189 }
190 else {
191 bone->localX = bone->x;
192 bone->localY = bone->y;
193 }
194
195 bone->localAngle = 0.0;
196 bone->localScaleX = 1.0;
197 bone->localScaleY = 1.0;
198
199 KisNodeSP child = groupLayer->lastChild();
200 while (child) {
201 if (child->visible() && child->inherits("KisGroupLayer")) {
202 bone->bones.append(parseBone(bone, qobject_cast<KisGroupLayer*>(child.data())));
203 }
204 child = child->prevSibling();
205 }
206
207 //qDebug() << "Created bone" << bone->id << "with" << bone->bones.size() << "bones";
208 return bone;
209}
QRect bounds() const override
ChildIterator< value_type, is_const > parent(const ChildIterator< value_type, is_const > &it)
Definition KisForest.h:327
QString name
qreal localScaleY
qreal localAngle
qreal localScaleX
QString name() const
virtual bool visible(bool recursive=false) const
QRect exactBounds() const override
KisNodeSP prevSibling() const
Definition kis_node.cpp:402
KisNodeSP lastChild() const
Definition kis_node.cpp:367

References Bone::bones, KisImage::bounds(), KisSharedPtr< T >::data(), KisLayer::exactBounds(), Bone::height, Bone::id, KisNode::lastChild(), Bone::localAngle, Bone::localScaleX, Bone::localScaleY, Bone::localX, Bone::localY, m_boneLayer, m_image, KisBaseNode::name(), Bone::name, Bone::parentBone, parseBone(), KisNode::prevSibling(), KisBaseNode::visible(), Bone::width, Bone::x, and Bone::y.

◆ parseFolder()

KisImportExportErrorCode KisSpriterExport::parseFolder ( KisGroupLayerSP parentGroup,
const QString & folderName,
const QString & basePath,
int * folderId = 0 )
private

Definition at line 80 of file kis_spriter_export.cpp.

81{
82// qDebug() << "parseFolder: parent" << parentGroup->name()
83// << "folderName" << folderName
84// << "basepath" << basePath;
85
86 int currentFolder=0;
87 if(folderId == 0)
88 {
89 folderId = &currentFolder;
90 }
91 QString pathName;
92 if (!folderName.isEmpty()) {
93 pathName = folderName + "/";
94 }
95
96
97 KisNodeSP child = parentGroup->lastChild();
98 while (child) {
99 if (child->visible() && child->inherits("KisGroupLayer")) {
100 KisImportExportErrorCode res = parseFolder(qobject_cast<KisGroupLayer*>(child.data()), child->name().split(" ").first(), basePath + "/" + pathName, folderId);
101 if (!res.isOk()) {
102 return res;
103 }
104 }
105 child = child->prevSibling();
106 }
107
108 Folder folder;
109 folder.id = *folderId;
110 folder.name = folderName;
111 folder.groupName = parentGroup->name();
112
113 int fileId = 0;
114 child = parentGroup->lastChild();
115
116 while (child) {
117 if (child->visible() && !child->inherits("KisGroupLayer") && !child->inherits("KisMask")) {
118 QRectF rc = m_image->bounds().intersected(child->exactBounds());
119 QString layerBaseName = child->name().split(" ").first();
121 file.id = fileId++;
122 file.pathName = pathName;
123 file.baseName = layerBaseName;
124 file.layerName = child->name();
125 file.name = folderName + "/" + layerBaseName + ".png";
126
127 qreal xmin = rc.left();
128 qreal ymin = rc.top();
129 qreal xmax = rc.right();
130 qreal ymax = rc.bottom();
131
132 file.width = xmax - xmin;
133 file.height = ymax - ymin;
134 file.x = xmin;
135 file.y = ymin;
136 //qDebug() << "Created file" << file.id << file.name << file.pathName << file.baseName << file.width << file.height << file.layerName;
137 KisImportExportErrorCode result = savePaintDevice(child->projection(), basePath + file.name);
138 if (result.isOk()) {
139 folder.files.append(file);
140 } else {
141 return result;
142 }
143 }
144
145 child = child->prevSibling();
146 }
147
148 if (folder.files.size() > 0) {
149 //qDebug() << "Adding folder" << folder.id << folder.name << folder.groupName << folder.files.length();
150 m_folders.append(folder);
151 (*folderId)++;
152 }
153
155}
KisImportExportErrorCode savePaintDevice(KisPaintDeviceSP dev, const QString &fileName)
virtual KisPaintDeviceSP projection() const =0
virtual QRect exactBounds() const

References KisImage::bounds(), KisSharedPtr< T >::data(), KisBaseNode::exactBounds(), Folder::files, Folder::groupName, Folder::id, KisImportExportErrorCode::isOk(), KisNode::lastChild(), m_folders, m_image, KisBaseNode::name(), Folder::name, ImportExportCodes::OK, parseFolder(), KisNode::prevSibling(), KisBaseNode::projection(), savePaintDevice(), and KisBaseNode::visible().

◆ savePaintDevice()

KisImportExportErrorCode KisSpriterExport::savePaintDevice ( KisPaintDeviceSP dev,
const QString & fileName )
private

Definition at line 55 of file kis_spriter_export.cpp.

56{
57 QFileInfo fi(fileName);
58
59 QDir d = fi.absoluteDir();
60 d.mkpath(d.path());
61 QRect rc = m_image->bounds().intersected(dev->exactBounds());
62
64 dev = new KisPaintDevice(*dev.data());
66 }
67
68 KisPNGOptions options;
69 options.forceSRGB = true;
70
73
74 KisPNGConverter converter(0);
75 KisImportExportErrorCode res = converter.buildFile(fileName, rc, m_image->xRes(), m_image->yRes(), dev, beginIt, endIt, options, 0);
76
77 return res;
78}
vKisAnnotationSP_it endAnnotations()
double xRes() const
double yRes() const
vKisAnnotationSP_it beginAnnotations()
static bool isColorSpaceSupported(const KoColorSpace *cs)
QRect exactBounds() const
const KoColorSpace * colorSpace() const
void convertTo(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags(), KUndo2Command *parentCommand=nullptr, KoUpdater *progressUpdater=nullptr)
vKisAnnotationSP::iterator vKisAnnotationSP_it
Definition kis_types.h:181
static KoColorSpaceRegistry * instance()

References KisImage::beginAnnotations(), KisImage::bounds(), KisPNGConverter::buildFile(), KisPaintDevice::colorSpace(), KisPaintDevice::convertTo(), KisImportExportFilter::d, KisSharedPtr< T >::data(), KisImage::endAnnotations(), KisPaintDevice::exactBounds(), KisPNGOptions::forceSRGB, KoColorSpaceRegistry::instance(), KisPNGConverter::isColorSpaceSupported(), m_image, KisImage::xRes(), and KisImage::yRes().

◆ supportsIO()

bool KisSpriterExport::supportsIO ( ) const
inlineoverridevirtual

Override and return false for the filters that use a library that cannot handle file handles, only file names.

Reimplemented from KisImportExportFilter.

Definition at line 99 of file kis_spriter_export.h.

99{ return false; }

◆ writeBone()

void KisSpriterExport::writeBone ( const Bone * bone,
QDomElement & timeline,
QDomDocument & scml )
private

Definition at line 297 of file kis_spriter_export.cpp.

298{
299 if (!bone) return;
300 QDomElement timeline = scml.createElement("timeline");
301 animation.appendChild(timeline);
302 timeline.setAttribute("id", m_timelineid);
303 timeline.setAttribute("name", bone->name);
304 timeline.setAttribute("object_type", "bone");
305
306 QDomElement key = scml.createElement("key");
307 timeline.appendChild(key);
308 key.setAttribute("id", "0");
309 key.setAttribute("spin", 0);
310
311 QDomElement boneEl = scml.createElement("bone");
312 key.appendChild(boneEl);
313 boneEl.setAttribute("x", QString::number(bone->fixLocalX, 'f', 2));
314 boneEl.setAttribute("y", QString::number(bone->fixLocalY, 'f', 2));
315 boneEl.setAttribute("angle", QString::number(bone->fixLocalAngle, 'f', 2));
316 boneEl.setAttribute("scale_x", QString::number(bone->fixLocalScaleX, 'f', 2));
317 boneEl.setAttribute("scale_y", QString::number(bone->fixLocalScaleY, 'f', 2));
318
319 m_timelineid++;
320
321 Q_FOREACH(const Bone *childBone, bone->bones) {
322 writeBone(childBone, animation, scml);
323 }
324}
qreal fixLocalScaleY

References Bone::bones, Bone::fixLocalAngle, Bone::fixLocalScaleX, Bone::fixLocalScaleY, Bone::fixLocalX, Bone::fixLocalY, m_timelineid, Bone::name, and writeBone().

◆ writeBoneRef()

void KisSpriterExport::writeBoneRef ( const Bone * bone,
QDomElement & mainline,
QDomDocument & scml )
private

Definition at line 281 of file kis_spriter_export.cpp.

282{
283 if (!bone) return;
284 QDomElement boneRef = scml.createElement("bone_ref");
285 key.appendChild(boneRef);
286 boneRef.setAttribute("id", bone->id);
287 if (bone->parentBone) {
288 boneRef.setAttribute("parent", bone->parentBone->id);
289 }
290 boneRef.setAttribute("timeline", m_timelineid++);
291 boneRef.setAttribute("key", "0");
292 Q_FOREACH(const Bone *childBone, bone->bones) {
293 writeBoneRef(childBone, key, scml);
294 }
295}

References Bone::bones, Bone::id, m_timelineid, Bone::parentBone, and writeBoneRef().

Member Data Documentation

◆ m_boneLayer

KisLayerSP KisSpriterExport::m_boneLayer
private

Definition at line 118 of file kis_spriter_export.h.

◆ m_folders

QList<Folder> KisSpriterExport::m_folders
private

Definition at line 114 of file kis_spriter_export.h.

◆ m_image

KisImageSP KisSpriterExport::m_image
private

Definition at line 112 of file kis_spriter_export.h.

◆ m_objects

QList<SpriterObject> KisSpriterExport::m_objects
private

Definition at line 116 of file kis_spriter_export.h.

◆ m_rootBone

Bone* KisSpriterExport::m_rootBone {nullptr}
private

Definition at line 115 of file kis_spriter_export.h.

115{nullptr};

◆ m_rootLayer

KisGroupLayerSP KisSpriterExport::m_rootLayer
private

Definition at line 117 of file kis_spriter_export.h.

◆ m_timelineid

qreal KisSpriterExport::m_timelineid {0.0}
private

Definition at line 113 of file kis_spriter_export.h.

113{0.0};

The documentation for this class was generated from the following files: