File indexing completed on 2024-05-12 15:58:09
0001 /* 0002 * SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com> 0003 * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "kis_asl_layer_style_serializer.h" 0009 #include "kis_image.h" 0010 0011 #include <QDomDocument> 0012 #include <QMultiHash> 0013 0014 #include <KisResourceModel.h> 0015 #include <KisEmbeddedResourceStorageProxy.h> 0016 0017 #include <KoResourceServerProvider.h> 0018 #include <resources/KoAbstractGradient.h> 0019 #include <resources/KoSegmentGradient.h> 0020 #include <resources/KoStopGradient.h> 0021 #include <resources/KoPattern.h> 0022 0023 #include "kis_layer_utils.h" 0024 #include "kis_dom_utils.h" 0025 0026 #include <kis_layer.h> 0027 #include <kis_pointer_utils.h> 0028 0029 #include "psd.h" 0030 #include "kis_global.h" 0031 0032 #include "asl/kis_asl_reader.h" 0033 #include "asl/kis_asl_xml_parser.h" 0034 #include "asl/kis_asl_writer_utils.h" 0035 0036 #include "asl/kis_asl_xml_writer.h" 0037 #include "asl/kis_asl_writer.h" 0038 0039 #include <functional> 0040 0041 using namespace std::placeholders; 0042 0043 KisAslLayerStyleSerializer::KisAslLayerStyleSerializer() 0044 : m_localResourcesInterface(new KisLocalStrokeResources()) 0045 { 0046 } 0047 0048 KisAslLayerStyleSerializer::~KisAslLayerStyleSerializer() 0049 { 0050 } 0051 0052 QVector<KisPSDLayerStyleSP> KisAslLayerStyleSerializer::styles() const 0053 { 0054 return m_stylesVector; 0055 } 0056 0057 void KisAslLayerStyleSerializer::setStyles(const QVector<KisPSDLayerStyleSP> &styles) 0058 { 0059 m_stylesVector = styles; 0060 Q_FOREACH(const KisPSDLayerStyleSP style, styles) { 0061 m_stylesHash.insert(style->psdUuid(), style); 0062 } 0063 m_initialized = true; 0064 } 0065 0066 QHash<QString, KoPatternSP> KisAslLayerStyleSerializer::patterns() const 0067 { 0068 return m_patternsStore; 0069 } 0070 0071 QVector<KoAbstractGradientSP> KisAslLayerStyleSerializer::gradients() const 0072 { 0073 return m_gradientsStore; 0074 } 0075 0076 QHash<QString, KisPSDLayerStyleSP> KisAslLayerStyleSerializer::stylesHash() 0077 { 0078 if (m_stylesHash.count() == 0 && m_stylesVector.count() != 0) { 0079 // build the hash 0080 Q_FOREACH(KisPSDLayerStyleSP style, m_stylesVector) { 0081 m_stylesHash.insert(style->psdUuid(), style); 0082 } 0083 } 0084 return m_stylesHash; 0085 } 0086 0087 QString compositeOpToBlendMode(const QString &compositeOp) 0088 { 0089 QString mode = "Nrml"; 0090 0091 if (compositeOp == COMPOSITE_OVER) { 0092 mode = "Nrml"; 0093 } else if (compositeOp == COMPOSITE_DISSOLVE) { 0094 mode = "Dslv"; 0095 } else if (compositeOp == COMPOSITE_DARKEN) { 0096 mode = "Drkn"; 0097 } else if (compositeOp == COMPOSITE_MULT) { 0098 mode = "Mltp"; 0099 } else if (compositeOp == COMPOSITE_BURN) { 0100 mode = "CBrn"; 0101 } else if (compositeOp == COMPOSITE_LINEAR_BURN) { 0102 mode = "linearBurn"; 0103 } else if (compositeOp == COMPOSITE_DARKER_COLOR) { 0104 mode = "darkerColor"; 0105 } else if (compositeOp == COMPOSITE_LIGHTEN) { 0106 mode = "Lghn"; 0107 } else if (compositeOp == COMPOSITE_SCREEN) { 0108 mode = "Scrn"; 0109 } else if (compositeOp == COMPOSITE_DODGE) { 0110 mode = "CDdg"; 0111 } else if (compositeOp == COMPOSITE_LINEAR_DODGE) { 0112 mode = "linearDodge"; 0113 } else if (compositeOp == COMPOSITE_LIGHTER_COLOR) { 0114 mode = "lighterColor"; 0115 } else if (compositeOp == COMPOSITE_OVERLAY) { 0116 mode = "Ovrl"; 0117 } else if (compositeOp == COMPOSITE_SOFT_LIGHT_PHOTOSHOP) { 0118 mode = "SftL"; 0119 } else if (compositeOp == COMPOSITE_HARD_LIGHT) { 0120 mode = "HrdL"; 0121 } else if (compositeOp == COMPOSITE_VIVID_LIGHT) { 0122 mode = "vividLight"; 0123 } else if (compositeOp == COMPOSITE_LINEAR_LIGHT) { 0124 mode = "linearLight"; 0125 } else if (compositeOp == COMPOSITE_PIN_LIGHT) { 0126 mode = "pinLight"; 0127 } else if (compositeOp == COMPOSITE_HARD_MIX_PHOTOSHOP) { 0128 mode = "hardMix"; 0129 } else if (compositeOp == COMPOSITE_DIFF) { 0130 mode = "Dfrn"; 0131 } else if (compositeOp == COMPOSITE_EXCLUSION) { 0132 mode = "Xclu"; 0133 } else if (compositeOp == COMPOSITE_SUBTRACT) { 0134 mode = "Sbtr"; 0135 } else if (compositeOp == COMPOSITE_DIVIDE) { 0136 mode = "divide"; 0137 } else if (compositeOp == COMPOSITE_HUE) { 0138 mode = "H "; 0139 } else if (compositeOp == COMPOSITE_SATURATION) { 0140 mode = "Strt"; 0141 } else if (compositeOp == COMPOSITE_COLOR) { 0142 mode = "Clr "; 0143 } else if (compositeOp == COMPOSITE_LUMINIZE) { 0144 mode = "Lmns"; 0145 } else { 0146 dbgKrita << "Unknown composite op:" << mode << "Returning \"Nrml\"!"; 0147 } 0148 0149 return mode; 0150 } 0151 0152 QString techniqueToString(psd_technique_type technique, const QString &typeId) 0153 { 0154 QString result = "SfBL"; 0155 0156 switch (technique) { 0157 case psd_technique_softer: 0158 result = "SfBL"; 0159 break; 0160 case psd_technique_precise: 0161 result = "PrBL"; 0162 break; 0163 case psd_technique_slope_limit: 0164 result = "Slmt"; 0165 break; 0166 } 0167 0168 if (typeId == "BETE" && technique == psd_technique_slope_limit) { 0169 warnKrita << "WARNING: techniqueToString: invalid technique type!" << ppVar(technique) << ppVar(typeId); 0170 } 0171 0172 return result; 0173 } 0174 0175 QString bevelStyleToString(psd_bevel_style style) 0176 { 0177 QString result = "OtrB"; 0178 0179 switch (style) { 0180 case psd_bevel_outer_bevel: 0181 result = "OtrB"; 0182 break; 0183 case psd_bevel_inner_bevel: 0184 result = "InrB"; 0185 break; 0186 case psd_bevel_emboss: 0187 result = "Embs"; 0188 break; 0189 case psd_bevel_pillow_emboss: 0190 result = "PlEb"; 0191 break; 0192 case psd_bevel_stroke_emboss: 0193 result = "strokeEmboss"; 0194 break; 0195 } 0196 0197 return result; 0198 } 0199 0200 QString gradientTypeToString(psd_gradient_style style) 0201 { 0202 QString result = "Lnr "; 0203 0204 switch (style) { 0205 case psd_gradient_style_linear: 0206 result = "Lnr "; 0207 break; 0208 case psd_gradient_style_radial: 0209 result = "Rdl "; 0210 break; 0211 case psd_gradient_style_angle: 0212 result = "Angl"; 0213 break; 0214 case psd_gradient_style_reflected: 0215 result = "Rflc"; 0216 break; 0217 case psd_gradient_style_diamond: 0218 result = "Dmnd"; 0219 break; 0220 } 0221 0222 return result; 0223 } 0224 0225 QString strokePositionToString(psd_stroke_position position) 0226 { 0227 QString result = "OutF"; 0228 0229 switch (position) { 0230 case psd_stroke_outside: 0231 result = "OutF"; 0232 break; 0233 case psd_stroke_inside: 0234 result = "InsF"; 0235 break; 0236 case psd_stroke_center: 0237 result = "CtrF"; 0238 break; 0239 } 0240 0241 return result; 0242 } 0243 0244 QString strokeFillTypeToString(psd_fill_type position) 0245 { 0246 QString result = "SClr"; 0247 0248 switch (position) { 0249 case psd_fill_solid_color: 0250 result = "SClr"; 0251 break; 0252 case psd_fill_gradient: 0253 result = "GrFl"; 0254 break; 0255 case psd_fill_pattern: 0256 result = "Ptrn"; 0257 break; 0258 } 0259 0260 return result; 0261 } 0262 0263 QVector<KoPatternSP> KisAslLayerStyleSerializer::fetchAllPatterns(const KisPSDLayerStyle *style) 0264 { 0265 QVector <KoPatternSP> allPatterns; 0266 0267 if (style->patternOverlay()->effectEnabled()) { 0268 allPatterns << style->patternOverlay()->pattern(style->resourcesInterface()); 0269 } 0270 0271 if (style->stroke()->effectEnabled() && 0272 style->stroke()->fillType() == psd_fill_pattern) { 0273 0274 allPatterns << style->stroke()->pattern(style->resourcesInterface()); 0275 } 0276 0277 if(style->bevelAndEmboss()->effectEnabled() && 0278 style->bevelAndEmboss()->textureEnabled()) { 0279 0280 allPatterns << style->bevelAndEmboss()->texturePattern(style->resourcesInterface()); 0281 } 0282 0283 KIS_SAFE_ASSERT_RECOVER(!allPatterns.contains(KoPatternSP())) 0284 { 0285 warnKrita << "WARNING: one or more patterns from the style is null"; 0286 allPatterns.removeAll(KoPatternSP()); 0287 } 0288 0289 return allPatterns; 0290 } 0291 0292 QString fetchPatternUuidSafe(KoPatternSP pattern, QHash<KoPatternSP, QString> patternToUuid) 0293 { 0294 if (patternToUuid.contains(pattern)) { 0295 return patternToUuid[pattern]; 0296 } else { 0297 warnKrita << "WARNING: the pattern is not present in the Uuid map!"; 0298 return "invalid-uuid"; 0299 } 0300 } 0301 0302 QDomDocument KisAslLayerStyleSerializer::formXmlDocument() const 0303 { 0304 KIS_ASSERT_RECOVER(!m_stylesVector.isEmpty()) { return QDomDocument(); } 0305 0306 QVector<KoPatternSP> allPatterns; 0307 0308 Q_FOREACH (KisPSDLayerStyleSP style, m_stylesVector) { 0309 allPatterns += fetchAllPatterns(style.data()); 0310 } 0311 0312 QHash<KoPatternSP, QString> patternToUuidMap; 0313 0314 KisAslXmlWriter w; 0315 0316 if (!allPatterns.isEmpty()) { 0317 w.enterList(ResourceType::Patterns); 0318 0319 Q_FOREACH (KoPatternSP pattern, allPatterns) { 0320 if (pattern) { 0321 if (!patternToUuidMap.contains(pattern)) { 0322 QString uuid = w.writePattern("", pattern); 0323 patternToUuidMap.insert(pattern, uuid); 0324 } 0325 } else { 0326 warnKrita << "WARNING: KisAslLayerStyleSerializer::saveToDevice: saved pattern is null!"; 0327 } 0328 } 0329 0330 w.leaveList(); 0331 } 0332 0333 Q_FOREACH (KisPSDLayerStyleSP style, m_stylesVector) { 0334 0335 w.enterDescriptor("", "", "null"); 0336 w.writeText("Nm ", style->name()); 0337 w.writeText("Idnt", style->psdUuid()); 0338 w.leaveDescriptor(); 0339 0340 w.enterDescriptor("", "", "Styl"); 0341 0342 w.enterDescriptor("documentMode", "", "documentMode"); 0343 w.leaveDescriptor(); 0344 0345 w.enterDescriptor("Lefx", "", "Lefx"); 0346 0347 w.writeUnitFloat("Scl ", "#Prc", 100); 0348 w.writeBoolean("masterFXSwitch", style->isEnabled()); 0349 0350 0351 // Drop Shadow 0352 const psd_layer_effects_drop_shadow *dropShadow = style->dropShadow(); 0353 if (dropShadow->effectEnabled()) { 0354 w.enterDescriptor("DrSh", "", "DrSh"); 0355 0356 w.writeBoolean("enab", dropShadow->effectEnabled()); 0357 w.writeEnum("Md ", "BlnM", compositeOpToBlendMode(dropShadow->blendMode())); 0358 w.writeColor("Clr ", dropShadow->color()); 0359 0360 w.writeUnitFloat("Opct", "#Prc", dropShadow->opacity()); 0361 w.writeBoolean("uglg", dropShadow->useGlobalLight()); 0362 w.writeUnitFloat("lagl", "#Ang", dropShadow->angle()); 0363 w.writeUnitFloat("Dstn", "#Pxl", dropShadow->distance()); 0364 w.writeUnitFloat("Ckmt", "#Pxl", dropShadow->spread()); 0365 w.writeUnitFloat("blur", "#Pxl", dropShadow->size()); 0366 w.writeUnitFloat("Nose", "#Prc", dropShadow->noise()); 0367 0368 w.writeBoolean("AntA", dropShadow->antiAliased()); 0369 0370 // FIXME: save curves 0371 w.writeCurve("TrnS", 0372 "Linear", 0373 QVector<QPointF>() << QPointF() << QPointF(255, 255)); 0374 0375 w.writeBoolean("layerConceals", dropShadow->knocksOut()); 0376 w.leaveDescriptor(); 0377 } 0378 0379 // Inner Shadow 0380 const psd_layer_effects_inner_shadow *innerShadow = style->innerShadow(); 0381 if (innerShadow->effectEnabled()) { 0382 w.enterDescriptor("IrSh", "", "IrSh"); 0383 0384 w.writeBoolean("enab", innerShadow->effectEnabled()); 0385 w.writeEnum("Md ", "BlnM", compositeOpToBlendMode(innerShadow->blendMode())); 0386 w.writeColor("Clr ", innerShadow->color()); 0387 0388 w.writeUnitFloat("Opct", "#Prc", innerShadow->opacity()); 0389 w.writeBoolean("uglg", innerShadow->useGlobalLight()); 0390 w.writeUnitFloat("lagl", "#Ang", innerShadow->angle()); 0391 w.writeUnitFloat("Dstn", "#Pxl", innerShadow->distance()); 0392 w.writeUnitFloat("Ckmt", "#Pxl", innerShadow->spread()); 0393 w.writeUnitFloat("blur", "#Pxl", innerShadow->size()); 0394 w.writeUnitFloat("Nose", "#Prc", innerShadow->noise()); 0395 0396 w.writeBoolean("AntA", innerShadow->antiAliased()); 0397 0398 // FIXME: save curves 0399 w.writeCurve("TrnS", 0400 "Linear", 0401 QVector<QPointF>() << QPointF() << QPointF(255, 255)); 0402 0403 w.leaveDescriptor(); 0404 } 0405 0406 // Outer Glow 0407 const psd_layer_effects_outer_glow *outerGlow = style->outerGlow(); 0408 if (outerGlow->effectEnabled()) { 0409 w.enterDescriptor("OrGl", "", "OrGl"); 0410 0411 w.writeBoolean("enab", outerGlow->effectEnabled()); 0412 w.writeEnum("Md ", "BlnM", compositeOpToBlendMode(outerGlow->blendMode())); 0413 0414 if (outerGlow->fillType() == psd_fill_gradient && outerGlow->gradient(style->resourcesInterface())) { 0415 KoSegmentGradient *segmentGradient = dynamic_cast<KoSegmentGradient*>(outerGlow->gradient(style->resourcesInterface()).data()); 0416 KoStopGradient *stopGradient = dynamic_cast<KoStopGradient*>(outerGlow->gradient(style->resourcesInterface()).data()); 0417 0418 if (segmentGradient && segmentGradient->valid()) { 0419 w.writeSegmentGradient("Grad", segmentGradient); 0420 } else if (stopGradient && stopGradient->valid()) { 0421 w.writeStopGradient("Grad", stopGradient); 0422 } else { 0423 warnKrita << "WARNING: OG: Unknown gradient type!"; 0424 w.writeColor("Clr ", outerGlow->color()); 0425 } 0426 0427 } else { 0428 w.writeColor("Clr ", outerGlow->color()); 0429 } 0430 0431 w.writeUnitFloat("Opct", "#Prc", outerGlow->opacity()); 0432 0433 w.writeEnum("GlwT", "BETE", techniqueToString(outerGlow->technique(), "BETE")); 0434 0435 w.writeUnitFloat("Ckmt", "#Pxl", outerGlow->spread()); 0436 w.writeUnitFloat("blur", "#Pxl", outerGlow->size()); 0437 w.writeUnitFloat("Nose", "#Prc", outerGlow->noise()); 0438 0439 w.writeUnitFloat("ShdN", "#Prc", outerGlow->jitter()); 0440 0441 w.writeBoolean("AntA", outerGlow->antiAliased()); 0442 0443 // FIXME: save curves 0444 w.writeCurve("TrnS", 0445 "Linear", 0446 QVector<QPointF>() << QPointF() << QPointF(255, 255)); 0447 0448 w.writeUnitFloat("Inpr", "#Prc", outerGlow->range()); 0449 0450 w.leaveDescriptor(); 0451 } 0452 0453 // Inner Glow 0454 const psd_layer_effects_inner_glow *innerGlow = style->innerGlow(); 0455 if (innerGlow->effectEnabled()) { 0456 w.enterDescriptor("IrGl", "", "IrGl"); 0457 0458 w.writeBoolean("enab", innerGlow->effectEnabled()); 0459 w.writeEnum("Md ", "BlnM", compositeOpToBlendMode(innerGlow->blendMode())); 0460 0461 if (innerGlow->fillType() == psd_fill_gradient && innerGlow->gradient(style->resourcesInterface())) { 0462 KoSegmentGradient *segmentGradient = dynamic_cast<KoSegmentGradient*>(innerGlow->gradient(style->resourcesInterface()).data()); 0463 KoStopGradient *stopGradient = dynamic_cast<KoStopGradient*>(innerGlow->gradient(style->resourcesInterface()).data()); 0464 0465 if (segmentGradient && innerGlow->gradient(style->resourcesInterface())->valid()) { 0466 w.writeSegmentGradient("Grad", segmentGradient); 0467 } else if (stopGradient && innerGlow->gradient(style->resourcesInterface())->valid()) { 0468 w.writeStopGradient("Grad", stopGradient); 0469 } else { 0470 warnKrita << "WARNING: IG: Unknown gradient type!"; 0471 w.writeColor("Clr ", innerGlow->color()); 0472 } 0473 0474 } else { 0475 w.writeColor("Clr ", innerGlow->color()); 0476 } 0477 0478 w.writeUnitFloat("Opct", "#Prc", innerGlow->opacity()); 0479 0480 w.writeEnum("GlwT", "BETE", techniqueToString(innerGlow->technique(), "BETE")); 0481 0482 w.writeUnitFloat("Ckmt", "#Pxl", innerGlow->spread()); 0483 w.writeUnitFloat("blur", "#Pxl", innerGlow->size()); 0484 0485 // NOTE: order is swapped in ASL! 0486 w.writeUnitFloat("ShdN", "#Prc", innerGlow->jitter()); 0487 w.writeUnitFloat("Nose", "#Prc", innerGlow->noise()); 0488 0489 w.writeBoolean("AntA", innerGlow->antiAliased()); 0490 0491 w.writeEnum("glwS", "IGSr", innerGlow->source() == psd_glow_center ? "SrcC" : "SrcE"); 0492 0493 // FIXME: save curves 0494 w.writeCurve("TrnS", 0495 "Linear", 0496 QVector<QPointF>() << QPointF() << QPointF(255, 255)); 0497 0498 w.writeUnitFloat("Inpr", "#Prc", innerGlow->range()); 0499 0500 w.leaveDescriptor(); 0501 } 0502 0503 // Bevel and Emboss 0504 const psd_layer_effects_bevel_emboss *bevelAndEmboss = style->bevelAndEmboss(); 0505 if (bevelAndEmboss->effectEnabled()) { 0506 w.enterDescriptor("ebbl", "", "ebbl"); 0507 0508 w.writeBoolean("enab", bevelAndEmboss->effectEnabled()); 0509 0510 w.writeEnum("hglM", "BlnM", compositeOpToBlendMode(bevelAndEmboss->highlightBlendMode())); 0511 w.writeColor("hglC", bevelAndEmboss->highlightColor()); 0512 w.writeUnitFloat("hglO", "#Prc", bevelAndEmboss->highlightOpacity()); 0513 0514 w.writeEnum("sdwM", "BlnM", compositeOpToBlendMode(bevelAndEmboss->shadowBlendMode())); 0515 w.writeColor("sdwC", bevelAndEmboss->shadowColor()); 0516 w.writeUnitFloat("sdwO", "#Prc", bevelAndEmboss->shadowOpacity()); 0517 0518 w.writeEnum("bvlT", "bvlT", techniqueToString(bevelAndEmboss->technique(), "bvlT")); 0519 w.writeEnum("bvlS", "BESl", bevelStyleToString(bevelAndEmboss->style())); 0520 0521 w.writeBoolean("uglg", bevelAndEmboss->useGlobalLight()); 0522 w.writeUnitFloat("lagl", "#Ang", bevelAndEmboss->angle()); 0523 w.writeUnitFloat("Lald", "#Ang", bevelAndEmboss->altitude()); 0524 0525 w.writeUnitFloat("srgR", "#Prc", bevelAndEmboss->depth()); 0526 w.writeUnitFloat("blur", "#Pxl", bevelAndEmboss->size()); 0527 w.writeEnum("bvlD", "BESs", bevelAndEmboss->direction() == psd_direction_up ? "In " : "Out "); 0528 0529 // FIXME: save curves 0530 w.writeCurve("TrnS", 0531 "Linear", 0532 QVector<QPointF>() << QPointF() << QPointF(255, 255)); 0533 0534 w.writeBoolean("antialiasGloss", bevelAndEmboss->glossAntiAliased()); 0535 0536 w.writeUnitFloat("Sftn", "#Pxl", bevelAndEmboss->soften()); 0537 0538 if (bevelAndEmboss->contourEnabled()) { 0539 w.writeBoolean("useShape", bevelAndEmboss->contourEnabled()); 0540 0541 // FIXME: save curves 0542 w.writeCurve("MpgS", 0543 "Linear", 0544 QVector<QPointF>() << QPointF() << QPointF(255, 255)); 0545 0546 w.writeBoolean("AntA", bevelAndEmboss->antiAliased()); 0547 w.writeUnitFloat("Inpr", "#Prc", bevelAndEmboss->contourRange()); 0548 } 0549 0550 w.writeBoolean("useTexture", bevelAndEmboss->textureEnabled()); 0551 0552 if (bevelAndEmboss->textureEnabled()) { 0553 w.writeBoolean("InvT", bevelAndEmboss->textureInvert()); 0554 w.writeBoolean("Algn", bevelAndEmboss->textureAlignWithLayer()); 0555 w.writeUnitFloat("Scl ", "#Prc", bevelAndEmboss->textureScale()); 0556 w.writeUnitFloat("textureDepth ", "#Prc", bevelAndEmboss->textureDepth()); 0557 0558 KoPatternSP pattern = bevelAndEmboss->texturePattern(style->resourcesInterface()); 0559 w.writePatternRef("Ptrn", pattern, fetchPatternUuidSafe(pattern, patternToUuidMap)); 0560 w.writePhasePoint("phase", bevelAndEmboss->texturePhase()); 0561 } 0562 0563 w.leaveDescriptor(); 0564 } 0565 0566 // Satin 0567 const psd_layer_effects_satin *satin = style->satin(); 0568 if (satin->effectEnabled()) { 0569 w.enterDescriptor("ChFX", "", "ChFX"); 0570 0571 w.writeBoolean("enab", satin->effectEnabled()); 0572 w.writeEnum("Md ", "BlnM", compositeOpToBlendMode(satin->blendMode())); 0573 w.writeColor("Clr ", satin->color()); 0574 0575 w.writeBoolean("AntA", satin->antiAliased()); 0576 w.writeBoolean("Invr", satin->invert()); 0577 w.writeUnitFloat("Opct", "#Prc", satin->opacity()); 0578 w.writeUnitFloat("lagl", "#Ang", satin->angle()); 0579 w.writeUnitFloat("Dstn", "#Pxl", satin->distance()); 0580 w.writeUnitFloat("blur", "#Pxl", satin->size()); 0581 0582 // FIXME: save curves 0583 w.writeCurve("MpgS", 0584 "Linear", 0585 QVector<QPointF>() << QPointF() << QPointF(255, 255)); 0586 0587 w.leaveDescriptor(); 0588 } 0589 0590 const psd_layer_effects_color_overlay *colorOverlay = style->colorOverlay(); 0591 if (colorOverlay->effectEnabled()) { 0592 w.enterDescriptor("SoFi", "", "SoFi"); 0593 0594 w.writeBoolean("enab", colorOverlay->effectEnabled()); 0595 w.writeEnum("Md ", "BlnM", compositeOpToBlendMode(colorOverlay->blendMode())); 0596 w.writeUnitFloat("Opct", "#Prc", colorOverlay->opacity()); 0597 w.writeColor("Clr ", colorOverlay->color()); 0598 0599 w.leaveDescriptor(); 0600 } 0601 0602 // Gradient Overlay 0603 const psd_layer_effects_gradient_overlay *gradientOverlay = style->gradientOverlay(); 0604 KoSegmentGradient *segmentGradient = dynamic_cast<KoSegmentGradient*>(gradientOverlay->gradient(style->resourcesInterface()).data()); 0605 KoStopGradient *stopGradient = dynamic_cast<KoStopGradient*>(gradientOverlay->gradient(style->resourcesInterface()).data()); 0606 0607 if (gradientOverlay->effectEnabled() && ((segmentGradient && segmentGradient->valid()) || (stopGradient && stopGradient->valid()))) { 0608 w.enterDescriptor("GrFl", "", "GrFl"); 0609 0610 w.writeBoolean("enab", gradientOverlay->effectEnabled()); 0611 w.writeEnum("Md ", "BlnM", compositeOpToBlendMode(gradientOverlay->blendMode())); 0612 w.writeUnitFloat("Opct", "#Prc", gradientOverlay->opacity()); 0613 0614 if (segmentGradient && segmentGradient->valid()) { 0615 w.writeSegmentGradient("Grad", segmentGradient); 0616 } else if (stopGradient && stopGradient->valid()) { 0617 w.writeStopGradient("Grad", stopGradient); 0618 } 0619 0620 w.writeUnitFloat("Angl", "#Ang", gradientOverlay->angle()); 0621 0622 w.writeEnum("Type", "GrdT", gradientTypeToString(gradientOverlay->style())); 0623 0624 w.writeBoolean("Rvrs", gradientOverlay->reverse()); 0625 w.writeBoolean("Algn", gradientOverlay->alignWithLayer()); 0626 w.writeUnitFloat("Scl ", "#Prc", gradientOverlay->scale()); 0627 0628 w.writeOffsetPoint("Ofst", gradientOverlay->gradientOffset()); 0629 0630 w.writeBoolean("Dthr", gradientOverlay->dither()); 0631 0632 w.leaveDescriptor(); 0633 } 0634 0635 // Pattern Overlay 0636 const psd_layer_effects_pattern_overlay *patternOverlay = style->patternOverlay(); 0637 if (patternOverlay->effectEnabled()) { 0638 w.enterDescriptor("patternFill", "", "patternFill"); 0639 0640 w.writeBoolean("enab", patternOverlay->effectEnabled()); 0641 w.writeEnum("Md ", "BlnM", compositeOpToBlendMode(patternOverlay->blendMode())); 0642 w.writeUnitFloat("Opct", "#Prc", patternOverlay->opacity()); 0643 0644 KoPatternSP pattern = patternOverlay->pattern(style->resourcesInterface()); 0645 w.writePatternRef("Ptrn", pattern, fetchPatternUuidSafe(pattern, patternToUuidMap)); 0646 0647 w.writeUnitFloat("Scl ", "#Prc", patternOverlay->scale()); 0648 w.writeBoolean("Algn", patternOverlay->alignWithLayer()); 0649 w.writePhasePoint("phase", patternOverlay->patternPhase()); 0650 0651 w.leaveDescriptor(); 0652 } 0653 0654 const psd_layer_effects_stroke *stroke = style->stroke(); 0655 if (stroke->effectEnabled()) { 0656 w.enterDescriptor("FrFX", "", "FrFX"); 0657 0658 w.writeBoolean("enab", stroke->effectEnabled()); 0659 0660 w.writeEnum("Styl", "FStl", strokePositionToString(stroke->position())); 0661 w.writeEnum("PntT", "FrFl", strokeFillTypeToString(stroke->fillType())); 0662 0663 w.writeEnum("Md ", "BlnM", compositeOpToBlendMode(stroke->blendMode())); 0664 w.writeUnitFloat("Opct", "#Prc", stroke->opacity()); 0665 0666 w.writeUnitFloat("Sz ", "#Pxl", stroke->size()); 0667 0668 if (stroke->fillType() == psd_fill_solid_color) { 0669 w.writeColor("Clr ", stroke->color()); 0670 } 0671 else if (stroke->fillType() == psd_fill_gradient) { 0672 KoSegmentGradient *segmentGradient = dynamic_cast<KoSegmentGradient*>(stroke->gradient(style->resourcesInterface()).data()); 0673 KoStopGradient *stopGradient = dynamic_cast<KoStopGradient*>(stroke->gradient(style->resourcesInterface()).data()); 0674 0675 if (segmentGradient && segmentGradient->valid()) { 0676 w.writeSegmentGradient("Grad", segmentGradient); 0677 } else if (stopGradient && stopGradient->valid()) { 0678 w.writeStopGradient("Grad", stopGradient); 0679 } else { 0680 warnKrita << "WARNING: Stroke: Unknown gradient type!"; 0681 w.writeColor("Clr ", stroke->color()); 0682 } 0683 0684 w.writeUnitFloat("Angl", "#Ang", stroke->angle()); 0685 w.writeEnum("Type", "GrdT", gradientTypeToString(stroke->style())); 0686 0687 w.writeBoolean("Rvrs", stroke->reverse()); 0688 w.writeUnitFloat("Scl ", "#Prc", stroke->scale()); 0689 w.writeBoolean("Algn", stroke->alignWithLayer()); 0690 w.writeOffsetPoint("Ofst", stroke->gradientOffset()); 0691 0692 w.writeBoolean("Dthr", stroke->dither()); 0693 0694 } else if (stroke->fillType() == psd_fill_pattern) { 0695 0696 KoPatternSP pattern = stroke->pattern(style->resourcesInterface()); 0697 w.writePatternRef("Ptrn", pattern, fetchPatternUuidSafe(pattern, patternToUuidMap)); 0698 w.writeUnitFloat("Scl ", "#Prc", stroke->scale()); 0699 w.writeBoolean("Lnkd", stroke->alignWithLayer()); 0700 w.writePhasePoint("phase", stroke->patternPhase()); 0701 } 0702 0703 w.leaveDescriptor(); 0704 } 0705 0706 w.leaveDescriptor(); 0707 w.leaveDescriptor(); 0708 } 0709 0710 return w.document(); 0711 } 0712 0713 inline QDomNode findNodeByClassId(const QString &classId, QDomNode parent) { 0714 return KisDomUtils::findElementByAttibute(parent, "node", "classId", classId); 0715 } 0716 0717 void replaceAllChildren(QDomNode src, QDomNode dst) 0718 { 0719 QDomNode node; 0720 0721 do { 0722 node = dst.lastChild(); 0723 dst.removeChild(node); 0724 0725 } while(!node.isNull()); 0726 0727 0728 node = src.firstChild(); 0729 while(!node.isNull()) { 0730 dst.appendChild(node); 0731 node = src.firstChild(); 0732 } 0733 0734 src.parentNode().removeChild(src); 0735 } 0736 0737 QDomDocument KisAslLayerStyleSerializer::formPsdXmlDocument() const 0738 { 0739 QDomDocument doc = formXmlDocument(); 0740 0741 QDomNode nullNode = findNodeByClassId("null", doc.documentElement()); 0742 QDomNode stylNode = findNodeByClassId("Styl", doc.documentElement()); 0743 QDomNode lefxNode = findNodeByClassId("Lefx", stylNode); 0744 0745 replaceAllChildren(lefxNode, nullNode); 0746 0747 return doc; 0748 } 0749 0750 QVector<KoResourceSP> KisAslLayerStyleSerializer::fetchEmbeddedResources(const KisPSDLayerStyle *style) 0751 { 0752 QVector<KoResourceSP> embeddedResources = implicitCastList<KoResourceSP>(fetchAllPatterns(style)); 0753 0754 if (style->gradientOverlay()->effectEnabled()) { 0755 embeddedResources << style->gradientOverlay()->gradient(style->resourcesInterface()); 0756 KIS_ASSERT(embeddedResources.last().data()); 0757 } 0758 0759 if (style->innerGlow()->effectEnabled() && style->innerGlow()->fillType() == psd_fill_gradient) { 0760 embeddedResources << style->innerGlow()->gradient(style->resourcesInterface()); 0761 KIS_ASSERT(embeddedResources.last().data()); 0762 } 0763 0764 if (style->outerGlow()->effectEnabled() && style->outerGlow()->fillType() == psd_fill_gradient) { 0765 embeddedResources << style->outerGlow()->gradient(style->resourcesInterface()); 0766 KIS_ASSERT(embeddedResources.last().data()); 0767 } 0768 0769 if (style->stroke()->effectEnabled() && style->stroke()->fillType() == psd_fill_gradient) { 0770 embeddedResources << style->stroke()->gradient(style->resourcesInterface()); 0771 KIS_ASSERT(embeddedResources.last().data()); 0772 } 0773 0774 KIS_SAFE_ASSERT_RECOVER(!embeddedResources.contains(KoResourceSP())) 0775 { 0776 embeddedResources.removeAll(KoResourceSP()); 0777 } 0778 0779 return embeddedResources; 0780 } 0781 0782 void KisAslLayerStyleSerializer::saveToDevice(QIODevice &device) 0783 { 0784 QDomDocument doc = formXmlDocument(); 0785 KIS_ASSERT(!doc.isNull()); 0786 0787 KisAslWriter writer; 0788 writer.writeFile(device, doc); 0789 } 0790 0791 bool KisAslLayerStyleSerializer::saveToFile(const QString& filename) 0792 { 0793 QFile file(filename); 0794 0795 if (!file.open(QIODevice::WriteOnly)) { 0796 dbgKrita << "Can't open file " << filename; 0797 return false; 0798 } 0799 saveToDevice(file); 0800 file.close(); 0801 0802 return true; 0803 } 0804 0805 void convertAndSetBlendMode(const QString &mode, std::function<void(const QString &)> setBlendMode) 0806 { 0807 QString compositeOp = COMPOSITE_OVER; 0808 0809 if (mode == "Nrml") { 0810 compositeOp = COMPOSITE_OVER; 0811 } else if (mode == "Dslv") { 0812 compositeOp = COMPOSITE_DISSOLVE; 0813 } else if (mode == "Drkn") { 0814 compositeOp = COMPOSITE_DARKEN; 0815 } else if (mode == "Mltp") { 0816 compositeOp = COMPOSITE_MULT; 0817 } else if (mode == "CBrn") { 0818 compositeOp = COMPOSITE_BURN; 0819 } else if (mode == "linearBurn") { 0820 compositeOp = COMPOSITE_LINEAR_BURN; 0821 } else if (mode == "darkerColor") { 0822 compositeOp = COMPOSITE_DARKER_COLOR; 0823 } else if (mode == "Lghn") { 0824 compositeOp = COMPOSITE_LIGHTEN; 0825 } else if (mode == "Scrn") { 0826 compositeOp = COMPOSITE_SCREEN; 0827 } else if (mode == "CDdg") { 0828 compositeOp = COMPOSITE_DODGE; 0829 } else if (mode == "linearDodge") { 0830 compositeOp = COMPOSITE_LINEAR_DODGE; 0831 } else if (mode == "lighterColor") { 0832 compositeOp = COMPOSITE_LIGHTER_COLOR; 0833 } else if (mode == "Ovrl") { 0834 compositeOp = COMPOSITE_OVERLAY; 0835 } else if (mode == "SftL") { 0836 compositeOp = COMPOSITE_SOFT_LIGHT_PHOTOSHOP; 0837 } else if (mode == "HrdL") { 0838 compositeOp = COMPOSITE_HARD_LIGHT; 0839 } else if (mode == "vividLight") { 0840 compositeOp = COMPOSITE_VIVID_LIGHT; 0841 } else if (mode == "linearLight") { 0842 compositeOp = COMPOSITE_LINEAR_LIGHT; 0843 } else if (mode == "pinLight") { 0844 compositeOp = COMPOSITE_PIN_LIGHT; 0845 } else if (mode == "hardMix") { 0846 compositeOp = COMPOSITE_HARD_MIX_PHOTOSHOP; 0847 } else if (mode == "Dfrn") { 0848 compositeOp = COMPOSITE_DIFF; 0849 } else if (mode == "Xclu") { 0850 compositeOp = COMPOSITE_EXCLUSION; 0851 } else if (mode == "Sbtr") { 0852 compositeOp = COMPOSITE_SUBTRACT; 0853 } else if (mode == "divide") { 0854 compositeOp = COMPOSITE_DIVIDE; 0855 } else if (mode == "H ") { 0856 compositeOp = COMPOSITE_HUE; 0857 } else if (mode == "Strt") { 0858 compositeOp = COMPOSITE_SATURATION; 0859 } else if (mode == "Clr ") { 0860 compositeOp = COMPOSITE_COLOR; 0861 } else if (mode == "Lmns") { 0862 compositeOp = COMPOSITE_LUMINIZE; 0863 } else { 0864 dbgKrita << "Unknown blending mode:" << mode << "Returning COMPOSITE_OVER!"; 0865 } 0866 0867 setBlendMode(compositeOp); 0868 } 0869 0870 void convertAndSetCurve(const QString &name, const QVector<QPointF> &points, std::function<void(const quint8 *)> setCurveLookupTable) 0871 { 0872 Q_UNUSED(name); 0873 Q_UNUSED(points); 0874 Q_UNUSED(setCurveLookupTable); 0875 0876 warnKrita << "convertAndSetBlendMode:" << "Curve conversion is not implemented yet"; 0877 } 0878 0879 template<typename T> 0880 void convertAndSetEnum(const QString &value, const QMap<QString, T> map, std::function<void(T)> setMappedValue) 0881 { 0882 setMappedValue(map[value]); 0883 } 0884 0885 inline QString _prepaddr(const QString &pref, const QString &addr) { 0886 return pref + addr; 0887 } 0888 0889 #define CONN_TEXT_RADDR(addr, method, object, type) m_catcher.subscribeText(addr, std::bind(&type::method, object, _1)) 0890 #define CONN_COLOR(addr, method, object, type, prefix) m_catcher.subscribeColor(_prepaddr(prefix, addr), std::bind(&type::method, object, _1)) 0891 #define CONN_UNITF(addr, unit, method, object, type, prefix) m_catcher.subscribeUnitFloat(_prepaddr(prefix, addr), unit, std::bind(&type::method, object, _1)) 0892 #define CONN_BOOL(addr, method, object, type, prefix) m_catcher.subscribeBoolean(_prepaddr(prefix, addr), std::bind(&type::method, object, _1)) 0893 0894 #define CONN_POINT(addr, method, object, type, prefix) m_catcher.subscribePoint(_prepaddr(prefix, addr), std::bind(&type::method, object, _1)) 0895 0896 #define CONN_COMPOSITE_OP(addr, method, object, type, prefix) \ 0897 { \ 0898 std::function<void(const QString &)> setter = std::bind(&type::method, object, _1); \ 0899 m_catcher.subscribeEnum(_prepaddr(prefix, addr), "BlnM", std::bind(convertAndSetBlendMode, _1, setter)); \ 0900 } 0901 0902 #define CONN_CURVE(addr, method, object, type, prefix) \ 0903 { \ 0904 std::function<void(const quint8 *)> setter = std::bind(&type::method, object, _1); \ 0905 m_catcher.subscribeCurve(_prepaddr(prefix, addr), std::bind(convertAndSetCurve, _1, _2, setter)); \ 0906 } 0907 0908 #define CONN_ENUM(addr, tag, method, map, mapped_type, object, type, prefix) \ 0909 { \ 0910 std::function<void(mapped_type)> setter = std::bind(&type::method, object, _1); \ 0911 m_catcher.subscribeEnum(_prepaddr(prefix, addr), tag, std::bind(convertAndSetEnum<mapped_type>, _1, map, setter)); \ 0912 } 0913 0914 #define CONN_GRADIENT(addr, method, object, type, prefix) \ 0915 { \ 0916 std::function<void(KoAbstractGradientSP)> setter = std::bind(&type::method, object, _1); \ 0917 m_catcher.subscribeGradient(_prepaddr(prefix, addr), std::bind(&KisAslLayerStyleSerializer::assignGradientObject, this, _1, setter)); \ 0918 } 0919 0920 #define CONN_PATTERN(addr, method, object, type, prefix) \ 0921 { \ 0922 std::function<void(KoPatternSP)> setter = std::bind(&type::method, object, _1); \ 0923 m_catcher.subscribePatternRef(_prepaddr(prefix, addr), std::bind(&KisAslLayerStyleSerializer::assignPatternObject, this, _1, _2, setter)); \ 0924 } 0925 0926 void KisAslLayerStyleSerializer::registerPatternObject(const KoPatternSP pattern, const QString& patternUuid) { 0927 0928 if (!pattern) { 0929 warnKrita << "WARNING: got an empty pattern:" << patternUuid; 0930 return; 0931 } 0932 0933 if (m_patternsStore.contains(patternUuid)) { 0934 warnKrita << "WARNING: ASL style contains a duplicated pattern!" << ppVar(pattern->name()) << ppVar(m_patternsStore[patternUuid]->name()); 0935 } else { 0936 pattern->setFilename(patternUuid + QString(".pat")); 0937 m_patternsStore.insert(patternUuid, pattern); 0938 m_localResourcesInterface->addResource(pattern); 0939 } 0940 } 0941 0942 void KisAslLayerStyleSerializer::assignPatternObject(const QString &patternUuid, const QString &patternName, std::function<void(KoPatternSP)> setPattern) 0943 { 0944 Q_UNUSED(patternName); 0945 0946 KoPatternSP pattern; 0947 0948 if (!m_patternsStore.contains(patternUuid)) { 0949 warnKrita << "WARNING: ASL style contains non-existent pattern reference! Searching for uuid: " 0950 << patternUuid << " (name: " << patternName << ")"; 0951 0952 QImage dumbImage(32, 32, QImage::Format_ARGB32); 0953 dumbImage.fill(Qt::red); 0954 KoPatternSP dumbPattern(new KoPattern(dumbImage, "invalid", "")); 0955 registerPatternObject(dumbPattern, patternUuid + QString("_invalid")); 0956 pattern = dumbPattern; 0957 } else { 0958 pattern = m_patternsStore[patternUuid]; 0959 } 0960 0961 setPattern(pattern); 0962 } 0963 0964 void KisAslLayerStyleSerializer::assignGradientObject(KoAbstractGradientSP gradient, std::function<void(KoAbstractGradientSP)> setGradient) 0965 { 0966 m_gradientsStore.append(gradient); 0967 m_localResourcesInterface->addResource(gradient); 0968 setGradient(gradient); 0969 } 0970 0971 class FillStylesCorrector { 0972 public: 0973 0974 static void correct(KisPSDLayerStyle *style) { 0975 correctWithoutPattern(style->outerGlow(), style->resourcesInterface()); 0976 correctWithoutPattern(style->innerGlow(), style->resourcesInterface()); 0977 correctWithPattern(style->stroke(), style->resourcesInterface()); 0978 } 0979 0980 private: 0981 0982 template <class T> 0983 static void correctWithPattern(T *config, KisResourcesInterfaceSP resourcesInterface) { 0984 if (config->pattern(resourcesInterface)) { 0985 config->setFillType(psd_fill_pattern); 0986 } else if (config->gradient(resourcesInterface)) { 0987 config->setFillType(psd_fill_gradient); 0988 } else { 0989 config->setFillType(psd_fill_solid_color); 0990 } 0991 } 0992 0993 template <class T> 0994 static void correctWithoutPattern(T *config, KisResourcesInterfaceSP resourcesInterface) { 0995 if (config->gradient(resourcesInterface)) { 0996 config->setFillType(psd_fill_gradient); 0997 } else { 0998 config->setFillType(psd_fill_solid_color); 0999 } 1000 } 1001 }; 1002 1003 void KisAslLayerStyleSerializer::connectCatcherToStyle(KisPSDLayerStyle *style, const QString &prefix) 1004 { 1005 CONN_TEXT_RADDR("/null/Nm ", setName, style, KisPSDLayerStyle); 1006 CONN_TEXT_RADDR("/null/Idnt", setPsdUuid, style, KisPSDLayerStyle); 1007 1008 CONN_BOOL("/masterFXSwitch", setEnabled, style, KisPSDLayerStyle, prefix); 1009 1010 psd_layer_effects_drop_shadow *dropShadow = style->dropShadow(); 1011 1012 CONN_COMPOSITE_OP("/DrSh/Md ", setBlendMode, dropShadow, psd_layer_effects_drop_shadow, prefix); 1013 CONN_COLOR("/DrSh/Clr ", setColor, dropShadow, psd_layer_effects_drop_shadow, prefix); 1014 CONN_UNITF("/DrSh/Opct", "#Prc", setOpacity, dropShadow, psd_layer_effects_drop_shadow, prefix); 1015 CONN_UNITF("/DrSh/lagl", "#Ang", setAngle, dropShadow, psd_layer_effects_drop_shadow, prefix); 1016 CONN_UNITF("/DrSh/Dstn", "#Pxl", setDistance, dropShadow, psd_layer_effects_drop_shadow, prefix); 1017 CONN_UNITF("/DrSh/Ckmt", "#Pxl", setSpread, dropShadow, psd_layer_effects_drop_shadow, prefix); 1018 CONN_UNITF("/DrSh/blur", "#Pxl", setSize, dropShadow, psd_layer_effects_drop_shadow, prefix); 1019 CONN_UNITF("/DrSh/Nose", "#Prc", setNoise, dropShadow, psd_layer_effects_drop_shadow, prefix); 1020 CONN_BOOL("/DrSh/enab", setEffectEnabled, dropShadow, psd_layer_effects_drop_shadow, prefix); 1021 CONN_BOOL("/DrSh/uglg", setUseGlobalLight, dropShadow, psd_layer_effects_drop_shadow, prefix); 1022 CONN_BOOL("/DrSh/AntA", setAntiAliased, dropShadow, psd_layer_effects_drop_shadow, prefix); 1023 CONN_BOOL("/DrSh/layerConceals", setKnocksOut, dropShadow, psd_layer_effects_drop_shadow, prefix); 1024 CONN_CURVE("/DrSh/TrnS", setContourLookupTable, dropShadow, psd_layer_effects_drop_shadow, prefix); 1025 1026 psd_layer_effects_inner_shadow *innerShadow = style->innerShadow(); 1027 1028 CONN_COMPOSITE_OP("/IrSh/Md ", setBlendMode, innerShadow, psd_layer_effects_inner_shadow, prefix); 1029 CONN_COLOR("/IrSh/Clr ", setColor, innerShadow, psd_layer_effects_inner_shadow, prefix); 1030 CONN_UNITF("/IrSh/Opct", "#Prc", setOpacity, innerShadow, psd_layer_effects_inner_shadow, prefix); 1031 CONN_UNITF("/IrSh/lagl", "#Ang", setAngle, innerShadow, psd_layer_effects_inner_shadow, prefix); 1032 CONN_UNITF("/IrSh/Dstn", "#Pxl", setDistance, innerShadow, psd_layer_effects_inner_shadow, prefix); 1033 CONN_UNITF("/IrSh/Ckmt", "#Pxl", setSpread, innerShadow, psd_layer_effects_inner_shadow, prefix); 1034 CONN_UNITF("/IrSh/blur", "#Pxl", setSize, innerShadow, psd_layer_effects_inner_shadow, prefix); 1035 CONN_UNITF("/IrSh/Nose", "#Prc", setNoise, innerShadow, psd_layer_effects_inner_shadow, prefix); 1036 CONN_BOOL("/IrSh/enab", setEffectEnabled, innerShadow, psd_layer_effects_inner_shadow, prefix); 1037 CONN_BOOL("/IrSh/uglg", setUseGlobalLight, innerShadow, psd_layer_effects_inner_shadow, prefix); 1038 CONN_BOOL("/IrSh/AntA", setAntiAliased, innerShadow, psd_layer_effects_inner_shadow, prefix); 1039 CONN_CURVE("/IrSh/TrnS", setContourLookupTable, innerShadow, psd_layer_effects_inner_shadow, prefix); 1040 1041 psd_layer_effects_outer_glow *outerGlow = style->outerGlow(); 1042 1043 CONN_COMPOSITE_OP("/OrGl/Md ", setBlendMode, outerGlow, psd_layer_effects_outer_glow, prefix); 1044 CONN_COLOR("/OrGl/Clr ", setColor, outerGlow, psd_layer_effects_outer_glow, prefix); 1045 CONN_UNITF("/OrGl/Opct", "#Prc", setOpacity, outerGlow, psd_layer_effects_outer_glow, prefix); 1046 CONN_UNITF("/OrGl/Ckmt", "#Pxl", setSpread, outerGlow, psd_layer_effects_outer_glow, prefix); 1047 CONN_UNITF("/OrGl/blur", "#Pxl", setSize, outerGlow, psd_layer_effects_outer_glow, prefix); 1048 CONN_UNITF("/OrGl/Nose", "#Prc", setNoise, outerGlow, psd_layer_effects_outer_glow, prefix); 1049 CONN_BOOL("/OrGl/enab", setEffectEnabled, outerGlow, psd_layer_effects_outer_glow, prefix); 1050 CONN_BOOL("/OrGl/AntA", setAntiAliased, outerGlow, psd_layer_effects_outer_glow, prefix); 1051 CONN_CURVE("/OrGl/TrnS", setContourLookupTable, outerGlow, psd_layer_effects_outer_glow, prefix); 1052 1053 QMap<QString, psd_technique_type> fillTechniqueMap; 1054 fillTechniqueMap.insert("PrBL", psd_technique_precise); 1055 fillTechniqueMap.insert("SfBL", psd_technique_softer); 1056 CONN_ENUM("/OrGl/GlwT", "BETE", setTechnique, fillTechniqueMap, psd_technique_type, outerGlow, psd_layer_effects_outer_glow, prefix); 1057 1058 CONN_GRADIENT("/OrGl/Grad", setGradient, outerGlow, psd_layer_effects_outer_glow, prefix); 1059 1060 CONN_UNITF("/OrGl/Inpr", "#Prc", setRange, outerGlow, psd_layer_effects_outer_glow, prefix); 1061 CONN_UNITF("/OrGl/ShdN", "#Prc", setJitter, outerGlow, psd_layer_effects_outer_glow, prefix); 1062 1063 1064 psd_layer_effects_inner_glow *innerGlow = style->innerGlow(); 1065 1066 CONN_COMPOSITE_OP("/IrGl/Md ", setBlendMode, innerGlow, psd_layer_effects_inner_glow, prefix); 1067 CONN_COLOR("/IrGl/Clr ", setColor, innerGlow, psd_layer_effects_inner_glow, prefix); 1068 CONN_UNITF("/IrGl/Opct", "#Prc", setOpacity, innerGlow, psd_layer_effects_inner_glow, prefix); 1069 CONN_UNITF("/IrGl/Ckmt", "#Pxl", setSpread, innerGlow, psd_layer_effects_inner_glow, prefix); 1070 CONN_UNITF("/IrGl/blur", "#Pxl", setSize, innerGlow, psd_layer_effects_inner_glow, prefix); 1071 CONN_UNITF("/IrGl/Nose", "#Prc", setNoise, innerGlow, psd_layer_effects_inner_glow, prefix); 1072 CONN_BOOL("/IrGl/enab", setEffectEnabled, innerGlow, psd_layer_effects_inner_glow, prefix); 1073 CONN_BOOL("/IrGl/AntA", setAntiAliased, innerGlow, psd_layer_effects_inner_glow, prefix); 1074 CONN_CURVE("/IrGl/TrnS", setContourLookupTable, innerGlow, psd_layer_effects_inner_glow, prefix); 1075 1076 CONN_ENUM("/IrGl/GlwT", "BETE", setTechnique, fillTechniqueMap, psd_technique_type, innerGlow, psd_layer_effects_inner_glow, prefix); 1077 1078 CONN_GRADIENT("/IrGl/Grad", setGradient, innerGlow, psd_layer_effects_inner_glow, prefix); 1079 1080 CONN_UNITF("/IrGl/Inpr", "#Prc", setRange, innerGlow, psd_layer_effects_inner_glow, prefix); 1081 CONN_UNITF("/IrGl/ShdN", "#Prc", setJitter, innerGlow, psd_layer_effects_inner_glow, prefix); 1082 1083 QMap<QString, psd_glow_source> glowSourceMap; 1084 glowSourceMap.insert("SrcC", psd_glow_center); 1085 glowSourceMap.insert("SrcE", psd_glow_edge); 1086 CONN_ENUM("/IrGl/glwS", "IGSr", setSource, glowSourceMap, psd_glow_source, innerGlow, psd_layer_effects_inner_glow, prefix); 1087 1088 1089 psd_layer_effects_satin *satin = style->satin(); 1090 1091 CONN_COMPOSITE_OP("/ChFX/Md ", setBlendMode, satin, psd_layer_effects_satin, prefix); 1092 CONN_COLOR("/ChFX/Clr ", setColor, satin, psd_layer_effects_satin, prefix); 1093 1094 CONN_UNITF("/ChFX/Opct", "#Prc", setOpacity, satin, psd_layer_effects_satin, prefix); 1095 CONN_UNITF("/ChFX/lagl", "#Ang", setAngle, satin, psd_layer_effects_satin, prefix); 1096 CONN_UNITF("/ChFX/Dstn", "#Pxl", setDistance, satin, psd_layer_effects_satin, prefix); 1097 CONN_UNITF("/ChFX/blur", "#Pxl", setSize, satin, psd_layer_effects_satin, prefix); 1098 1099 CONN_BOOL("/ChFX/enab", setEffectEnabled, satin, psd_layer_effects_satin, prefix); 1100 CONN_BOOL("/ChFX/AntA", setAntiAliased, satin, psd_layer_effects_satin, prefix); 1101 CONN_BOOL("/ChFX/Invr", setInvert, satin, psd_layer_effects_satin, prefix); 1102 CONN_CURVE("/ChFX/MpgS", setContourLookupTable, satin, psd_layer_effects_satin, prefix); 1103 1104 psd_layer_effects_color_overlay *colorOverlay = style->colorOverlay(); 1105 1106 CONN_COMPOSITE_OP("/SoFi/Md ", setBlendMode, colorOverlay, psd_layer_effects_color_overlay, prefix); 1107 CONN_COLOR("/SoFi/Clr ", setColor, colorOverlay, psd_layer_effects_color_overlay, prefix); 1108 CONN_UNITF("/SoFi/Opct", "#Prc", setOpacity, colorOverlay, psd_layer_effects_color_overlay, prefix); 1109 CONN_BOOL("/SoFi/enab", setEffectEnabled, colorOverlay, psd_layer_effects_color_overlay, prefix); 1110 1111 psd_layer_effects_gradient_overlay *gradientOverlay = style->gradientOverlay(); 1112 1113 CONN_COMPOSITE_OP("/GrFl/Md ", setBlendMode, gradientOverlay, psd_layer_effects_gradient_overlay, prefix); 1114 CONN_UNITF("/GrFl/Opct", "#Prc", setOpacity, gradientOverlay, psd_layer_effects_gradient_overlay, prefix); 1115 CONN_UNITF("/GrFl/Scl ", "#Prc", setScale, gradientOverlay, psd_layer_effects_gradient_overlay, prefix); 1116 CONN_UNITF("/GrFl/Angl", "#Ang", setAngle, gradientOverlay, psd_layer_effects_gradient_overlay, prefix); 1117 CONN_BOOL("/GrFl/enab", setEffectEnabled, gradientOverlay, psd_layer_effects_gradient_overlay, prefix); 1118 CONN_BOOL("/GrFl/Dthr", setDither, gradientOverlay, psd_layer_effects_gradient_overlay, prefix); 1119 CONN_BOOL("/GrFl/Rvrs", setReverse, gradientOverlay, psd_layer_effects_gradient_overlay, prefix); 1120 CONN_BOOL("/GrFl/Algn", setAlignWithLayer, gradientOverlay, psd_layer_effects_gradient_overlay, prefix); 1121 CONN_POINT("/GrFl/Ofst", setGradientOffset, gradientOverlay, psd_layer_effects_gradient_overlay, prefix); 1122 CONN_GRADIENT("/GrFl/Grad", setGradient, gradientOverlay, psd_layer_effects_gradient_overlay, prefix); 1123 1124 1125 QMap<QString, psd_gradient_style> gradientStyleMap; 1126 gradientStyleMap.insert("Lnr ", psd_gradient_style_linear); 1127 gradientStyleMap.insert("Rdl ", psd_gradient_style_radial); 1128 gradientStyleMap.insert("Angl", psd_gradient_style_angle); 1129 gradientStyleMap.insert("Rflc", psd_gradient_style_reflected); 1130 gradientStyleMap.insert("Dmnd", psd_gradient_style_diamond); 1131 CONN_ENUM("/GrFl/Type", "GrdT", setStyle, gradientStyleMap, psd_gradient_style, gradientOverlay, psd_layer_effects_gradient_overlay, prefix); 1132 1133 psd_layer_effects_pattern_overlay *patternOverlay = style->patternOverlay(); 1134 1135 CONN_BOOL("/patternFill/enab", setEffectEnabled, patternOverlay, psd_layer_effects_pattern_overlay, prefix); 1136 CONN_COMPOSITE_OP("/patternFill/Md ", setBlendMode, patternOverlay, psd_layer_effects_pattern_overlay, prefix); 1137 CONN_UNITF("/patternFill/Opct", "#Prc", setOpacity, patternOverlay, psd_layer_effects_pattern_overlay, prefix); 1138 CONN_PATTERN("/patternFill/Ptrn", setPattern, patternOverlay, psd_layer_effects_pattern_overlay, prefix); 1139 CONN_UNITF("/patternFill/Scl ", "#Prc", setScale, patternOverlay, psd_layer_effects_pattern_overlay, prefix); 1140 CONN_BOOL("/patternFill/Algn", setAlignWithLayer, patternOverlay, psd_layer_effects_pattern_overlay, prefix); 1141 CONN_POINT("/patternFill/phase", setPatternPhase, patternOverlay, psd_layer_effects_pattern_overlay, prefix); 1142 1143 psd_layer_effects_stroke *stroke = style->stroke(); 1144 1145 CONN_COMPOSITE_OP("/FrFX/Md ", setBlendMode, stroke, psd_layer_effects_stroke, prefix); 1146 CONN_BOOL("/FrFX/enab", setEffectEnabled, stroke, psd_layer_effects_stroke, prefix); 1147 CONN_UNITF("/FrFX/Opct", "#Prc", setOpacity, stroke, psd_layer_effects_stroke, prefix); 1148 CONN_UNITF("/FrFX/Sz ", "#Pxl", setSize, stroke, psd_layer_effects_stroke, prefix); 1149 1150 QMap<QString, psd_stroke_position> strokeStyleMap; 1151 strokeStyleMap.insert("OutF", psd_stroke_outside); 1152 strokeStyleMap.insert("InsF", psd_stroke_inside); 1153 strokeStyleMap.insert("CtrF", psd_stroke_center); 1154 CONN_ENUM("/FrFX/Styl", "FStl", setPosition, strokeStyleMap, psd_stroke_position, stroke, psd_layer_effects_stroke, prefix); 1155 1156 QMap<QString, psd_fill_type> strokeFillType; 1157 strokeFillType.insert("SClr", psd_fill_solid_color); 1158 strokeFillType.insert("GrFl", psd_fill_gradient); 1159 strokeFillType.insert("Ptrn", psd_fill_pattern); 1160 CONN_ENUM("/FrFX/PntT", "FrFl", setFillType, strokeFillType, psd_fill_type, stroke, psd_layer_effects_stroke, prefix); 1161 1162 // Color type 1163 CONN_COLOR("/FrFX/Clr ", setColor, stroke, psd_layer_effects_stroke, prefix); 1164 1165 // Gradient Type 1166 CONN_GRADIENT("/FrFX/Grad", setGradient, stroke, psd_layer_effects_stroke, prefix); 1167 CONN_UNITF("/FrFX/Angl", "#Ang", setAngle, stroke, psd_layer_effects_stroke, prefix); 1168 CONN_UNITF("/FrFX/Scl ", "#Prc", setScale, stroke, psd_layer_effects_stroke, prefix); 1169 CONN_ENUM("/FrFX/Type", "GrdT", setStyle, gradientStyleMap, psd_gradient_style, stroke, psd_layer_effects_stroke, prefix); 1170 CONN_BOOL("/FrFX/Rvrs", setReverse, stroke, psd_layer_effects_stroke, prefix); 1171 CONN_BOOL("/FrFX/Algn", setAlignWithLayer, stroke, psd_layer_effects_stroke, prefix); 1172 CONN_POINT("/FrFX/Ofst", setGradientOffset, stroke, psd_layer_effects_stroke, prefix); 1173 CONN_BOOL("/FrFX/Dthr", setDither, stroke, psd_layer_effects_stroke, prefix); 1174 1175 // Pattern type 1176 1177 CONN_PATTERN("/FrFX/Ptrn", setPattern, stroke, psd_layer_effects_stroke, prefix); 1178 CONN_BOOL("/FrFX/Lnkd", setAlignWithLayer, stroke, psd_layer_effects_stroke, prefix); // yes, we share the params... 1179 CONN_POINT("/FrFX/phase", setPatternPhase, stroke, psd_layer_effects_stroke, prefix); 1180 1181 1182 psd_layer_effects_bevel_emboss *bevelAndEmboss = style->bevelAndEmboss(); 1183 1184 CONN_BOOL("/ebbl/enab", setEffectEnabled, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1185 1186 CONN_COMPOSITE_OP("/ebbl/hglM", setHighlightBlendMode, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1187 CONN_COLOR("/ebbl/hglC", setHighlightColor, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1188 CONN_UNITF("/ebbl/hglO", "#Prc", setHighlightOpacity, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1189 1190 CONN_COMPOSITE_OP("/ebbl/sdwM", setShadowBlendMode, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1191 CONN_COLOR("/ebbl/sdwC", setShadowColor, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1192 CONN_UNITF("/ebbl/sdwO", "#Prc", setShadowOpacity, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1193 1194 QMap<QString, psd_technique_type> bevelTechniqueMap; 1195 bevelTechniqueMap.insert("PrBL", psd_technique_precise); 1196 bevelTechniqueMap.insert("SfBL", psd_technique_softer); 1197 bevelTechniqueMap.insert("Slmt", psd_technique_slope_limit); 1198 CONN_ENUM("/ebbl/bvlT", "bvlT", setTechnique, bevelTechniqueMap, psd_technique_type, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1199 1200 QMap<QString, psd_bevel_style> bevelStyleMap; 1201 bevelStyleMap.insert("OtrB", psd_bevel_outer_bevel); 1202 bevelStyleMap.insert("InrB", psd_bevel_inner_bevel); 1203 bevelStyleMap.insert("Embs", psd_bevel_emboss); 1204 bevelStyleMap.insert("PlEb", psd_bevel_pillow_emboss); 1205 bevelStyleMap.insert("strokeEmboss", psd_bevel_stroke_emboss); 1206 CONN_ENUM("/ebbl/bvlS", "BESl", setStyle, bevelStyleMap, psd_bevel_style, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1207 1208 CONN_BOOL("/ebbl/uglg", setUseGlobalLight, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1209 1210 CONN_UNITF("/ebbl/lagl", "#Ang", setAngle, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1211 CONN_UNITF("/ebbl/Lald", "#Ang", setAltitude, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1212 1213 CONN_UNITF("/ebbl/srgR", "#Prc", setDepth, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1214 1215 CONN_UNITF("/ebbl/blur", "#Pxl", setSize, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1216 1217 1218 QMap<QString, psd_direction> bevelDirectionMap; 1219 bevelDirectionMap.insert("In ", psd_direction_up); 1220 bevelDirectionMap.insert("Out ", psd_direction_down); 1221 CONN_ENUM("/ebbl/bvlD", "BESs", setDirection, bevelDirectionMap, psd_direction, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1222 1223 CONN_CURVE("/ebbl/TrnS", setContourLookupTable, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1224 1225 CONN_BOOL("/ebbl/antialiasGloss", setGlossAntiAliased, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1226 1227 CONN_UNITF("/ebbl/Sftn", "#Pxl", setSoften, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1228 1229 // Use shape mode 1230 1231 CONN_BOOL("/ebbl/useShape", setContourEnabled, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1232 CONN_CURVE("/ebbl/MpgS", setGlossContourLookupTable, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1233 CONN_BOOL("/ebbl/AntA", setAntiAliased, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1234 CONN_UNITF("/ebbl/Inpr", "#Prc", setContourRange, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1235 1236 // Use texture mode 1237 1238 CONN_BOOL("/ebbl/useTexture", setTextureEnabled, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1239 CONN_BOOL("/ebbl/InvT", setTextureInvert, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1240 CONN_BOOL("/ebbl/Algn", setTextureAlignWithLayer, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1241 CONN_UNITF("/ebbl/Scl ", "#Prc", setTextureScale, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1242 CONN_UNITF("/ebbl/textureDepth", "#Prc", setTextureDepth, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1243 CONN_PATTERN("/ebbl/Ptrn", setTexturePattern, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1244 CONN_POINT("/ebbl/phase", setTexturePhase, bevelAndEmboss, psd_layer_effects_bevel_emboss, prefix); 1245 } 1246 1247 void KisAslLayerStyleSerializer::newStyleStarted(bool isPsdStructure) 1248 { 1249 m_stylesVector.append(toQShared(new KisPSDLayerStyle("", m_localResourcesInterface))); 1250 KisPSDLayerStyleSP currentStyleSP = m_stylesVector.last(); 1251 KisPSDLayerStyle *currentStyle = currentStyleSP.data(); 1252 1253 psd_layer_effects_context *context = currentStyleSP->context(); 1254 context->keep_original = 0; 1255 1256 QString prefix = isPsdStructure ? "/null" : "/Styl/Lefx"; 1257 connectCatcherToStyle(currentStyle, prefix); 1258 } 1259 1260 bool KisAslLayerStyleSerializer::readFromFile(const QString& filename) 1261 { 1262 QFile file(filename); 1263 if (file.size() == 0) return false; 1264 1265 if (!file.open(QIODevice::ReadOnly)) { 1266 dbgKrita << "Can't open file " << filename; 1267 return false; 1268 } 1269 1270 readFromDevice(file); 1271 file.close(); 1272 1273 return m_initialized; 1274 } 1275 1276 QVector<KisPSDLayerStyleSP> KisAslLayerStyleSerializer::collectAllLayerStyles(KisNodeSP root) 1277 { 1278 KisLayer* layer = qobject_cast<KisLayer*>(root.data()); 1279 QVector<KisPSDLayerStyleSP> layerStyles; 1280 1281 if (layer && layer->layerStyle()) { 1282 KisPSDLayerStyleSP clone = layer->layerStyle()->clone().dynamicCast<KisPSDLayerStyle>(); 1283 clone->setName(i18nc("Auto-generated layer style name for embedded styles (style itself)", "<%1> (embedded)", layer->name())); 1284 layerStyles << clone; 1285 } 1286 1287 KisNodeSP child = root->firstChild(); 1288 while (child) { 1289 layerStyles += collectAllLayerStyles(child); 1290 child = child->nextSibling(); 1291 } 1292 1293 return layerStyles; 1294 } 1295 1296 void KisAslLayerStyleSerializer::assignAllLayerStylesToLayers(KisNodeSP root, const QString &storageLocation) 1297 { 1298 QVector<KisPSDLayerStyleSP> styles; 1299 1300 KisEmbeddedResourceStorageProxy resourcesProxy(storageLocation); 1301 1302 if (!storageLocation.isEmpty()) { 1303 Q_FOREACH(KoPatternSP pattern, patterns().values()) { 1304 resourcesProxy.addResource(pattern); 1305 } 1306 Q_FOREACH(KoAbstractGradientSP gradient, gradients()) { 1307 resourcesProxy.addResource(gradient); 1308 } 1309 } 1310 1311 Q_FOREACH (KisPSDLayerStyleSP style, m_stylesVector) { 1312 KisPSDLayerStyleSP newStyle = style->clone().dynamicCast<KisPSDLayerStyle>(); 1313 newStyle->setResourcesInterface(resourcesProxy.detachedResourcesInterface()); 1314 newStyle->setValid(true); 1315 1316 if (!storageLocation.isEmpty()) { 1317 resourcesProxy.addResource(newStyle); 1318 } 1319 1320 styles << newStyle; 1321 } 1322 1323 KisLayerUtils::recursiveApplyNodes(root, [styles] (KisNodeSP node) { 1324 KisLayer* layer = qobject_cast<KisLayer*>(node.data()); 1325 1326 if (layer && layer->layerStyle()) { 1327 QUuid uuid = layer->layerStyle()->uuid(); 1328 1329 bool found = false; 1330 1331 Q_FOREACH (KisPSDLayerStyleSP style, styles) { 1332 if (style->uuid() == uuid) { 1333 layer->setLayerStyle(style->cloneWithResourcesSnapshot(style->resourcesInterface(), 0)); 1334 found = true; 1335 break; 1336 } 1337 } 1338 1339 if (!found) { 1340 warnKrita << "WARNING: loading layer style for" << layer->name() << "failed! It requests inexistent style:" << uuid; 1341 } 1342 } 1343 }); 1344 } 1345 1346 void KisAslLayerStyleSerializer::readFromDevice(QIODevice &device) 1347 { 1348 m_catcher.subscribePattern("/patterns/KisPattern", std::bind(&KisAslLayerStyleSerializer::registerPatternObject, this, _1, _2)); 1349 m_catcher.subscribePattern("/Patterns/KisPattern", std::bind(&KisAslLayerStyleSerializer::registerPatternObject, this, _1, _2)); 1350 m_catcher.subscribeNewStyleStarted(std::bind(&KisAslLayerStyleSerializer::newStyleStarted, this, false)); 1351 1352 KisAslReader reader; 1353 const QDomDocument doc = reader.readFile(device); 1354 1355 if (doc.isNull()) { 1356 m_initialized = false; 1357 return; 1358 } 1359 1360 //dbgKrita << ppVar(doc.toString()); 1361 1362 //KisAslObjectCatcher c2; 1363 KisAslXmlParser parser; 1364 parser.parseXML(doc, m_catcher); 1365 1366 QMultiHash<QString, KisPSDLayerStyleSP> allStyles; 1367 QHash<QString, KisPSDLayerStyleSP> cleanedStyles; 1368 1369 for(const auto &style : m_stylesVector) 1370 allStyles.insert(style->psdUuid(), style); 1371 1372 // correct all the layer styles 1373 for (const auto &style : allStyles) { 1374 FillStylesCorrector::correct(style.data()); 1375 1376 if (allStyles.count(style->psdUuid()) > 1) { 1377 const auto &existingStyle = cleanedStyles.find(style->psdUuid()); 1378 1379 if (existingStyle != cleanedStyles.end()) { 1380 if (existingStyle.value()->name() != style->name()) { 1381 qWarning() << "Duplicated UUID" << style->psdUuid() << "for styles" << style->name() << "and" 1382 << existingStyle.value()->name(); 1383 style->setMD5Sum(""); 1384 style->setUuid(QUuid::createUuid()); 1385 } else { 1386 qWarning() << "Duplicated style" << style->name(); 1387 continue; 1388 } 1389 } 1390 } 1391 1392 style->setValid(!style->isEmpty()); 1393 1394 style->setFilename(style->uuid().toString()); 1395 1396 cleanedStyles.insert(style->psdUuid(), style); 1397 } 1398 1399 m_stylesVector = cleanedStyles.values().toVector(); 1400 1401 m_initialized = true; 1402 } 1403 1404 void KisAslLayerStyleSerializer::registerPSDPattern(const QDomDocument &doc) 1405 { 1406 KisAslCallbackObjectCatcher catcher; 1407 catcher.subscribePattern("/Patterns/KisPattern", std::bind(&KisAslLayerStyleSerializer::registerPatternObject, this, _1, _2)); 1408 catcher.subscribePattern("/patterns/KisPattern", std::bind(&KisAslLayerStyleSerializer::registerPatternObject, this, _1, _2)); 1409 1410 //KisAslObjectCatcher c2; 1411 KisAslXmlParser parser; 1412 parser.parseXML(doc, catcher); 1413 } 1414 1415 void KisAslLayerStyleSerializer::readFromPSDXML(const QDomDocument &doc) 1416 { 1417 // The caller prepares the document using the following code 1418 // 1419 // KisAslReader reader; 1420 // QDomDocument doc = reader.readLfx2PsdSection(device); 1421 1422 m_stylesVector.clear(); 1423 1424 //m_catcher.subscribePattern("/Patterns/KisPattern", std::bind(&KisAslLayerStyleSerializer::registerPatternObject, this, _1)); 1425 m_catcher.subscribeNewStyleStarted(std::bind(&KisAslLayerStyleSerializer::newStyleStarted, this, true)); 1426 1427 //KisAslObjectCatcher c2; 1428 KisAslXmlParser parser; 1429 parser.parseXML(doc, m_catcher); 1430 1431 // correct all the layer styles 1432 Q_FOREACH (KisPSDLayerStyleSP style, m_stylesVector) { 1433 FillStylesCorrector::correct(style.data()); 1434 } 1435 }