Krita Source Code Documentation
Loading...
Searching...
No Matches
KisGradientConversion.cpp
Go to the documentation of this file.
1/*
2 * KDE. Krita Project.
3 *
4 * SPDX-FileCopyrightText: 2020 Deif Lou <ginoba@gmail.com>
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9#include <QList>
10
13
15
17{
18 QGradientStops toQGradientStops(KoAbstractGradientSP gradient,
19 KoCanvasResourcesInterfaceSP canvasResourcesInterface)
20 {
21 if (!gradient) {
22 return QGradientStops();
23 }
24 if (gradient.dynamicCast<KoStopGradient>()) {
25 return toQGradientStops(gradient.dynamicCast<KoStopGradient>(), canvasResourcesInterface);
26 } else if (gradient.dynamicCast<KoSegmentGradient>()) {
27 return toQGradientStops(gradient.dynamicCast<KoSegmentGradient>(), canvasResourcesInterface);
28 }
29 return QGradientStops();
30 }
31
32 QGradientStop toQGradientStop(const KoColor &color, KoGradientStopType type, qreal position,
33 KoCanvasResourcesInterfaceSP canvasResourcesInterface)
34 {
35 QGradientStop stop;
36 stop.first = position;
37
38 if (type == FOREGROUNDSTOP) {
39 if (canvasResourcesInterface) {
40 canvasResourcesInterface->resource(KoCanvasResource::ForegroundColor).value<KoColor>().toQColor(&stop.second);
41 return stop;
42 }
43 } else if (type == BACKGROUNDSTOP) {
44 if (canvasResourcesInterface) {
45 canvasResourcesInterface->resource(KoCanvasResource::BackgroundColor).value<KoColor>().toQColor(&stop.second);
46 return stop;
47 }
48 }
49
50 color.toQColor(&stop.second);
51 return stop;
52 }
53
54 QGradientStops toQGradientStops(KoStopGradientSP gradient,
55 KoCanvasResourcesInterfaceSP canvasResourcesInterface)
56 {
57 QGradientStops stops;
58
59 if (!gradient) {
60 return stops;
61 }
62
63 qreal lastStopPosition = -1.0;
64 for (const KoGradientStop &stopGradientStop : gradient->stops()) {
65 if (qFuzzyCompare(stopGradientStop.position, lastStopPosition)) {
66 stops << toQGradientStop(
67 stopGradientStop.color, stopGradientStop.type, stopGradientStop.position + 0.000001,
68 canvasResourcesInterface
69 );
70 lastStopPosition = stopGradientStop.position + 0.000001;
71 } else {
72 stops << toQGradientStop(
73 stopGradientStop.color, stopGradientStop.type, stopGradientStop.position,
74 canvasResourcesInterface
75 );
76 lastStopPosition = stopGradientStop.position;
77 }
78 }
79 return stops;
80 }
81
82 QGradientStop toQGradientStop(const KoColor &color, KoGradientSegmentEndpointType type, qreal offset,
83 KoCanvasResourcesInterfaceSP canvasResourcesInterface)
84 {
85 QGradientStop stop;
86 stop.first = offset;
87
88 if (type == FOREGROUND_ENDPOINT) {
89 if (canvasResourcesInterface) {
90 canvasResourcesInterface->resource(KoCanvasResource::ForegroundColor).value<KoColor>().toQColor(&stop.second);
91 return stop;
92 }
93 } else if (type == FOREGROUND_TRANSPARENT_ENDPOINT) {
94 if (canvasResourcesInterface) {
95 canvasResourcesInterface->resource(KoCanvasResource::ForegroundColor).value<KoColor>().toQColor(&stop.second);
96 stop.second.setAlpha(0);
97 return stop;
98 }
99 } else if (type == BACKGROUND_ENDPOINT) {
100 if (canvasResourcesInterface) {
101 canvasResourcesInterface->resource(KoCanvasResource::BackgroundColor).value<KoColor>().toQColor(&stop.second);
102 return stop;
103 }
104 } else if (type == BACKGROUND_TRANSPARENT_ENDPOINT) {
105 if (canvasResourcesInterface) {
106 canvasResourcesInterface->resource(KoCanvasResource::BackgroundColor).value<KoColor>().toQColor(&stop.second);
107 stop.second.setAlpha(0);
108 return stop;
109 }
110 }
111
112 color.toQColor(&stop.second);
113 return stop;
114 }
115
116 QGradientStops toQGradientStops(KoSegmentGradientSP gradient,
117 KoCanvasResourcesInterfaceSP canvasResourcesInterface)
118 {
119 QGradientStops stops;
120
121 if (!gradient) {
122 return stops;
123 }
124
125 QGradientStop lastStop;
126 lastStop.first = -1.0;
127
128 for (KoGradientSegment *segment : gradient->segments()) {
129 QGradientStop stop;
130
131 stop = toQGradientStop(
132 segment->startColor(), segment->startType(), segment->startOffset(),
133 canvasResourcesInterface
134 );
135 if (qFuzzyCompare(stop.first, lastStop.first)) {
136 if (stop.second != lastStop.second) {
137 stop.first = stop.first + 0.000001;
138 stops << stop;
139 lastStop = stop;
140 }
141 } else {
142 stops << stop;
143 lastStop = stop;
144 }
145
146 stop = toQGradientStop(
147 segment->endColor(), segment->endType(), segment->endOffset(),
148 canvasResourcesInterface
149 );
150 if (qFuzzyCompare(stop.first, lastStop.first)) {
151 if (stop.second != lastStop.second) {
152 stop.first = stop.first + 0.000001;
153 stops << stop;
154 lastStop = stop;
155 }
156 } else {
157 stops << stop;
158 lastStop = stop;
159 }
160 }
161
162 return stops;
163 }
164
165 QGradient* toQGradient(KoAbstractGradientSP gradient, KoCanvasResourcesInterfaceSP canvasResourcesInterface)
166 {
167 if (!gradient) {
168 return nullptr;
169 }
170 if (gradient.dynamicCast<KoStopGradient>()) {
171 return toQGradient(gradient.dynamicCast<KoStopGradient>(), canvasResourcesInterface);
172 } else if (gradient.dynamicCast<KoSegmentGradient>()) {
173 return toQGradient(gradient.dynamicCast<KoSegmentGradient>(), canvasResourcesInterface);
174 }
175 return nullptr;
176 }
177
178 QGradient* toQGradient(KoStopGradientSP gradient, KoCanvasResourcesInterfaceSP canvasResourcesInterface)
179 {
180 if (!gradient) {
181 return nullptr;
182 }
183 QGradient *qGradient = new QLinearGradient;
184 qGradient->setStops(toQGradientStops(gradient, canvasResourcesInterface));
185 return qGradient;
186 }
187
188 QGradient* toQGradient(KoSegmentGradientSP gradient, KoCanvasResourcesInterfaceSP canvasResourcesInterface)
189 {
190 if (!gradient) {
191 return nullptr;
192 }
193 QGradient *qGradient = new QLinearGradient;
194 qGradient->setStops(toQGradientStops(gradient, canvasResourcesInterface));
195 return qGradient;
196 }
197
198 KoAbstractGradientSP toAbstractGradient(const QGradientStops &gradient)
199 {
200 return toStopGradient(gradient).dynamicCast<KoAbstractGradient>();
201 }
202
203 KoAbstractGradientSP toAbstractGradient(const QGradient *gradient)
204 {
205 if (!gradient) {
206 return nullptr;
207 }
208 return toStopGradient(gradient).dynamicCast<KoAbstractGradient>();
209 }
210
212 {
213 if (!gradient) {
214 return nullptr;
215 }
216 return gradient->clone().dynamicCast<KoAbstractGradient>();
217 }
218
220 {
221 if (!gradient) {
222 return nullptr;
223 }
224 return gradient->clone().dynamicCast<KoAbstractGradient>();
225 }
226
227 KoStopGradientSP toStopGradient(const QGradientStops &gradient)
228 {
229 KoStopGradientSP stopGradient(new KoStopGradient);
231
232 for (const QGradientStop &qGradientStop : gradient) {
233 KoGradientStop stop;
234 stop.type = COLORSTOP;
235 stop.position = qGradientStop.first;
236 stop.color = KoColor(qGradientStop.second, stopGradient->colorSpace());
237 stops << stop;
238 }
239
240 stopGradient->setStops(stops);
241 stopGradient->setType(QGradient::LinearGradient);
242 stopGradient->setValid(true);
243
244 return stopGradient;
245 }
246
247 KoStopGradientSP toStopGradient(const QGradient *gradient)
248 {
249 if (!gradient || gradient->type() == QGradient::NoGradient) {
250 return nullptr;
251 }
252 KoStopGradientSP stopGradient = toStopGradient(gradient->stops());
253 stopGradient->setType(gradient->type());
254 stopGradient->setSpread(gradient->spread());
255 return stopGradient;
256 }
257
259 KoCanvasResourcesInterfaceSP canvasResourcesInterface)
260 {
261 if (!gradient) {
262 return nullptr;
263 }
264 if (gradient.dynamicCast<KoStopGradient>()) {
265 return gradient->clone().dynamicCast<KoStopGradient>();
266 } else if (gradient.dynamicCast<KoSegmentGradient>()) {
267 return toStopGradient(gradient.dynamicCast<KoSegmentGradient>(), canvasResourcesInterface);
268 }
269 return nullptr;
270 }
271
273 KoCanvasResourcesInterfaceSP canvasResourcesInterface)
274 {
275 KoGradientStop stop;
276
277 stop.position = offset;
278
279 if (type == FOREGROUND_ENDPOINT) {
280 stop.type = FOREGROUNDSTOP;
281 stop.color = color;
282 } else if (type == FOREGROUND_TRANSPARENT_ENDPOINT) {
283 stop.type = COLORSTOP;
284 if (canvasResourcesInterface) {
285 stop.color = canvasResourcesInterface->resource(KoCanvasResource::ForegroundColor).value<KoColor>();
286 } else {
287 stop.color = color;
288 }
289 stop.color.setOpacity(static_cast<quint8>(0));
290 } else if (type == BACKGROUND_ENDPOINT) {
291 stop.type = BACKGROUNDSTOP;
292 stop.color = color;
293 } else if (type == BACKGROUND_TRANSPARENT_ENDPOINT) {
294 stop.type = COLORSTOP;
295 if (canvasResourcesInterface) {
296 stop.color = canvasResourcesInterface->resource(KoCanvasResource::BackgroundColor).value<KoColor>();
297 } else {
298 stop.color = color;
299 }
300 stop.color.setOpacity(static_cast<quint8>(0));
301 } else {
302 stop.type = COLORSTOP;
303 stop.color = color;
304 }
305
306 return stop;
307 }
308
310 {
311 if (!gradient) {
312 return nullptr;
313 }
314
315 KoStopGradientSP stopGradient(new KoStopGradient);
317
318 KoGradientStop lastStop;
319 lastStop.position = -1.0;
320
321 for (KoGradientSegment *segment : gradient->segments()) {
322 KoGradientStop stop;
323
324 stop = toKoGradientStop(
325 segment->startColor(), segment->startType(), segment->startOffset(),
326 canvasResourcesInterface
327 );
328 stop.color.convertTo(stopGradient->colorSpace());
329 if (!qFuzzyCompare(stop.position, lastStop.position) || stop.type != lastStop.type || stop.color != lastStop.color) {
330 stops << stop;
331 lastStop.type = stop.type;
332 lastStop.color = stop.color;
333 lastStop.position = stop.position;
334 }
335
336 stop = toKoGradientStop(
337 segment->endColor(), segment->endType(), segment->endOffset(),
338 canvasResourcesInterface
339 );
340 stop.color.convertTo(stopGradient->colorSpace());
341 if (!qFuzzyCompare(stop.position, lastStop.position) || stop.type != lastStop.type || stop.color != lastStop.color) {
342 stops << stop;
343 lastStop.type = stop.type;
344 lastStop.color = stop.color;
345 lastStop.position = stop.position;
346 }
347 }
348
349 stopGradient->setType(gradient->type());
350 stopGradient->setSpread(gradient->spread());
351 stopGradient->setStops(stops);
352
353 stopGradient->setName(gradient->name());
354 stopGradient->setFilename(gradient->filename());
355 stopGradient->setValid(true);
356
357 return stopGradient;
358 }
359
360 KoSegmentGradientSP toSegmentGradient(const QGradientStops &gradient)
361 {
362 KoSegmentGradientSP segmentGradient(new KoSegmentGradient);
363 const QGradientStops &stops = gradient;
364
365 for (int i = 0; i < stops.size() - 1; ++i) {
366 if (qFuzzyCompare(stops[i].first, stops[i + 1].first)) {
367 continue;
368 }
369 segmentGradient->createSegment(
371 stops[i].first, stops[i + 1].first, (stops[i].first + stops[i + 1].first) / 2,
372 stops[i].second, stops[i + 1].second
373 );
374 }
375
376 segmentGradient->setValid(true);
377
378 return segmentGradient;
379 }
380
381 KoSegmentGradientSP toSegmentGradient(const QGradient *gradient)
382 {
383 if (!gradient || gradient->type() == QGradient::NoGradient) {
384 return nullptr;
385 }
386 KoSegmentGradientSP segmentGradient = toSegmentGradient(gradient->stops());
387 segmentGradient->setType(gradient->type());
388 segmentGradient->setSpread(gradient->spread());
389 return segmentGradient;
390 }
391
393 {
394 if (!gradient) {
395 return nullptr;
396 }
397 if (gradient.dynamicCast<KoSegmentGradient>()) {
398 return gradient->clone().dynamicCast<KoSegmentGradient>();
399 } else if (gradient.dynamicCast<KoStopGradient>()) {
400 return toSegmentGradient(gradient.dynamicCast<KoStopGradient>());
401 }
402 return nullptr;
403 }
404
406 {
407 if (!gradient) {
408 return nullptr;
409 }
410
411 KoSegmentGradientSP segmentGradient(new KoSegmentGradient);
412 QList<KoGradientStop> stops = gradient->stops();
413
414 for (int i = 0; i < stops.size() - 1; ++i) {
415 if (qFuzzyCompare(stops[i].position, stops[i + 1].position)) {
416 continue;
417 }
418
419 KoGradientSegmentEndpointType startType, endType;
420 const KoGradientStopType startStopType = stops[i].type;
421 const KoGradientStopType endStopType = stops[i + 1].type;
422
423 if (startStopType == FOREGROUNDSTOP) {
424 startType = FOREGROUND_ENDPOINT;
425 } else if (startStopType == BACKGROUNDSTOP) {
426 startType = BACKGROUND_ENDPOINT;
427 } else {
428 startType = COLOR_ENDPOINT;
429 }
430
431 if (endStopType == FOREGROUNDSTOP) {
432 endType = FOREGROUND_ENDPOINT;
433 } else if (endStopType == BACKGROUNDSTOP) {
434 endType = BACKGROUND_ENDPOINT;
435 } else {
436 endType = COLOR_ENDPOINT;
437 }
438
439 segmentGradient->createSegment(
441 stops[i].position, stops[i + 1].position, (stops[i].position + stops[i + 1].position) / 2,
442 stops[i].color.toQColor(), stops[i + 1].color.toQColor(),
443 startType, endType
444 );
445 }
446
447 segmentGradient->setType(gradient->type());
448 segmentGradient->setSpread(gradient->spread());
449
450 segmentGradient->setName(gradient->name());
451 segmentGradient->setFilename(gradient->filename());
452 segmentGradient->setValid(true);
453
454 return segmentGradient;
455 }
456}
KoGradientSegmentEndpointType
@ COLOR_ENDPOINT
@ BACKGROUND_TRANSPARENT_ENDPOINT
@ FOREGROUND_ENDPOINT
@ BACKGROUND_ENDPOINT
@ FOREGROUND_TRANSPARENT_ENDPOINT
@ INTERP_LINEAR
@ COLOR_INTERP_RGB
KoGradientStopType
@ FOREGROUNDSTOP
@ BACKGROUNDSTOP
@ COLORSTOP
void convertTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
Definition KoColor.cpp:136
void setOpacity(quint8 alpha)
Definition KoColor.cpp:333
void toQColor(QColor *c) const
a convenience method for the above.
Definition KoColor.cpp:198
Write API docs here.
static bool qFuzzyCompare(half p1, half p2)
Namespace containing functions to convert to/from different types of gradients.
QGradient * toQGradient(KoAbstractGradientSP gradient, KoCanvasResourcesInterfaceSP canvasResourcesInterface)
Convert a KoAbstractGradientSP to a QGradient.
KoStopGradientSP toStopGradient(const QGradientStops &gradient)
Convert a QGradientStop list to a KoStopGradientSP.
KoGradientStop toKoGradientStop(const KoColor &color, KoGradientSegmentEndpointType type, qreal offset, KoCanvasResourcesInterfaceSP canvasResourcesInterface)
KoSegmentGradientSP toSegmentGradient(const QGradientStops &gradient)
Convert a QGradientStop list to a krita segment gradient.
QGradientStops toQGradientStops(KoAbstractGradientSP gradient, KoCanvasResourcesInterfaceSP canvasResourcesInterface)
Convert a KoAbstractGradientSP to a QGradientStop list.
QGradientStop toQGradientStop(const KoColor &color, KoGradientStopType type, qreal position, KoCanvasResourcesInterfaceSP canvasResourcesInterface)
KoAbstractGradientSP toAbstractGradient(const QGradientStops &gradient)
Convert a QGradientStop list to a krita abstract gradient.
@ BackgroundColor
The active background color selected for this canvas.
@ ForegroundColor
The active foreground color selected for this canvas.
KoGradientStopType type