Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_brush_export.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2016 Boudewijn Rempt <boud@valdyas.org>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#include "kis_brush_export.h"
8
9#include <QCheckBox>
10#include <QSlider>
11#include <QBuffer>
12
13#include <KoProperties.h>
14#include <KoDialog.h>
15#include <kpluginfactory.h>
16#include <QFileInfo>
17
19#include <kis_paint_device.h>
20#include <KisViewManager.h>
21#include <kis_image.h>
22#include <KisDocument.h>
23#include <kis_paint_layer.h>
25#include <kis_gbr_brush.h>
26#include <kis_imagepipe_brush.h>
29#include <KisWdgOptionsBrush.h>
31#include <kis_config.h>
32
43
44
45K_PLUGIN_FACTORY_WITH_JSON(KisBrushExportFactory, "krita_brush_export.json", registerPlugin<KisBrushExport>();)
46
47KisBrushExport::KisBrushExport(QObject *parent, const QVariantList &) : KisImportExportFilter(parent)
48{
49}
50
54
56{
57
58// XXX: Loading the parasite itself was commented out -- needs investigation
59// KisAnnotationSP annotation = document->savingImage()->annotation("ImagePipe Parasite");
60// KisPipeBrushParasite parasite;
61// if (annotation) {
62// QBuffer buf(const_cast<QByteArray*>(&annotation->annotation()));
63// buf.open(QBuffer::ReadOnly);
64// parasite.loadFromDevice(&buf);
65// buf.close();
66// }
67
68 KisBrushExportOptions exportOptions;
69
70 if (document->savingImage()->dynamicPropertyNames().contains("brushspacing")) {
71 exportOptions.spacing = document->savingImage()->property("brushspacing").toFloat();
72 } else {
73 exportOptions.spacing = configuration->getDouble(KEY_SPACING);
74 }
75
76 if (!configuration->getString(KEY_NAME).isEmpty()) {
77 exportOptions.name = configuration->getString(KEY_NAME);
78 } else {
79 exportOptions.name = document->savingImage()->objectName();
80 }
81
82 exportOptions.mask = configuration->getBool(KEY_MASK);
83 exportOptions.preserveAlpha = configuration->getBool(KEY_PRESERVE_ALPHA);
84 exportOptions.brushStyle = configuration->getInt(KEY_BRUSH_STYLE);
85 exportOptions.dimensions = configuration->getInt(KEY_DIMENSIONS);
86
87 for (int i = 0; i < KisPipeBrushParasite::MaxDim; ++i) {
88 exportOptions.selectionModes[i] = configuration->getInt(KEY_SELECTION_MODE + QString::number(i));
89 exportOptions.ranks[i] = configuration->getInt(KEY_RANK + QString::number(i));
90 }
91
92 KisGbrBrush *brush = 0;
93 if (mimeType() == "image/x-gimp-brush") {
94 brush = new KisGbrBrush(filename());
95 } else if (mimeType() == "image/x-gimp-brush-animated") {
96 brush = new KisImagePipeBrush(filename());
97 } else {
99 }
100
101 qApp->processEvents(); // For vector layers to be updated
102
103 QRect rc = document->savingImage()->bounds();
104
105 brush->setSpacing(exportOptions.spacing);
106
107 KisImagePipeBrush *pipeBrush = dynamic_cast<KisImagePipeBrush*>(brush);
108 if (pipeBrush) {
109 // Create parasite.
111 devices.append(QVector<KisPaintDevice*>());
112
113 KoProperties properties;
114 properties.setProperty("visible", true);
115 QList<KisNodeSP> layers = document->savingImage()->root()->childNodes(QStringList("KisLayer"), properties);
116 Q_FOREACH (KisNodeSP node, layers) {
117 // push_front to behave exactly as gimp for gih creation
118 devices[0].prepend(node->projection().data());
119 }
120
122 for (int i = 0; i < KisPipeBrushParasite::MaxDim; ++i) {
123 modes.append((KisParasite::SelectionMode)exportOptions.selectionModes[i]);
124 }
125
126 KisPipeBrushParasite parasite;
127 parasite.dim = exportOptions.dimensions;
128 parasite.ncells = devices.at(0).count();
129
130 int maxRanks = 0;
131 for (int i = 0; i < KisPipeBrushParasite::MaxDim; ++i) {
132 // ### This can mask some bugs, be careful here in the future
133 parasite.rank[i] = exportOptions.ranks[i];
134 parasite.selection[i] = modes.at(i);
135 maxRanks += exportOptions.ranks[i];
136 }
137
138 if (maxRanks > layers.count()) {
140 }
141 // XXX needs movement!
142 parasite.setBrushesCount();
143 pipeBrush->setParasite(parasite);
144 pipeBrush->setDevices(devices, rc.width(), rc.height());
145 } else {
146 if (exportOptions.mask) {
147 QImage image = document->savingImage()->projection()->convertToQImage(0, 0, 0, rc.width(), rc.height(), KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags());
148 brush->setImage(image);
149 brush->setBrushTipImage(image);
150 } else {
151 brush->initFromPaintDev(document->savingImage()->projection(),0,0,rc.width(), rc.height());
152 }
153 }
154
155 brush->setName(exportOptions.name);
156 // brushes are created after devices are loaded, call mask mode after that
157 enumBrushApplication maskMode;
158 if (exportOptions.mask) {
159 brush->makeMaskImage(exportOptions.preserveAlpha);
160 maskMode = exportOptions.preserveAlpha ? LIGHTNESSMAP : ALPHAMASK;
161 } else {
162 maskMode = IMAGESTAMP;
163 }
164 brush->setBrushApplication(maskMode);
165 brush->setWidth(rc.width());
166 brush->setHeight(rc.height());
167
168 if (brush->saveToDevice(io)) {
170 } else {
172 }
173}
174
175KisPropertiesConfigurationSP KisBrushExport::defaultConfiguration(const QByteArray &/*from*/, const QByteArray &/*to*/) const
176{
178 cfg->setProperty(KEY_SPACING, 1.0);
179 cfg->setProperty(KEY_NAME, "");
180 cfg->setProperty(KEY_MASK, true);
181 cfg->setProperty(KEY_PRESERVE_ALPHA, false);
182 cfg->setProperty(KEY_BRUSH_STYLE, 0);
183 cfg->setProperty(KEY_DIMENSIONS, 1);
184
185 for (int i = 0; i < KisPipeBrushParasite::MaxDim; ++i) {
186 cfg->setProperty(KEY_SELECTION_MODE + QString::number(i), KisParasite::Incremental);
187 cfg->getInt(KEY_RANK + QString::number(i), 0);
188 }
189 return cfg;
190}
191
192KisConfigWidget *KisBrushExport::createConfigurationWidget(QWidget *parent, const QByteArray &/*from*/, const QByteArray &to) const
193{
194 KisWdgOptionsBrush *wdg = new KisWdgOptionsBrush(parent);
195 if (to == "image/x-gimp-brush") {
196 wdg->styleGroupBox->setVisible(false);
197 wdg->animStyleGroup->setVisible(false);
198 } else if (to == "image/x-gimp-brush-animated") {
199 wdg->styleGroupBox->setVisible(true);
200 wdg->animStyleGroup->setVisible(true);
201 }
202
204
205 // preload gih name with chosen filename
206 QFileInfo fileLocation(filename());
207 wdg->nameLineEdit->setText(fileLocation.completeBaseName());
208 return wdg;
209}
210
212{
213 QList<QPair<KoID, KoID> > supportedColorModels;
214 supportedColorModels << QPair<KoID, KoID>()
215 << QPair<KoID, KoID>(RGBAColorModelID, Integer8BitsColorDepthID)
216 << QPair<KoID, KoID>(GrayAColorModelID, Integer8BitsColorDepthID);
217 addSupportedColorModels(supportedColorModels, "Gimp Brushes");
218 if (mimeType() == "image/x-gimp-brush-animated") {
221 }
222}
223
224
225#include "kis_brush_export.moc"
226
VertexDescriptor get(PredecessorMap const &m, VertexDescriptor v)
QList< QString > QStringList
const QString KEY_MASK
const QString KEY_RANK
const QString KEY_DIMENSIONS
const QString KEY_SELECTION_MODE
const QString KEY_BRUSH_STYLE
const QString KEY_PRESERVE_ALPHA
const QString KEY_NAME
const QString KEY_SPACING
const KoID GrayAColorModelID("GRAYA", ki18n("Grayscale/Alpha"))
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
~KisBrushExport() override
KisImportExportErrorCode convert(KisDocument *document, QIODevice *io, KisPropertiesConfigurationSP configuration=0) override
KisConfigWidget * createConfigurationWidget(QWidget *parent, const QByteArray &from="", const QByteArray &to="") const override
createConfigurationWidget creates a widget that can be used to define the settings for a given import...
KisPropertiesConfigurationSP defaultConfiguration(const QByteArray &from="", const QByteArray &to="") const override
defaultConfiguration defines the default settings for the given import export filter
KisBrushExport(QObject *parent, const QVariantList &)
void initializeCapabilities() override
virtual void setSpacing(double spacing)
void setWidth(qint32 width)
void setHeight(qint32 height)
virtual void setBrushApplication(enumBrushApplication brushApplication)
static KisExportCheckRegistry * instance()
void setBrushTipImage(const QImage &image) override
bool initFromPaintDev(KisPaintDeviceSP image, int x, int y, int w, int h)
bool saveToDevice(QIODevice *dev) const override
virtual void makeMaskImage(bool preserveAlpha)
void setDevices(QVector< QVector< KisPaintDevice * > > devices, int w, int h)
void setParasite(const KisPipeBrushParasite &parasite)
The base class for import and export filters.
void addSupportedColorModels(QList< QPair< KoID, KoID > > supportedColorModels, const QString &name, KisExportCheckBase::Level level=KisExportCheckBase::PARTIALLY)
void addCapability(KisExportCheckBase *capability)
KisParasite::SelectionMode selection[MaxDim]
void setBrushesCount()
Initializes the brushesCount helper.
void setConfiguration(const KisPropertiesConfigurationSP cfg) override
void setProperty(const QString &name, const QVariant &value)
K_PLUGIN_FACTORY_WITH_JSON(KritaASCCDLFactory, "kritaasccdl.json", registerPlugin< KritaASCCDL >();) KritaASCCDL
enumBrushApplication
Definition kis_brush.h:38
@ ALPHAMASK
Definition kis_brush.h:39
@ IMAGESTAMP
Definition kis_brush.h:40
@ LIGHTNESSMAP
Definition kis_brush.h:41
virtual KisPaintDeviceSP projection() const =0
qint32 selectionModes[KisPipeBrushParasite::MaxDim]
qint32 ranks[KisPipeBrushParasite::MaxDim]
void setName(const QString &name)
void setImage(const QImage &image)