Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_auto_brush_factory.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2008 Boudewijn Rempt <boud@valdyas.org>
3 * SPDX-FileCopyrightText: 2010-2011 Lukáš Tvrdý <lukast.dev@gmail.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
9
10#include <QDomDocument>
11
12#include "kis_auto_brush.h"
13#include "kis_mask_generator.h"
14#include <kis_dom_utils.h>
16#include "kis_mask_generator.h"
17
18
19KoResourceLoadResult KisAutoBrushFactory::createBrush(const QDomElement &brushDefinition, KisResourcesInterfaceSP resourcesInterface)
20{
21 std::optional<KisBrushModel::BrushData> data =
22 createBrushModel(brushDefinition, resourcesInterface);
23
24 if (data) {
25 return createBrush(*data, resourcesInterface);
26 }
27
28 // fallback, should never reach!
30}
31
33{
34 return createBrush(data.common, data.autoBrush, resourcesInterface);
35}
36
37std::optional<KisBrushModel::BrushData>
38KisAutoBrushFactory::createBrushModel(const QDomElement &element, KisResourcesInterfaceSP resourcesInterface)
39{
40 Q_UNUSED(resourcesInterface);
41
43
45 brush.common.angle = KisDomUtils::toDouble(element.attribute("angle", "0.0"));
46 brush.common.spacing = KisDomUtils::toDouble(element.attribute("spacing", "1.0"));
47 brush.common.useAutoSpacing = KisDomUtils::toInt(element.attribute("useAutoSpacing", "0"));
48 brush.common.autoSpacingCoeff = KisDomUtils::toDouble(element.attribute("autoSpacingCoeff", "1.0"));
49
50 // auto brush settings
51
52 brush.autoBrush.randomness = KisDomUtils::toDouble(element.attribute("randomness", "0.0"));
53 brush.autoBrush.density = KisDomUtils::toDouble(element.attribute("density", "1.0"));
54
55 // generator settings
56
57 QDomElement generatorEl = element.firstChildElement("MaskGenerator");
58
59 // backward compatibility -- it was mistakenly named radius for 2.2
61 generatorEl.hasAttribute("radius") ?
62 KisDomUtils::toDouble(generatorEl.attribute("radius", "1.0")) :
63 KisDomUtils::toDouble(generatorEl.attribute("diameter", "1.0"));
64
65 brush.autoBrush.generator.ratio = KisDomUtils::toDouble(generatorEl.attribute("ratio", "1.0"));
66 brush.autoBrush.generator.horizontalFade = KisDomUtils::toDouble(generatorEl.attribute("hfade", "0.0"));
67 brush.autoBrush.generator.verticalFade = KisDomUtils::toDouble(generatorEl.attribute("vfade", "0.0"));
68 brush.autoBrush.generator.antialiasEdges = generatorEl.attribute("antialiasEdges", "0").toInt();
69 brush.autoBrush.generator.spikes = generatorEl.attribute("spikes", "2").toInt();
70
71 const QString shape = generatorEl.attribute("type", "circle");
74
75 const QString type = generatorEl.attribute("id", DefaultId.id());
78 type == SoftId.id() ? KisBrushModel::Soft :
80
81 if (generatorEl.hasAttribute("softness_curve")) {
82 brush.autoBrush.generator.curveString = generatorEl.attribute("softness_curve","");
83 }
84
85 return {brush};
86}
87
88void KisAutoBrushFactory::toXML(QDomDocument &doc, QDomElement &e, const KisBrushModel::BrushData &model)
89{
90 e.setAttribute("type", id());
91 e.setAttribute("BrushVersion", "2");
92
93 e.setAttribute("spacing", QString::number(model.common.spacing));
94 e.setAttribute("useAutoSpacing", QString::number(model.common.useAutoSpacing));
95 e.setAttribute("autoSpacingCoeff", QString::number(model.common.autoSpacingCoeff));
96 e.setAttribute("angle", QString::number(model.common.angle));
97 e.setAttribute("randomness", QString::number(model.autoBrush.randomness));
98 e.setAttribute("density", QString::number(model.autoBrush.density));
99
100 {
101 QDomElement shapeElt = doc.createElement("MaskGenerator");
102
103 shapeElt.setAttribute("diameter", QString::number(model.autoBrush.generator.diameter));
104 shapeElt.setAttribute("ratio", QString::number(model.autoBrush.generator.ratio));
105 shapeElt.setAttribute("hfade", QString::number(model.autoBrush.generator.horizontalFade));
106 shapeElt.setAttribute("vfade", QString::number(model.autoBrush.generator.verticalFade));
107 shapeElt.setAttribute("spikes", model.autoBrush.generator.spikes);
108 shapeElt.setAttribute("type", model.autoBrush.generator.shape == KisBrushModel::Circle ? "circle" : "rct");
109 shapeElt.setAttribute("antialiasEdges", model.autoBrush.generator.antialiasEdges);
110
111
112 QString idString;
114 idString = DefaultId.id();
115 } else if (model.autoBrush.generator.type == KisBrushModel::Soft) {
116 idString = SoftId.id();
117 } else {
118 idString = GaussId.id();
119 }
120
121 shapeElt.setAttribute("id", idString);
122
123 if (!model.autoBrush.generator.curveString.isEmpty()) {
124 shapeElt.setAttribute("softness_curve", model.autoBrush.generator.curveString);
125 }
126
127 e.appendChild(shapeElt);
128 }
129}
130
132{
133 Q_UNUSED(resourcesInterface);
134
135 KisMaskGenerator *generator = 0;
136
137 if (autoBrushData.generator.type == KisBrushModel::Default &&
138 autoBrushData.generator.shape == KisBrushModel::Circle) {
139
140 generator = new KisCircleMaskGenerator(autoBrushData.generator.diameter,
141 autoBrushData.generator.ratio,
142 autoBrushData.generator.horizontalFade,
143 autoBrushData.generator.verticalFade,
144 autoBrushData.generator.spikes,
145 autoBrushData.generator.antialiasEdges);
146
147 } else if (autoBrushData.generator.type == KisBrushModel::Default &&
148 autoBrushData.generator.shape == KisBrushModel::Rectangle) {
149
150 generator = new KisRectangleMaskGenerator(autoBrushData.generator.diameter,
151 autoBrushData.generator.ratio,
152 autoBrushData.generator.horizontalFade,
153 autoBrushData.generator.verticalFade,
154 autoBrushData.generator.spikes,
155 autoBrushData.generator.antialiasEdges);
156
157
158 } else if (autoBrushData.generator.type == KisBrushModel::Soft) {
159
160 QString curveString = autoBrushData.generator.curveString;
161 if (curveString.isEmpty()) {
162 curveString = "0,1;1,0";
163 }
164
165 const KisCubicCurve curve(curveString);
166
167 if (autoBrushData.generator.shape == KisBrushModel::Circle) {
168 generator = new KisCurveCircleMaskGenerator(autoBrushData.generator.diameter,
169 autoBrushData.generator.ratio,
170 autoBrushData.generator.horizontalFade,
171 autoBrushData.generator.verticalFade,
172 autoBrushData.generator.spikes,
173 curve,
174 autoBrushData.generator.antialiasEdges);
175 } else {
176 generator = new KisCurveRectangleMaskGenerator(autoBrushData.generator.diameter,
177 autoBrushData.generator.ratio,
178 autoBrushData.generator.horizontalFade,
179 autoBrushData.generator.verticalFade,
180 autoBrushData.generator.spikes,
181 curve,
182 autoBrushData.generator.antialiasEdges);
183 }
184
185 } else if (autoBrushData.generator.type == KisBrushModel::Gaussian &&
186 autoBrushData.generator.shape == KisBrushModel::Circle) {
187
188 generator = new KisGaussCircleMaskGenerator(autoBrushData.generator.diameter,
189 autoBrushData.generator.ratio,
190 autoBrushData.generator.horizontalFade,
191 autoBrushData.generator.verticalFade,
192 autoBrushData.generator.spikes,
193 autoBrushData.generator.antialiasEdges);
194
195 } else if (autoBrushData.generator.type == KisBrushModel::Gaussian &&
196 autoBrushData.generator.shape == KisBrushModel::Rectangle) {
197
198 generator = new KisGaussRectangleMaskGenerator(autoBrushData.generator.diameter,
199 autoBrushData.generator.ratio,
200 autoBrushData.generator.horizontalFade,
201 autoBrushData.generator.verticalFade,
202 autoBrushData.generator.spikes,
203 autoBrushData.generator.antialiasEdges);
204 }
205
206 KisBrushSP brush = KisBrushSP(new KisAutoBrush(generator, commonData.angle, autoBrushData.randomness, autoBrushData.density));
207 brush->setSpacing(commonData.spacing);
208 brush->setAutoSpacing(commonData.useAutoSpacing, commonData.autoSpacingCoeff);
209
210 return {brush};
211}
void toXML(QDomDocument &doc, QDomElement &element, const KisBrushModel::BrushData &model) override
KoResourceLoadResult createBrush(const QDomElement &brushDefinition, KisResourcesInterfaceSP resourcesInterface) override
std::optional< KisBrushModel::BrushData > createBrushModel(const QDomElement &element, KisResourcesInterfaceSP resourcesInterface) override
QString id() const
Definition KoID.cpp:63
A simple wrapper object for the main information about the resource.
const KoID SoftId("soft", ki18n("Soft"))
generate brush mask from former softbrush paintop, where softness is based on curve
const KoID DefaultId("default", ki18n("Default"))
generate Krita default mask generator
const KoID GaussId("gauss", ki18n("Gaussian"))
generate brush mask with a Gaussian-blurred edge
QSharedPointer< KisBrush > KisBrushSP
Definition kis_brush.h:49
double toDouble(const QString &str, bool *ok=nullptr)
int toInt(const QString &str, bool *ok=nullptr)
const QString Brushes
AutoBrushGeneratorData generator