Krita Source Code Documentation
Loading...
Searching...
No Matches
MyPaintPaintOpPreset.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2020 Ashwin Dhakaita <ashwingpdhakaita@gmail.com>
3 * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
9
10#include <QFile>
11#include <QFileInfo>
12#include <array>
13#include <libmypaint/mypaint-brush.h>
14#include <png.h>
15
16#include <KisResourceLocator.h>
18#include <KoColorConversions.h>
20#include <kis_debug.h>
21
23#include "MyPaintSensorPack.h"
25
27
28public:
29 MyPaintBrush *brush;
30 QImage icon;
31 QByteArray json;
32};
33
35 : KisPaintOpPreset(fileName)
36 , d(new Private)
37{
38 d->brush = mypaint_brush_new();
39 mypaint_brush_from_defaults(d->brush);
40}
41
43 : KisPaintOpPreset(rhs)
44 , d(new Private(*rhs.d))
45{
46 d->brush = mypaint_brush_new();
47
48 if (d->json.isEmpty()) {
49 mypaint_brush_from_defaults(d->brush);
50 } else {
51 mypaint_brush_from_string(d->brush, d->json);
52 }
53}
54
56
57 mypaint_brush_unref(d->brush);
58 delete d;
59}
60
65
66void KisMyPaintPaintOpPreset::setColor(const KoColor color, const KoColorSpace *colorSpace) {
67
68 float hue, saturation, value;
69#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
70 qreal r = 0, g = 0, b = 0;
71#else
72 float r = 0, g = 0, b = 0;
73#endif
74 QColor dstColor;
75
76 if (colorSpace->colorModelId() == RGBAColorModelID) {
77 colorSpace->toQColor(color.data(), &dstColor);
78 dstColor.getRgbF(&r, &g, &b);
79 }
80
81 RGBToHSV(r, g, b, &hue, &saturation, &value);
82
83 mypaint_brush_set_base_value(d->brush, MYPAINT_BRUSH_SETTING_COLOR_H, (hue)/360);
84 mypaint_brush_set_base_value(d->brush, MYPAINT_BRUSH_SETTING_COLOR_S, (saturation));
85 mypaint_brush_set_base_value(d->brush, MYPAINT_BRUSH_SETTING_COLOR_V, (value));
86}
87
89
90 if(settings->getProperty(MYPAINT_JSON).isNull()) {
91 mypaint_brush_from_defaults(d->brush);
92 }
93 else {
94 QByteArray ba = settings->getProperty(MYPAINT_JSON).toByteArray();
95 mypaint_brush_from_string(d->brush, ba);
96 }
97
98 mypaint_brush_new_stroke(d->brush);
99}
100
102
103 return d->brush;
104}
105
107{
108 if (!dev->isSequential())
109 dev->seek(0); // ensure we do read *all* the bytes
110
111 std::array<png_byte, 8> signature;
112 dev->peek(reinterpret_cast<char*>(signature.data()), 8);
113
114#if PNG_LIBPNG_VER < 10400
115 if (png_check_sig(signature, 8)) {
116#else
117 if (png_sig_cmp(signature.data(), 0, 8) == 0) {
118#endif
119 // this is a koresource
121 apply(settings());
122 // correct filename
123 const QString f = filename();
124 if (f.endsWith(".myb", Qt::CaseInsensitive)) {
125 setFilename(QFileInfo(f).completeBaseName().append(KisPaintOpPreset::defaultFileExtension()));
126 }
127 return true;
128 } else {
129 warnPlugins << "Failed loading MyPaint preset from KoResource serialization";
130 return false;
131 }
132 }
133
134 const QByteArray ba(dev->readAll());
135 d->json = ba;
136 // mypaint can handle invalid json files too, so this is the only way to find out if it was correct mypaint file or not...
137 // if the json is incorrect, the brush will get the default mypaint brush settings
138 // which looks like a round brush with low opacity and high spacing
139 bool success = mypaint_brush_from_string(d->brush, ba);
140 const float isEraser = mypaint_brush_get_base_value(d->brush, MYPAINT_BRUSH_SETTING_ERASER);
141
143 s->setProperty("paintop", "mypaintbrush");
144 s->setProperty("filename", this->filename());
145 s->setProperty(MYPAINT_JSON, this->getJsonData());
146 s->setProperty("EraserMode", qRound(isEraser));
147
148
149 {
155 auto recoverDeprecatedProperty = [] (auto data, KisPaintOpSettingsSP settings) {
158
159 data.read(settings.data());
160 data.write(settings.data());
161 };
162
163 recoverDeprecatedProperty(MyPaintRadiusLogarithmicData(), s);
164 recoverDeprecatedProperty(MyPaintOpacityData(), s);
165 recoverDeprecatedProperty(MyPaintHardnessData(), s);
166 }
167
168
169 if (!metadata().contains("paintopid")) {
170 addMetaData("paintopid", "mypaintbrush");
171 }
172
173 this->setSettings(s);
174 setName(QFileInfo(filename()).baseName());
175 setValid(success);
176
177 return success;
178}
179
184
186{
187 return QFileInfo(filename()).baseName() + "_prev.png";
188}
189
191
192 return d->json;
193}
float value(const T *src, size_t ch)
void RGBToHSV(float r, float g, float b, float *h, float *s, float *v)
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
const QString MYPAINT_JSON
void apply(KisPaintOpSettingsSP settings)
bool loadFromDevice(QIODevice *dev, KisResourcesInterfaceSP resourcesInterface) override
void updateThumbnail() override
updateThumbnail updates the thumbnail for this resource. Reimplement if your thumbnail is something e...
KoResourceSP clone() const override
void setColor(const KoColor color, const KoColorSpace *colorSpace)
KisMyPaintPaintOpPreset(const QString &fileName="")
QString thumbnailPath() const override
thumbnailPath returns the path to a separate thumbnail image, outside the actual resource file itself...
bool isNull() const
virtual void toQColor(const quint8 *src, QColor *c) const =0
virtual KoID colorModelId() const =0
quint8 * data()
Definition KoColor.h:144
#define warnPlugins
Definition kis_debug.h:93
QSharedPointer< T > toQShared(T *ptr)
KisResourcesInterfaceSP resourcesInterface() const
QString defaultFileExtension() const override
bool loadFromDevice(QIODevice *dev, KisResourcesInterfaceSP resourcesInterface) override
void setSettings(KisPaintOpSettingsSP settings)
replace the current settings object with the specified settings
KisPaintOpSettingsSP settings
void setValid(bool valid)
void setName(const QString &name)
void addMetaData(QString key, QVariant value)
store the given key, value pair in the resource
void setFilename(const QString &filename)
QString filename
QMap< QString, QVariant > metadata
KoResourceSignature signature() const
virtual QImage thumbnail() const
thumbnail the thumbnail image to use in resource selectors