Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_psd_layer_style.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2014 Boudewijn Rempt <boud@valdyas.org>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
7
8#include <QBuffer>
9#include <QIODevice>
10#include <QUuid>
11#include <KLocalizedString>
12
13#include <kis_assert.h>
14#include <kis_global.h>
15#include <psd_utils.h>
17
19#include <KoAbstractGradient.h>
21#include <KoMD5Generator.h>
22
24
25
26struct Q_DECL_HIDDEN KisPSDLayerStyle::Private
27{
28 Private(KisResourcesInterfaceSP _resourcesInterface)
29 : version(-1)
30 , effectEnabled(true)
31 , resourcesInterface(_resourcesInterface)
32 {
33 if (!resourcesInterface) {
34 resourcesInterface.reset(new KisLocalStrokeResources());
35 }
36 }
37
38 Private(const Private &rhs)
39 : name(rhs.name),
40 uuid(rhs.uuid),
41 version(rhs.version),
42 effectEnabled(rhs.effectEnabled),
43 context(rhs.context),
44 drop_shadow(rhs.drop_shadow),
45 inner_shadow(rhs.inner_shadow),
46 outer_glow(rhs.outer_glow),
47 inner_glow(rhs.inner_glow),
48 bevel_emboss(rhs.bevel_emboss),
49 satin(rhs.satin),
50 color_overlay(rhs.color_overlay),
51 gradient_overlay(rhs.gradient_overlay),
52 pattern_overlay(rhs.pattern_overlay),
53 stroke(rhs.stroke),
54 resourcesInterface(rhs.resourcesInterface)
55 {}
56
58 {
59 if (this != &rhs) {
60 name = rhs.name;
61 uuid = rhs.uuid;
62 version = rhs.version;
63 effectEnabled = rhs.effectEnabled;
64 context = rhs.context;
65 drop_shadow = rhs.drop_shadow;
66 inner_shadow = rhs.inner_shadow;
67 outer_glow = rhs.outer_glow;
68 inner_glow = rhs.inner_glow;
69 bevel_emboss = rhs.bevel_emboss;
70 satin = rhs.satin;
71 color_overlay = rhs.color_overlay;
72 gradient_overlay = rhs.gradient_overlay;
73 pattern_overlay = rhs.pattern_overlay;
74 stroke = rhs.stroke;
75 resourcesInterface = rhs.resourcesInterface;
76 }
77
78 return *this;
79 }
80
81 QString name;
82 QUuid uuid;
83 quint16 version;
96
98
100};
101
102KisPSDLayerStyle::KisPSDLayerStyle(const QString &filename, KisResourcesInterfaceSP resourcesInterface)
103 : KoResource(filename)
104 , d(new Private(resourcesInterface))
105{
106 d->name = i18n("Unnamed");
107 d->version = 7;
108}
109
114
116 : KoResource(rhs)
117 , d(new Private(*rhs.d))
118{
119 setValid(valid());
120}
121
123{
124 return d->effectEnabled;
125}
126
128{
129 d->effectEnabled = value;
130}
131
133{
134 return toQShared(new KisPSDLayerStyle(*this)).dynamicCast<KoResource>();
135}
136
138{
139 return false;
140}
141
142bool KisPSDLayerStyle::loadFromDevice(QIODevice *dev, KisResourcesInterfaceSP resourcesInterface)
143{
144 Q_UNUSED(dev);
145 Q_UNUSED(resourcesInterface);
146 return false;
147}
148
149bool KisPSDLayerStyle::saveToDevice(QIODevice *) const
150{
151 KIS_SAFE_ASSERT_RECOVER_NOOP(false && "KisPSDLayerStyle is not meant to be serializable!");
152 return false;
153}
154
156{
157 *d = Private(d->resourcesInterface);
158}
159
161{
162 return !(d->drop_shadow.effectEnabled() ||
163 d->inner_shadow.effectEnabled() ||
164 d->outer_glow.effectEnabled() ||
165 d->inner_glow.effectEnabled() ||
166 d->bevel_emboss.effectEnabled() ||
167 d->satin.effectEnabled() ||
168 d->color_overlay.effectEnabled() ||
169 d->gradient_overlay.effectEnabled() ||
170 d->pattern_overlay.effectEnabled() ||
171 d->stroke.effectEnabled());
172}
173
174QString KisPSDLayerStyle::name() const
175{
176 return d->name;
177}
178
180{
181 d->name = value;
182 dynamic_cast<KoResource*>(this)->setName(value);
183}
184
185QUuid KisPSDLayerStyle::uuid() const
186{
187 if (d->uuid.isNull()) {
188 d->uuid = QUuid::createUuid();
189 }
190
191 return d->uuid;
192}
193
195{
196 d->uuid = value;
197 this->setMD5Sum(KoMD5Generator::generateHash(value.toByteArray()));
198}
199
201{
202 return uuid().toString().mid(1, 36);
203}
204
206{
207 setUuid(QUuid(QString("{%1}").arg(value)));
208}
209
211{
212 return &d->context;
213}
214
216{
217 return &d->drop_shadow;
218}
219
221{
222 return &d->inner_shadow;
223}
224
226{
227 return &d->outer_glow;
228}
229
231{
232 return &d->inner_glow;
233}
234
236{
237 return &d->satin;
238}
239
241{
242 return &d->color_overlay;
243}
244
246{
247 return &d->gradient_overlay;
248}
249
251{
252 return &d->pattern_overlay;
253}
254
256{
257 return &d->stroke;
258}
259
261{
262 return &d->bevel_emboss;
263}
264
266{
267 return &d->context;
268}
269
271{
272 return &d->drop_shadow;
273}
274
276{
277 return &d->inner_shadow;
278}
279
281{
282 return &d->outer_glow;
283}
284
286{
287 return &d->inner_glow;
288}
289
291{
292 return &d->satin;
293}
294
296{
297 return &d->color_overlay;
298}
299
304
309
311{
312 return &d->stroke;
313}
314
319
321{
322 return d->resourcesInterface;
323}
324
326{
327 d->resourcesInterface = resourcesInterface;
328}
329
334
336{
337 KisPSDLayerStyleSP style = KisRequiredResourcesOperators::cloneWithResourcesSnapshot<KisPSDLayerStyleSP>(this, globalResourcesInterface);
338
345 if (!requiredCanvasResources().isEmpty() && !canvasResourcesInterface) {
346 qWarning() << "KisPSDLayerStyle::cloneWithResourcesSnapshot: layer style"
347 << name() << "is expected to have all the canvas resources"
348 << "backed, but still depends on something";
349 qWarning() << ppVar(requiredCanvasResources());
350 }
351
352 if (canvasResourcesInterface) {
353
354 QSharedPointer<KisLocalStrokeResources> localResourcesSnapshot =
355 style->resourcesInterface().dynamicCast<KisLocalStrokeResources>();
356 KIS_ASSERT_RECOVER_RETURN_VALUE(localResourcesSnapshot, style);
357
358 auto bakeGradient = [canvasResourcesInterface, localResourcesSnapshot] (KoAbstractGradientSP gradient) {
359 if (gradient && !gradient->requiredCanvasResources().isEmpty()) {
360
367 KoAbstractGradientSP clonedGradient =
368 gradient->cloneAndBakeVariableColors(canvasResourcesInterface);
369
370 localResourcesSnapshot->removeResource(gradient);
371 localResourcesSnapshot->addResource(clonedGradient);
372 }
373 };
374
375 if (style->gradientOverlay()->effectEnabled()) {
376 bakeGradient(style->gradientOverlay()->gradient(localResourcesSnapshot));
377 }
378
379 if (style->innerGlow()->effectEnabled() && style->innerGlow()->fillType() == psd_fill_gradient) {
380 bakeGradient(style->innerGlow()->gradient(localResourcesSnapshot));
381 }
382
383 if (style->outerGlow()->effectEnabled() && style->outerGlow()->fillType() == psd_fill_gradient) {
384 bakeGradient(style->outerGlow()->gradient(localResourcesSnapshot));
385 }
386
387 if (style->stroke()->effectEnabled() && style->stroke()->fillType() == psd_fill_gradient) {
388 bakeGradient(style->stroke()->gradient(localResourcesSnapshot));
389 }
390 }
391
392 return style;
393}
394
396{
398
399 Q_FOREACH(const KoEmbeddedResource &resource, d->sideLoadedResources) {
400 KoResourceSignature sig = resource.signature();
401
405 if (!globalResourcesInterface->source(sig.type)
406 .exactMatch(sig.md5sum, sig.filename, sig.name)) {
407
408 resources << resource;
409 }
410 }
411
412 return resources;
413}
414
416{
417 d->sideLoadedResources.clear();
418}
419
421{
422 d->sideLoadedResources = value;
423}
424
426{
428 const auto linkedResourceSignatures = KisAslLayerStyleSerializer::fetchLinkedResourceSignatures(this);
429
430 Q_FOREACH(const KoResourceSignature &sig, linkedResourceSignatures) {
431 result << globalResourcesInterface->source(sig.type).bestMatchLoadResult(sig.md5sum, sig.filename, sig.name);
432 }
433
434 return result;
435}
436
438{
439 QList<int> result;
440
441 auto addCanvasResources = [&result] (KoAbstractGradientSP gradient) {
442 if (gradient) {
443 result << gradient->requiredCanvasResources();
444 }
445 };
446
448 addCanvasResources(gradientOverlay()->gradient(resourcesInterface()));
449 }
450
451 if (innerGlow()->effectEnabled() && innerGlow()->fillType() == psd_fill_gradient) {
452 addCanvasResources(innerGlow()->gradient(resourcesInterface()));
453 }
454
455 if (outerGlow()->effectEnabled() && outerGlow()->fillType() == psd_fill_gradient) {
456 addCanvasResources(outerGlow()->gradient(resourcesInterface()));
457 }
458
459 if (stroke()->effectEnabled() && stroke()->fillType() == psd_fill_gradient) {
460 addCanvasResources(stroke()->gradient(resourcesInterface()));
461 }
462
464
465 return result;
466}
float value(const T *src, size_t ch)
static QVector< KoResourceSignature > fetchLinkedResourceSignatures(const KisPSDLayerStyle *style)
a KisResourcesInterface-like resources storage for preloaded resources
const KoResourceSignature & signature() const
static QString generateHash(const QString &filename)
generateHash reads the given file and generates a hex-encoded md5sum for the file.
A simple wrapper object for the main information about the resource.
bool effectEnabled() const
Definition psd.h:261
#define KIS_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:85
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
#define ppVar(var)
Definition kis_debug.h:155
QSharedPointer< T > toQShared(T *ptr)
void makeContainerUnique(C &container)
@ psd_fill_gradient
Definition psd.h:125
The KisPSDLayerStyle class implements loading, saving and applying the PSD layer effects.
KisResourcesInterfaceSP resourcesInterface
QList< int > requiredCanvasResources() const override
KisPSDLayerStyleSP cloneWithResourcesSnapshot(KisResourcesInterfaceSP globalResourcesInterface, KoCanvasResourcesInterfaceSP canvasResourcesInterface) const
QList< KoResourceLoadResult > linkedResources(KisResourcesInterfaceSP globalResourcesInterface) const override
Private(const Private &rhs)
bool hasLocalResourcesSnapshot() const
QList< KoEmbeddedResource > sideLoadedResources
bool loadFromDevice(QIODevice *dev, KisResourcesInterfaceSP resourcesInterface) override
psd_layer_effects_inner_glow inner_glow
psd_layer_effects_context context
const psd_layer_effects_bevel_emboss * bevelAndEmboss() const
psd_layer_effects_color_overlay color_overlay
bool saveToDevice(QIODevice *dev) const override
psd_layer_effects_gradient_overlay gradient_overlay
void setEnabled(bool value)
bool isSerializable() const override
psd_layer_effects_outer_glow outer_glow
void setSideLoadedResources(const QList< KoEmbeddedResource > &value)
void clearSideLoadedResources() override
void setResourcesInterface(KisResourcesInterfaceSP resourcesInterface)
const psd_layer_effects_drop_shadow * dropShadow() const
const psd_layer_effects_color_overlay * colorOverlay() const
const psd_layer_effects_gradient_overlay * gradientOverlay() const
void setName(const QString &value)
void setUuid(const QUuid &value)
psd_layer_effects_bevel_emboss bevel_emboss
psd_layer_effects_inner_shadow inner_shadow
void setPsdUuid(const QString &value)
const psd_layer_effects_inner_glow * innerGlow() const
psd_layer_effects_stroke stroke
psd_layer_effects_pattern_overlay pattern_overlay
Private operator=(const Private &rhs)
KoResourceSP clone() const override
KisPSDLayerStyle(const QString &filename="", KisResourcesInterfaceSP resourcesInterface=KisResourcesInterfaceSP())
const psd_layer_effects_pattern_overlay * patternOverlay() const
const psd_layer_effects_inner_shadow * innerShadow() const
psd_layer_effects_drop_shadow drop_shadow
Private(KisResourcesInterfaceSP _resourcesInterface)
const psd_layer_effects_outer_glow * outerGlow() const
psd_layer_effects_satin satin
void setValid(bool valid)
void setMD5Sum(const QString &md5sum)
Set the md5sum of this resource. It must be in hex-encoded string format.