Krita

Node.cpp
1 /*
2  * SPDX-FileCopyrightText: 2016 Boudewijn Rempt <[email protected]>
3  *
4  * SPDX-License-Identifier: LGPL-2.0-or-later
5  */
6 #include <QUrl>
7 #include <QScopedPointer>
8 #include <QUuid>
9 
10 #include <KoColorSpace.h>
11 #include <KoColorSpaceRegistry.h>
12 #include <KoColorTransformation.h>
13 
14 #include <KisDocument.h>
15 #include <KisMimeDatabase.h>
16 #include <KisPart.h>
17 #include <kis_image.h>
18 #include <kis_types.h>
19 #include <kis_node.h>
20 #include <kis_paint_layer.h>
21 #include <kis_group_layer.h>
22 #include <kis_file_layer.h>
23 #include <kis_adjustment_layer.h>
24 #include <kis_generator_layer.h>
25 #include <kis_clone_layer.h>
26 #include <kis_shape_layer.h>
27 #include <KisReferenceImagesLayer.h>
28 #include <kis_transparency_mask.h>
29 #include <kis_filter_mask.h>
30 #include <kis_transform_mask.h>
31 #include <kis_selection_mask.h>
32 #include <lazybrush/kis_colorize_mask.h>
33 #include <kis_layer.h>
34 #include <kis_meta_data_merge_strategy.h>
35 #include <kis_meta_data_merge_strategy_registry.h>
36 #include <kis_filter_strategy.h>
37 #include <commands/kis_node_compositeop_command.h>
38 #include <commands/kis_image_layer_add_command.h>
39 #include <commands/kis_image_layer_remove_command.h>
40 #include <commands_new/kis_set_layer_style_command.h>
41 #include <kis_processing_applicator.h>
42 #include <kis_asl_layer_style_serializer.h>
43 
44 #include <kis_raster_keyframe_channel.h>
45 #include <kis_keyframe.h>
46 #include "kis_selection.h"
47 
48 #include "InfoObject.h"
49 #include "Krita.h"
50 #include "Node.h"
51 #include "Channel.h"
52 #include "Filter.h"
53 #include "Selection.h"
54 
55 #include "GroupLayer.h"
56 #include "CloneLayer.h"
57 #include "FilterLayer.h"
58 #include "FillLayer.h"
59 #include "FileLayer.h"
60 #include "VectorLayer.h"
61 #include "FilterMask.h"
62 #include "SelectionMask.h"
63 #include "TransparencyMask.h"
64 #include "TransformMask.h"
65 #include "ColorizeMask.h"
66 
67 #include "LibKisUtils.h"
68 #include <kis_layer_utils.h>
69 
70 struct Node::Private {
71  Private() {}
72  KisImageWSP image;
73  KisNodeSP node;
74 };
75 
76 Node::Node(KisImageSP image, KisNodeSP node, QObject *parent)
77  : QObject(parent)
78  , d(new Private)
79 {
80  d->image = image;
81  d->node = node;
82 }
83 
84 Node *Node::createNode(KisImageSP image, KisNodeSP node, QObject *parent)
85 {
86  if (node.isNull()) {
87  return 0;
88  }
89  if (node->inherits("KisGroupLayer")) {
90  return new GroupLayer(dynamic_cast<KisGroupLayer*>(node.data()));
91  }
92  else if (node->inherits("KisCloneLayer")) {
93  return new CloneLayer(dynamic_cast<KisCloneLayer*>(node.data()));
94  }
95  else if (node->inherits("KisFileLayer")) {
96  return new FileLayer(dynamic_cast<KisFileLayer*>(node.data()));
97  }
98  else if (node->inherits("KisAdjustmentLayer")) {
99  return new FilterLayer(dynamic_cast<KisAdjustmentLayer*>(node.data()));
100  }
101  else if (node->inherits("KisGeneratorLayer")) {
102  return new FillLayer(dynamic_cast<KisGeneratorLayer*>(node.data()));
103  }
104  else if (node->inherits("KisShapeLayer")) {
105  return new VectorLayer(dynamic_cast<KisShapeLayer*>(node.data()));
106  }
107  else if (node->inherits("KisFilterMask")) {
108  return new FilterMask(image, dynamic_cast<KisFilterMask*>(node.data()));
109  }
110  else if (node->inherits("KisSelectionMask")) {
111  return new SelectionMask(image, dynamic_cast<KisSelectionMask*>(node.data()));
112  }
113  else if (node->inherits("KisTransparencyMask")) {
114  return new TransparencyMask(image, dynamic_cast<KisTransparencyMask*>(node.data()));
115  }
116  else if (node->inherits("KisTransformMask")) {
117  return new TransformMask(image, dynamic_cast<KisTransformMask*>(node.data()));
118  }
119  else if (node->inherits("KisColorizeMask")) {
120  return new ColorizeMask(image, dynamic_cast<KisColorizeMask*>(node.data()));
121  }
122  else {
123  return new Node(image, node, parent);
124  }
125 }
126 
127 Node::~Node()
128 {
129  delete d;
130 }
131 
132 bool Node::operator==(const Node &other) const
133 {
134  return (d->node == other.d->node
135  && d->image == other.d->image);
136 }
137 
138 bool Node::operator!=(const Node &other) const
139 {
140  return !(operator==(other));
141 }
142 
144 {
145  KisNodeSP clone = d->node->clone();
146  Node *node = Node::createNode(0, clone);
147  return node;
148 }
149 
150 
151 bool Node::alphaLocked() const
152 {
153  if (!d->node) return false;
154  KisPaintLayerSP paintLayer = qobject_cast<KisPaintLayer*>(d->node.data());
155  if (paintLayer) {
156  return paintLayer->alphaLocked();
157  }
158  return false;
159 }
160 
161 void Node::setAlphaLocked(bool value)
162 {
163  if (!d->node) return;
164  KisPaintLayerSP paintLayer = qobject_cast<KisPaintLayer*>(d->node.data());
165  if (paintLayer) {
166  paintLayer->setAlphaLocked(value);
167  }
168 }
169 
170 
172 {
173  if (!d->node) return QString();
174 
175  return d->node->compositeOpId();
176 }
177 
179 {
180  if (!d->node) return;
181 
182  KUndo2Command *cmd = new KisNodeCompositeOpCommand(d->node,
183  value);
184 
185  KisProcessingApplicator::runSingleCommandStroke(d->image, cmd);
186  d->image->waitForDone();
187 }
188 
189 
191 {
193 
194  if (!d->node) return channels;
195  if (!d->node->inherits("KisLayer")) return channels;
196 
197  Q_FOREACH(KoChannelInfo *info, d->node->colorSpace()->channels()) {
198  Channel *channel = new Channel(d->node, info);
199  channels << channel;
200  }
201 
202  return channels;
203 }
204 
206 {
207  QList<Node*> nodes;
208  if (d->node) {
209  KisNodeList nodeList;
210  int childCount = d->node->childCount();
211  for (int i = 0; i < childCount; ++i) {
212  nodeList << d->node->at(i);
213  }
214  nodes = LibKisUtils::createNodeList(nodeList, d->image);
215  }
216  return nodes;
217 }
218 
219 QList<Node*> Node::findChildNodes(const QString &name, bool recursive, bool partialMatch, const QString &type, int colorLabelIndex) const
220 {
221  if (!d->node) return {};
222 
223  QList<Node*> nodes;
224  KisNodeList nodeList = KisLayerUtils::findNodesByName(d->node, name, recursive, partialMatch);
225 
226  if (!type.isEmpty()) {
227  for (int i = nodeList.size() - 1; i >= 0; i--) {
228  if ((type == "paintlayer" && !qobject_cast<const KisPaintLayer*>(nodeList.at(i))) ||
229  (type == "vectorlayer" && !qobject_cast<const KisShapeLayer*>(nodeList.at(i))) ||
230  (type == "grouplayer" && !qobject_cast<const KisGroupLayer*>(nodeList.at(i))) ||
231  (type == "filelayer" && !qobject_cast<const KisFileLayer*>(nodeList.at(i))) ||
232  (type == "filterlayer" && !qobject_cast<const KisAdjustmentLayer*>(nodeList.at(i))) ||
233  (type == "filllayer" && !qobject_cast<const KisGeneratorLayer*>(nodeList.at(i))) ||
234  (type == "clonelayer" && !qobject_cast<const KisCloneLayer*>(nodeList.at(i))) ||
235  (type == "transformmask" && !qobject_cast<const KisTransformMask*>(nodeList.at(i))) ||
236  (type == "referenceimageslayer" && !qobject_cast<const KisReferenceImagesLayer*>(nodeList.at(i))) ||
237  (type == "transparencymask" && !qobject_cast<const KisTransformMask*>(nodeList.at(i))) ||
238  (type == "filtermask" && !qobject_cast<const KisFilterMask*>(nodeList.at(i))) ||
239  (type == "selectionmask" && !qobject_cast<const KisSelectionMask*>(nodeList.at(i))) ||
240  (type == "colorizemask" && !qobject_cast<const KisColorizeMask*>(nodeList.at(i)))
241  ) {
242  nodeList.removeAt(i);
243  }
244  }
245  }
246 
247  if (colorLabelIndex > 0) {
248  for (int i = nodeList.size() - 1; i >= 0; i--) {
249  if (nodeList.at(i)->colorLabelIndex() != colorLabelIndex) {
250  nodeList.removeAt(i);
251  }
252  }
253  }
254 
255  return LibKisUtils::createNodeList(nodeList, d->image);
256 }
257 
258 bool Node::addChildNode(Node *child, Node *above)
259 {
260  if (!d->node) return false;
261 
262  KUndo2Command *cmd = 0;
263 
264  if (above) {
265  cmd = new KisImageLayerAddCommand(d->image, child->node(), d->node, above->node());
266  } else {
267  cmd = new KisImageLayerAddCommand(d->image, child->node(), d->node, d->node->childCount());
268  }
269 
270  KisProcessingApplicator::runSingleCommandStroke(d->image, cmd);
271  d->image->waitForDone();
272 
273  return true;
274 }
275 
277 {
278  if (!d->node) return false;
279  return child->remove();
280 }
281 
283 {
284  if (!d->node) return;
285  KisNodeSP node = d->node->firstChild();
286  while (node) {
287  d->image->removeNode(node);
288  node = node->nextSibling();
289  }
290  Q_FOREACH(Node *node, nodes) {
291  d->image->addNode(node->node(), d->node);
292  }
293 }
294 
295 int Node::colorLabel() const
296 {
297  if (!d->node) return 0;
298  return d->node->colorLabelIndex();
299 }
300 
301 void Node::setColorLabel(int index)
302 {
303  if (!d->node) return;
304  d->node->setColorLabelIndex(index);
305 }
306 
308 {
309  if (!d->node) return "";
310  if (!d->node->projection()) return d->node->colorSpace()->colorDepthId().id();
311  return d->node->projection()->colorSpace()->colorDepthId().id();
312 }
313 
315 {
316  if (!d->node) return "";
317  if (!d->node->projection()) return d->node->colorSpace()->colorModelId().id();
318  return d->node->projection()->colorSpace()->colorModelId().id();
319 }
320 
321 
323 {
324  if (!d->node) return "";
325  if (!d->node->projection()) return d->node->colorSpace()->profile()->name();
326  return d->node->projection()->colorSpace()->profile()->name();
327 }
328 
329 bool Node::setColorProfile(const QString &colorProfile)
330 {
331  if (!d->node) return false;
332  if (!d->node->inherits("KisLayer")) return false;
333  KisLayer *layer = qobject_cast<KisLayer*>(d->node.data());
334  const KoColorProfile *profile = KoColorSpaceRegistry::instance()->profileByName(colorProfile);
335  bool result = d->image->assignLayerProfile(layer, profile);
336  d->image->waitForDone();
337  return result;
338 }
339 
340 bool Node::setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile)
341 {
342  if (!d->node) return false;
343  if (!d->node->inherits("KisLayer")) return false;
344  const KoColorProfile *profile = KoColorSpaceRegistry::instance()->profileByName(colorProfile);
345  if (!profile) return false;
346  const KoColorSpace *dstCs = KoColorSpaceRegistry::instance()->colorSpace(colorModel,
347  colorDepth,
348  profile);
349  d->image->convertLayerColorSpace(d->node, dstCs, KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags());
350  d->image->waitForDone();
351  return true;
352 }
353 
354 bool Node::animated() const
355 {
356  if (!d->node) return false;
357  return d->node->isAnimated();
358 }
359 
361 {
362  if (!d->node) return;
363  d->node->enableAnimation();
364 }
365 
366 void Node::setPinnedToTimeline(bool pinned) const
367 {
368  if (!d->node) return;
369  d->node->setPinnedToTimeline(pinned);
370 }
371 
373 {
374  if (!d->node) return false;
375  return d->node->isPinnedToTimeline();
376 }
377 
378 bool Node::collapsed() const
379 {
380  if (!d->node) return false;
381  return d->node->collapsed();
382 }
383 
384 void Node::setCollapsed(bool collapsed)
385 {
386  if (!d->node) return;
387  d->node->setCollapsed(collapsed);
388 }
389 
390 bool Node::inheritAlpha() const
391 {
392  if (!d->node) return false;
393  if (!d->node->inherits("KisLayer")) return false;
394  return qobject_cast<const KisLayer*>(d->node)->alphaChannelDisabled();
395 }
396 
397 void Node::setInheritAlpha(bool value)
398 {
399  if (!d->node) return;
400  if (!d->node->inherits("KisLayer")) return;
401  const_cast<KisLayer*>(qobject_cast<const KisLayer*>(d->node))->disableAlphaChannel(value);
402 }
403 
404 bool Node::locked() const
405 {
406  if (!d->node) return false;
407  return d->node->userLocked();
408 }
409 
410 void Node::setLocked(bool value)
411 {
412  if (!d->node) return;
413  d->node->setUserLocked(value);
414 }
415 
417 {
418  return !d->node->extent().isEmpty();
419 }
420 
422 {
423  if (!d->node) return QString();
424  return d->node->name();
425 }
426 
428 {
429  if (!d->node) return;
430  d->node->setName(name);
431 }
432 
433 
434 int Node::opacity() const
435 {
436  if (!d->node) return 0;
437  return d->node->opacity();
438 }
439 
440 void Node::setOpacity(int value)
441 {
442  if (!d->node) return;
443  if (value < 0) value = 0;
444  if (value > 255) value = 255;
445  d->node->setOpacity(value);
446 }
447 
448 
450 {
451  if (!d->node) return 0;
452  if (!d->node->parent()) return 0;
453  return Node::createNode(d->image, d->node->parent());
454 }
455 
457 {
458  if (!d->node) return QString();
459  if (qobject_cast<const KisPaintLayer*>(d->node)) {
460  return "paintlayer";
461  }
462  else if (qobject_cast<const KisGroupLayer*>(d->node)) {
463  return "grouplayer";
464  }
465  if (qobject_cast<const KisFileLayer*>(d->node)) {
466  return "filelayer";
467  }
468  if (qobject_cast<const KisAdjustmentLayer*>(d->node)) {
469  return "filterlayer";
470  }
471  if (qobject_cast<const KisGeneratorLayer*>(d->node)) {
472  return "filllayer";
473  }
474  if (qobject_cast<const KisCloneLayer*>(d->node)) {
475  return "clonelayer";
476  }
477  if (qobject_cast<const KisReferenceImagesLayer*>(d->node)) {
478  return "referenceimageslayer";
479  }
480  if (qobject_cast<const KisShapeLayer*>(d->node)) {
481  return "vectorlayer";
482  }
483  if (qobject_cast<const KisTransparencyMask*>(d->node)) {
484  return "transparencymask";
485  }
486  if (qobject_cast<const KisFilterMask*>(d->node)) {
487  return "filtermask";
488  }
489  if (qobject_cast<const KisTransformMask*>(d->node)) {
490  return "transformmask";
491  }
492  if (qobject_cast<const KisSelectionMask*>(d->node)) {
493  return "selectionmask";
494  }
495  if (qobject_cast<const KisColorizeMask*>(d->node)) {
496  return "colorizemask";
497  }
498  return QString();
499 }
500 
502 {
503  QIcon icon;
504  if (d->node) {
505  icon = d->node->icon();
506  }
507  return icon;
508 }
509 
510 bool Node::visible() const
511 {
512  if (!d->node) return false;
513  return d->node->visible();
514 }
515 
516 bool Node::hasKeyframeAtTime(int frameNumber)
517 {
518  if (!d->node || !d->node->isAnimated()) return false;
519 
520  KisRasterKeyframeChannel *rkc = dynamic_cast<KisRasterKeyframeChannel*>(d->node->getKeyframeChannel(KisKeyframeChannel::Raster.id()));
521  if (!rkc) return false;
522 
523  KisKeyframeSP currentKeyframe = rkc->keyframeAt(frameNumber);
524 
525  if (!currentKeyframe) {
526  return false;
527  }
528 
529  return true;
530 }
531 
532 void Node::setVisible(bool visible)
533 {
534  if (!d->node) return;
535  d->node->setVisible(visible);
536 }
537 
538 
539 QByteArray Node::pixelData(int x, int y, int w, int h) const
540 {
541  QByteArray ba;
542 
543  if (!d->node) return ba;
544 
545  KisPaintDeviceSP dev = d->node->paintDevice();
546  if (!dev) return ba;
547 
548  ba.resize(w * h * dev->pixelSize());
549  dev->readBytes(reinterpret_cast<quint8*>(ba.data()), x, y, w, h);
550  return ba;
551 }
552 
553 QByteArray Node::pixelDataAtTime(int x, int y, int w, int h, int time) const
554 {
555  QByteArray ba;
556 
557  if (!d->node || !d->node->isAnimated()) return ba;
558 
559  //
560  KisRasterKeyframeChannel *rkc = dynamic_cast<KisRasterKeyframeChannel*>(d->node->getKeyframeChannel(KisKeyframeChannel::Raster.id()));
561  if (!rkc) return ba;
562  KisRasterKeyframeSP frame = rkc->keyframeAt<KisRasterKeyframe>(time);
563  if (!frame) return ba;
564  KisPaintDeviceSP dev = new KisPaintDevice(*d->node->paintDevice(), KritaUtils::DeviceCopyMode::CopySnapshot);
565  if (!dev) return ba;
566 
567  frame->writeFrameToDevice(dev);
568 
569  ba.resize(w * h * dev->pixelSize());
570  dev->readBytes(reinterpret_cast<quint8*>(ba.data()), x, y, w, h);
571  return ba;
572 }
573 
574 
575 QByteArray Node::projectionPixelData(int x, int y, int w, int h) const
576 {
577  QByteArray ba;
578 
579  if (!d->node) return ba;
580 
581  KisPaintDeviceSP dev;
582  if (const KisColorizeMask *mask = qobject_cast<const KisColorizeMask*>(d->node)) {
583 
584  dev = mask->coloringProjection();
585  } else {
586  dev = d->node->projection();
587  }
588  if (!dev) return ba;
589 
590  ba.resize(w * h * dev->pixelSize());
591  dev->readBytes(reinterpret_cast<quint8*>(ba.data()), x, y, w, h);
592  return ba;
593 }
594 
595 bool Node::setPixelData(QByteArray value, int x, int y, int w, int h)
596 {
597  if (!d->node) return false;
598  KisPaintDeviceSP dev = d->node->paintDevice();
599  if (!dev) return false;
600  if (value.length() < w * h * (int)dev->colorSpace()->pixelSize()) {
601  qWarning() << "Node::setPixelData: not enough data to write to the paint device";
602  return false;
603  }
604  dev->writeBytes((const quint8*)value.constData(), x, y, w, h);
605  return true;
606 }
607 
609 {
610  if (!d->node) return QRect();
611  return d->node->exactBounds();
612 }
613 
614 void Node::move(int x, int y)
615 {
616  if (!d->node) return;
617  d->node->setX(x);
618  d->node->setY(y);
619 }
620 
622 {
623  if (!d->node) return QPoint();
624  return QPoint(d->node->x(), d->node->y());
625 }
626 
628 {
629  if (!d->node) return false;
630  if (!d->node->parent()) return false;
631 
632  KUndo2Command *cmd = new KisImageLayerRemoveCommand(d->image, d->node);
633 
634  KisProcessingApplicator::runSingleCommandStroke(d->image, cmd);
635  d->image->waitForDone();
636 
637  return true;
638 }
639 
641 {
642  if (!d->node) return 0;
643  return Node::createNode(d->image, d->node->clone());
644 }
645 
646 bool Node::save(const QString &filename, double xRes, double yRes, const InfoObject &exportConfiguration, const QRect &exportRect)
647 {
648  if (!d->node) return false;
649  if (filename.isEmpty()) return false;
650 
651  KisPaintDeviceSP projection = d->node->projection();
652  QRect bounds = (exportRect.isEmpty())? d->node->exactBounds() : exportRect;
653 
654  QString mimeType = KisMimeDatabase::mimeTypeForFile(filename, false);
655  QScopedPointer<KisDocument> doc(KisPart::instance()->createDocument());
656 
657  KisImageSP dst = new KisImage(doc->createUndoStore(),
658  bounds.right(),
659  bounds.bottom(),
660  projection->compositionSourceColorSpace(),
661  d->node->name());
662  dst->setResolution(xRes, yRes);
663  doc->setFileBatchMode(Krita::instance()->batchmode());
664  doc->setCurrentImage(dst);
665  KisPaintLayer* paintLayer = new KisPaintLayer(dst, "paint device", d->node->opacity());
666  paintLayer->paintDevice()->makeCloneFrom(projection, bounds);
667  dst->addNode(paintLayer, dst->rootLayer(), KisLayerSP(0));
668  dst->cropImage(bounds);
669  dst->initialRefreshGraph();
670 
671  bool r = doc->exportDocumentSync(filename, mimeType.toLatin1(), exportConfiguration.configuration());
672  if (!r) {
673  qWarning() << doc->errorMessage();
674  }
675  return r;
676 }
677 
679 {
680  if (!d->node) return 0;
681  if (!qobject_cast<KisLayer*>(d->node.data())) return 0;
682  if (!d->node->prevSibling()) return 0;
683 
684  d->image->mergeDown(qobject_cast<KisLayer*>(d->node.data()), KisMetaData::MergeStrategyRegistry::instance()->get("Drop"));
685  d->image->waitForDone();
686 
687  return Node::createNode(d->image, d->node->prevSibling());
688 }
689 
690 void Node::scaleNode(QPointF origin, int width, int height, QString strategy)
691 {
692  if (!d->node) return;
693  if (!qobject_cast<KisLayer*>(d->node.data())) return;
694  if (!d->node->parent()) return;
695 
696  KisFilterStrategy *actualStrategy = KisFilterStrategyRegistry::instance()->get(strategy);
697  if (!actualStrategy) actualStrategy = KisFilterStrategyRegistry::instance()->get("Bicubic");
698 
699  const QRect bounds(d->node->exactBounds());
700 
701  d->image->scaleNode(d->node,
702  origin,
703  qreal(width) / bounds.width(),
704  qreal(height) / bounds.height(),
705  actualStrategy, 0);
706  d->image->waitForDone();
707 }
708 
709 void Node::rotateNode(double radians)
710 {
711  if (!d->node) return;
712  if (!qobject_cast<KisLayer*>(d->node.data())) return;
713  if (!d->node->parent()) return;
714 
715  d->image->rotateNode(d->node, radians, 0);
716  d->image->waitForDone();
717 }
718 
719 void Node::cropNode(int x, int y, int w, int h)
720 {
721  if (!d->node) return;
722  if (!qobject_cast<KisLayer*>(d->node.data())) return;
723  if (!d->node->parent()) return;
724 
725  QRect rect = QRect(x, y, w, h);
726  d->image->cropNode(d->node, rect);
727  d->image->waitForDone();
728 }
729 
730 void Node::shearNode(double angleX, double angleY)
731 {
732  if (!d->node) return;
733  if (!qobject_cast<KisLayer*>(d->node.data())) return;
734  if (!d->node->parent()) return;
735 
736  d->image->shearNode(d->node, angleX, angleY, 0);
737  d->image->waitForDone();
738 }
739 
740 QImage Node::thumbnail(int w, int h)
741 {
742  if (!d->node) return QImage();
743  return d->node->createThumbnail(w, h);
744 }
745 
747 {
748  if (!d->node) return QString();
749 
750  KisLayer *layer = qobject_cast<KisLayer*>(d->node.data());
751 
752  if (!layer) return QString();
753 
754  KisPSDLayerStyleSP layerStyle = layer->layerStyle();
755 
756  if (!layerStyle) return QString();
757 
758  KisAslLayerStyleSerializer serializer;
759 
760  serializer.setStyles(QVector<KisPSDLayerStyleSP>() << layerStyle);
761 
762  return serializer.formPsdXmlDocument().toString();
763 }
764 
766 {
767  if (!d->node) return false;
768 
769  KisLayer *layer = qobject_cast<KisLayer*>(d->node.data());
770 
771  if (!layer) return false;
772 
773  QDomDocument aslDoc;
774 
775  if (!aslDoc.setContent(asl)) {
776  qWarning() << "ASL string format is invalid!";
777  return false;
778  }
779 
780  KisAslLayerStyleSerializer serializer;
781 
782  serializer.registerPSDPattern(aslDoc);
783  serializer.readFromPSDXML(aslDoc);
784 
785  if (serializer.styles().size() != 1) return false;
786 
787  KisPSDLayerStyleSP newStyle = serializer.styles().first();
788  KUndo2Command *cmd = new KisSetLayerStyleCommand(layer, layer->layerStyle(), newStyle);
789 
790  KisProcessingApplicator::runSingleCommandStroke(d->image, cmd);
791  d->image->waitForDone();
792 
793  return true;
794 }
795 
796 int Node::index() const
797 {
798  if (!d->node) return -1;
799  if (!d->node->parent()) return -1;
800 
801  return d->node->parent()->index(d->node);
802 }
803 
805 {
806  if (!d->node) return QUuid();
807  return d->node->uuid();
808 }
809 
810 KisPaintDeviceSP Node::paintDevice() const
811 {
812  return d->node->paintDevice();
813 }
814 
815 KisImageSP Node::image() const
816 {
817  return d->image;
818 }
819 
820 KisNodeSP Node::node() const
821 {
822  return d->node;
823 }
bool alphaLocked() const
alphaLocked checks whether the node is a paint layer and returns whether it is alpha locked
Definition: Node.cpp:151
A Channel represents a single channel in a Node.
Definition: Channel.h:22
bool hasExtents()
does the node have any content in it?
Definition: Node.cpp:416
virtual QString type() const
type Krita has several types of nodes, split in layers and masks.
Definition: Node.cpp:456
QImage thumbnail(int w, int h)
thumbnail create a thumbnail of the given dimensions.
Definition: Node.cpp:740
InfoObject wrap a properties map.
Definition: InfoObject.h:19
bool inheritAlpha() const
inheritAlpha checks whether this node has the inherits alpha flag set
Definition: Node.cpp:390
Node * duplicate()
duplicate returns a full copy of the current node.
Definition: Node.cpp:640
int opacity() const
return the opacity of the Node.
Definition: Node.cpp:434
int right() const const
bool hasKeyframeAtTime(int frameNumber)
Check to see if frame number on layer is a keyframe.
Definition: Node.cpp:516
bool animated() const
Krita layers can be animated, i.e., have frames.
Definition: Node.cpp:354
bool setColorProfile(const QString &colorProfile)
setColorProfile set the color profile of the image to the given profile.
Definition: Node.cpp:329
void setChildNodes(QList< Node * > nodes)
setChildNodes this replaces the existing set of child nodes with the new set.
Definition: Node.cpp:282
The ColorizeMask class A colorize mask is a mask type node that can be used to color in line art.
Definition: ColorizeMask.h:59
bool save(const QString &filename, double xRes, double yRes, const InfoObject &exportConfiguration, const QRect &exportRect=QRect())
save exports the given node with this filename.
Definition: Node.cpp:646
int width() const const
bool setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
QByteArray toLatin1() const const
QList< Node * > childNodes() const
childNodes
Definition: Node.cpp:205
The GroupLayer class A group layer is a layer that can contain other layers.
Definition: GroupLayer.h:29
QString layerStyleToAsl()
layerStyleToAsl retrieve the current layer's style in ASL format.
Definition: Node.cpp:746
bool visible() const
Check whether the current Node is visible in the layer stack.
Definition: Node.cpp:510
bool removeChildNode(Node *child)
removeChildNode removes the given node from the list of children.
Definition: Node.cpp:276
int index() const
index the index of the node inside the parent
Definition: Node.cpp:796
bool locked() const
locked checks whether the Node is locked.
Definition: Node.cpp:404
The TransformMask class A transform mask is a mask type node that can be used to store transformation...
Definition: TransformMask.h:22
QPoint position() const
position returns the position of the paint device of this node.
Definition: Node.cpp:621
QString colorDepth() const
colorDepth A string describing the color depth of the image:
Definition: Node.cpp:307
void rotateNode(double radians)
rotateNode rotate this layer by the given radians.
Definition: Node.cpp:709
void setName(QString name)
rename the Node to the given name
Definition: Node.cpp:427
The SelectionMask class A selection mask is a mask type node that can be used to store selections.
Definition: SelectionMask.h:26
int colorLabel() const
Sets a color label index associated to the layer.
Definition: Node.cpp:295
QRect bounds() const
bounds return the exact bounds of the node's paint device
Definition: Node.cpp:608
void enableAnimation() const
enableAnimation make the current layer animated, so it can have frames.
Definition: Node.cpp:360
int bottom() const const
QString colorProfile() const
Definition: Node.cpp:322
QUuid uniqueId() const
uniqueId uniqueId of the node
Definition: Node.cpp:804
The CloneLayer class A clone layer is a layer that takes a reference inside the image and shows the e...
Definition: CloneLayer.h:25
static Krita * instance()
instance retrieve the singleton instance of the Application object.
Definition: Krita.cpp:402
QList< Node * > findChildNodes(const QString &name=QString(), bool recursive=false, bool partialMatch=false, const QString &type=QString(), int colorLabelIndex=0) const
findChildNodes
Definition: Node.cpp:219
bool collapsed() const
returns the collapsed state of this node
Definition: Node.cpp:378
void setInheritAlpha(bool value)
set the Inherit Alpha flag to the given value
Definition: Node.cpp:397
bool isEmpty() const const
QByteArray pixelDataAtTime(int x, int y, int w, int h, int time) const
pixelDataAtTime a basic function to get pixeldata from an animated node at a given time.
Definition: Node.cpp:553
The TransparencyMask class A transparency mask is a mask type node that can be used to show and hide ...
void move(int x, int y)
move the pixels to the given x, y location in the image coordinate space.
Definition: Node.cpp:614
bool remove()
remove removes this node from its parent image.
Definition: Node.cpp:627
Node * mergeDown()
mergeDown merges the given node with the first visible node underneath this node in the layerstack.
Definition: Node.cpp:678
The FillLayer class A fill layer is much like a filter layer in that it takes a name and filter.
Definition: FillLayer.h:24
void setAlphaLocked(bool value)
setAlphaLocked set the layer to value if the node is paint layer.
Definition: Node.cpp:161
bool setPixelData(QByteArray value, int x, int y, int w, int h)
setPixelData writes the given bytes, of which there must be enough, into the Node,...
Definition: Node.cpp:595
bool isPinnedToTimeline() const
Definition: Node.cpp:372
The FileLayer class A file layer is a layer that can reference an external image and show said refere...
Definition: FileLayer.h:26
bool addChildNode(Node *child, Node *above)
addChildNode adds the given node in the list of children.
Definition: Node.cpp:258
void setBlendingMode(QString value)
setBlendingMode set the blending mode of the node to the given value
Definition: Node.cpp:178
void setOpacity(int value)
set the opacity of the Node to the given value.
Definition: Node.cpp:440
bool setLayerStyleFromAsl(const QString &asl)
setLayerStyleFromAsl set a new layer style for this node.
Definition: Node.cpp:765
Node * parentNode() const
return the Node that is the parent of the current Node, or 0 if this is the root Node.
Definition: Node.cpp:449
QIcon icon() const
icon
Definition: Node.cpp:501
void setPinnedToTimeline(bool pinned) const
Sets whether or not node should be pinned to the Timeline Docker, regardless of selection activity.
Definition: Node.cpp:366
void setVisible(bool visible)
Set the visibility of the current node to.
Definition: Node.cpp:532
void setColorLabel(int index)
setColorLabel sets a color label index associated to the layer.
Definition: Node.cpp:301
void shearNode(double angleX, double angleY)
shearNode perform a shear operation on this node.
Definition: Node.cpp:730
Node represents a layer or mask in a Krita image's Node hierarchy.
Definition: Node.h:21
int height() const const
void resize(int size)
bool isEmpty() const const
const char * constData() const const
bool setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile)
setColorSpace convert the node to the given colorspace
Definition: Node.cpp:340
void setCollapsed(bool collapsed)
Sets the state of the node to the value of.
Definition: Node.cpp:384
QString blendingMode() const
Definition: Node.cpp:171
QList< Channel * > channels() const
channels creates a list of Channel objects that can be used individually to show or hide certain chan...
Definition: Node.cpp:190
The VectorLayer class A vector layer is a special layer that stores and shows vector shapes.
Definition: VectorLayer.h:31
QByteArray pixelData(int x, int y, int w, int h) const
pixelData reads the given rectangle from the Node's paintable pixels, if those exist,...
Definition: Node.cpp:539
QByteArray projectionPixelData(int x, int y, int w, int h) const
projectionPixelData reads the given rectangle from the Node's projection (that is,...
Definition: Node.cpp:575
int length() const const
void scaleNode(QPointF origin, int width, int height, QString strategy)
scaleNode
Definition: Node.cpp:690
void setLocked(bool value)
set the Locked flag to the give value
Definition: Node.cpp:410
QString colorModel() const
colorModel retrieve the current color model of this document:
Definition: Node.cpp:314
The FilterMask class A filter mask, unlike a filter layer, will add a non-destructive filter to the c...
Definition: FilterMask.h:28
QString name() const
Definition: Node.cpp:421
QObject * parent() const const
Node * clone() const
clone clone the current node.
Definition: Node.cpp:143
char * data()
void cropNode(int x, int y, int w, int h)
cropNode crop this layer.
Definition: Node.cpp:719
The FilterLayer class A filter layer will, when compositing, take the composited image up to the poin...
Definition: FilterLayer.h:33
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Fri Sep 22 2023 04:09:51 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.