7#ifndef PSD_ADDITIONAL_LAYER_INFO_BLOCK_H
8#define PSD_ADDITIONAL_LAYER_INFO_BLOCK_H
10#include "kritapsd_export.h"
12#include <QDomDocument>
39#include <QVariantHash>
48 quint16 input_floor {0};
49 quint16 input_ceiling {2};
50 quint16 output_floor {0};
51 quint16 output_ceiling {0};
60 quint16 extra_level_count {0};
63 quint8 lookup_table[3][256];
69 quint16 channel_index {0};
70 quint16 point_count {0};
71 quint16 output_value[19];
72 quint16 input_value[19];
77 quint16 curve_count {0};
79 quint8 lookup_table[3][256];
88 quint8 lookup_table[256];
94 qint8 magenta_green[3];
96 bool preserve_luminosity {
false};
97 quint8 lookup_table[3][256];
103 quint8 hue_or_colorization {0};
104 qint8 colorization_hue {0};
106 qint8 colorization_saturation {0};
107 qint8 colorization_lightness {0};
109 qint8 master_hue {0};
110 qint8 master_saturation {0};
111 qint8 master_lightness {0};
112 qint8 range_values[6][4];
115 qint8 setting_values[6][3];
117 quint8 lookup_table[6][360];
123 quint16 correction_method {0};
124 qint8 cyan_correction[10];
125 qint8 magenta_correction[10];
126 qint8 yellow_correction[10];
127 qint8 black_correction[10];
141 quint8 lookup_table[256];
146 bool monochrome {
false};
148 qint8 green_magenta[4];
149 qint8 blue_yellow[4];
160 bool preserve_luminosity {
true};
196 v.setValue(fill_color);
197 cfg->setProperty(
"color",
v);
199 doc.setContent(cfg->toXML());
204 if (cfg->name() !=
"color") {
207 fill_color = cfg->getColor(
"color");
213 w.enterDescriptor(
"",
"",
"null");
224 w.writeColor(
"Clr ", fill_color);
231 return QBrush(c, Qt::SolidPattern);
241 QString style {QString(
"linear")};
242 QString repeat {QString(
"none")};
243 double scale {100.0};
244 bool reverse {
false};
245 bool dithered {
false};
246 bool align_with_layer {
false};
254 QDomDocument document;
255 QDomElement gradientElement = document.createElement(
"gradient");
256 gradientElement.setAttribute(
"name", newGradient->name());
260 gradient->
toXML(document, gradientElement);
263 gradient->
toXML(document, gradientElement);
266 document.appendChild(gradientElement);
286 }
else if (type ==
"Rdl "){
288 }
else if (type ==
"Angl"){
290 }
else if (type ==
"Rflc"){
299 align_with_layer = align;
324 cfg->setProperty(
"gradient", gradient.toString());
325 cfg->setProperty(
"dither", dithered);
326 cfg->setProperty(
"reverse", reverse);
328 cfg->setProperty(
"shape", style);
329 cfg->setProperty(
"repeat", repeat);
331 cfg->setProperty(
"end_position_coordinate_system",
"polar");
333 cfg->setProperty(
"end_position_distance_units",
"percent_of_width");
334 cfg->setProperty(
"start_position_x_units",
"percent_of_width");
335 cfg->setProperty(
"start_position_y_units",
"percent_of_height");
338 double fixedAngle = fmod(360.0 + angle, 360.0);
340 double scaleModifier = 1.0;
342 if (style ==
"square") {
343 fixedAngle = fmod((45.0 + fixedAngle), 360.0);
346 double halfAngle = fmod(fabs(fixedAngle), 180.0);
348 if (halfAngle >= 45.0 && halfAngle < 135.0) {
349 scaleModifier = (scaleModifier) * (imageHeight / imageWidth);
353 double halfAngle = fmod(fabs(fixedAngle), 180.0);
355 if (halfAngle >= 45.0 && halfAngle < 135.0) {
356 scaleModifier = (scaleModifier) * (imageHeight / imageWidth);
361 cfg->setProperty(
"end_position_angle", fixedAngle);
363 if (style ==
"linear") {
366 QPointF center(imageWidth*0.5, imageHeight*0.5);
369 rotate.rotate(fixedAngle);
370 QTransform tf = QTransform::fromTranslate(-center.x(), -center.y())
371 * rotate * QTransform::fromTranslate(center.x(), center.y());
372 QPointF topleft = tf.inverted().map(QPointF(0.0, 0.0));
373 double xPercentage = (topleft.x()/double(imageWidth)) * 100.0;
374 double yPercentage = (topleft.y()/double(imageHeight)) * 100.0;
376 cfg->setProperty(
"end_position_distance", scale * scaleModifier);
377 cfg->setProperty(
"start_position_x", xPercentage + offset.x());
378 cfg->setProperty(
"start_position_y", yPercentage + offset.y());
380 cfg->setProperty(
"end_position_distance", scale * 0.5 * fabs(scaleModifier));
381 cfg->setProperty(
"start_position_x", (50.0)+offset.x());
382 cfg->setProperty(
"start_position_y", (50.0)+offset.y());
386 doc.setContent(cfg->toXML());
391 if (cfg->name() !=
"gradient") {
395 bool res = bool(gradient.setContent(cfg->getString(
"gradient",
"")));
396 dithered = cfg->getBool(
"dither");
397 reverse = cfg->getBool(
"reverse");
398 align_with_layer =
false;
400 style = cfg->getString(
"shape",
"linear");
401 repeat = cfg->getString(
"repeat",
"none");
403 bool polar = (cfg->getString(
"end_position_coordinate_system") ==
"polar");
405 QPointF start(cfg->getDouble(
"start_position_x", 0.0), cfg->getDouble(
"start_position_y", 0.0));
407 angle = cfg->getDouble(
"end_position_angle", 0.0);
408 scale = cfg->getDouble(
"end_position_distance", 100.0);
411 QPointF end(cfg->getDouble(
"end_position_x", 1.0), cfg->getDouble(
"end_position_y", 1.0));
413 double width = start.x() - end.x();
414 double height = start.y() - end.y();
416 scale = sqrt((width*width) + (height*height));
420 if (style ==
"linear") {
421 QPointF center(imageWidth*0.5, imageHeight*0.5);
424 rotate.rotate(angle);
425 QTransform tf = QTransform::fromTranslate(-center.x(), -center.y())
426 * rotate * QTransform::fromTranslate(center.x(), center.y());
427 QPointF topleft = tf.inverted().map(QPointF(0.0, 0.0));
428 double xPercentage = (topleft.x()/double(imageWidth)) * 100.0;
429 double yPercentage = (topleft.y()/double(imageHeight)) * 100.0;
430 offset = QPointF((start.x() - xPercentage), (start.y() - yPercentage));
433 offset = QPointF((start.x() - 50.0), (start.y() - 50.0));
436 double scaleModifier = 1.0;
437 if (style ==
"square") {
439 double halfAngle = fmod(fabs(angle), 180.0);
441 if (halfAngle >= 45.0 && halfAngle < 135.0) {
442 scaleModifier = (scaleModifier) * (imageHeight / imageWidth);
445 angle = angle - 45.0;
447 angle = 360.0 - angle;
451 double halfAngle = fmod(fabs(angle), 180.0);
453 if (halfAngle >= 45.0 && halfAngle < 135.0) {
454 scaleModifier = (scaleModifier) * (imageHeight / imageWidth);
460 angle = (0.0 - fmod(angle, 180.0));
463 scale /= fabs(scaleModifier);
471 w.enterDescriptor(
"",
"",
"null");
480 if (!gradient.isNull()) {
481 const QDomElement gradientElement = gradient.firstChildElement();
482 if (!gradientElement.isNull()) {
483 const QString gradientType = gradientElement.attribute(
"type");
484 if (gradientType ==
"stop") {
487 w.writeStopGradient(
"Grad", grad);
489 }
else if (gradientType ==
"segment") {
492 w.writeSegmentGradient(
"Grad", grad);
497 w.writeBoolean(
"Dthr", dithered);
498 w.writeBoolean(
"Rvrs", reverse);
499 w.writeUnitFloat(
"Angl",
"#Ang", angle);
501 QString type =
"Lnr ";
502 if (style ==
"linear"){
504 }
else if (style ==
"radial") {
506 }
else if (style ==
"conical"){
508 }
else if (style ==
"bilinear"){
510 }
else if (style ==
"square") {
514 w.writeEnum(
"Type",
"GrdT", type);
515 w.writeBoolean(
"Algn", align_with_layer);
516 w.writeUnitFloat(
"Scl ",
"#Prc", scale);
517 w.writePoint(
"Ofst", offset);
521 QGradient *grad = getGradient();
523 QBrush brush = *grad;
526 return QBrush(Qt::transparent);
529 QGradient *pointer =
nullptr;
530 if (!gradient.isNull()) {
531 const QDomElement gradientElement = gradient.firstChildElement();
532 if (!gradientElement.isNull()) {
533 const QString gradientType = gradientElement.attribute(
"type");
534 if (gradientType ==
"stop") {
539 }
else if (gradientType ==
"segment") {
548 QGradient::CoordinateMode mode = QGradient::ObjectBoundingMode;
549 pointer->setCoordinateMode(mode);
552 QGradientStops newStops;
553 Q_FOREACH(QGradientStop stop, pointer->stops()) {
554 newStops.append(QPair<double, QColor>(1.0-stop.first, stop.second));
556 pointer->setStops(newStops);
559 QLinearGradient *g =
static_cast<QLinearGradient*
>(pointer);
560 QLineF line = QLineF::fromPolar(0.5*(scale*0.01), angle);
561 line.translate(QPointF(0.5, 0.5)+(offset*0.01));
563 if (style ==
"radial") {
564 QRadialGradient *r =
new QRadialGradient(line.p1(), line.length());
565 r->setCoordinateMode(mode);
567 r->setSpread(pointer->spread());
568 r->setStops(pointer->stops());
571 }
else if (style ==
"bilinear") {
572 QLinearGradient *b =
new QLinearGradient();
573 Q_FOREACH(QGradientStop stop, pointer->stops()) {
574 double pos = 0.5 - stop.first*0.5;
575 b->setColorAt(pos, stop.second);
576 double pos2 = 1.0 - pos;
578 b->setColorAt(pos2, stop.second);
581 b->setCoordinateMode(mode);
583 b->setFinalStop(line.p2());
584 line.setAngle(180+angle);
585 b->setStart(line.p2());
588 g->setFinalStop(line.p2());
589 line.setAngle(180+angle);
590 g->setStart(line.p2());
600 if (gradient->coordinateMode() == QGradient::ObjectBoundingMode) {
601 align_with_layer =
true;
603 if (gradient->type() == QGradient::LinearGradient) {
604 const QLinearGradient *g =
static_cast<const QLinearGradient*
>(gradient);
605 QLineF line(g->start(), g->finalStop());
606 offset = (line.center()-QPointF(0.5, 0.5))*100.0;
607 angle = line.angle();
609 angle = (0.0 - fmod(angle, 180.0));
611 scale = (line.length())*100.0;
614 const QRadialGradient *g =
static_cast<const QRadialGradient*
>(gradient);
615 offset = (g->center()-QPointF(0.5, 0.5)) * 100.0;
617 scale = (g->radius()*2) * 100.0;
623 QGradient *pointer = getGradient();
629 if (style ==
"radial" || style ==
"linear") {
638 double scale {100.0};
643 bool align_with_layer {
false};
661 align_with_layer = align;
676 cfg->setProperty(
"pattern", patternName);
677 cfg->setProperty(
"fileName", QString(patternID +
".pat"));
678 cfg->setProperty(
"md5",
"");
681 double fixedAngle = 360.0 - fmod(360.0 + angle, 360.0);
683 cfg->setProperty(
"transform_scale_x", scale / 100);
684 cfg->setProperty(
"transform_scale_y", scale / 100);
685 cfg->setProperty(
"transform_rotation_z", fixedAngle);
687 cfg->setProperty(
"transform_offset_x", offset.x());
688 cfg->setProperty(
"transform_offset_y", offset.y());
690 doc.setContent(cfg->toXML());
695 if (cfg->name() !=
"pattern") {
699 const QString patternMD5 = cfg->getString(
"md5",
"");
700 const QString patternNameTemp = cfg->getString(
"pattern",
"Grid01.pat");
701 const QString patternFileName = cfg->getString(
"fileName",
"");
706 patternName = cfg->getString(
"pattern",
"");
710 align_with_layer =
false;
712 scale = cfg->getDouble(
"transform_scale_x", 1.0) * 100;
714 angle = 360.0 - cfg->getDouble(
"transform_rotation_z", 0.0);
716 angle = (180.0 - angle);
719 offset = QPointF(cfg->getInt(
"transform_offset_x", 0), cfg->getInt(
"transform_offset_y", 0));
726 w.enterDescriptor(
"",
"",
"null");
728 if (patternID.isEmpty()) {
729 qWarning() <<
"This pattern cannot be saved: No pattern UUID available.";
730 return QDomDocument();
742 w.enterDescriptor(
"Ptrn",
"",
"Ptrn");
744 w.writeText(
"Nm ", patternName);
745 w.writeText(
"Idnt", patternID);
750 w.writeBoolean(
"Algn", align_with_layer);
751 w.writeUnitFloat(
"Scl ",
"#Prc", scale);
752 w.writeUnitFloat(
"Angl",
"#Ang", angle);
753 w.writePoint(
"phase", offset);
757 const QString patternMD5 =
"";
758 const QString patternNameTemp = patternName;
759 const QString patternFileName = QString(patternID +
".pat");
768 loadPattern(embeddedProxy);
770 bg->setPattern(pattern->pattern());
775 QSizeF size = bg->patternOriginalSize();
776 QPointF refPoint(offset.x()/size.width(), offset.y()/size.height());
777 size = QSizeF(size.width() * (0.01*scale), size.height() * (0.01*scale));
778 bg->setPatternDisplaySize(size);
779 bg->setReferencePointOffset(refPoint);
785 loadPattern(embeddedProxy);
787 brush.setTextureImage(pattern->pattern());
792 QTransform t = QTransform::fromScale(scale*0.01, scale*0.01);
794 brush.setTransform(t);
801 qint32 font_type {0};
802 qint8 font_name[256];
803 qint8 font_family_name[256];
804 qint8 font_style_name[256];
806 qint32 number_axes_vector {0};
807 qint32 *vector {
nullptr};
817 qint32 base_shift {0};
818 bool auto_kern {
false};
823 qint32 char_count {0};
824 qint8 orientation {0};
826 qint8 actual_char {0};
831 double transform_info[6];
832 qint8 faces_count {0};
834 qint8 styles_count {0};
837 qint32 scaling_factor {0};
838 qint32 character_count {0};
839 qint32 horz_place {0};
840 qint32 vert_place {0};
841 qint32 select_start {0};
842 qint32 select_end {0};
843 qint8 lines_count {0};
846 bool anti_alias {
false};
857 bool isHorizontal {
true};
882 isHorizontal =
false;
906 w.enterDescriptor(
"",
"",
"TxLr");
908 w.writeText(
"Txt ", text);
909 w.writeEnum(
"textGridding",
"textGridding",
"none");
911 w.writeEnum(
"Ornt",
"Ornt",
"Hrzn");
913 w.writeEnum(
"Ornt",
"Ornt",
"Vrtc");
915 w.writeEnum(
"AntA",
"Annt",
"AnCr");
917 w.enterDescriptor(
"bounds",
"",
"bounds");
918 w.writeUnitFloat(
"Left",
"#Pnt",
bounds.left());
919 w.writeUnitFloat(
"Top ",
"#Pnt",
bounds.top());
920 w.writeUnitFloat(
"Rght",
"#Pnt",
bounds.right());
921 w.writeUnitFloat(
"Btom",
"#Pnt",
bounds.bottom());
924 if (!boundingBox.isEmpty()) {
925 w.enterDescriptor(
"boundingBox",
"",
"boundingBox");
926 w.writeUnitFloat(
"Left",
"#Pnt", boundingBox.left());
927 w.writeUnitFloat(
"Top ",
"#Pnt", boundingBox.top());
928 w.writeUnitFloat(
"Rght",
"#Pnt", boundingBox.right());
929 w.writeUnitFloat(
"Btom",
"#Pnt", boundingBox.bottom());
932 w.writeInteger(
"TextIndex", textIndex);
934 w.writeRawData(
"EngineData", &ba);
943 w.enterDescriptor(
"",
"",
"warp");
945 w.writeEnum(
"warpStyle",
"warpStyle",
"warpNone");
946 w.writeDouble(
"warpValue", 0);
947 w.writeDouble(
"warpPerspective", 0);
948 w.writeDouble(
"warpPerspectiveOther", 0);
949 w.writeEnum(
"warpRotate",
"Ornt",
"Hrzn");
962 bool isSmooth {
false};
967 bool isClosed {
false};
970 bool initialFillRecord {
false};
978 bool notLink {
false};
979 bool disable {
false};
985 int strokeVersion {2};
987 bool strokeEnabled {
false};
988 bool fillEnabled {
true};
991 bool gradient{
false};
993 bool scaleLock {
false};
994 bool strokeAdjust {
false};
998 double opacity {1.0};
1000 double resolution {72.0};
1001 bool pixelWidth {
false};
1004 strokeVersion = version;
1008 strokeEnabled = enabled;
1011 fillEnabled = enabled;
1014 pen.setWidthF(width);
1018 pen.setWidthF(width);
1023 pen.setDashOffset(dashOffset);
1026 pen.setMiterLimit(limit);
1029 if (val ==
"strokeStyleButtCap") {
1030 pen.setCapStyle(Qt::FlatCap);
1031 }
else if (val ==
"strokeStyleSquareCap") {
1032 pen.setCapStyle(Qt::SquareCap);
1033 }
else if (val ==
"strokeStyleRoundCap") {
1034 pen.setCapStyle(Qt::RoundCap);
1038 if (val ==
"strokeStyleMiterJoin") {
1039 pen.setJoinStyle(Qt::MiterJoin);
1040 }
else if (val ==
"strokeStyleBevelJoin") {
1041 pen.setJoinStyle(Qt::BevelJoin);
1042 }
else if (val ==
"strokeStyleRoundJoin") {
1043 pen.setJoinStyle(Qt::RoundJoin);
1048 scaleLock = enabled;
1052 strokeAdjust = enabled;
1058 dashPattern.append(qMax(val, 1e-6));
1068 pen = stroke->resultLinePen();
1069 gradient = stroke->lineBrush().gradient()?
true:
false;
1070 opacity = stroke->color().alphaF();
1071 dashPattern = stroke->lineDashes();
1098 w.enterDescriptor(
"",
"",
"strokeStyle");
1100 w.writeInteger(
"strokeStyleVersion", 2);
1101 w.writeBoolean(
"strokeEnabled", strokeEnabled);
1102 w.writeBoolean(
"fillEnabled", fillEnabled);
1104 w.writeUnitFloat(
"strokeStyleLineWidth",
"#Pxl", pen.widthF() * (resolution / 72.0));
1105 w.writeUnitFloat(
"strokeStyleLineDashOffset ",
"#Pnt", pen.dashOffset());
1106 w.writeDouble(
"strokeStyleMiterLimit", pen.miterLimit());
1108 QString linecap =
"strokeStyleButtCap";
1109 if (pen.capStyle() == Qt::SquareCap) {
1110 linecap =
"strokeStyleSquareCap";
1111 }
else if (pen.capStyle() == Qt::RoundCap) {
1112 linecap =
"strokeStyleRoundCap";
1114 QString linejoin =
"strokeStyleMiterJoin";
1115 if (pen.joinStyle() == Qt::BevelJoin) {
1116 linejoin =
"strokeStyleBevelJoin";
1117 }
else if (pen.joinStyle() == Qt::RoundJoin) {
1118 linejoin =
"strokeStyleRoundJoin";
1120 w.writeEnum(
"strokeStyleLineCapType",
"strokeStyleLineCapType", linecap);
1121 w.writeEnum(
"strokeStyleLineJoinType",
"strokeStyleLineJoinType", linejoin);
1124 w.writeEnum(
"strokeStyleLineAlignment",
"strokeStyleLineAlignment",
"strokeStyleAlignCenter");
1126 w.writeBoolean(
"strokeStyleScaleLock",
false);
1127 w.writeBoolean(
"strokeStyleStrokeAdjust",
false);
1129 w.enterList(
"strokeStyleLineDashSet");
1130 Q_FOREACH(
const double val, dashPattern) {
1132 w.writeUnitFloat(
"",
"#Nne", 0);
1134 w.writeUnitFloat(
"",
"#Nne", val);
1139 w.writeEnum(
"strokeStyleBlendMode",
"BlnM",
"Nrml");
1140 w.writeUnitFloat(
"strokeStyleOpacity ",
"#Prc", opacity * 100.0);
1145 w.enterDescriptor(
"strokeStyleContent",
"",
"gradientLayer");
1149 w.leaveDescriptor();
1151 w.enterDescriptor(
"strokeStyleContent",
"",
"solidColorLayer");
1158 w.leaveDescriptor();
1161 w.writeDouble(
"strokeStyleResolution", resolution);
1163 w.leaveDescriptor();
1165 return w.document();
1169 double width = pen.widthF();
1170 width = (width / resolution) * 72.0;
1171 stroke->setLineWidth(width);
1172 stroke->setCapStyle(pen.capStyle());
1173 stroke->setJoinStyle(pen.joinStyle());
1174 stroke->setDashOffset(pen.dashOffset());
1175 stroke->setMiterLimit(pen.miterLimit());
1176 if (dashPattern.isEmpty()) {
1179 if (dashPattern.size() % 2 > 0) {
1181 pattern.append(dashPattern);
1182 stroke->setLineStyle(Qt::CustomDashLine, pattern);
1184 stroke->setLineStyle(Qt::CustomDashLine, dashPattern);
1194 {1,
"RectangleShape"},
1195 {5,
"EllipseShape"},
1248 QString descriptorPath = path+
"/keyDescriptorList/null";
1276 w.enterDescriptor(
"",
"",
"null");
1278 w.enterList(
"keyDescriptorList");
1280 w.enterDescriptor(
"",
"",
"null");
1295 w.writePointRect(
"keyOriginPolyPreviousTightBoxCorners",
originBoxCorners);
1297 w.writeDouble(
"keyOriginPolyPixelHSF", 1);
1304 w.leaveDescriptor();
1308 w.leaveDescriptor();
1310 return w.document();
1336 angle = QLineF(poly.first(), poly.value(1)).angle();
1337 double w = QLineF(poly.first(), poly.value(1)).length();
1338 double h = QLineF(poly.first(), poly.value(3)).length();
1339 size = QSizeF(w, h);
1360 bool read(QIODevice &io);
1361 bool write(QIODevice &io,
KisNodeSP node);
1363 void writeLuniBlockEx(QIODevice &io,
const QString &layerName);
1364 void writeLsctBlockEx(QIODevice &io,
psd_section_type sectionType,
bool isPassThrough,
const QString &blendModeKey);
1365 void writeLfx2BlockEx(QIODevice &io,
const QDomDocument &stylesXmlDoc,
bool useLfxsLayerStyleFormat);
1366 void writePattBlockEx(QIODevice &io,
const QDomDocument &patternsXmlDoc);
1367 void writeLclrBlockEx(QIODevice &io,
const quint16 &labelColor);
1369 void writeFillLayerBlockEx(QIODevice &io,
const QDomDocument &fillConfig,
psd_fill_type type);
1372 void writeVectorStrokeDataEx(QIODevice &io,
const QDomDocument &vectorStroke);
1373 void writeVectorOriginationDataEx(QIODevice &io,
const QDomDocument &vectorOrigination);
1374 void writeTxt2BlockEx(QIODevice &io,
const QVariantHash txt2Hash);
1388 quint16 labelColor{0};
1404 template<psd_
byte_order
byteOrder = psd_
byte_order::psdBigEndian>
1405 void readImpl(QIODevice &io);
1407 template<psd_
byte_order
byteOrder = psd_
byte_order::psdBigEndian>
1408 void writeLuniBlockExImpl(QIODevice &io,
const QString &layerName);
1410 template<psd_
byte_order
byteOrder = psd_
byte_order::psdBigEndian>
1411 void writeLsctBlockExImpl(QIODevice &io,
psd_section_type sectionType,
bool isPassThrough,
const QString &blendModeKey);
1413 template<psd_
byte_order
byteOrder = psd_
byte_order::psdBigEndian>
1414 void writeLfx2BlockExImpl(QIODevice &io,
const QDomDocument &stylesXmlDoc,
bool useLfxsLayerStyleFormat);
1416 template<psd_
byte_order
byteOrder = psd_
byte_order::psdBigEndian>
1417 void writePattBlockExImpl(QIODevice &io,
const QDomDocument &patternsXmlDoc);
1419 template<psd_
byte_order
byteOrder = psd_
byte_order::psdBigEndian>
1420 void writeLclrBlockExImpl(QIODevice &io,
const quint16 &lclr);
1422 template<psd_
byte_order
byteOrder = psd_
byte_order::psdBigEndian>
1423 void writeFillLayerBlockExImpl(QIODevice &io,
const QDomDocument &fillConfig,
psd_fill_type type);
1425 template<psd_
byte_order
byteOrder = psd_
byte_order::psdBigEndian>
1428 template<psd_
byte_order
byteOrder = psd_
byte_order::psdBigEndian>
1431 template<psd_
byte_order
byteOrder = psd_
byte_order::psdBigEndian>
1432 void writeVectorStrokeDataImpl(QIODevice &io,
const QDomDocument &vectorStroke);
1434 template<psd_
byte_order
byteOrder = psd_
byte_order::psdBigEndian>
1435 void writeVectorOriginationDataImpl(QIODevice &io,
const QDomDocument &vectorOrigination);
1437 template<psd_
byte_order
byteOrder = psd_
byte_order::psdBigEndian>
1438 void writeTxt2BlockExImpl(QIODevice &io,
const QVariantHash txt2Hash);
const KoID Float32BitsColorDepthID("F32", ki18n("32-bit float/channel"))
const KoID LABAColorModelID("LABA", ki18n("L*a*b*/Alpha"))
void subscribeDouble(const QString &path, ASLCallbackDouble callback)
void subscribeRawData(const QString &path, ASLCallbackRawData callback)
void subscribeEnum(const QString &path, const QString &typeId, ASLCallbackString callback)
void subscribeInteger(const QString &path, ASLCallbackInteger callback)
void subscribeUnitRect(const QString &path, const QString &unit, ASLCallbackRect callback)
void subscribeUnitFloat(const QString &path, const QString &unit, ASLCallbackDouble callback)
void subscribeGradient(const QString &path, ASLCallbackGradient callback)
void subscribeColor(const QString &path, ASLCallbackColor callback)
void subscribePoint(const QString &path, ASLCallbackPoint callback)
void subscribeBoolean(const QString &path, ASLCallbackBoolean callback)
void subscribeTransform(const QString &path, ASLCallbackTransform callback)
void subscribePatternRef(const QString &path, ASLCallbackPatternRef callback)
QVariantHash parseCosToJson(QByteArray *ba)
static QByteArray writeCosFromVariantHash(const QVariantHash doc)
static KisGeneratorRegistry * instance()
static KisResourcesInterfaceSP instance()
A simple solid color shape background.
virtual KoID colorModelId() const =0
void convertTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
const KoColorProfile * profile() const
return the current profile
void setOpacity(quint8 alpha)
KoColor convertedTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
void fromQColor(const QColor &c)
Convenient function for converting from a QColor.
const KoColorSpace * colorSpace() const
return the current colorSpace
void toQColor(QColor *c) const
a convenience method for the above.
void setProfile(const KoColorProfile *profile)
assign new profile without converting pixel data
const T value(const QString &id) const
A gradient shape background.
A pattern shape background.
QImage pattern() const
pattern the actual pattern image
KoResourceSP resource() const noexcept
void toXML(QDomDocument &doc, QDomElement &gradientElt) const
toXML convert the gradient to xml.
static KoSegmentGradient fromXML(const QDomElement &elt)
fromXML get a segment gradient from xml.
QGradient * toQGradient() const override
reimplemented
static QSharedPointer< KoStopGradient > fromQGradient(const QGradient *gradient)
Creates KoStopGradient from a QGradient.
QGradient * toQGradient() const override
reimplemented
void toXML(QDomDocument &doc, QDomElement &gradientElt) const
toXML Convert the gradient to an XML string.
static KoStopGradient fromXML(const QDomElement &elt)
fromXML convert a gradient from xml.
The PsdAdditionalLayerInfoBlock class implements the Additional Layer Information block.
ExtraLayerInfoBlockHandler m_layerInfoBlockHandler
psd_section_type sectionDividerType
const PSDHeader & m_header
QVector< QDomDocument > embeddedPatterns
QDomDocument vectorStroke
UserMaskInfoBlockHandler m_userMaskBlockHandler
QDomDocument vectorOriginationData
QString sectionDividerBlendMode
std::function< bool(QIODevice &)> ExtraLayerInfoBlockHandler
QDomDocument layerStyleXml
psd_vector_mask vectorMask
std::function< bool(QIODevice &)> UserMaskInfoBlockHandler
T kisRadiansToDegrees(T radians)
T kisDegreesToRadians(T degrees)
virtual KisFilterConfigurationSP defaultConfiguration(KisResourcesInterfaceSP resourcesInterface) const
KisResourcesInterfaceSP resourcesInterface()
virtual bool isSuitableForOutput() const =0
static KoColorSpaceRegistry * instance()
void setType(const QString type)
bool loadFromConfig(KisFilterConfigurationSP cfg)
void setAlignWithLayer(bool align)
void setAngle(float Angl)
void setReverse(bool Rvrs)
QGradient * getGradient()
void setDither(bool Dthr)
void setFromQGradient(const QGradient *gradient)
void setGradient(const KoAbstractGradientSP &newGradient)
void setOffset(QPointF Ofst)
static void setupCatcher(const QString path, KisAslCallbackObjectCatcher &catcher, psd_layer_gradient_fill *data)
QDomDocument getFillLayerConfig()
QSharedPointer< KoShapeBackground > getBackground()
void writeASL(KisAslXmlWriter &w)
void setOffset(QPointF phase)
QSharedPointer< KoShapeBackground > getBackground(KisEmbeddedResourceStorageProxy &embeddedProxy)
void setAngle(float Angl)
static void setupCatcher(const QString path, KisAslCallbackObjectCatcher &catcher, psd_layer_pattern_fill *data)
void setPatternRef(const QString Idnt, const QString name)
bool loadFromConfig(KisFilterConfigurationSP cfg)
QBrush getBrush(KisEmbeddedResourceStorageProxy &embeddedProxy)
void setAlignWithLayer(bool align)
void loadPattern(KisEmbeddedResourceStorageProxy &embeddedProxy)
QDomDocument getFillLayerConfig() const
void writeASL(KisAslXmlWriter &w)
QSharedPointer< KoShapeBackground > getBackground()
static void setupCatcher(const QString path, KisAslCallbackObjectCatcher &catcher, psd_layer_solid_color *data)
void writeASL(KisAslXmlWriter &w)
void setColor(const KoColor &color)
QDomDocument getFillLayerConfig()
bool loadFromConfig(KisFilterConfigurationSP cfg)
QDomDocument textWarpXML()
void setBottom(float val)
void setEngineData(QByteArray ba)
static void setupCatcher(const QString path, KisAslCallbackObjectCatcher &catcher, psd_layer_type_shape *data)
void setWritingMode(const QString val)
QDomDocument textDataASLXML()
QList< psd_path_node > nodes
QList< psd_path_sub_path > subPaths
double clipBoardResolution
void setOriginPolyTrueRectCorners(QPointF p)
void setOriginType(int type)
QPolygonF originPolyTrueRectCorners
Only 7 an 8, same as originBoxCorners.
QRectF originShapeBBox
pre-transform bbox.
void setOriginResolution(double res)
double originPolyPixelHSF
Only 7 and 8, no clue.
void setTransform(QTransform t)
void setOriginShapeBBox(QRectF ShapeBBox)
static void setupCatcher(const QString path, KisAslCallbackObjectCatcher &catcher, psd_vector_origination_data *data)
int originType
1 = rect, 2 = rounded rect?, 3 = ? 4 = ? 5 = ellipse, 6 = ?, 7 = polygon, 8 = star,...
void setOriginBoxCorners(QPointF p)
void setOriginPolySides(int sides)
double originResolution
Resolution of the coordinates.
int originPolySides
Only for 7 and 8.
void OriginalSizeAndAngle(QSizeF &size, double &angle)
bool canMakeParametricShape()
QPolygonF originPolyPreviousTightBoxCorners
Only 7 an 8, same as originBoxCorners.
QPolygonF originBoxCorners
post-transform bbox as a polygon, seen on 1, 7, 8 and 9.
double originPolyStarRatio
Only for 8, percentage of small radius to big radius.
const QMap< int, QString > typeToName
void setOriginPolyTightBoxCorners(QPointF p)
void setOriginPolyStarRatio(double ratio)
void appendToDashPattern(double val)
void setFillEnabled(bool enabled)
void setResolution(double res)
void setLineJoinType(const QString val)
void setStrokeEnabled(bool enabled)
void setScaleLock(bool enabled)
void loadFromShapeStroke(KoShapeStrokeSP stroke)
void setStrokePixel(double width)
void setStrokeWidth(double width)
static void setupCatcher(const QString path, KisAslCallbackObjectCatcher &catcher, psd_vector_stroke_data *data)
void setOpacityFromPercentage(double o)
void setStrokeDashOffset(double dashOffset)
void setupShapeStroke(KoShapeStrokeSP stroke)
void setLineCapType(const QString val)
QVector< double > dashPattern
void setStrokeMiterLimit(double limit)
void setStrokeAdjust(bool enabled)
void setVersion(int version)