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;
293 while (node) {
295 node = node->nextSibling();
296 }
297 Q_FOREACH(Node *node, nodes) {
298 d->image->addNode(node->node(), d->node);
299 }
300}
301
303{
304 if (!d->node) return 0;
305 return d->node->colorLabelIndex();
306}
307
308void Node::setColorLabel(int index)
309{
310 if (!d->node) return;
312}
313
314QString Node::colorDepth() const
315{
316 if (!d->node) return "";
317 if (!d->node->projection()) return d->node->colorSpace()->colorDepthId().id();
318 return d->node->projection()->colorSpace()->colorDepthId().id();
319}
320
321QString Node::colorModel() const
322{
323 if (!d->node) return "";
324 if (!d->node->projection()) return d->node->colorSpace()->colorModelId().id();
325 return d->node->projection()->colorSpace()->colorModelId().id();
326}
327
328
329QString Node::colorProfile() const
330{
331 if (!d->node) return "";
332 if (!d->node->projection()) return d->node->colorSpace()->profile()->name();
333 return d->node->projection()->colorSpace()->profile()->name();
334}
335
336bool Node::setColorProfile(const QString &colorProfile)
337{
338 if (!d->node) return false;
339 if (!d->node->inherits("KisLayer")) return false;
340 KisLayer *layer = qobject_cast<KisLayer*>(d->node.data());
342 bool result = d->image->assignLayerProfile(layer, profile);
343 d->image->waitForDone();
344 return result;
345}
346
347bool Node::setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile)
348{
349 if (!d->node) return false;
350 if (!d->node->inherits("KisLayer")) return false;
352 if (!profile) return false;
355 profile);
357 d->image->waitForDone();
358 return true;
359}
360
361bool Node::animated() const
362{
363 if (!d->node) return false;
364 return d->node->isAnimated();
365}
366
368{
369 if (!d->node) return;
371}
372
373void Node::setPinnedToTimeline(bool pinned) const
374{
375 if (!d->node) return;
376 d->node->setPinnedToTimeline(pinned);
377}
378
380{
381 if (!d->node) return false;
382 return d->node->isPinnedToTimeline();
383}
384
385bool Node::collapsed() const
386{
387 if (!d->node) return false;
388 return d->node->collapsed();
389}
390
391void Node::setCollapsed(bool collapsed)
392{
393 if (!d->node) return;
395}
396
398{
399 if (!d->node) return false;
400 if (!d->node->inherits("KisLayer")) return false;
401 return qobject_cast<const KisLayer*>(d->node)->alphaChannelDisabled();
402}
403
405{
406 if (!d->node) return;
407 if (!d->node->inherits("KisLayer")) return;
408 const_cast<KisLayer*>(qobject_cast<const KisLayer*>(d->node))->disableAlphaChannel(value);
409}
410
411bool Node::locked() const
412{
413 if (!d->node) return false;
414 return d->node->userLocked();
415}
416
418{
419 if (!d->node) return;
421}
422
424{
425 return !d->node->extent().isEmpty();
426}
427
428QString Node::name() const
429{
430 if (!d->node) return QString();
431 return d->node->name();
432}
433
434void Node::setName(QString name)
435{
436 if (!d->node) return;
437 d->node->setName(name);
438}
439
440
441int Node::opacity() const
442{
443 if (!d->node) return 0;
444 return d->node->opacity();
445}
446
448{
449 if (!d->node) return;
450 if (value < 0) value = 0;
451 if (value > 255) value = 255;
453}
454
455
457{
458 if (!d->node) return 0;
459 if (!d->node->parent()) return 0;
460 return Node::createNode(d->image, d->node->parent());
461}
462
463QString Node::type() const
464{
465 if (!d->node) return QString();
466 if (qobject_cast<const KisPaintLayer*>(d->node)) {
467 return "paintlayer";
468 }
469 else if (qobject_cast<const KisGroupLayer*>(d->node)) {
470 return "grouplayer";
471 }
472 if (qobject_cast<const KisFileLayer*>(d->node)) {
473 return "filelayer";
474 }
475 if (qobject_cast<const KisAdjustmentLayer*>(d->node)) {
476 return "filterlayer";
477 }
478 if (qobject_cast<const KisGeneratorLayer*>(d->node)) {
479 return "filllayer";
480 }
481 if (qobject_cast<const KisCloneLayer*>(d->node)) {
482 return "clonelayer";
483 }
484 if (qobject_cast<const KisReferenceImagesLayer*>(d->node)) {
485 return "referenceimageslayer";
486 }
487 if (qobject_cast<const KisShapeLayer*>(d->node)) {
488 return "vectorlayer";
489 }
490 if (qobject_cast<const KisTransparencyMask*>(d->node)) {
491 return "transparencymask";
492 }
493 if (qobject_cast<const KisFilterMask*>(d->node)) {
494 return "filtermask";
495 }
496 if (qobject_cast<const KisTransformMask*>(d->node)) {
497 return "transformmask";
498 }
499 if (qobject_cast<const KisSelectionMask*>(d->node)) {
500 return "selectionmask";
501 }
502 if (qobject_cast<const KisColorizeMask*>(d->node)) {
503 return "colorizemask";
504 }
505 return QString();
506}
507
508QIcon Node::icon() const
509{
510 QIcon icon;
511 if (d->node) {
512 icon = d->node->icon();
513 }
514 return icon;
515}
516
517bool Node::visible() const
518{
519 if (!d->node) return false;
520 return d->node->visible();
521}
522
523bool Node::hasKeyframeAtTime(int frameNumber)
524{
525 if (!d->node || !d->node->isAnimated()) return false;
526
528 if (!rkc) return false;
529
530 KisKeyframeSP currentKeyframe = rkc->keyframeAt(frameNumber);
531
532 if (!currentKeyframe) {
533 return false;
534 }
535
536 return true;
537}
538
539void Node::setVisible(bool visible)
540{
541 if (!d->node) return;
543}
544
545
546QByteArray Node::pixelData(int x, int y, int w, int h) const
547{
548 QByteArray ba;
549
550 if (!d->node) return ba;
551
553 if (!dev) return ba;
554
555 ba.resize(w * h * dev->pixelSize());
556 dev->readBytes(reinterpret_cast<quint8*>(ba.data()), x, y, w, h);
557 return ba;
558}
559
560QByteArray Node::pixelDataAtTime(int x, int y, int w, int h, int time) const
561{
562 QByteArray ba;
563
564 if (!d->node || !d->node->isAnimated()) return ba;
565
566 //
568 if (!rkc) return ba;
570 if (!frame) return ba;
572 if (!dev) return ba;
573
574 frame->writeFrameToDevice(dev);
575
576 ba.resize(w * h * dev->pixelSize());
577 dev->readBytes(reinterpret_cast<quint8*>(ba.data()), x, y, w, h);
578 return ba;
579}
580
581
582QByteArray Node::projectionPixelData(int x, int y, int w, int h) const
583{
584 QByteArray ba;
585
586 if (!d->node) return ba;
587
589 if (const KisColorizeMask *mask = qobject_cast<const KisColorizeMask*>(d->node)) {
590
591 dev = mask->coloringProjection();
592 } else {
593 dev = d->node->projection();
594 }
595 if (!dev) return ba;
596
597 ba.resize(w * h * dev->pixelSize());
598 dev->readBytes(reinterpret_cast<quint8*>(ba.data()), x, y, w, h);
599 return ba;
600}
601
602bool Node::setPixelData(QByteArray value, int x, int y, int w, int h)
603{
604 if (!d->node) return false;
606 if (!dev) return false;
607 if (value.length() < w * h * (int)dev->colorSpace()->pixelSize()) {
608 qWarning() << "Node::setPixelData: not enough data to write to the paint device";
609 return false;
610 }
611 dev->writeBytes((const quint8*)value.constData(), x, y, w, h);
612 return true;
613}
614
615QRect Node::bounds() const
616{
617 if (!d->node) return QRect();
618 return d->node->exactBounds();
619}
620
621void Node::move(int x, int y)
622{
623 if (!d->node) return;
624 d->node->setX(x);
625 d->node->setY(y);
626}
627
628QPoint Node::position() const
629{
630 if (!d->node) return QPoint();
631 return QPoint(d->node->x(), d->node->y());
632}
633
635{
636 if (!d->node) return false;
637 if (!d->node->parent()) return false;
638
640
642 d->image->waitForDone();
643
644 return true;
645}
646
648{
649 if (!d->node) return 0;
650 return Node::createNode(d->image, d->node->clone());
651}
652
653bool Node::save(const QString &filename, double xRes, double yRes, const InfoObject &exportConfiguration, const QRect &exportRect)
654{
655 if (!d->node) return false;
656 if (filename.isEmpty()) return false;
657
658 KisPaintDeviceSP projection = d->node->projection();
659 QRect bounds = (exportRect.isEmpty())? d->node->exactBounds() : exportRect;
660
661 QString mimeType = KisMimeDatabase::mimeTypeForFile(filename, false);
662 QScopedPointer<KisDocument> doc(KisPart::instance()->createDocument());
663
664 KisImageSP dst = new KisImage(doc->createUndoStore(),
665 bounds.right(),
666 bounds.bottom(),
667 projection->compositionSourceColorSpace(),
668 d->node->name());
669 dst->setResolution(xRes, yRes);
670 doc->setFileBatchMode(Krita::instance()->batchmode());
671 doc->setCurrentImage(dst);
672 KisPaintLayer* paintLayer = new KisPaintLayer(dst, "paint device", d->node->opacity());
673 paintLayer->paintDevice()->makeCloneFrom(projection, bounds);
674 dst->addNode(paintLayer, dst->rootLayer(), KisLayerSP(0));
675 dst->cropImage(bounds);
676 dst->initialRefreshGraph();
677
678 bool r = doc->exportDocumentSync(filename, mimeType.toLatin1(), exportConfiguration.configuration());
679 if (!r) {
680 qWarning() << doc->errorMessage();
681 }
682 return r;
683}
684
686{
687 if (!d->node) return 0;
688 if (!qobject_cast<KisLayer*>(d->node.data())) return 0;
689 if (!d->node->prevSibling()) return 0;
690
691 d->image->mergeDown(qobject_cast<KisLayer*>(d->node.data()), KisMetaData::MergeStrategyRegistry::instance()->get("Drop"));
692 d->image->waitForDone();
693
695}
696
697void Node::scaleNode(QPointF origin, int width, int height, QString strategy)
698{
699 if (!d->node) return;
700 if (!qobject_cast<KisLayer*>(d->node.data())) return;
701 if (!d->node->parent()) return;
702
703 KisFilterStrategy *actualStrategy = KisFilterStrategyRegistry::instance()->get(strategy);
704 if (!actualStrategy) actualStrategy = KisFilterStrategyRegistry::instance()->get("Bicubic");
705
706 const QRect bounds(d->node->exactBounds());
707
709 origin,
710 qreal(width) / bounds.width(),
711 qreal(height) / bounds.height(),
712 actualStrategy, 0);
713 d->image->waitForDone();
714}
715
716void Node::rotateNode(double radians)
717{
718 if (!d->node) return;
719 if (!qobject_cast<KisLayer*>(d->node.data())) return;
720 if (!d->node->parent()) return;
721
722 d->image->rotateNode(d->node, radians, 0);
723 d->image->waitForDone();
724}
725
726void Node::cropNode(int x, int y, int w, int h)
727{
728 if (!d->node) return;
729 if (!qobject_cast<KisLayer*>(d->node.data())) return;
730 if (!d->node->parent()) return;
731
732 QRect rect = QRect(x, y, w, h);
733 d->image->cropNode(d->node, rect);
734 d->image->waitForDone();
735}
736
737void Node::shearNode(double angleX, double angleY)
738{
739 if (!d->node) return;
740 if (!qobject_cast<KisLayer*>(d->node.data())) return;
741 if (!d->node->parent()) return;
742
743 d->image->shearNode(d->node, angleX, angleY, 0);
744 d->image->waitForDone();
745}
746
747QImage Node::thumbnail(int w, int h)
748{
749 if (!d->node) return QImage();
750 return d->node->createThumbnail(w, h);
751}
752
754{
755 if (!d->node) return QString();
756
757 KisLayer *layer = qobject_cast<KisLayer*>(d->node.data());
758
759 if (!layer) return QString();
760
761 KisPSDLayerStyleSP layerStyle = layer->layerStyle();
762
763 if (!layerStyle) return QString();
764
766
767 serializer.setStyles(QVector<KisPSDLayerStyleSP>() << layerStyle);
768
769 return serializer.formPsdXmlDocument().toString();
770}
771
772bool Node::setLayerStyleFromAsl(const QString &asl)
773{
774 if (!d->node) return false;
775
776 KisLayer *layer = qobject_cast<KisLayer*>(d->node.data());
777
778 if (!layer) return false;
779
780 QDomDocument aslDoc;
781
782 if (!aslDoc.setContent(asl)) {
783 qWarning() << "ASL string format is invalid!";
784 return false;
785 }
786
788
789 serializer.registerPSDPattern(aslDoc);
790 serializer.readFromPSDXML(aslDoc);
791
792 if (serializer.styles().size() != 1) return false;
793
794 KisPSDLayerStyleSP newStyle = serializer.styles().first();
795 KUndo2Command *cmd = new KisSetLayerStyleCommand(layer, layer->layerStyle(), newStyle);
796
798 d->image->waitForDone();
799
800 return true;
801}
802
803int Node::index() const
804{
805 if (!d->node) return -1;
806 if (!d->node->parent()) return -1;
807
808 return d->node->parent()->index(d->node);
809}
810
811QUuid Node::uniqueId() const
812{
813 if (!d->node) return QUuid();
814 return d->node->uuid();
815}
816
818{
819 return d->node->paintDevice();
820}
821
823{
824 return d->image;
825}
826
828{
829 return d->node;
830}
831
833{
834 // Taken from KisTool:nodePaintAbility().
836 KisCanvas2 *canvas = mainWindow->activeView()->canvasBase();
837 if (canvas->resourceManager()->resource(KoCanvasResource::CurrentPaintOpPreset).isNull()) {
838 return "UNPAINTABLE";
839 }
840
841 if (!d->node) {
842 return "UNPAINTABLE";
843 }
844
845 if (d->node->inherits("KisShapeLayer")) {
846 return "VECTOR";
847 }
848 if (d->node->inherits("KisCloneLayer")) {
849 return "CLONE";
850 }
851 if (d->node->paintDevice()) {
852
853 KisPaintOpPresetSP currentPaintOpPreset = canvas->resourceManager()->resource(KoCanvasResource::CurrentPaintOpPreset).value<KisPaintOpPresetSP>();
854 if (currentPaintOpPreset->paintOp().id() == "mypaintbrush") {
855 const KoColorSpace *colorSpace = d->node->paintDevice()->colorSpace();
856 if (colorSpace->colorModelId() != RGBAColorModelID) {
857 return "MYPAINTBRUSH_UNPAINTABLE";
858 }
859 }
860
861 return "PAINT";
862 }
863
864 return "UNPAINTABLE";
865}
866
867void Node::paintLine(const QPointF pointOne, const QPointF pointTwo, double pressureOne, double pressureTwo, const QString strokeStyle)
868{
869 if (paintAbility() != "PAINT") {
870 dbgScript << "Script attempted to use Node::paintLine() on an unpaintable node, ignoring.";
871 return;
872 }
873
874 KisPaintInformation pointOneInfo;
875 pointOneInfo.setPressure(pressureOne);
876 pointOneInfo.setPos(pointOne);
877
878 KisPaintInformation pointTwoInfo;
879 pointTwoInfo.setPressure(pressureTwo);
880 pointTwoInfo.setPos(pointTwo);
881
883 helper.paintLine(pointOneInfo, pointTwoInfo);
884}
885
886
887void Node::paintRectangle(const QRectF &rect, const QString strokeStyle, const QString fillStyle)
888{
889 if (paintAbility() != "PAINT") {
890 dbgScript << "Script attempted to use Node::paintRectangle() on an unpaintable node, ignoring.";
891 return;
892 }
893
894 // reference class where this stuff is being done. Maybe can use the "facade" like that does for setup?
895 // void KisFigurePaintingToolHelper::paintRect(const QRectF &rect)
896
897 KisFigurePaintingToolHelper helper = PaintingResources::createHelper(d->image, node(), strokeStyle, fillStyle);
898 helper.paintRect(rect);
899}
900
901
902void Node::paintPolygon(const QList<QPointF> listPoint, const QString strokeStyle, const QString fillStyle)
903{
904 if (paintAbility() != "PAINT") {
905 dbgScript << "Script attempted to use Node::paintPolygon() on an unpaintable node, ignoring.";
906 return;
907 }
908
909 // strategy needs points in vPointF format
910 QVector<QPointF> points = points.fromList(listPoint);
911 KisFigurePaintingToolHelper helper = PaintingResources::createHelper(d->image, node(), strokeStyle, fillStyle);
912 helper.paintPolygon(points);
913}
914
915
916void Node::paintEllipse(const QRectF &rect, const QString strokeStyle, const QString fillStyle)
917{
918 if (paintAbility() != "PAINT") {
919 dbgScript << "Script attempted to use Node::paintEllipse() on an unpaintable node, ignoring.";
920 return;
921 }
922
923 KisFigurePaintingToolHelper helper = PaintingResources::createHelper(d->image, node(), strokeStyle, fillStyle);
924 helper.paintEllipse(rect);
925}
926
927
928void Node::paintPath(const QPainterPath &path, const QString strokeStyle, const QString fillStyle)
929{
930 if (paintAbility() != "PAINT") {
931 dbgScript << "Script attempted to use Node::paintPath() on an unpaintable node, ignoring.";
932 return;
933 }
934
935 KisFigurePaintingToolHelper helper = PaintingResources::createHelper(d->image, node(), strokeStyle, fillStyle);
936 helper.paintPainterPath(path);
937}
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:483
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:390
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:697
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:902
Node * mergeDown()
mergeDown merges the given node with the first visible node underneath this node in the layerstack....
Definition Node.cpp:685
bool operator==(const Node &other) const
Definition Node.cpp:139
void setCollapsed(bool collapsed)
Definition Node.cpp:391
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:367
Node(KisImageSP image, KisNodeSP node, QObject *parent=0)
Definition Node.cpp:83
QString colorDepth() const
Definition Node.cpp:314
void setOpacity(int value)
Definition Node.cpp:447
bool locked() const
locked checks whether the Node is locked. A locked node cannot be changed.
Definition Node.cpp:411
QUuid uniqueId() const
uniqueId uniqueId of the node
Definition Node.cpp:811
QPoint position() const
position returns the position of the paint device of this node. The position is always 0,...
Definition Node.cpp:628
void setPinnedToTimeline(bool pinned) const
Sets whether or not node should be pinned to the Timeline Docker, regardless of selection activity.
Definition Node.cpp:373
void move(int x, int y)
Definition Node.cpp:621
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:916
QIcon icon() const
icon
Definition Node.cpp:508
bool visible() const
Definition Node.cpp:517
QString colorModel() const
colorModel retrieve the current color model of this document:
Definition Node.cpp:321
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:867
bool operator!=(const Node &other) const
Definition Node.cpp:145
bool hasKeyframeAtTime(int frameNumber)
Definition Node.cpp:523
void shearNode(double angleX, double angleY)
shearNode perform a shear operation on this node.
Definition Node.cpp:737
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:602
friend class FilterMask
Definition Node.h:703
friend class TransparencyMask
Definition Node.h:705
KisNodeSP node() const
Definition Node.cpp:827
bool setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile)
setColorSpace convert the node to the given colorspace
Definition Node.cpp:347
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:463
~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:887
void setLocked(bool value)
Definition Node.cpp:417
bool animated() const
Krita layers can be animated, i.e., have frames.
Definition Node.cpp:361
bool remove()
remove removes this node from its parent image.
Definition Node.cpp:634
bool inheritAlpha() const
inheritAlpha checks whether this node has the inherits alpha flag set
Definition Node.cpp:397
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:546
void setName(QString name)
Definition Node.cpp:434
KisImageSP image() const
Definition Node.cpp:822
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:653
void cropNode(int x, int y, int w, int h)
cropNode crop this layer.
Definition Node.cpp:726
QString paintAbility()
paintAbility can be used to determine whether this node can be painted on with the current brush pres...
Definition Node.cpp:832
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:716
int index() const
index the index of the node inside the parent
Definition Node.cpp:803
int opacity() const
Definition Node.cpp:441
bool collapsed() const
Definition Node.cpp:385
bool setLayerStyleFromAsl(const QString &asl)
setLayerStyleFromAsl set a new layer style for this node.
Definition Node.cpp:772
int colorLabel() const
Definition Node.cpp:302
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:753
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:336
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:747
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:928
bool hasExtents()
does the node have any content in it?
Definition Node.cpp:423
friend class FillLayer
Definition Node.h:701
KisPaintDeviceSP paintDevice() const
paintDevice gives access to the internal paint device of this Node
Definition Node.cpp:817
Node * duplicate()
duplicate returns a full copy of the current node. The node is not inserted in the graphic
Definition Node.cpp:647
void setInheritAlpha(bool value)
Definition Node.cpp:404
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:428
Node * parentNode() const
Definition Node.cpp:456
void setVisible(bool visible)
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:582
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:308
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:560
bool isPinnedToTimeline() const
Definition Node.cpp:379
QRect bounds() const
bounds return the exact bounds of the node's paint device
Definition Node.cpp:615
QString colorProfile() const
Definition Node.cpp:329
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
KisNodeSP nextSibling() const
Definition kis_node.cpp:408
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