Krita Source Code Documentation
Loading...
Searching...
No Matches
KisTxt2Utils Class Reference

The KisTxt2Utils class. More...

#include <kis_txt2_utls.h>

Static Public Member Functions

static QVariantHash defaultTxt2 ()
 defaultTxt2 Generate a default txt2 varianthash. This includes stuff like Kinsoku sets default fonts and other things that might be expected but Krita doesn't write itself.
 
static QVariantHash tyShFromTxt2 (const QVariantHash Txt2, const QRectF boundsInPx, int textIndex)
 tyShFromTxt2 Txt2 is more or less a superset of tySh, so this function allows generating the tySh data from a Txt2 hash.
 
static QVariantHash uncompressKeys (QVariantHash doc)
 uncompressKeys One of the problems with the Txt2 block is that older versions of photoshop (cs2-cs3 era) stored the dictionary keys as names, while new versions stores it as numbers. This function translates the numbers to the names.
 

Detailed Description

The KisTxt2Utils class.

Utils for handling text engine data inside the Txt2 additional info block. This is a global section info block, which contains more extensive data to the TySh additional info block.

Definition at line 20 of file kis_txt2_utls.h.

Member Function Documentation

◆ defaultTxt2()

QVariantHash KisTxt2Utils::defaultTxt2 ( )
static

defaultTxt2 Generate a default txt2 varianthash. This includes stuff like Kinsoku sets default fonts and other things that might be expected but Krita doesn't write itself.

Returns
a default txt2 hash.

Definition at line 1103 of file kis_txt2_utls.cpp.

1104{
1105 QVariantHash doc;
1106
1107 QVariantHash documentResources;
1108 QVariantHash documentObjects;
1109
1110 QVariantHash fontSet;
1111 QVariantList fontResources;
1112
1113 QVariantHash fontInvis {
1114 {"/Name", "AdobeInvisFont"},
1115 {"/Type", 0}
1116 };
1117
1118 QVariantHash fontMyriad {
1119 {"/Name", "MyriadPro-Regular"},
1120 {"/Type", 0},
1121 {"/Version", "Version 2.115;PS 2.000;hotconv 1.0.81;makeotf.lib2.5.63406"}
1122 };
1123 QVariantHash fR = {
1124 {"/Resource", QVariantHash({{"/Identifier", fontMyriad}, {"/StreamTag", "/CoolTypeFont"}})}
1125 };
1126 fontResources.append(fR);
1127 fR = {
1128 {"/Resource", QVariantHash({{"/Identifier", fontInvis}, {"/StreamTag", "/CoolTypeFont"}})}
1129 };
1130 fontResources.append(fR);
1131
1132 fontSet.insert("/Resources", fontResources);
1133 documentResources.insert("/FontSet", fontSet);
1134 QVariantHash kinsokuSet;
1135 QVariantList kinsokuResources;
1136 QVariantList kinsokuDisplay;
1137 QVariantHash kin = QVariantHash ({{"/Resource", QVariantHash({ {"/Name", "None"}, {"/Data", kinsokuNone}})}});
1138 kinsokuResources.append(kin);
1139 kinsokuDisplay.append(QVariantHash({{"/Resource", 0}}));
1140 kin = QVariantHash ({{"/Resource", QVariantHash({ {"/Name", "PhotoshopKinsokuHard"}, {"/Data", kinsokuHard}})}});
1141 kinsokuResources.append(kin);
1142 kinsokuDisplay.append(QVariantHash({{"/Resource", 1}}));
1143 kin = QVariantHash ({{"/Resource", QVariantHash({ {"/Name", "PhotoshopKinsokuSoft"}, {"/Data", kinsokuSoft}})}});
1144 kinsokuResources.append(kin);
1145 kinsokuDisplay.append(QVariantHash({{"/Resource", 2}}));
1146 kin = QVariantHash ({{"/Resource", QVariantHash({ {"/Name", "Hard"}, {"/Data", kinsokuHard}})}});
1147 kinsokuResources.append(kin);
1148 kinsokuDisplay.append(QVariantHash({{"/Resource", 3}}));
1149 kin = QVariantHash ({{"/Resource", QVariantHash({ {"/Name", "Soft"}, {"/Data", kinsokuSoft}})}});
1150 kinsokuResources.append(kin);
1151 kinsokuDisplay.append(QVariantHash({{"/Resource", 4}}));
1152 kinsokuSet.insert("/Resources", kinsokuResources);
1153 kinsokuSet.insert("/DisplayList", kinsokuDisplay);
1154 documentResources.insert("/KinsokuSet", kinsokuSet);
1155
1156 //QVariantHash listStyleSet;
1157 //documentResources.insert("/ListStyleSet", listStyleSet);
1158 QVariantHash mojiKumiCodeToClassSet = {
1159 {"/Resources", QVariantList({
1160 QVariantHash({
1161 {"/Resource", QVariantHash({
1162 {"/Name", ""}
1163 })
1164 }
1165 })
1166 })},
1167 {"/DisplayList", QVariantList({QVariantHash({{"/Resource", 0}})})}
1168 };
1169 documentResources.insert("/MojiKumiCodeToClassSet", mojiKumiCodeToClassSet);
1170
1171 QHash<QString, int> mojilist {
1172 {"Photoshop6MojiKumiSet4", 2},
1173 {"Photoshop6MojiKumiSet3", 4},
1174 {"Photoshop6MojiKumiSet2", 3},
1175 {"Photoshop6MojiKumiSet1", 1},
1176 {"YakumonoHankaku", 1},
1177 {"GyomatsuYakumonoHankaku", 3},
1178 {"GyomatsuYakumonoZenkaku", 4},
1179 {"YakumonoZenkaku", 2},
1180 };
1181
1182 QVariantHash mojiKumiTableSet;
1183
1184 QVariantList mojiResources;
1185 QVariantList mojiDisplay;
1186
1187 Q_FOREACH(const QString key, mojilist.keys()) {
1188 mojiDisplay.append(QVariantHash({{"/Resource", mojiDisplay.size()}}));
1189 QVariantHash mojikumiTable = {
1190 {"/Name", key},
1191 {"/Members", QVariantHash({
1192 {"/CodeToClass", 0},
1193 {"/PredefinedTag", mojilist.value(key)}
1194
1195 })
1196 },
1197 };
1198
1199 mojiResources.append(mojikumiTable);
1200 }
1201
1202 mojiKumiTableSet.insert("/Resources", mojiResources);
1203 mojiKumiTableSet.insert("/DisplayList", mojiDisplay);
1204 documentResources.insert("/MojiKumiTableSet", mojiKumiTableSet);
1205
1206 QVariantHash paragraphSheetSet = {
1207 {"/Resources", QVariantList({
1208 QVariantHash({
1209 {"/Resource", QVariantHash({
1210 {"/Name", "Normal RGB"},
1211 {"/Features", defaultParagraph}
1212 })
1213 }
1214 })
1215 })},
1216 {"/DisplayList", QVariantList({QVariantHash({{"/Resource", 0}})})}
1217 };
1218 documentResources.insert("/ParagraphSheetSet", paragraphSheetSet);
1219 QVariantHash styleSheetSet = {
1220 {"/Resources", QVariantList({
1221 QVariantHash({
1222 {"/Resource", QVariantHash({
1223 {"/Name", "Normal RGB"},
1224 {"/Features", defaultStyle}
1225 })
1226 }
1227 })
1228 })},
1229 {"/DisplayList", QVariantList({QVariantHash({{"/Resource", 0}})})}
1230 };
1231 documentResources.insert("/StyleSheetSet", styleSheetSet);
1232
1233 QVariantHash textFrameSet;
1234 textFrameSet.insert("/Resources", QVariantList());
1235 documentResources.insert("/TextFrameSet", textFrameSet);
1236
1237 // Document settings ----------
1238 QVariantHash DocumentSettings;
1239 DocumentSettings.insert("/DefaultStoryDir", 0);
1240 // smart quote?
1241 // alternate glyph?
1242 DocumentSettings.insert("/SubscriptPosition", 0.333);
1243 DocumentSettings.insert("/SubscriptSize", 0.583);
1244 DocumentSettings.insert("/SuperscriptPosition", 0.333);
1245 DocumentSettings.insert("/SuperscriptSize", 0.583);
1246 DocumentSettings.insert("/SmallCapSize", 0.7);
1247 DocumentSettings.insert("/NormalParagraphSheet", 0);
1248 DocumentSettings.insert("/NormalStyleSheet", 0);
1249 documentObjects.insert("/DocumentSettings", DocumentSettings);
1250 QVariantHash OriginalNormalParagraphFeatures = defaultParagraph;
1251 documentObjects.insert("/OriginalNormalParagraphFeatures", OriginalNormalParagraphFeatures);
1252 QVariantHash OriginalNormalStyleFeatures = defaultStyle;
1253 documentObjects.insert("/OriginalNormalStyleFeatures", OriginalNormalStyleFeatures);
1254 QVariantList TextObjects;
1255 documentObjects.insert("/TextObjects", TextObjects);
1256
1257 doc.insert("/DocumentResources", documentResources);
1258 doc.insert("/DocumentObjects", documentObjects);
1259 return doc;
1260}
static QVariantHash kinsokuHard
static QVariantHash defaultParagraph
static QVariantHash kinsokuSoft
static QVariantHash defaultStyle
static QVariantHash kinsokuNone

References defaultParagraph, defaultStyle, kinsokuHard, kinsokuNone, and kinsokuSoft.

◆ tyShFromTxt2()

QVariantHash KisTxt2Utils::tyShFromTxt2 ( const QVariantHash Txt2,
const QRectF boundsInPx,
int textIndex )
static

tyShFromTxt2 Txt2 is more or less a superset of tySh, so this function allows generating the tySh data from a Txt2 hash.

Parameters
Txt2the global txt2 hash.
textIndexthe text object index for which to generate the tySh data.
Returns
the tySh variantHash

Definition at line 1367 of file kis_txt2_utls.cpp.

1368{
1369 QVariantHash tySh;
1370
1371 const QVariantHash documentObjects = Txt2.value("/DocumentObjects").toHash();
1372 const QVariantList textObjects = documentObjects.value("/TextObjects").toList();
1373 QVariantHash textObject;
1374 if (textIndex < textObjects.size()) {
1375 textObject = textObjects.value(textIndex).toHash();
1376 }
1377
1378
1379 const QVariantHash model = textObject.value("/Model").toHash();
1380 const QVariantHash view = textObject.value("/View").toHash();
1381
1382 const QVariantHash documentResources = Txt2.value("/DocumentResources").toHash();
1383 const QVariantList textFrames = documentResources.value("/TextFrameSet").toHash().value("/Resources").toList();
1384
1385 QVariantHash engineDict;
1386
1387 QVariantHash editor;
1388 editor.insert("/Text", model.value("/Text"));
1389 engineDict.insert("/Editor", editor);
1390
1391
1392 engineDict.insert("/GridInfo", defaultGrid);
1393
1394 // paragraph
1395 const QVariantHash para = model.value("/ParagraphRun").toHash();
1396 const QVariantList paraRunArray = para.value("/RunArray").toList();
1397 // if we want to go over each entry, here's the moment to do so.
1398 const int length = paraRunArray.value(0).toHash().value("/Length").toInt();
1399 const QVariantHash paraSheet = paraRunArray.value(0).toHash().value("/RunData").toHash()["/ParagraphSheet"].toHash();
1400 const QVariantHash paragraphStyle = simplifyParagraphSheet(paraSheet.value("/Features").toHash());
1401 QVariantHash paragraphRun;
1402 paragraphRun["/RunLengthArray"] = QVariantList({QVariant(length)});
1403 QVariantHash paragraphAdjustments = QVariantHash {
1404 {"/Axis", QVariantList({1.0, 0.0, 1.0})},
1405 {"/XY", QVariantList({0.0, 0.0})}
1406 };
1407 paragraphRun["/RunArray"] = QVariantList({ QVariantHash{
1408 {"/ParagraphSheet", paragraphStyle},
1409 {"/Adjustments", paragraphAdjustments}
1410 }
1411 });
1412 paragraphRun.insert("/IsJoinable", 1); //no idea what this means.
1413 paragraphRun.insert("/DefaultRunData", QVariantHash{
1414 {"/ParagraphSheet",
1415 QVariantHash{{"/DefaultStyleSheet", 0},
1416 {"/Properties", QVariantHash()}} },
1417 {"/Adjustments", paragraphAdjustments}});
1418
1419 engineDict.insert("/ParagraphRun", paragraphRun);
1420
1421 const QVariantHash txt2StyleRun = model.value("/StyleRun").toHash();
1422 const QVariantList txt2RunArray = txt2StyleRun.value("/RunArray").toList();
1423 QVariantHash styleRun;
1424
1425 QVariantList properStyleRun;
1426 QVariantList styleRunArray;
1427 Q_FOREACH(const QVariant entry, txt2RunArray) {
1428 QVariantHash properStyle;
1429 const QVariantHash fea = entry.toHash().value("/RunData").toHash().value("/StyleSheet").toHash().value("/Features").toHash();
1430 properStyle.insert("/StyleSheetData", simplifyStyleSheet(fea));
1431 QVariantHash s;
1432 s.insert("/StyleSheet", properStyle);
1433 properStyleRun.append(s);
1434 styleRunArray.append(entry.toHash().value("/Length").toInt());
1435 }
1436 styleRun.insert("/RunArray", properStyleRun);
1437 styleRun.insert("/RunLengthArray", styleRunArray);
1438 styleRun.insert("/IsJoinable", 2);
1439
1440 styleRun.insert("/DefaultRunData", QVariantHash{{"/StyleSheet", QVariantHash{{"/StyleSheetData", QVariantHash()}} }});
1441 engineDict.insert("/StyleRun", styleRun);
1442 // rendered data...
1443
1444 const int frameIndex = view.value("/Frames").toList().value(0).toHash().value("/Resource").toInt();
1445 const QVariantHash textFrame = textFrames.value(frameIndex).toHash().value("/Resource").toHash();
1446 const QVariantHash textFrameData = textFrame.value("/Data").toHash();
1447 QVariantHash rendered;
1448 int shapeType = textFrameData.value("/Type", QVariant(0)).toInt(); // 0 point, 1 paragraph, 2, text on path
1449 int writingDirection = textFrameData.value("/LineOrientation", QVariant(0)).toInt();
1450 QVariantHash photoshop = QVariantHash {{"/ShapeType", qMax(1, shapeType)},
1451 {"/TransformPoint0", QVariantList({1.0, 0.0})},
1452 {"/TransformPoint1", QVariantList({0.0, 1.0})},
1453 {"/TransformPoint2", QVariantList({0.0, 0.0})}};
1454 if (shapeType == 0) {
1455 photoshop["/PointBase"] = QVariantList({0.0, 0.0});
1456 } else if (shapeType == 1) {
1457 // this is the bounding box of the paragraph shape.
1458 photoshop["/BoxBounds"] = QVariantList({0.0, 0.0, boundsInPx.width(), boundsInPx.height()});
1459 }
1460 QVariantHash renderChild = QVariantHash{
1461 {"/ShapeType", shapeType},
1462 {"/Procession", 0},
1463 {"/Lines", QVariantHash{{"/WritingDirection", writingDirection}, {"/Children", QVariantList()}}},
1464 {"/Cookie", QVariantHash{{"/Photoshop", photoshop}}}};
1465 rendered["/Version"] = 1;
1466 rendered["/Shapes"] = QVariantHash{{"/WritingDirection", writingDirection}, {"/Children", QVariantList({renderChild})}};
1467
1468 engineDict.insert("/Rendered", rendered);
1469
1470 // storysheet
1471 const QVariantHash storySheet = textObject.value("/StorySheet").toHash();
1472 engineDict.insert("/UseFractionalGlyphWidths", storySheet.value("/UseFractionalGlyphWidths", QVariant(true)).toBool());
1473 engineDict.insert("/AntiAlias", storySheet.value("/AntiAlias", QVariant(1)).toInt());
1474
1475 QVariantHash resourceDict;
1476
1477 const QVariantList docFontSet = documentResources.value("/FontSet").toHash().value("/Resources").toList();
1478 QVariantList fontSet;
1479 Q_FOREACH(QVariant entry, docFontSet) {
1480 const QVariantHash docFont = entry.toHash().value("/Resource").toHash();
1481 QVariantHash font = docFont.value("/Identifier").toHash();
1482 font.insert("/FontType", font.value("/Type"));
1483 font.remove("/Version");
1484 font.remove("/Type");
1485 font.insert("/Script", 0);
1486 font.insert("/Synthetic", 0);
1487 fontSet.append(font);
1488 }
1489 resourceDict.insert("/FontSet", fontSet);
1490
1491 const QVariantHash documentSettings = documentObjects.value("/DocumentSettings").toHash();
1492
1493 QVariantHash kinHard = kinsokuHard;
1494 kinHard.remove("/PredefinedTag");
1495 kinHard.insert("/Name", "PhotoshopKinsokuHard");
1496 QVariantHash kinSoft = kinsokuSoft;
1497 kinSoft.remove("/PredefinedTag");
1498 kinSoft.insert("/Name", "PhotoshopKinsokuSoft");
1499 resourceDict.insert("/KinsokuSet", QVariantList({kinHard, kinSoft}));
1500 resourceDict.insert("/MojiKumiSet", QVariantList( {QVariantHash{{"/InternalName", "Photoshop6MojiKumiSet1"}},
1501 QVariantHash{{"/InternalName", "Photoshop6MojiKumiSet2"}},
1502 QVariantHash{{"/InternalName", "Photoshop6MojiKumiSet3"}},
1503 QVariantHash{{"/InternalName", "Photoshop6MojiKumiSet4"}}
1504 }));
1505 resourceDict.insert("/SubscriptPosition", documentSettings.value("/SubscriptPosition"));
1506 resourceDict.insert("/SubscriptSize", documentSettings.value("/SubscriptSize"));
1507 resourceDict.insert("/SuperscriptPosition", documentSettings.value("/SuperscriptPosition"));
1508 resourceDict.insert("/SuperscriptSize", documentSettings.value("/SuperscriptSize"));
1509 resourceDict.insert("/SmallCapSize", documentSettings.value("/SmallCapSize"));
1510 resourceDict.insert("/TheNormalParagraphSheet", documentSettings.value("/NormalParagraphSheet"));
1511 resourceDict.insert("/TheNormalStyleSheet", documentSettings.value("/NormalStyleSheet"));
1512
1513 const QVariantList docStyleSheetSets = documentResources.value("/StyleSheetSet").toHash().value("/Resources").toList();
1514 QVariantList resourceStyleSheetList;
1515 Q_FOREACH(QVariant entry, docStyleSheetSets) {
1516 const QVariantHash styleSheet = entry.toHash().value("/Resource").toHash();
1517 QVariantHash newSheet;
1518 newSheet.insert("/Name", styleSheet.value("/Name"));
1519 newSheet.insert("/StyleSheetData", simplifyStyleSheet(styleSheet.value("/Features").toHash()));
1520 resourceStyleSheetList.append(newSheet);
1521 }
1522
1523 const QVariantList docParagraphSheetSets = documentResources.value("/ParagraphSheetSet").toHash().value("/Resources").toList();
1524 QVariantList resourceParagraphSheetList;
1525 Q_FOREACH(QVariant entry, docParagraphSheetSets) {
1526 const QVariantHash styleSheet = entry.toHash().value("/Resource").toHash();
1527 QVariantHash newSheet;
1528 newSheet.insert("/Name", styleSheet.value("/Name"));
1529 newSheet.insert("/Properties", simplifyParagraphSheet(styleSheet.value("/Features").toHash()));
1530 newSheet.insert("/DefaultStyleSheet", 0);
1531 resourceParagraphSheetList.append(newSheet);
1532 }
1533
1534 resourceDict.insert("/StyleSheetSet", resourceStyleSheetList);
1535 resourceDict.insert("/ParagraphSheetSet", resourceParagraphSheetList);
1536
1537 tySh.insert("/EngineDict", engineDict);
1538 tySh.insert("/DocumentResources", resourceDict);
1539 tySh.insert("/ResourceDict", resourceDict);
1540 return tySh;
1541}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
QVariantHash defaultGrid
static QVariantHash simplifyParagraphSheet(const QVariantHash complex)
static QVariantHash simplifyStyleSheet(const QVariantHash complex)
int toInt(const QString &str, bool *ok=nullptr)

References defaultGrid, kinsokuHard, kinsokuSoft, length(), simplifyParagraphSheet(), and simplifyStyleSheet().

◆ uncompressKeys()

QVariantHash KisTxt2Utils::uncompressKeys ( QVariantHash doc)
static

uncompressKeys One of the problems with the Txt2 block is that older versions of photoshop (cs2-cs3 era) stored the dictionary keys as names, while new versions stores it as numbers. This function translates the numbers to the names.

Thankfully the inkscape devs had already figured out the numbers and their keys, so special thanks to them for documenting that:

https://gitlab.com/inkscape/extras/extension-ai/-/blob/main/ docs/specification_amendments/text_documents.md?ref_type=heads

Parameters
docinput txt2 doc.
Returns
documented with keys translated to names.

Definition at line 887 of file kis_txt2_utls.cpp.

888{
889
890 QVariantHash newDoc;
891 Q_FOREACH(QString key, doc.keys()) {
892 if (key == "/0") {
893 newDoc.insert("/DocumentResources", uncompressKeysDocumentResources(doc.value(key).toHash()));
894 } else if (key == "/1") {
895 newDoc.insert("/DocumentObjects", uncompressKeysDocumentObjects(doc.value(key).toHash()));
896 } else {
897 newDoc.insert(key, doc.value(key));
898 }
899 }
900 return newDoc;
901}
QVariantHash uncompressKeysDocumentObjects(const QVariantHash object)
QVariantHash uncompressKeysDocumentResources(const QVariantHash object)

References uncompressKeysDocumentObjects(), and uncompressKeysDocumentResources().


The documentation for this class was generated from the following files: