Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_qmic_import_tools.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2013 Dmitry Kazakov <dimula73@gmail.com>
3 * SPDX-FileCopyrightText: 2013 Lukáš Tvrdý <lukast.dev@gmail.com>
4 * SPDX-FileCopyrightText: 2022 L. E. Segovia <amy@amyspark.me>
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9#include <QRegularExpression>
10
16#include <kis_command_utils.h>
17#include <kis_layer_utils.h>
18#include <kis_node.h>
19#include <kis_paint_layer.h>
20#include <kis_painter.h>
21#include <kis_selection.h>
22#include <kis_types.h>
23
24#include "gmic.h"
26#include "kis_qmic_interface.h"
28
30{
31[[nodiscard]] KUndo2Command *
33 KisNode *node,
34 KisSelectionSP selection)
35{
36 dbgPlugins << "KisQmicImportTools::applyLayerNameChanges";
37
38 auto *cmd = new KisCommandUtils::CompositeCommand();
39
40 dbgPlugins << "Layer name: " << srcGmicImage.m_layerName;
41
42 {
43 const QRegularExpression modeRe(R"(mode\‍(\s*([^)]*)\s*\))");
44 QRegularExpressionMatch match;
45 if (srcGmicImage.m_layerName.contains(modeRe, &match)) {
46 QString modeStr = match.captured(1).trimmed();
47 auto translatedMode =
49 dbgPlugins << "Detected mode: " << modeStr << " => "
50 << translatedMode;
51 if (!translatedMode.isNull()) {
52 cmd->addCommand(
53 new KisNodeCompositeOpCommand(node, translatedMode));
54 }
55 }
56 }
57
58 {
59 const QRegularExpression opacityRe(R"(opacity\‍(\s*([^)]*)\s*\))");
60 QRegularExpressionMatch match;
61 if (srcGmicImage.m_layerName.contains(opacityRe, &match)) {
62 const float opacity = match.captured(1).toFloat();
63 dbgPlugins << "Detected opacity: " << opacity
64 << std::lround(opacity / 100.f * 255.f);
65 cmd->addCommand(
66 new KisNodeOpacityCommand(node,
67 static_cast<quint8>(std::lround(
68 float(opacity * 255) / 100.f))));
69 }
70 }
71
72 {
73const QRegularExpression nameRe(R"(name\‍(\s*([^)]*)\s*\))");
74
75 QRegularExpressionMatch match;
76 if (srcGmicImage.m_layerName.contains(nameRe, &match)) {
77 const auto name = KisQmicSimpleConvertor::gMicNameToName(match.captured(1));
78 dbgPlugins << "Detected layer name: " << name;
79 cmd->addCommand(new KisNodeRenameCommand(node, node->name(), name));
80 // apply command
81 }
82 }
83
84 if (!selection) {
85 // Some GMic filters encode layer position into the layer name.
86 // E.g. from extract foreground: "name([unnamed]
87 // [foreground]),pos(55,35)"
88 const QRegularExpression positionPattern(
89 R"(pos\‍(\s*(-?\d*)[^)](-?\d*)\s*\))");
90 const QRegularExpressionMatch match =
91 positionPattern.match(srcGmicImage.m_layerName);
92 if (match.hasMatch()) {
93 const auto x = match.captured(1).toInt();
94 const auto y = match.captured(2).toInt();
95 const QPoint oldPos(node->x(), node->y());
96 const QPoint newPos(x, y);
97 dbgPlugins << "Detected layer position: " << oldPos << newPos
98 << node->paintDevice()->exactBounds();
99 cmd->addCommand(new KisNodeMoveCommand2(node, oldPos, newPos));
100 }
101 }
102
103 return cmd;
104}
105
106void gmicImageToPaintDevice(const KisQMicImage &srcGmicImage,
108 KisSelectionSP selection,
109 const QRect &dstRect)
110{
111 dbgPlugins << "KisQmicImportTools::gmicImageToPaintDevice()" << dstRect;
112
113 if (selection) {
115 KisQmicSimpleConvertor::convertFromGmicFast(srcGmicImage, src, 255.0f);
116 KisPainter painter(dst, selection);
118 painter.bitBlt(dstRect.topLeft(),
119 src,
120 QRect(QPoint(0, 0), dstRect.size()));
121 } else {
122 KisQmicSimpleConvertor::convertFromGmicFast(srcGmicImage, dst, 255.0f);
123 }
124}
125
127inputNodes(KisImageSP image, InputLayerMode inputMode, KisNodeSP currentNode)
128{
129 /*
130 ACTIVE_LAYER,
131 ALL_LAYERS,
132 ACTIVE_LAYER_BELOW_LAYER,
133 ACTIVE_LAYER_ABOVE_LAYER,
134 ALL_VISIBLE_LAYERS,
135 ALL_INVISIBLE_LAYERS,
136 ALL_VISIBLE_LAYERS_DECR,
137 ALL_INVISIBLE_DECR,
138 ALL_DECR
139 */
140 const auto isAvailable = [](KisNodeSP node) -> bool {
141 auto *paintLayer = dynamic_cast<KisPaintLayer *>(node.data());
142 return paintLayer && paintLayer->visible(false);
143 };
144
145 KisNodeListSP result(new QList<KisNodeSP>());
146 switch (inputMode) {
148 break;
149 }
151 if (isAvailable(currentNode)) {
152 result->prepend(currentNode);
153 }
154 break; // drop down in case of one more layer modes
155 }
156 case InputLayerMode::All: {
157 result = [&]() {
160 image->root(),
161 [&](KisNodeSP item) {
162 auto *paintLayer =
163 dynamic_cast<KisPaintLayer *>(item.data());
164 if (paintLayer) {
165 r->prepend(item);
166 }
167 });
168 return r;
169 }();
170 break;
171 }
173 if (isAvailable(currentNode)) {
174 result->prepend(currentNode);
175 if (isAvailable(currentNode->prevSibling())) {
176 result->prepend(currentNode->prevSibling());
177 }
178 }
179 break;
180 }
182 if (isAvailable(currentNode)) {
183 result->prepend(currentNode);
184 if (isAvailable(currentNode->nextSibling())) {
185 result->prepend(currentNode->nextSibling());
186 }
187 }
188 break;
189 }
192 const bool visibility = (inputMode == InputLayerMode::AllInvisible);
193
194 result = [&]() {
197 image->root(),
198 [&](KisNodeSP item) {
199 auto *paintLayer =
200 dynamic_cast<KisPaintLayer *>(item.data());
201 if (paintLayer
202 && paintLayer->visible(false) == visibility) {
203 r->prepend(item);
204 }
205 });
206 return r;
207 }();
208 break;
209 }
211 default: {
212 qWarning()
213 << "Inputmode" << static_cast<int>(inputMode)
214 << "must be specified by GMic or is not implemented in Krita";
215 break;
216 }
217 }
218 return result;
219}
220} // namespace KisQmicImportTools
const QString COMPOSITE_COPY
The command for setting the composite op.
The command for setting the node opacity.
The command for setting the node's name.
QRect exactBounds() const
const KoColorSpace * colorSpace() const
void bitBlt(qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)
void setCompositeOpId(const KoCompositeOp *op)
static QString gMicNameToName(QString name)
static void convertFromGmicFast(const KisQMicImage &gmicImage, KisPaintDeviceSP dst, float gmicUnitValue)
Fast versions.
static QString stringToBlendingMode(QString str)
InputLayerMode
Definition gmic.h:21
#define dbgPlugins
Definition kis_debug.h:51
void recursiveApplyNodes(NodePointer node, Functor func)
KUndo2Command * applyLayerNameChanges(const KisQMicImage &srcGmicImage, KisNode *node, KisSelectionSP selection)
void gmicImageToPaintDevice(const KisQMicImage &srcGmicImage, KisPaintDeviceSP dst, KisSelectionSP selection, const QRect &dstRect)
KisNodeListSP inputNodes(KisImageSP image, InputLayerMode inputMode, KisNodeSP currentNode)
virtual qint32 y() const
virtual qint32 x() const
virtual KisPaintDeviceSP paintDevice() const =0
QString name() const
virtual bool visible(bool recursive=false) const
KisNodeSP prevSibling() const
Definition kis_node.cpp:402
KisNodeSP nextSibling() const
Definition kis_node.cpp:408