File indexing completed on 2024-05-12 15:59:44
0001 /* 0002 * SPDX-FileCopyrightText: 2010 Boudewijn Rempt <boud@valdyas.org> 0003 * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 /* 0008 * Constants and defines taken from gimp and psdparse 0009 */ 0010 #ifndef PSD_H 0011 #define PSD_H 0012 0013 #include "kritapsdutils_export.h" 0014 0015 #include <QPair> 0016 #include <QString> 0017 #include <QVector> 0018 #include <cstdint> 0019 0020 #include <KoColor.h> 0021 #include <KoColorModelStandardIds.h> 0022 #include <KoCompositeOpRegistry.h> 0023 #include <KoPattern.h> 0024 #include <resources/KoAbstractGradient.h> 0025 #include <KisResourcesInterface.h> 0026 0027 const int MAX_CHANNELS = 56; 0028 0029 const int MAX_PSD_SIZE = 30000; 0030 0031 typedef qint32 Fixed; /* Represents a fixed point implied decimal */ 0032 0033 enum class psd_byte_order : std::uint_least8_t { 0034 psdBigEndian = 0, 0035 psdLittleEndian, 0036 psdInvalidByteOrder = 255, 0037 }; 0038 0039 enum psd_compression_type : std::uint16_t { 0040 Uncompressed = 0, 0041 RLE, 0042 ZIP, 0043 ZIPWithPrediction, 0044 Unknown = 255, 0045 }; 0046 0047 /** 0048 * Image color/depth modes 0049 */ 0050 enum psd_color_mode { 0051 Bitmap = 0, 0052 Grayscale = 1, 0053 Indexed = 2, 0054 RGB = 3, 0055 CMYK = 4, 0056 MultiChannel = 7, 0057 DuoTone = 8, 0058 Lab = 9, 0059 Gray16, 0060 RGB48, 0061 Lab48, 0062 CMYK64, 0063 DeepMultichannel, 0064 Duotone16, 0065 COLORMODE_UNKNOWN = 9000 0066 }; 0067 0068 struct PsdResource { 0069 QString type; 0070 QString md5; 0071 QString filename; 0072 QString name; 0073 }; 0074 0075 /** 0076 * Color samplers, apparently distict from PSDColormode 0077 */ 0078 namespace psd_color_sampler 0079 { 0080 enum PSDColorSamplers { 0081 RGB, 0082 HSB, 0083 CMYK, 0084 PANTONE, // LAB 0085 FOCOLTONE, // CMYK 0086 TRUMATCH, // CMYK 0087 TOYO, // LAB 0088 LAB, 0089 GRAYSCALE, 0090 HKS, // CMYK 0091 DIC, // LAB 0092 TOTAL_INK, 0093 MONITOR_RGB, 0094 DUOTONE, 0095 OPACITY, 0096 ANPA = 3000 // LAB 0097 }; 0098 } 0099 0100 // EFFECTS 0101 enum psd_gradient_style { 0102 psd_gradient_style_linear, // 'Lnr ' 0103 psd_gradient_style_radial, // 'Rdl ' 0104 psd_gradient_style_angle, // 'Angl' 0105 psd_gradient_style_reflected, // 'Rflc' 0106 psd_gradient_style_diamond // 'Dmnd' 0107 }; 0108 0109 enum psd_color_stop_type { 0110 psd_color_stop_type_foreground_color, // 'FrgC' 0111 psd_color_stop_type_background_Color, // 'BckC' 0112 psd_color_stop_type_user_stop // 'UsrS' 0113 }; 0114 0115 enum psd_technique_type { 0116 psd_technique_softer, 0117 psd_technique_precise, 0118 psd_technique_slope_limit, 0119 }; 0120 0121 enum psd_stroke_position { psd_stroke_outside, psd_stroke_inside, psd_stroke_center }; 0122 0123 enum psd_fill_type { 0124 psd_fill_solid_color, 0125 psd_fill_gradient, 0126 psd_fill_pattern, 0127 }; 0128 0129 enum psd_glow_source { 0130 psd_glow_center, 0131 psd_glow_edge, 0132 }; 0133 0134 enum psd_bevel_style { 0135 psd_bevel_outer_bevel, 0136 psd_bevel_inner_bevel, 0137 psd_bevel_emboss, 0138 psd_bevel_pillow_emboss, 0139 psd_bevel_stroke_emboss, 0140 }; 0141 0142 enum psd_direction { psd_direction_up, psd_direction_down }; 0143 0144 enum psd_section_type { psd_other = 0, psd_open_folder, psd_closed_folder, psd_bounding_divider }; 0145 0146 // GRADIENT MAP 0147 // Each color stop 0148 struct psd_gradient_color_stop { 0149 qint32 location; // Location of color stop 0150 qint32 midpoint; // Midpoint of color stop 0151 KoColor actual_color; 0152 psd_color_stop_type color_stop_type; 0153 }; 0154 0155 // Each transparency stop 0156 struct psd_gradient_transparency_stop { 0157 qint32 location; // Location of transparency stop 0158 qint32 midpoint; // Midpoint of transparency stop 0159 qint8 opacity; // Opacity of transparency stop 0160 }; 0161 0162 // Gradient settings (Photoshop 6.0) 0163 struct psd_layer_gradient_map { 0164 bool reverse; // Is gradient reverse 0165 bool dithered; // Is gradient dithered 0166 qint32 name_length; 0167 quint16 *name; // Name of the gradient: Unicode string, padded 0168 qint8 number_color_stops; // Number of color stops to follow 0169 psd_gradient_color_stop *color_stop; 0170 qint8 number_transparency_stops; // Number of transparency stops to follow 0171 psd_gradient_transparency_stop *transparency_stop; 0172 qint8 expansion_count; // Expansion count ( = 2 for Photoshop 6.0) 0173 qint8 interpolation; // Interpolation if length above is non-zero 0174 qint8 length; // Length (= 32 for Photoshop 6.0) 0175 qint8 mode; // Mode for this gradient 0176 qint32 random_number_seed; // Random number seed 0177 qint8 showing_transparency_flag; // Flag for showing transparency 0178 qint8 using_vector_color_flag; // Flag for using vector color 0179 qint32 roughness_factor; // Roughness factor 0180 QColor min_color; 0181 QColor max_color; 0182 QColor lookup_table[256]; 0183 }; 0184 0185 struct psd_gradient_color { 0186 qint32 smoothness; 0187 qint32 name_length; 0188 quint16 *name; // Name of the gradient: Unicode string, padded 0189 qint8 number_color_stops; // Number of color stops to follow 0190 psd_gradient_color_stop *color_stop; 0191 qint8 number_transparency_stops; // Number of transparency stops to follow 0192 psd_gradient_transparency_stop *transparency_stop; 0193 }; 0194 0195 struct psd_pattern { 0196 psd_color_mode color_mode = Bitmap; // The image mode of the file. 0197 quint8 height = 0; // Point: vertical, 2 bytes and horizontal, 2 bytes 0198 quint8 width = 0; 0199 QString name; 0200 QString uuid; 0201 qint32 version = 0; 0202 quint8 top = 0; // Rectangle: top, left, bottom, right 0203 quint8 left = 0; 0204 quint8 bottom = 0; 0205 quint8 right = 0; 0206 qint32 max_channel = 0; // Max channels 0207 qint32 channel_number = 0; 0208 QVector<QRgb> color_table; 0209 }; 0210 0211 struct psd_layer_effects_context { 0212 psd_layer_effects_context() 0213 : keep_original(false) 0214 { 0215 } 0216 0217 bool keep_original; 0218 }; 0219 0220 #define PSD_LOOKUP_TABLE_SIZE 256 0221 0222 // dsdw, isdw: https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/PhotoshopFileFormats.htm#50577409_22203 0223 class KRITAPSDUTILS_EXPORT psd_layer_effects_shadow_base 0224 { 0225 public: 0226 psd_layer_effects_shadow_base() 0227 : m_invertsSelection(false) 0228 , m_edgeHidden(true) 0229 , m_effectEnabled(false) 0230 , m_blendMode(COMPOSITE_MULT) 0231 , m_color(KoColor::fromXML("<color channeldepth='U8'><sRGB r='0.0' g='0.0' b='0.0'/></color>")) 0232 , m_nativeColor(KoColor::fromXML("<color channeldepth='U8'><sRGB r='0.0' g='0.0' b='0.0'/></color>")) 0233 , m_opacity(75) 0234 , m_angle(120) 0235 , m_useGlobalLight(true) 0236 , m_distance(21) 0237 , m_spread(0) 0238 , m_size(21) 0239 , m_antiAliased(0) 0240 , m_noise(0) 0241 , m_knocksOut(false) 0242 , m_fillType(psd_fill_solid_color) 0243 , m_technique(psd_technique_softer) 0244 , m_range(100) 0245 , m_jitter(0) 0246 { 0247 for (int i = 0; i < PSD_LOOKUP_TABLE_SIZE; ++i) { 0248 m_contourLookupTable[i] = i; 0249 } 0250 } 0251 0252 virtual ~psd_layer_effects_shadow_base(); 0253 0254 QPoint calculateOffset(const psd_layer_effects_context *context) const; 0255 0256 void setEffectEnabled(bool value) 0257 { 0258 m_effectEnabled = value; 0259 } 0260 0261 bool effectEnabled() const 0262 { 0263 return m_effectEnabled; 0264 } 0265 0266 QString blendMode() const 0267 { 0268 return m_blendMode; 0269 } 0270 0271 KoColor color() const 0272 { 0273 return m_color; 0274 } 0275 0276 KoColor nativeColor() const 0277 { 0278 return m_nativeColor; 0279 } 0280 0281 qint32 opacity() const 0282 { 0283 return m_opacity; 0284 } 0285 0286 qint32 angle() const 0287 { 0288 return m_angle; 0289 } 0290 0291 bool useGlobalLight() const 0292 { 0293 return m_useGlobalLight; 0294 } 0295 0296 qint32 distance() const 0297 { 0298 return m_distance; 0299 } 0300 0301 qint32 spread() const 0302 { 0303 return m_spread; 0304 } 0305 0306 qint32 size() const 0307 { 0308 return m_size; 0309 } 0310 0311 const quint8 *contourLookupTable() const 0312 { 0313 return m_contourLookupTable; 0314 } 0315 0316 bool antiAliased() const 0317 { 0318 return m_antiAliased; 0319 } 0320 0321 qint32 noise() const 0322 { 0323 return m_noise; 0324 } 0325 0326 bool knocksOut() const 0327 { 0328 return m_knocksOut; 0329 } 0330 0331 bool invertsSelection() const 0332 { 0333 return m_invertsSelection; 0334 } 0335 0336 bool edgeHidden() const 0337 { 0338 return m_edgeHidden; 0339 } 0340 0341 psd_fill_type fillType() const 0342 { 0343 return m_fillType; 0344 } 0345 0346 psd_technique_type technique() const 0347 { 0348 return m_technique; 0349 } 0350 0351 qint32 range() const 0352 { 0353 return m_range; 0354 } 0355 0356 qint32 jitter() const 0357 { 0358 return m_jitter; 0359 } 0360 0361 KoResourceSignature gradientLink() const { 0362 return m_gradientLink; 0363 } 0364 0365 KoAbstractGradientSP gradient(KisResourcesInterfaceSP resourcesInterface) const 0366 { 0367 auto source = resourcesInterface->source<KoAbstractGradient>(m_gradientLink.type); 0368 return source.bestMatch(m_gradientLink.md5sum, m_gradientLink.filename, m_gradientLink.name); 0369 } 0370 0371 public: 0372 void setBlendMode(QString value) 0373 { 0374 m_blendMode = value; 0375 } 0376 0377 void setColor(KoColor value) 0378 { 0379 m_color = value; 0380 } 0381 0382 void setNativeColor(KoColor value) 0383 { 0384 m_nativeColor = value; 0385 } 0386 0387 void setOpacity(qint32 value) 0388 { 0389 m_opacity = value; 0390 } 0391 0392 void setAngle(qint32 value) 0393 { 0394 m_angle = value; 0395 } 0396 0397 void setUseGlobalLight(bool value) 0398 { 0399 m_useGlobalLight = value; 0400 } 0401 0402 void setDistance(qint32 value) 0403 { 0404 m_distance = value; 0405 } 0406 0407 void setSpread(qint32 value) 0408 { 0409 m_spread = value; 0410 } 0411 0412 void setSize(qint32 value) 0413 { 0414 m_size = value; 0415 } 0416 0417 void setContourLookupTable(const quint8 *value) 0418 { 0419 memcpy(m_contourLookupTable, value, PSD_LOOKUP_TABLE_SIZE * sizeof(quint8)); 0420 } 0421 0422 void setAntiAliased(bool value) 0423 { 0424 m_antiAliased = value; 0425 } 0426 0427 void setNoise(qint32 value) 0428 { 0429 m_noise = value; 0430 } 0431 0432 void setKnocksOut(bool value) 0433 { 0434 m_knocksOut = value; 0435 } 0436 0437 void setInvertsSelection(bool value) 0438 { 0439 m_invertsSelection = value; 0440 } 0441 0442 void setEdgeHidden(bool value) 0443 { 0444 m_edgeHidden = value; 0445 } 0446 0447 void setFillType(psd_fill_type value) 0448 { 0449 m_fillType = value; 0450 } 0451 0452 void setTechnique(psd_technique_type value) 0453 { 0454 m_technique = value; 0455 } 0456 0457 void setRange(qint32 value) 0458 { 0459 m_range = value; 0460 } 0461 0462 void setJitter(qint32 value) 0463 { 0464 m_jitter = value; 0465 } 0466 0467 void setGradient(KoAbstractGradientSP value) 0468 { 0469 m_gradientLink.type = value->resourceType().first; 0470 m_gradientLink.md5sum = value->md5Sum(); 0471 m_gradientLink.filename = value->filename(); 0472 m_gradientLink.name = value->name(); 0473 } 0474 0475 virtual void scaleLinearSizes(qreal scale); 0476 0477 private: 0478 // internal 0479 bool m_invertsSelection; 0480 bool m_edgeHidden; 0481 0482 private: 0483 bool m_effectEnabled; // Effect enabled 0484 0485 QString m_blendMode; // already in Krita format! 0486 KoColor m_color; 0487 KoColor m_nativeColor; 0488 qint32 m_opacity; // Opacity as a percent (0...100) 0489 qint32 m_angle; // Angle in degrees 0490 bool m_useGlobalLight; // Use this angle in all of the layer effects 0491 qint32 m_distance; // Distance in pixels 0492 qint32 m_spread; // Intensity as a percent 0493 qint32 m_size; // Blur value in pixels 0494 0495 quint8 m_contourLookupTable[PSD_LOOKUP_TABLE_SIZE]; 0496 bool m_antiAliased; 0497 qint32 m_noise; 0498 bool m_knocksOut; 0499 0500 // for Outer/Inner Glow 0501 psd_fill_type m_fillType; 0502 psd_technique_type m_technique; 0503 qint32 m_range; 0504 qint32 m_jitter; 0505 KoResourceSignature m_gradientLink; 0506 }; 0507 0508 class KRITAPSDUTILS_EXPORT psd_layer_effects_shadow_common : public psd_layer_effects_shadow_base 0509 { 0510 public: 0511 /// FIXME: 'using' is not supported by MSVC, so please refactor in 0512 /// some other way to ensure that the setters are not used 0513 /// in the classes we don't want 0514 0515 // using psd_layer_effects_shadow_base::setBlendMode; 0516 // using psd_layer_effects_shadow_base::setColor; 0517 // using psd_layer_effects_shadow_base::setOpacity; 0518 // using psd_layer_effects_shadow_base::setAngle; 0519 // using psd_layer_effects_shadow_base::setUseGlobalLight; 0520 // using psd_layer_effects_shadow_base::setDistance; 0521 // using psd_layer_effects_shadow_base::setSpread; 0522 // using psd_layer_effects_shadow_base::setSize; 0523 // using psd_layer_effects_shadow_base::setContourLookupTable; 0524 // using psd_layer_effects_shadow_base::setAntiAliased; 0525 // using psd_layer_effects_shadow_base::setNoise; 0526 0527 ~psd_layer_effects_shadow_common() override; 0528 }; 0529 0530 class KRITAPSDUTILS_EXPORT psd_layer_effects_drop_shadow : public psd_layer_effects_shadow_common 0531 { 0532 public: 0533 /// FIXME: 'using' is not supported by MSVC, so please refactor in 0534 /// some other way to ensure that the setters are not used 0535 /// in the classes we don't want 0536 0537 // using psd_layer_effects_shadow_base::setKnocksOut; 0538 ~psd_layer_effects_drop_shadow(); 0539 }; 0540 0541 // isdw: https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/PhotoshopFileFormats.htm#50577409_22203 0542 class KRITAPSDUTILS_EXPORT psd_layer_effects_inner_shadow : public psd_layer_effects_shadow_common 0543 { 0544 public: 0545 psd_layer_effects_inner_shadow() 0546 { 0547 setKnocksOut(false); 0548 setInvertsSelection(true); 0549 setEdgeHidden(false); 0550 } 0551 0552 ~psd_layer_effects_inner_shadow() override; 0553 }; 0554 0555 class KRITAPSDUTILS_EXPORT psd_layer_effects_glow_common : public psd_layer_effects_shadow_base 0556 { 0557 public: 0558 psd_layer_effects_glow_common() 0559 { 0560 setKnocksOut(true); 0561 setDistance(0); 0562 setBlendMode(COMPOSITE_LINEAR_DODGE); 0563 setColor(KoColor::fromXML("<color channeldepth='U8'><sRGB r='1.0' g='1.0' b='1.0'/></color>")); 0564 } 0565 ~psd_layer_effects_glow_common() override; 0566 /// FIXME: 'using' is not supported by MSVC, so please refactor in 0567 /// some other way to ensure that the setters are not used 0568 /// in the classes we don't want 0569 0570 // using psd_layer_effects_shadow_base::setBlendMode; 0571 // using psd_layer_effects_shadow_base::setColor; 0572 // using psd_layer_effects_shadow_base::setOpacity; 0573 0574 // using psd_layer_effects_shadow_base::setSpread; 0575 // using psd_layer_effects_shadow_base::setSize; 0576 // using psd_layer_effects_shadow_base::setContourLookupTable; 0577 // using psd_layer_effects_shadow_base::setAntiAliased; 0578 // using psd_layer_effects_shadow_base::setNoise; 0579 0580 // using psd_layer_effects_shadow_base::setFillType; 0581 // using psd_layer_effects_shadow_base::setTechnique; 0582 // using psd_layer_effects_shadow_base::setRange; 0583 // using psd_layer_effects_shadow_base::setJitter; 0584 // using psd_layer_effects_shadow_base::setGradient; 0585 }; 0586 0587 // oglw: https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/PhotoshopFileFormats.htm#50577409_25738 0588 class KRITAPSDUTILS_EXPORT psd_layer_effects_outer_glow : public psd_layer_effects_glow_common 0589 { 0590 public: 0591 ~psd_layer_effects_outer_glow() override; 0592 }; 0593 0594 // iglw: https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/PhotoshopFileFormats.htm#50577409_27692 0595 class KRITAPSDUTILS_EXPORT psd_layer_effects_inner_glow : public psd_layer_effects_glow_common 0596 { 0597 public: 0598 psd_layer_effects_inner_glow() 0599 : m_source(psd_glow_edge) 0600 { 0601 setInvertsSelection(true); 0602 setEdgeHidden(false); 0603 setKnocksOut(false); 0604 } 0605 0606 psd_glow_source source() const 0607 { 0608 return m_source; 0609 } 0610 void setSource(psd_glow_source value) 0611 { 0612 m_source = value; 0613 } 0614 ~psd_layer_effects_inner_glow() override; 0615 0616 private: 0617 psd_glow_source m_source; 0618 }; 0619 0620 struct psd_layer_effects_satin : public psd_layer_effects_shadow_base { 0621 psd_layer_effects_satin() 0622 { 0623 setInvert(false); 0624 setUseGlobalLight(false); 0625 setDistance(8); 0626 setSize(7); 0627 setSpread(0); 0628 setKnocksOut(true); 0629 setEdgeHidden(false); 0630 setBlendMode(COMPOSITE_LINEAR_BURN); 0631 } 0632 0633 /// FIXME: 'using' is not supported by MSVC, so please refactor in 0634 /// some other way to ensure that the setters are not used 0635 /// in the classes we don't want 0636 0637 // using psd_layer_effects_shadow_base::setBlendMode; 0638 // using psd_layer_effects_shadow_base::setColor; 0639 // using psd_layer_effects_shadow_base::setOpacity; 0640 0641 // // NOTE: no global light setting explicitly! 0642 // using psd_layer_effects_shadow_base::setAngle; 0643 // using psd_layer_effects_shadow_base::setDistance; 0644 0645 // using psd_layer_effects_shadow_base::setSize; 0646 0647 // using psd_layer_effects_shadow_base::setContourLookupTable; 0648 // using psd_layer_effects_shadow_base::setAntiAliased; 0649 0650 bool invert() const 0651 { 0652 return m_invert; 0653 } 0654 0655 void setInvert(bool value) 0656 { 0657 m_invert = value; 0658 } 0659 0660 private: 0661 bool m_invert; 0662 }; 0663 0664 // bevl: https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/PhotoshopFileFormats.htm#50577409_31889 0665 struct psd_layer_effects_bevel_emboss : public psd_layer_effects_shadow_base { 0666 psd_layer_effects_bevel_emboss() 0667 : m_style(psd_bevel_inner_bevel) 0668 , m_technique(psd_technique_softer) 0669 , m_depth(100) 0670 , m_direction(psd_direction_up) 0671 , m_soften(0) 0672 , 0673 0674 m_altitude(30) 0675 , 0676 0677 m_glossAntiAliased(false) 0678 , 0679 0680 m_highlightBlendMode(COMPOSITE_SCREEN) 0681 , m_highlightColor(KoColor::fromXML("<color channeldepth='U8'><sRGB r='1.0' g='1.0' b='1.0'/></color>")) 0682 , m_highlightOpacity(75) 0683 , 0684 0685 m_shadowBlendMode(COMPOSITE_MULT) 0686 , m_shadowColor(KoColor::fromXML("<color channeldepth='U8'><sRGB r='0.0' g='0.0' b='0.0'/></color>")) 0687 , m_shadowOpacity(75) 0688 , 0689 0690 m_contourEnabled(false) 0691 , m_contourRange(100) 0692 , 0693 0694 m_textureEnabled(false) 0695 , m_textureScale(100) 0696 , m_textureDepth(100) 0697 , m_textureInvert(false) 0698 , 0699 0700 m_textureAlignWithLayer(true) 0701 , m_textureHorizontalPhase(0) 0702 , m_textureVerticalPhase(0) 0703 { 0704 for (int i = 0; i < PSD_LOOKUP_TABLE_SIZE; ++i) { 0705 m_glossContourLookupTable[i] = i; 0706 } 0707 } 0708 0709 /// FIXME: 'using' is not supported by MSVC, so please refactor in 0710 /// some other way to ensure that the setters are not used 0711 /// in the classes we don't want 0712 0713 // using psd_layer_effects_shadow_base::setSize; 0714 0715 // using psd_layer_effects_shadow_base::setAngle; 0716 // using psd_layer_effects_shadow_base::setUseGlobalLight; 0717 0718 // using psd_layer_effects_shadow_base::setContourLookupTable; 0719 // using psd_layer_effects_shadow_base::setAntiAliased; 0720 0721 psd_bevel_style style() const 0722 { 0723 return m_style; 0724 } 0725 void setStyle(psd_bevel_style value) 0726 { 0727 m_style = value; 0728 } 0729 0730 psd_technique_type technique() const 0731 { 0732 return m_technique; 0733 } 0734 void setTechnique(psd_technique_type value) 0735 { 0736 m_technique = value; 0737 } 0738 0739 int depth() const 0740 { 0741 return m_depth; 0742 } 0743 void setDepth(int value) 0744 { 0745 m_depth = value; 0746 } 0747 0748 psd_direction direction() const 0749 { 0750 return m_direction; 0751 } 0752 void setDirection(psd_direction value) 0753 { 0754 m_direction = value; 0755 } 0756 0757 int soften() const 0758 { 0759 return m_soften; 0760 } 0761 void setSoften(int value) 0762 { 0763 m_soften = value; 0764 } 0765 0766 int altitude() const 0767 { 0768 return m_altitude; 0769 } 0770 void setAltitude(int value) 0771 { 0772 m_altitude = value; 0773 } 0774 0775 const quint8 *glossContourLookupTable() const 0776 { 0777 return m_glossContourLookupTable; 0778 } 0779 0780 void setGlossContourLookupTable(const quint8 *value) 0781 { 0782 memcpy(m_glossContourLookupTable, value, PSD_LOOKUP_TABLE_SIZE * sizeof(quint8)); 0783 } 0784 0785 bool glossAntiAliased() const 0786 { 0787 return m_glossAntiAliased; 0788 } 0789 void setGlossAntiAliased(bool value) 0790 { 0791 m_glossAntiAliased = value; 0792 } 0793 0794 QString highlightBlendMode() const 0795 { 0796 return m_highlightBlendMode; 0797 } 0798 void setHighlightBlendMode(QString value) 0799 { 0800 m_highlightBlendMode = value; 0801 } 0802 0803 KoColor highlightColor() const 0804 { 0805 return m_highlightColor; 0806 } 0807 void setHighlightColor(KoColor value) 0808 { 0809 m_highlightColor = value; 0810 } 0811 0812 qint32 highlightOpacity() const 0813 { 0814 return m_highlightOpacity; 0815 } 0816 void setHighlightOpacity(qint32 value) 0817 { 0818 m_highlightOpacity = value; 0819 } 0820 0821 QString shadowBlendMode() const 0822 { 0823 return m_shadowBlendMode; 0824 } 0825 void setShadowBlendMode(QString value) 0826 { 0827 m_shadowBlendMode = value; 0828 } 0829 0830 KoColor shadowColor() const 0831 { 0832 return m_shadowColor; 0833 } 0834 void setShadowColor(KoColor value) 0835 { 0836 m_shadowColor = value; 0837 } 0838 0839 qint32 shadowOpacity() const 0840 { 0841 return m_shadowOpacity; 0842 } 0843 void setShadowOpacity(qint32 value) 0844 { 0845 m_shadowOpacity = value; 0846 } 0847 0848 bool contourEnabled() const 0849 { 0850 return m_contourEnabled; 0851 } 0852 void setContourEnabled(bool value) 0853 { 0854 m_contourEnabled = value; 0855 } 0856 0857 int contourRange() const 0858 { 0859 return m_contourRange; 0860 } 0861 void setContourRange(int value) 0862 { 0863 m_contourRange = value; 0864 } 0865 0866 bool textureEnabled() const 0867 { 0868 return m_textureEnabled; 0869 } 0870 void setTextureEnabled(bool value) 0871 { 0872 m_textureEnabled = value; 0873 } 0874 0875 KoResourceSignature texturePatternLink() const { 0876 return m_texturePatternLink; 0877 } 0878 0879 KoPatternSP texturePattern(KisResourcesInterfaceSP resourcesInterface) const 0880 { 0881 auto source = resourcesInterface->source<KoPattern>(m_texturePatternLink.type); 0882 return source.bestMatch(m_texturePatternLink.md5sum, m_texturePatternLink.filename, m_texturePatternLink.name); 0883 } 0884 0885 void setTexturePattern(KoPatternSP value) 0886 { 0887 m_texturePatternLink.type = value->resourceType().first; 0888 m_texturePatternLink.md5sum = value->md5Sum(); 0889 m_texturePatternLink.filename = value->filename(); 0890 m_texturePatternLink.name = value->name(); 0891 0892 } 0893 0894 int textureScale() const 0895 { 0896 return m_textureScale; 0897 } 0898 void setTextureScale(int value) 0899 { 0900 m_textureScale = value; 0901 } 0902 0903 int textureDepth() const 0904 { 0905 return m_textureDepth; 0906 } 0907 void setTextureDepth(int value) 0908 { 0909 m_textureDepth = value; 0910 } 0911 0912 bool textureInvert() const 0913 { 0914 return m_textureInvert; 0915 } 0916 void setTextureInvert(bool value) 0917 { 0918 m_textureInvert = value; 0919 } 0920 0921 bool textureAlignWithLayer() const 0922 { 0923 return m_textureAlignWithLayer; 0924 } 0925 void setTextureAlignWithLayer(bool value) 0926 { 0927 m_textureAlignWithLayer = value; 0928 } 0929 0930 void setTexturePhase(const QPointF &phase) 0931 { 0932 m_textureHorizontalPhase = phase.x(); 0933 m_textureVerticalPhase = phase.y(); 0934 } 0935 0936 QPointF texturePhase() const 0937 { 0938 return QPointF(m_textureHorizontalPhase, m_textureVerticalPhase); 0939 } 0940 0941 int textureHorizontalPhase() const 0942 { 0943 return m_textureHorizontalPhase; 0944 } 0945 void setTextureHorizontalPhase(int value) 0946 { 0947 m_textureHorizontalPhase = value; 0948 } 0949 0950 int textureVerticalPhase() const 0951 { 0952 return m_textureVerticalPhase; 0953 } 0954 void setTextureVerticalPhase(int value) 0955 { 0956 m_textureVerticalPhase = value; 0957 } 0958 0959 void scaleLinearSizes(qreal scale) override 0960 { 0961 psd_layer_effects_shadow_base::scaleLinearSizes(scale); 0962 m_soften *= scale; 0963 m_textureScale *= scale; 0964 } 0965 0966 private: 0967 psd_bevel_style m_style; 0968 psd_technique_type m_technique; 0969 int m_depth; 0970 psd_direction m_direction; // Up or down 0971 int m_soften; // Blur value in pixels. 0972 0973 int m_altitude; 0974 0975 quint8 m_glossContourLookupTable[256]; 0976 bool m_glossAntiAliased; 0977 0978 QString m_highlightBlendMode; // already in Krita format 0979 KoColor m_highlightColor; 0980 qint32 m_highlightOpacity; // Highlight opacity as a percent 0981 0982 QString m_shadowBlendMode; // already in Krita format 0983 KoColor m_shadowColor; 0984 qint32 m_shadowOpacity; // Shadow opacity as a percent 0985 0986 bool m_contourEnabled; 0987 int m_contourRange; 0988 0989 bool m_textureEnabled; 0990 KoResourceSignature m_texturePatternLink; 0991 int m_textureScale; 0992 int m_textureDepth; 0993 bool m_textureInvert; 0994 0995 bool m_textureAlignWithLayer; 0996 int m_textureHorizontalPhase; // 0..100% 0997 int m_textureVerticalPhase; // 0..100% 0998 }; 0999 1000 struct psd_layer_effects_overlay_base : public psd_layer_effects_shadow_base { 1001 psd_layer_effects_overlay_base() 1002 : m_scale(100) 1003 , m_alignWithLayer(true) 1004 , m_dither(false) 1005 , m_reverse(false) 1006 , m_style(psd_gradient_style_linear) 1007 , m_gradientXOffset(0) 1008 , m_gradientYOffset(0) 1009 , m_horizontalPhase(0) 1010 , m_verticalPhase(0) 1011 { 1012 setUseGlobalLight(false); 1013 } 1014 1015 /// FIXME: 'using' is not supported by MSVC, so please refactor in 1016 /// some other way to ensure that the setters are not used 1017 /// in the classes we don't want 1018 1019 // using psd_layer_effects_shadow_base::setBlendMode; 1020 // using psd_layer_effects_shadow_base::setOpacity; 1021 1022 int scale() const 1023 { 1024 return m_scale; 1025 } 1026 1027 bool alignWithLayer() const 1028 { 1029 return m_alignWithLayer; 1030 } 1031 1032 bool dither() const 1033 { 1034 return m_dither; 1035 } 1036 1037 bool reverse() const 1038 { 1039 return m_reverse; 1040 } 1041 1042 psd_gradient_style style() const 1043 { 1044 return m_style; 1045 } 1046 1047 int gradientXOffset() const 1048 { 1049 return m_gradientXOffset; 1050 } 1051 1052 int gradientYOffset() const 1053 { 1054 return m_gradientYOffset; 1055 } 1056 1057 KoResourceSignature patternLink() const { 1058 return m_patternLink; 1059 } 1060 1061 KoPatternSP pattern(KisResourcesInterfaceSP resourcesInterface) const 1062 { 1063 auto source = resourcesInterface->source<KoPattern>(m_patternLink.type); 1064 return source.bestMatch(m_patternLink.md5sum, m_patternLink.filename, m_patternLink.name); 1065 } 1066 1067 int horizontalPhase() const 1068 { 1069 return m_horizontalPhase; 1070 } 1071 1072 int verticalPhase() const 1073 { 1074 return m_verticalPhase; 1075 } 1076 1077 // refactor that 1078 public: 1079 void setScale(int value) 1080 { 1081 m_scale = value; 1082 } 1083 1084 void setAlignWithLayer(bool value) 1085 { 1086 m_alignWithLayer = value; 1087 } 1088 1089 void setDither(bool value) 1090 { 1091 m_dither = value; 1092 } 1093 1094 void setReverse(bool value) 1095 { 1096 m_reverse = value; 1097 } 1098 1099 void setStyle(psd_gradient_style value) 1100 { 1101 m_style = value; 1102 } 1103 1104 void setGradientOffset(const QPointF &pt) 1105 { 1106 m_gradientXOffset = qRound(pt.x()); 1107 m_gradientYOffset = qRound(pt.y()); 1108 } 1109 1110 QPointF gradientOffset() const 1111 { 1112 return QPointF(m_gradientXOffset, m_gradientYOffset); 1113 } 1114 1115 void setPattern(KoPatternSP value) 1116 { 1117 m_patternLink.type = value->resourceType().first; 1118 m_patternLink.md5sum = value->md5Sum(); 1119 m_patternLink.filename = value->filename(); 1120 m_patternLink.name = value->name(); 1121 } 1122 1123 void setPatternPhase(const QPointF &phase) 1124 { 1125 m_horizontalPhase = phase.x(); 1126 m_verticalPhase = phase.y(); 1127 } 1128 1129 QPointF patternPhase() const 1130 { 1131 return QPointF(m_horizontalPhase, m_verticalPhase); 1132 } 1133 1134 void scaleLinearSizes(qreal scale) override 1135 { 1136 psd_layer_effects_shadow_base::scaleLinearSizes(scale); 1137 m_scale *= scale; 1138 } 1139 1140 private: 1141 // Gradient+Pattern 1142 int m_scale; 1143 bool m_alignWithLayer; 1144 1145 // Gradient 1146 bool m_dither; 1147 bool m_reverse; 1148 psd_gradient_style m_style; 1149 int m_gradientXOffset; // 0..100% 1150 int m_gradientYOffset; // 0..100% 1151 1152 // Pattern 1153 KoResourceSignature m_patternLink; 1154 int m_horizontalPhase; // 0..100% 1155 int m_verticalPhase; // 0..100% 1156 1157 protected: 1158 /// FIXME: 'using' is not supported by MSVC, so please refactor in 1159 /// some other way to ensure that the setters are not used 1160 /// in the classes we don't want 1161 1162 // must be called in the derived classes' c-tor 1163 // using psd_layer_effects_shadow_base::setFillType; 1164 }; 1165 1166 // sofi: https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/PhotoshopFileFormats.htm#50577409_70055 1167 struct psd_layer_effects_color_overlay : public psd_layer_effects_overlay_base { 1168 psd_layer_effects_color_overlay() 1169 { 1170 setFillType(psd_fill_solid_color); 1171 setColor(KoColor::fromXML("<color channeldepth='U8'><sRGB r='1.0' g='1.0' b='1.0'/></color>")); 1172 } 1173 1174 /// FIXME: 'using' is not supported by MSVC, so please refactor in 1175 /// some other way to ensure that the setters are not used 1176 /// in the classes we don't want 1177 1178 // using psd_layer_effects_shadow_base::setColor; 1179 }; 1180 1181 struct psd_layer_effects_gradient_overlay : public psd_layer_effects_overlay_base { 1182 psd_layer_effects_gradient_overlay() 1183 { 1184 setFillType(psd_fill_gradient); 1185 setAngle(90); 1186 setReverse(false); 1187 setScale(100); 1188 setAlignWithLayer(true); 1189 setStyle(psd_gradient_style_linear); 1190 } 1191 1192 public: 1193 /// FIXME: 'using' is not supported by MSVC, so please refactor in 1194 /// some other way to ensure that the setters are not used 1195 /// in the classes we don't want 1196 1197 // using psd_layer_effects_shadow_base::setGradient; 1198 // using psd_layer_effects_shadow_base::setAngle; 1199 1200 // using psd_layer_effects_overlay_base::setReverse; 1201 // using psd_layer_effects_overlay_base::setScale; 1202 // using psd_layer_effects_overlay_base::setAlignWithLayer; 1203 // using psd_layer_effects_overlay_base::setStyle; 1204 1205 // using psd_layer_effects_overlay_base::setGradientOffset; 1206 // using psd_layer_effects_overlay_base::gradientOffset; 1207 }; 1208 1209 struct psd_layer_effects_pattern_overlay : public psd_layer_effects_overlay_base { 1210 psd_layer_effects_pattern_overlay() 1211 { 1212 setFillType(psd_fill_pattern); 1213 setScale(100); 1214 setAlignWithLayer(true); 1215 } 1216 1217 /// FIXME: 'using' is not supported by MSVC, so please refactor in 1218 /// some other way to ensure that the setters are not used 1219 /// in the classes we don't want 1220 1221 // using psd_layer_effects_overlay_base::setScale; 1222 // using psd_layer_effects_overlay_base::setAlignWithLayer; 1223 1224 // using psd_layer_effects_overlay_base::setPattern; 1225 1226 // using psd_layer_effects_overlay_base::setPatternPhase; 1227 // using psd_layer_effects_overlay_base::patternPhase; 1228 1229 private: 1230 // These are unused 1231 /*int m_scale; 1232 bool m_alignWithLayer; 1233 KoPatternSP m_pattern; 1234 1235 int m_horizontalPhase; 1236 int m_verticalPhase;*/ 1237 }; 1238 1239 struct psd_layer_effects_stroke : public psd_layer_effects_overlay_base { 1240 psd_layer_effects_stroke() 1241 : m_position(psd_stroke_outside) 1242 { 1243 setFillType(psd_fill_solid_color); 1244 setColor(KoColor::fromXML("<color channeldepth='U8'><sRGB r='0.0' g='0.0' b='0.0'/></color>")); 1245 1246 setAngle(90); 1247 setReverse(false); 1248 setScale(100); 1249 setAlignWithLayer(true); 1250 setStyle(psd_gradient_style_linear); 1251 1252 setScale(100); 1253 setAlignWithLayer(true); 1254 } 1255 1256 /// FIXME: 'using' is not supported by MSVC, so please refactor in 1257 /// some other way to ensure that the setters are not used 1258 /// in the classes we don't want 1259 1260 // using psd_layer_effects_shadow_base::setFillType; 1261 // using psd_layer_effects_shadow_base::setSize; 1262 1263 // using psd_layer_effects_shadow_base::setColor; 1264 1265 // using psd_layer_effects_shadow_base::setGradient; 1266 // using psd_layer_effects_shadow_base::setAngle; 1267 // using psd_layer_effects_overlay_base::setReverse; 1268 // using psd_layer_effects_overlay_base::setScale; 1269 // using psd_layer_effects_overlay_base::setAlignWithLayer; 1270 // using psd_layer_effects_overlay_base::setStyle; 1271 1272 // using psd_layer_effects_overlay_base::setGradientOffset; 1273 // using psd_layer_effects_overlay_base::gradientOffset; 1274 1275 // using psd_layer_effects_overlay_base::setPattern; 1276 1277 // using psd_layer_effects_overlay_base::setPatternPhase; 1278 // using psd_layer_effects_overlay_base::patternPhase; 1279 1280 psd_stroke_position position() const 1281 { 1282 return m_position; 1283 } 1284 void setPosition(psd_stroke_position value) 1285 { 1286 m_position = value; 1287 } 1288 1289 private: 1290 psd_stroke_position m_position; 1291 }; 1292 1293 /** 1294 * Convert PsdColorMode to pigment colormodelid and colordepthid. 1295 * @see KoColorModelStandardIds 1296 * 1297 * @return a QPair containing ColorModelId and ColorDepthID 1298 */ 1299 QPair<QString, QString> KRITAPSDUTILS_EXPORT psd_colormode_to_colormodelid(psd_color_mode colormode, quint16 channelDepth); 1300 1301 /** 1302 * Convert the Photoshop blend mode strings to Pigment compositeop id's 1303 */ 1304 QString KRITAPSDUTILS_EXPORT psd_blendmode_to_composite_op(const QString &blendmode); 1305 QString KRITAPSDUTILS_EXPORT composite_op_to_psd_blendmode(const QString &compositeOp); 1306 1307 1308 #if defined(__clang__) && __clang_major__ < 10 1309 inline QDebug &operator<<(QDebug &self, psd_compression_type type) 1310 { 1311 self << static_cast<std::uint16_t>(type); 1312 return self; 1313 }; 1314 #endif 1315 1316 #endif // PSD_H