Krita Source Code Documentation
Loading...
Searching...
No Matches
Node.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2016 Boudewijn Rempt <boud@valdyas.org>
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>
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>
24#include <kis_generator_layer.h>
25#include <kis_clone_layer.h>
26#include <kis_shape_layer.h>
29#include <kis_filter_mask.h>
30#include <kis_transform_mask.h>
31#include <kis_selection_mask.h>
33#include <kis_layer.h>
36#include <kis_filter_strategy.h>
43
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#include "PaintingResources.h"
71#include "KisMainWindow.h"
72#include "kis_canvas2.h"
75
76
82
83Node::Node(KisImageSP image, KisNodeSP node, QObject *parent)
84 : QObject(parent)
85 , d(new Private)
86{
87 d->image = image;
88 d->node = node;
89}
90
91Node *Node::createNode(KisImageSP image, KisNodeSP node, QObject *parent)
92{
93 if (node.isNull()) {
94 return 0;
95 }
96 if (node->inherits("KisGroupLayer")) {
97 return new GroupLayer(dynamic_cast<KisGroupLayer*>(node.data()));
98 }
99 else if (node->inherits("KisCloneLayer")) {
100 return new CloneLayer(dynamic_cast<KisCloneLayer*>(node.data()));
101 }
102 else if (node->inherits("KisFileLayer")) {
103 return new FileLayer(dynamic_cast<KisFileLayer*>(node.data()));
104 }
105 else if (node->inherits("KisAdjustmentLayer")) {
106 return new FilterLayer(dynamic_cast<KisAdjustmentLayer*>(node.data()));
107 }
108 else if (node->inherits("KisGeneratorLayer")) {
109 return new FillLayer(dynamic_cast<KisGeneratorLayer*>(node.data()));
110 }
111 else if (node->inherits("KisShapeLayer")) {
112 return new VectorLayer(dynamic_cast<KisShapeLayer*>(node.data()));
113 }
114 else if (node->inherits("KisFilterMask")) {
115 return new FilterMask(image, dynamic_cast<KisFilterMask*>(node.data()));
116 }
117 else if (node->inherits("KisSelectionMask")) {
118 return new SelectionMask(image, dynamic_cast<KisSelectionMask*>(node.data()));
119 }
120 else if (node->inherits("KisTransparencyMask")) {
121 return new TransparencyMask(image, dynamic_cast<KisTransparencyMask*>(node.data()));
122 }
123 else if (node->inherits("KisTransformMask")) {
124 return new TransformMask(image, dynamic_cast<KisTransformMask*>(node.data()));
125 }
126 else if (node->inherits("KisColorizeMask")) {
127 return new ColorizeMask(image, dynamic_cast<KisColorizeMask*>(node.data()));
128 }
129 else {
130 return new Node(image, node, parent);
131 }
132}
133
135{
136 delete d;
137}
138
139bool Node::operator==(const Node &other) const
140{
141 return (d->node == other.d->node
142 && d->image == other.d->image);
143}
144
145bool Node::operator!=(const Node &other) const
146{
147 return !(operator==(other));
148}
149
151{
152 KisNodeSP clone = d->node->clone();
154 return node;
155}
156
157
159{
160 if (!d->node) return false;
161 KisPaintLayerSP paintLayer = qobject_cast<KisPaintLayer*>(d->node.data());
162 if (paintLayer) {
163 return paintLayer->alphaLocked();
164 }
165 return false;
166}
167
169{
170 if (!d->node) return;
171 KisPaintLayerSP paintLayer = qobject_cast<KisPaintLayer*>(d->node.data());
172 if (paintLayer) {
173 paintLayer->setAlphaLocked(value);
174 }
175}
176
177
178QString Node::blendingMode() const
179{
180 if (!d->node) return QString();
181
182 return d->node->compositeOpId();
183}
184
186{
187 if (!d->node) return;
188
190 value);
191
193 d->image->waitForDone();
194}
195
196
198{
200
201 if (!d->node) return channels;
202 if (!d->node->inherits("KisLayer")) return channels;
203
204 Q_FOREACH(KoChannelInfo *info, d->node->colorSpace()->channels()) {
205 Channel *channel = new Channel(d->node, info);
206 channels << channel;
207 }
208
209 return channels;
210}
211
213{
214 QList<Node*> nodes;
215 if (d->node) {
216 KisNodeList nodeList;
217 int childCount = d->node->childCount();
218 for (int i = 0; i < childCount; ++i) {
219 nodeList << d->node->at(i);
220 }
221 nodes = LibKisUtils::createNodeList(nodeList, d->image);
222 }
223 return nodes;
224}
225
226QList<Node*> Node::findChildNodes(const QString &name, bool recursive, bool partialMatch, const QString &type, int colorLabelIndex) const
227{
228 if (!d->node) return {};
229
230 QList<Node*> nodes;
231 KisNodeList nodeList = KisLayerUtils::findNodesByName(d->node, name, recursive, partialMatch);
232
233 if (!type.isEmpty()) {
234 for (int i = nodeList.size() - 1; i >= 0; i--) {
235 if ((type == "paintlayer" && !qobject_cast<const KisPaintLayer*>(nodeList.at(i))) ||
236 (type == "vectorlayer" && !qobject_cast<const KisShapeLayer*>(nodeList.at(i))) ||
237 (type == "grouplayer" && !qobject_cast<const KisGroupLayer*>(nodeList.at(i))) ||
238 (type == "filelayer" && !qobject_cast<const KisFileLayer*>(nodeList.at(i))) ||
239 (type == "filterlayer" && !qobject_cast<const KisAdjustmentLayer*>(nodeList.at(i))) ||
240 (type == "filllayer" && !qobject_cast<const KisGeneratorLayer*>(nodeList.at(i))) ||
241 (type == "clonelayer" && !qobject_cast<const KisCloneLayer*>(nodeList.at(i))) ||
242 (type == "transformmask" && !qobject_cast<const KisTransformMask*>(nodeList.at(i))) ||
243 (type == "referenceimageslayer" && !qobject_cast<const KisReferenceImagesLayer*>(nodeList.at(i))) ||
244 (type == "transparencymask" && !qobject_cast<const KisTransformMask*>(nodeList.at(i))) ||
245 (type == "filtermask" && !qobject_cast<const KisFilterMask*>(nodeList.at(i))) ||
246 (type == "selectionmask" && !qobject_cast<const KisSelectionMask*>(nodeList.at(i))) ||
247 (type == "colorizemask" && !qobject_cast<const KisColorizeMask*>(nodeList.at(i)))
248 ) {
249 nodeList.removeAt(i);
250 }
251 }
252 }
253
254 if (colorLabelIndex > 0) {
255 for (int i = nodeList.size() - 1; i >= 0; i--) {
256 if (nodeList.at(i)->colorLabelIndex() != colorLabelIndex) {
257 nodeList.removeAt(i);
258 }
259 }
260 }
261
262 return LibKisUtils::createNodeList(nodeList, d->image);
263}
264
265bool Node::addChildNode(Node *child, Node *above)
266{
267 if (!d->node) return false;
268
269 KUndo2Command *cmd = 0;
270
271 if (above) {
272 cmd = new KisImageLayerAddCommand(d->image, child->node(), d->node, above->node());
273 } else {
274 cmd = new KisImageLayerAddCommand(d->image, child->node(), d->node, d->node->childCount());
275 }
276
278 d->image->waitForDone();
279
280 return true;
281}
282
284{
285 if (!d->node) return false;
286 return child->remove();
287}
288
290{
291 if (!d->node) return;
292 while (d->node->firstChild()) {
294 }
295 Q_FOREACH(Node *node, nodes) {
296 d->image->addNode(node->node(), d->node);
297 }
298}
299
301{
302 if (!d->node) return 0;
303 return d->node->colorLabelIndex();
304}
305
306void Node::setColorLabel(int index)
307{
308 if (!d->node) return;
310}
311
312QString Node::colorDepth() const
313{
314 if (!d->node) return "";
315 if (!d->node->projection()) return d->node->colorSpace()->colorDepthId().id();
316 return d->node->projection()->colorSpace()->colorDepthId().id();
317}
318
319QString Node::colorModel() const
320{
321 if (!d->node) return "";
322 if (!d->node->projection()) return d->node->colorSpace()->colorModelId().id();
323 return d->node->projection()->colorSpace()->colorModelId().id();
324}
325
326
327QString Node::colorProfile() const
328{
329 if (!d->node) return "";
330 if (!d->node->projection()) return d->node->colorSpace()->profile()->name();
331 return d->node->projection()->colorSpace()->profile()->name();
332}
333
334bool Node::setColorProfile(const QString &colorProfile)
335{
336 if (!d->node) return false;
337 if (!d->node->inherits("KisLayer")) return false;
338 KisLayer *layer = qobject_cast<KisLayer*>(d->node.data());
340 bool result = d->image->assignLayerProfile(layer, profile);
341 d->image->waitForDone();
342 return result;
343}
344
345bool Node::setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile)
346{
347 if (!d->node) return false;
348 if (!d->node->inherits("KisLayer")) return false;
350 if (!profile) return false;
353 profile);
355 d->image->waitForDone();
356 return true;
357}
358
359bool Node::animated() const
360{
361 if (!d->node) return false;
362 return d->node->isAnimated();
363}
364
366{
367 if (!d->node) return;
369}
370
371void Node::setPinnedToTimeline(bool pinned) const
372{
373 if (!d->node) return;
374 d->node->setPinnedToTimeline(pinned);
375}
376
378{
379 if (!d->node) return false;
380 return d->node->isPinnedToTimeline();
381}
382
383bool Node::collapsed() const
384{
385 if (!d->node) return false;
386 return d->node->collapsed();
387}
388
389void Node::setCollapsed(bool collapsed)
390{
391 if (!d->node) return;
393}
394
396{
397 if (!d->node) return false;
398 if (!d->node->inherits("KisLayer")) return false;
399 return qobject_cast<const KisLayer*>(d->node)->alphaChannelDisabled();
400}
401
403{
404 if (!d->node) return;
405 if (!d->node->inherits("KisLayer")) return;
406 const_cast<KisLayer*>(qobject_cast<const KisLayer*>(d->node))->disableAlphaChannel(value);
407}
408
409bool Node::locked() const
410{
411 if (!d->node) return false;
412 return d->node->userLocked();
413}
414
416{
417 if (!d->node) return;
419}
420
422{
423 return !d->node->extent().isEmpty();
424}
425
426QString Node::name() const
427{
428 if (!d->node) return QString();
429 return d->node->name();
430}
431
432void Node::setName(QString name)
433{
434 if (!d->node) return;
435 d->node->setName(name);
436}
437
438
439int Node::opacity() const
440{
441 if (!d->node) return 0;
442 return d->node->opacity();
443}
444
446{
447 if (!d->node) return;
448 if (value < 0) value = 0;
449 if (value > 255) value = 255;
451}
452
453
455{
456 if (!d->node) return 0;
457 if (!d->node->parent()) return 0;
458 return Node::createNode(d->image, d->node->parent());
459}
460
461QString Node::type() const
462{
463 if (!d->node) return QString();
464 if (qobject_cast<const KisPaintLayer*>(d->node)) {
465 return "paintlayer";
466 }
467 else if (qobject_cast<const KisGroupLayer*>(d->node)) {
468 return "grouplayer";
469 }
470 if (qobject_cast<const KisFileLayer*>(d->node)) {
471 return "filelayer";
472 }
473 if (qobject_cast<const KisAdjustmentLayer*>(d->node)) {
474 return "filterlayer";
475 }
476 if (qobject_cast<const KisGeneratorLayer*>(d->node)) {
477 return "filllayer";
478 }
479 if (qobject_cast<const KisCloneLayer*>(d->node)) {
480 return "clonelayer";
481 }
482 if (qobject_cast<const KisReferenceImagesLayer*>(d->node)) {
483 return "referenceimageslayer";
484 }
485 if (qobject_cast<const KisShapeLayer*>(d->node)) {
486 return "vectorlayer";
487 }
488 if (qobject_cast<const KisTransparencyMask*>(d->node)) {
489 return "transparencymask";
490 }
491 if (qobject_cast<const KisFilterMask*>(d->node)) {
492 return "filtermask";
493 }
494 if (qobject_cast<const KisTransformMask*>(d->node)) {
495 return "transformmask";
496 }
497 if (qobject_cast<const KisSelectionMask*>(d->node)) {
498 return "selectionmask";
499 }
500 if (qobject_cast<const KisColorizeMask*>(d->node)) {
501 return "colorizemask";
502 }
503 return QString();
504}
505
506QIcon Node::icon() const
507{
508 QIcon icon;
509 if (d->node) {
510 icon = d->node->icon();
511 }
512 return icon;
513}
514
515bool Node::visible() const
516{
517 if (!d->node) return false;
518 return d->node->visible();
519}
520
521bool Node::hasKeyframeAtTime(int frameNumber)
522{
523 if (!d->node || !d->node->isAnimated()) return false;
524
526 if (!rkc) return false;
527
528 KisKeyframeSP currentKeyframe = rkc->keyframeAt(frameNumber);
529
530 if (!currentKeyframe) {
531 return false;
532 }
533
534 return true;
535}
536
537void Node::setVisible(bool visible)
538{
539 if (!d->node) return;
541}
542
543
544QByteArray Node::pixelData(int x, int y, int w, int h) const
545{
546 QByteArray ba;
547
548 if (!d->node) return ba;
549
551 if (!dev) return ba;
552
553 ba.resize(w * h * dev->pixelSize());
554 dev->readBytes(reinterpret_cast<quint8*>(ba.data()), x, y, w, h);
555 return ba;
556}
557
558QByteArray Node::pixelDataAtTime(int x, int y, int w, int h, int time) const
559{
560 QByteArray ba;
561
562 if (!d->node || !d->node->isAnimated()) return ba;
563
564 //
566 if (!rkc) return ba;
568 if (!frame) return ba;
570 if (!dev) return ba;
571
572 frame->writeFrameToDevice(dev);
573
574 ba.resize(w * h * dev->pixelSize());
575 dev->readBytes(reinterpret_cast<quint8*>(ba.data()), x, y, w, h);
576 return ba;
577}
578
579
580QByteArray Node::projectionPixelData(int x, int y, int w, int h) const
581{
582 QByteArray ba;
583
584 if (!d->node) return ba;
585
587 if (const KisColorizeMask *mask = qobject_cast<const KisColorizeMask*>(d->node)) {
588
589 dev = mask->coloringProjection();
590 } else {
591 dev = d->node->projection();
592 }
593 if (!dev) return ba;
594
595 ba.resize(w * h * dev->pixelSize());
596 dev->readBytes(reinterpret_cast<quint8*>(ba.data()), x, y, w, h);
597 return ba;
598}
599
600bool Node::setPixelData(QByteArray value, int x, int y, int w, int h)
601{
602 if (!d->node) return false;
604 if (!dev) return false;
605 if (value.length() < w * h * (int)dev->colorSpace()->pixelSize()) {
606 qWarning() << "Node::setPixelData: not enough data to write to the paint device";
607 return false;
608 }
609 dev->writeBytes((const quint8*)value.constData(), x, y, w, h);
610 return true;
611}
612
613QRect Node::bounds() const
614{
615 if (!d->node) return QRect();
616 return d->node->exactBounds();
617}
618
619void Node::move(int x, int y)
620{
621 if (!d->node) return;
622 d->node->setX(x);
623 d->node->setY(y);
624}
625
626QPoint Node::position() const
627{
628 if (!d->node) return QPoint();
629 return QPoint(d->node->x(), d->node->y());
630}
631
633{
634 if (!d->node) return false;
635 if (!d->node->parent()) return false;
636
638
640 d->image->waitForDone();
641
642 return true;
643}
644
646{
647 if (!d->node) return 0;
648 return Node::createNode(d->image, d->node->clone());
649}
650
651bool Node::save(const QString &filename, double xRes, double yRes, const InfoObject &exportConfiguration, const QRect &exportRect)
652{
653 if (!d->node) return false;
654 if (filename.isEmpty()) return false;
655
656 KisPaintDeviceSP projection = d->node->projection();
657 QRect bounds = (exportRect.isEmpty())? d->node->exactBounds() : exportRect;
658
659 QString mimeType = KisMimeDatabase::mimeTypeForFile(filename, false);
660 QScopedPointer<KisDocument> doc(KisPart::instance()->createDocument());
661
662 KisImageSP dst = new KisImage(doc->createUndoStore(),
663 bounds.right(),
664 bounds.bottom(),
665 projection->compositionSourceColorSpace(),
666 d->node->name());
667 dst->setResolution(xRes, yRes);
668 doc->setFileBatchMode(Krita::instance()->batchmode());
669 doc->setCurrentImage(dst);
670 KisPaintLayer* paintLayer = new KisPaintLayer(dst, "paint device", d->node->opacity());
671 paintLayer->paintDevice()->makeCloneFrom(projection, bounds);
672 dst->addNode(paintLayer, dst->rootLayer(), KisLayerSP(0));
673 dst->cropImage(bounds);
674 dst->initialRefreshGraph();
675
676 bool r = doc->exportDocumentSync(filename, mimeType.toLatin1(), exportConfiguration.configuration());
677 if (!r) {
678 qWarning() << doc->errorMessage();
679 }
680 return r;
681}
682
684{
685 if (!d->node) return 0;
686 if (!qobject_cast<KisLayer*>(d->node.data())) return 0;
687 if (!d->node->prevSibling()) return 0;
688
689 d->image->mergeDown(qobject_cast<KisLayer*>(d->node.data()), KisMetaData::MergeStrategyRegistry::instance()->get("Drop"));
690 d->image->waitForDone();
691
693}
694
695void Node::scaleNode(QPointF origin, int width, int height, QString strategy)
696{
697 if (!d->node) return;
698 if (!qobject_cast<KisLayer*>(d->node.data())) return;
699 if (!d->node->parent()) return;
700
701 KisFilterStrategy *actualStrategy = KisFilterStrategyRegistry::instance()->get(strategy);
702 if (!actualStrategy) actualStrategy = KisFilterStrategyRegistry::instance()->get("Bicubic");
703
704 const QRect bounds(d->node->exactBounds());
705
707 origin,
708 qreal(width) / bounds.width(),
709 qreal(height) / bounds.height(),
710 actualStrategy, 0);
711 d->image->waitForDone();
712}
713
714void Node::rotateNode(double radians)
715{
716 if (!d->node) return;
717 if (!qobject_cast<KisLayer*>(d->node.data())) return;
718 if (!d->node->parent()) return;
719
720 d->image->rotateNode(d->node, radians, 0);
721 d->image->waitForDone();
722}
723
724void Node::cropNode(int x, int y, int w, int h)
725{
726 if (!d->node) return;
727 if (!qobject_cast<KisLayer*>(d->node.data())) return;
728 if (!d->node->parent()) return;
729
730 QRect rect = QRect(x, y, w, h);
731 d->image->cropNode(d->node, rect);
732 d->image->waitForDone();
733}
734
735void Node::shearNode(double angleX, double angleY)
736{
737 if (!d->node) return;
738 if (!qobject_cast<KisLayer*>(d->node.data())) return;
739 if (!d->node->parent()) return;
740
741 d->image->shearNode(d->node, angleX, angleY, 0);
742 d->image->waitForDone();
743}
744
745QImage Node::thumbnail(int w, int h)
746{
747 if (!d->node) return QImage();
748 return d->node->createThumbnail(w, h);
749}
750
752{
753 if (!d->node) return QString();
754
755 KisLayer *layer = qobject_cast<KisLayer*>(d->node.data());
756
757 if (!layer) return QString();
758
759 KisPSDLayerStyleSP layerStyle = layer->layerStyle();
760
761 if (!layerStyle) return QString();
762
764
765 serializer.setStyles(QVector<KisPSDLayerStyleSP>() << layerStyle);
766
767 return serializer.formPsdXmlDocument().toString();
768}
769
770bool Node::setLayerStyleFromAsl(const QString &asl)
771{
772 if (!d->node) return false;
773
774 KisLayer *layer = qobject_cast<KisLayer*>(d->node.data());
775
776 if (!layer) return false;
777
778 QDomDocument aslDoc;
779
780 if (!aslDoc.setContent(asl)) {
781 qWarning() << "ASL string format is invalid!";
782 return false;
783 }
784
786
787 serializer.registerPSDPattern(aslDoc);
788 serializer.readFromPSDXML(aslDoc);
789
790 if (serializer.styles().size() != 1) return false;
791
792 KisPSDLayerStyleSP newStyle = serializer.styles().first();
793 KUndo2Command *cmd = new KisSetLayerStyleCommand(layer, layer->layerStyle(), newStyle);
794
796 d->image->waitForDone();
797
798 return true;
799}
800
801int Node::index() const
802{
803 if (!d->node) return -1;
804 if (!d->node->parent()) return -1;
805
806 return d->node->parent()->index(d->node);
807}
808
809QUuid Node::uniqueId() const
810{
811 if (!d->node) return QUuid();
812 return d->node->uuid();
813}
814
816{
817 return d->node->paintDevice();
818}
819
821{
822 return d->image;
823}
824
826{
827 return d->node;
828}
829
831{
832 // Taken from KisTool:nodePaintAbility().
834 KisCanvas2 *canvas = mainWindow->activeView()->canvasBase();
835 if (canvas->resourceManager()->resource(KoCanvasResource::CurrentPaintOpPreset).isNull()) {
836 return "UNPAINTABLE";
837 }
838
839 if (!d->node) {
840 return "UNPAINTABLE";
841 }
842
843 if (d->node->inherits("KisShapeLayer")) {
844 return "VECTOR";
845 }
846 if (d->node->inherits("KisCloneLayer")) {
847 return "CLONE";
848 }
849 if (d->node->paintDevice()) {
850
851 KisPaintOpPresetSP currentPaintOpPreset = canvas->resourceManager()->resource(KoCanvasResource::CurrentPaintOpPreset).value<KisPaintOpPresetSP>();
852 if (currentPaintOpPreset->paintOp().id() == "mypaintbrush") {
853 const KoColorSpace *colorSpace = d->node->paintDevice()->colorSpace();
854 if (colorSpace->colorModelId() != RGBAColorModelID) {
855 return "MYPAINTBRUSH_UNPAINTABLE";
856 }
857 }
858
859 return "PAINT";
860 }
861
862 return "UNPAINTABLE";
863}
864
865void Node::paintLine(const QPointF pointOne, const QPointF pointTwo, double pressureOne, double pressureTwo, const QString strokeStyle)
866{
867 if (paintAbility() != "PAINT") {
868 dbgScript << "Script attempted to use Node::paintLine() on an unpaintable node, ignoring.";
869 return;
870 }
871
872 KisPaintInformation pointOneInfo;
873 pointOneInfo.setPressure(pressureOne);
874 pointOneInfo.setPos(pointOne);
875
876 KisPaintInformation pointTwoInfo;
877 pointTwoInfo.setPressure(pressureTwo);
878 pointTwoInfo.setPos(pointTwo);
879
881 helper.paintLine(pointOneInfo, pointTwoInfo);
882}
883
884
885void Node::paintRectangle(const QRectF &rect, const QString strokeStyle, const QString fillStyle)
886{
887 if (paintAbility() != "PAINT") {
888 dbgScript << "Script attempted to use Node::paintRectangle() on an unpaintable node, ignoring.";
889 return;
890 }
891
892 // reference class where this stuff is being done. Maybe can use the "facade" like that does for setup?
893 // void KisFigurePaintingToolHelper::paintRect(const QRectF &rect)
894
895 KisFigurePaintingToolHelper helper = PaintingResources::createHelper(d->image, node(), strokeStyle, fillStyle);
896 helper.paintRect(rect);
897}
898
899
900void Node::paintPolygon(const QList<QPointF> listPoint, const QString strokeStyle, const QString fillStyle)
901{
902 if (paintAbility() != "PAINT") {
903 dbgScript << "Script attempted to use Node::paintPolygon() on an unpaintable node, ignoring.";
904 return;
905 }
906
907 // strategy needs points in vPointF format
908 QVector<QPointF> points = points.fromList(listPoint);
909 KisFigurePaintingToolHelper helper = PaintingResources::createHelper(d->image, node(), strokeStyle, fillStyle);
910 helper.paintPolygon(points);
911}
912
913
914void Node::paintEllipse(const QRectF &rect, const QString strokeStyle, const QString fillStyle)
915{
916 if (paintAbility() != "PAINT") {
917 dbgScript << "Script attempted to use Node::paintEllipse() on an unpaintable node, ignoring.";
918 return;
919 }
920
921 KisFigurePaintingToolHelper helper = PaintingResources::createHelper(d->image, node(), strokeStyle, fillStyle);
922 helper.paintEllipse(rect);
923}
924
925
926void Node::paintPath(const QPainterPath &path, const QString strokeStyle, const QString fillStyle)
927{
928 if (paintAbility() != "PAINT") {
929 dbgScript << "Script attempted to use Node::paintPath() on an unpaintable node, ignoring.";
930 return;
931 }
932
933 KisFigurePaintingToolHelper helper = PaintingResources::createHelper(d->image, node(), strokeStyle, fillStyle);
934 helper.paintPainterPath(path);
935}
float value(const T *src, size_t ch)
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
KisPropertiesConfigurationSP configuration() const
configuration gives access to the internal configuration object. Must be used internally in libkis
QVector< KisPSDLayerStyleSP > styles() const
void readFromPSDXML(const QDomDocument &doc)
void registerPSDPattern(const QDomDocument &doc)
void setStyles(const QVector< KisPSDLayerStyleSP > &styles)
void paintPainterPath(const QPainterPath &path)
void paintLine(const KisPaintInformation &pi0, const KisPaintInformation &pi1)
The KisFileLayer class loads a particular file as a layer into the layer stack.
static KisFilterStrategyRegistry * instance()
The command for adding a layer.
void scaleNode(KisNodeSP node, const QPointF &center, qreal scaleX, qreal scaleY, KisFilterStrategy *filterStrategy, KisSelectionSP selection)
start asynchronous operation on scaling a subtree of nodes starting at node
void waitForDone()
KisGroupLayerSP rootLayer() const
void cropNode(KisNodeSP node, const QRect &newRect, const bool activeFrameOnly=false)
start asynchronous operation on cropping a subtree of nodes starting at node
Definition kis_image.cc:931
void shearNode(KisNodeSP node, double angleX, double angleY, KisSelectionSP selection)
start asynchronous operation on shearing a subtree of nodes starting at node
void cropImage(const QRect &newRect)
start asynchronous operation on cropping the image
Definition kis_image.cc:870
bool assignLayerProfile(KisNodeSP node, const KoColorProfile *profile)
void initialRefreshGraph()
void mergeDown(KisLayerSP l, const KisMetaData::MergeStrategy *strategy)
void convertLayerColorSpace(KisNodeSP node, const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
void setResolution(double xres, double yres)
void rotateNode(KisNodeSP node, double radians, KisSelectionSP selection)
start asynchronous operation on rotating a subtree of nodes starting at node
static const KoID Raster
KisKeyframeSP keyframeAt(int time) const
Get a keyframe at specified time. Used primarily when the value of a given keyframe is needed.
Main window for Krita.
QPointer< KisView > activeView
static QString mimeTypeForFile(const QString &file, bool checkExistingFiles=true)
Find the mimetype for the given filename. The filename must include a suffix.
The command for setting the composite op.
quint32 pixelSize() const
virtual const KoColorSpace * compositionSourceColorSpace() const
const KoColorSpace * colorSpace() const
void readBytes(quint8 *data, qint32 x, qint32 y, qint32 w, qint32 h) const
void makeCloneFrom(KisPaintDeviceSP src, const QRect &rect)
void writeBytes(const quint8 *data, qint32 x, qint32 y, qint32 w, qint32 h)
void setPos(const QPointF &p)
void setPressure(qreal p)
Set the pressure.
static KisPart * instance()
Definition KisPart.cpp:131
KisMainWindow * currentMainwindow() const
Definition KisPart.cpp:459
static void runSingleCommandStroke(KisImageSP image, KUndo2Command *cmd, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
runSingleCommandStroke creates a stroke and runs cmd in it. The text() field of cmd is used as a titl...
The KisRasterKeyframeChannel is a concrete KisKeyframeChannel subclass that stores and manages KisRas...
The KisRasterKeyframe class is a concrete subclass of KisKeyframe that wraps a physical raster image ...
bool isNull() const
QPointer< KoCanvasResourceProvider > resourceManager
virtual quint32 pixelSize() const =0
QList< KoChannelInfo * > channels
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
virtual const KoColorProfile * profile() const =0
T get(const QString &id) const
QString id() const
Definition KoID.cpp:63
static Krita * instance()
instance retrieve the singleton instance of the Application object.
Definition Krita.cpp:396
Definition Node.h:24
bool alphaLocked() const
alphaLocked checks whether the node is a paint layer and returns whether it is alpha locked
Definition Node.cpp:158
void setBlendingMode(QString value)
setBlendingMode set the blending mode of the node to the given value
Definition Node.cpp:185
QList< Node * > childNodes() const
childNodes
Definition Node.cpp:212
void scaleNode(QPointF origin, int width, int height, QString strategy)
scaleNode
Definition Node.cpp:695
void setAlphaLocked(bool value)
setAlphaLocked set the layer to value if the node is paint layer.
Definition Node.cpp:168
void paintPolygon(const QList< QPointF > points, const QString strokeStyle=PaintingResources::defaultStrokeStyle, const QString fillStyle=PaintingResources::defaultFillStyle)
paint a polygon on the canvas. Uses current brush preset
Definition Node.cpp:900
Node * mergeDown()
mergeDown merges the given node with the first visible node underneath this node in the layerstack....
Definition Node.cpp:683
bool operator==(const Node &other) const
Definition Node.cpp:139
void setCollapsed(bool collapsed)
Definition Node.cpp:389
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:197
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:226
void enableAnimation() const
enableAnimation make the current layer animated, so it can have frames.
Definition Node.cpp:365
Node(KisImageSP image, KisNodeSP node, QObject *parent=0)
Definition Node.cpp:83
QString colorDepth() const
Definition Node.cpp:312
void setOpacity(int value)
Definition Node.cpp:445
bool locked() const
locked checks whether the Node is locked. A locked node cannot be changed.
Definition Node.cpp:409
QUuid uniqueId() const
uniqueId uniqueId of the node
Definition Node.cpp:809
QPoint position() const
position returns the position of the paint device of this node. The position is always 0,...
Definition Node.cpp:626
void setPinnedToTimeline(bool pinned) const
Sets whether or not node should be pinned to the Timeline Docker, regardless of selection activity.
Definition Node.cpp:371
void move(int x, int y)
Definition Node.cpp:619
void setChildNodes(QList< Node * > nodes)
setChildNodes this replaces the existing set of child nodes with the new set.
Definition Node.cpp:289
void paintEllipse(const QRectF &rect, const QString strokeStyle=PaintingResources::defaultStrokeStyle, const QString fillStyle=PaintingResources::defaultFillStyle)
paint an ellipse on the canvas. Uses current brush preset
Definition Node.cpp:914
QIcon icon() const
icon
Definition Node.cpp:506
bool visible() const
Definition Node.cpp:515
QString colorModel() const
colorModel retrieve the current color model of this document:
Definition Node.cpp:319
Private *const d
Definition Node.h:721
void paintLine(const QPointF pointOne, const QPointF pointTwo, double pressureOne=1.0, double pressureTwo=1.0, const QString strokeStyle=PaintingResources::defaultStrokeStyle)
paint a line on the canvas. Uses current brush preset
Definition Node.cpp:865
bool operator!=(const Node &other) const
Definition Node.cpp:145
bool hasKeyframeAtTime(int frameNumber)
Definition Node.cpp:521
void shearNode(double angleX, double angleY)
shearNode perform a shear operation on this node.
Definition Node.cpp:735
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:600
friend class FilterMask
Definition Node.h:703
friend class TransparencyMask
Definition Node.h:705
KisNodeSP node() const
Definition Node.cpp:825
bool setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile)
setColorSpace convert the node to the given colorspace
Definition Node.cpp:345
virtual QString type() const
type Krita has several types of nodes, split in layers and masks. Group layers can contain other laye...
Definition Node.cpp:461
~Node() override
Definition Node.cpp:134
void paintRectangle(const QRectF &rect, const QString strokeStyle=PaintingResources::defaultStrokeStyle, const QString fillStyle=PaintingResources::defaultFillStyle)
paint a rectangle on the canvas. Uses current brush preset
Definition Node.cpp:885
void setLocked(bool value)
Definition Node.cpp:415
bool animated() const
Krita layers can be animated, i.e., have frames.
Definition Node.cpp:359
bool remove()
remove removes this node from its parent image.
Definition Node.cpp:632
bool inheritAlpha() const
inheritAlpha checks whether this node has the inherits alpha flag set
Definition Node.cpp:395
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:544
void setName(QString name)
Definition Node.cpp:432
KisImageSP image() const
Definition Node.cpp:820
friend class SelectionMask
Definition Node.h:704
bool save(const QString &filename, double xRes, double yRes, const InfoObject &exportConfiguration, const QRect &exportRect=QRect())
save exports the given node with this filename. The extension of the filename determines the filetype...
Definition Node.cpp:651
void cropNode(int x, int y, int w, int h)
cropNode crop this layer.
Definition Node.cpp:724
QString paintAbility()
paintAbility can be used to determine whether this node can be painted on with the current brush pres...
Definition Node.cpp:830
static Node * createNode(KisImageSP image, KisNodeSP node, QObject *parent=0)
Definition Node.cpp:91
void rotateNode(double radians)
rotateNode rotate this layer by the given radians.
Definition Node.cpp:714
int index() const
index the index of the node inside the parent
Definition Node.cpp:801
int opacity() const
Definition Node.cpp:439
bool collapsed() const
Definition Node.cpp:383
bool setLayerStyleFromAsl(const QString &asl)
setLayerStyleFromAsl set a new layer style for this node.
Definition Node.cpp:770
int colorLabel() const
Definition Node.cpp:300
QString blendingMode() const
Definition Node.cpp:178
friend class FilterLayer
Definition Node.h:700
QString layerStyleToAsl()
layerStyleToAsl retrieve the current layer's style in ASL format.
Definition Node.cpp:751
friend class FileLayer
Definition Node.h:699
friend class VectorLayer
Definition Node.h:702
bool setColorProfile(const QString &colorProfile)
setColorProfile set the color profile of the image to the given profile. The profile has to be regist...
Definition Node.cpp:334
bool addChildNode(Node *child, Node *above)
addChildNode adds the given node in the list of children.
Definition Node.cpp:265
QImage thumbnail(int w, int h)
thumbnail create a thumbnail of the given dimensions. The thumbnail is sized according to the layer d...
Definition Node.cpp:745
void paintPath(const QPainterPath &path, const QString strokeStyle=PaintingResources::defaultStrokeStyle, const QString fillStyle=PaintingResources::defaultFillStyle)
paint a custom path on the canvas. Uses current brush preset
Definition Node.cpp:926
bool hasExtents()
does the node have any content in it?
Definition Node.cpp:421
friend class FillLayer
Definition Node.h:701
KisPaintDeviceSP paintDevice() const
paintDevice gives access to the internal paint device of this Node
Definition Node.cpp:815
Node * duplicate()
duplicate returns a full copy of the current node. The node is not inserted in the graphic
Definition Node.cpp:645
void setInheritAlpha(bool value)
Definition Node.cpp:402
friend class TransformMask
Definition Node.h:706
bool removeChildNode(Node *child)
removeChildNode removes the given node from the list of children.
Definition Node.cpp:283
QString name() const
Definition Node.cpp:426
Node * parentNode() const
Definition Node.cpp:454
void setVisible(bool visible)
Definition Node.cpp:537
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:580
void setColorLabel(int index)
setColorLabel sets a color label index associated to the layer. The actual color of the label and the...
Definition Node.cpp:306
friend class CloneLayer
Definition Node.h:708
Node * clone() const
clone clone the current node. The node is not associated with any image.
Definition Node.cpp:150
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:558
bool isPinnedToTimeline() const
Definition Node.cpp:377
QRect bounds() const
bounds return the exact bounds of the node's paint device
Definition Node.cpp:613
QString colorProfile() const
Definition Node.cpp:327
friend class GroupLayer
Definition Node.h:698
friend class ColorizeMask
Definition Node.h:707
#define bounds(x, a, b)
#define dbgScript
Definition kis_debug.h:56
KisDocument * createDocument(QList< KisNodeSP > nodes, KisImageSP srcImage, const QRect &copiedBounds)
QList< KisNodeSP > findNodesByName(KisNodeSP root, const QString &name, bool recursive, bool partialMatch)
QList< Node * > createNodeList(KisNodeList kisnodes, KisImageWSP image)
KisFigurePaintingToolHelper createHelper(KisImageWSP image, KisNodeSP node, const QString strokeStyle=defaultStrokeStyle, const QString fillStyle=defaultFillStyle)
void setPinnedToTimeline(bool pinned)
virtual void setUserLocked(bool l)
QUuid uuid() const
virtual KisPaintDeviceSP projection() const =0
const QString & compositeOpId() const
virtual qint32 y() const
void setOpacity(quint8 val)
virtual void setVisible(bool visible, bool loading=false)
bool isPinnedToTimeline() const
KisKeyframeChannel * getKeyframeChannel(const QString &id, bool create)
virtual QRect exactBounds() const
virtual QImage createThumbnail(qint32 w, qint32 h, Qt::AspectRatioMode aspectRatioMode=Qt::IgnoreAspectRatio)
virtual void setX(qint32)
virtual void setY(qint32)
void setColorLabelIndex(int index)
void setName(const QString &name)
void setCollapsed(bool collapsed)
virtual const KoColorSpace * colorSpace() const =0
virtual qint32 x() const
int colorLabelIndex() const
virtual QRect extent() const
bool userLocked() const
bool isAnimated() const
virtual KisPaintDeviceSP paintDevice() const =0
QString name() const
quint8 opacity() const
virtual bool visible(bool recursive=false) const
void enableAnimation()
virtual QIcon icon() const
KisPSDLayerStyleSP layerStyle
Definition kis_layer.cc:171
bool addNode(KisNodeSP node, KisNodeSP parent=KisNodeSP(), KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)
bool removeNode(KisNodeSP node)
KisNodeSP prevSibling() const
Definition kis_node.cpp:402
KisNodeSP firstChild() const
Definition kis_node.cpp:361
int index(const KisNodeSP node) const
Definition kis_node.cpp:432
virtual KisNodeSP clone() const =0
quint32 childCount() const
Definition kis_node.cpp:414
KisNodeWSP parent
Definition kis_node.cpp:86
KisNodeSP at(quint32 index) const
Definition kis_node.cpp:421
bool alphaLocked() const
KisPaintDeviceSP paintDevice
void setAlphaLocked(bool lock)
const KoColorProfile * profileByName(const QString &name) const
const KoColorSpace * colorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile)
static KoColorSpaceRegistry * instance()
KisImageWSP image
Definition Node.cpp:79
KisNodeSP node
Definition Node.cpp:80