Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_txt2_utls.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2023 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#include "kis_txt2_utls.h"
8#include <QVariantHash>
9#include <QVariant>
10#include <QVariantList>
11#include <QDebug>
12#include <QRectF>
13
14QVariantHash uncompressColor(const QVariantHash object) {
15 QVariantHash newObject;
16 Q_FOREACH(QString key, object.keys()) {
17 QVariant val = object.value(key);
18 if (key == "/0") {
19 QVariantHash color = val.toHash();
20 QVariantHash newColor;
21 Q_FOREACH(QString key, color.keys()) {
22 if (key == "/1") {
23 newColor.insert("/Values", color.value(key));
24 } else if (key == "/0") {
25 newColor.insert("/Type", color.value(key));
26 } else {
27 newColor.insert(key, color.value(key));
28 }
29 }
30 newObject.insert("/Color", newColor);
31 } else if (key == "/99") {
32 newObject.insert("/StreamTag", val);
33 } else {
34 newObject.insert(key, val);
35 }
36 }
37 return newObject;
38}
39
40QVariantHash uncompressStyleSheetFeatures(const QVariantHash object) {
41 QVariantHash newObject;
42
43 const QMap<QString, QString> keyList{
44 {"/0", "/Font"},
45 {"/1", "/FontSize"},
46 {"/2", "/FauxBold"},
47 {"/3", "/FauxItalic"},
48 {"/4", "/AutoLeading"},
49
50 {"/5", "/Leading"},
51 {"/6", "/HorizontalScale"},
52 {"/7", "/VerticalScale"},
53 {"/8", "/Tracking"},
54 {"/9", "/BaselineShift"},
55
56 {"/10", "/CharacterRotation"},
57 {"/11", "/AutoKern"},
58 {"/12", "/FontCaps"},
59 {"/13", "/FontBaseline"},
60 {"/14", "/FontOTPosition"},
61
62 {"/15", "/StrikethroughPosition"},
63 {"/16", "/UnderlinePosition"},
64 {"/17", "/UnderlineOffset"},
65 {"/18", "/Ligatures"},
66 {"/19", "/DiscretionaryLigatures"},
67
68 {"/20", "/ContextualLigatures"},
69 {"/21", "/AlternateLigatures"},
70 {"/22", "/OldStyle"},
71 {"/23", "/Fractions"},
72 {"/24", "/Ordinals"},
73
74 {"/25", "/Swash"},
75 {"/26", "/Titling"},
76 {"/27", "/ConnectionForms"},
77 {"/28", "/StylisticAlternates"},
78 {"/29", "/Ornaments"},
79
80 {"/30", "/FigureStyle"},
81 {"/31", "/ProportionalMetrics"},
82 {"/32", "/Kana"},
83 {"/33", "/Italics"},
84 {"/34", "/Ruby"},
85
86 {"/35", "/BaselineDirection"},
87 {"/36", "/Tsume"},
88 {"/37", "/StyleRunAlignment"},
89 {"/38", "/Language"},
90 {"/39", "/JapaneseAlternateFeature"},
91
92 {"/40", "/EnableWariChu"},
93 {"/41", "/WariChuLineCount"},
94 {"/42", "/WariChuLineGap"},
95 {"/43", "/WariChuSubLineAmount"},
96 {"/44", "/WariChuWidowAmount"},
97
98 {"/45", "/WariChuOrphanAmount"},
99 {"/46", "/WariChuJustification"},
100 {"/47", "/TCYUpDownAdjustment"},
101 {"/48", "/TCYLeftRightAdjustment"},
102 {"/49", "/LeftAki"},
103
104 {"/50", "/RightAki"},
105 {"/51", "/JiDori"},
106 {"/52", "/NoBreak"},
107 //{"/53", "/FillColor"},
108 //{"/54", "/StrokeColor"},
109
110 {"/55", "/Blend"},
111 {"/56", "/FillFlag"},
112 {"/57", "/StrokeFlag"},
113 {"/58", "/FillFirst"},
114 {"/59", "/FillOverPrint"},
115
116 {"/60", "/StrokeOverPrint"},
117 {"/61", "/LineCap"},
118 {"/62", "/LineJoin"},
119 {"/63", "/LineWidth"},
120 {"/64", "/MiterLimit"},
121
122 {"/65", "/LineDashOffset"},
123 {"/66", "/LineDashArray"},
124 {"/67", "/Type"},
125 {"/68", "/Kashidas"},
126 {"/69", "/DirOverride"},
127
128 {"/70", "/DigitSet"},
129 {"/71", "/DiacVPos"},
130 {"/72", "/DiacXOffset"},
131 {"/73", "/DiacYOffset"},
132 {"/74", "/OverlapSwash"},
133
134 {"/75", "/JustificationAlternates"},
135 {"/76", "/StretchedAlternates"},
136 {"/77", "/FillVisibleFlag"},
137 {"/78", "/StrokeVisibleFlag"},
138 //{"/79", "/FillBackgroundColor"},
139
140 {"/80", "/FillBackgroundFlag"},
141 {"/81", "/UnderlineStyle"},
142 {"/82", "/DashedUnderlineGapLength"},
143 {"/83", "/DashedUnderlineDashLength"},
144 {"/84", "/SlashedZero"},
145
146 {"/85", "/StylisticSets"},
147 {"/86", "/CustomFeature"},
148 {"/87", "/MarkYDistFromBaseline"},
149 {"/88", "/AutoMydfb"},
150 {"/89", "/RefFontSize"},
151
152 {"/90", "/FontSizeRefType"},
153 {"/92", "/MagicLineGap"},
154 {"/92", "/MagicWordGap"},
155 };
156
157 Q_FOREACH(QString key, object.keys()) {
158 QVariant val = object.value(key);
159 if (key == "/53") {
160 newObject.insert("/FillColor", uncompressColor(val.toHash()));
161 } else if (key == "/54") {
162 newObject.insert("/StrokeColor", uncompressColor(val.toHash()));
163 } else if (key == "/79") {
164 newObject.insert("/FillBackgroundColor", uncompressColor(val.toHash()));
165 } else if (keyList.keys().contains(key)) {
166 newObject.insert(keyList.value(key), val);
167 } else {
168 newObject.insert(key, val);
169 }
170 }
171 return newObject;
172}
173
174QVariantHash uncompressParagraphSheetFeatures(const QVariantHash object) {
175 QVariantHash newObject;
176
177 const QMap<QString, QString> keyList{
178 {"/0", "/Justification"},
179 {"/1", "/FirstLineIndent"},
180 {"/2", "/StartIndent"},
181 {"/3", "/EndIndent"},
182 {"/4", "/SpaceBefore"},
183
184 {"/5", "/SpaceAfter"},
185 {"/6", "/DropCaps"},
186 {"/7", "/AutoLeading"},
187 {"/8", "/LeadingType"},
188 {"/9", "/AutoHyphenate"},
189
190 {"/10", "/HyphenatedWordSize"},
191 {"/11", "/PreHyphen"},
192 {"/12", "/PostHyphen"},
193 {"/13", "/ConsecutiveHyphens"},
194 {"/14", "/Zone"},
195
196 {"/15", "/HyphenateCapitalized"},
197 {"/16", "/HyphenationPreference"},
198 {"/17", "/WordSpacing"},
199 {"/18", "/LetterSpacing"},
200 {"/19", "/GlyphSpacing"},
201
202 {"/20", "/SingleWordJustification"},
203 {"/21", "/Hanging"},
204 {"/22", "/AutoTCY"},
205 {"/23", "/KeepTogether"},
206 {"/24", "/BurasagariType"},
207
208 {"/25", "/KinsokuOrder"},
209 {"/26", "/KurikaeshiMojiShori"},
210 {"/27", "/Kinsoku"},
211 {"/28", "/MojiKumiTable"},
212 {"/29", "/EveryLineComposer"},
213
214 {"/30", "/TabStops"},
215 {"/31", "/DefaultTabWidth"},
216 //{"/32", "/DefaultStyle"},
217 {"/33", "/ParagraphDirection"},
218 {"/34", "/JustificationMethod"},
219
220 {"/35", "/ComposerEngine"},
221 {"/36", "/ListStyle"},
222 {"/37", "/ListTier"},
223 {"/38", "/ListSkip"},
224 {"/39", "/ListOffset"},
225
226 {"/40", "/KashidaWidth"}
227 };
228
229 Q_FOREACH(QString key, object.keys()) {
230 QVariant val = object.value(key);
231 if (key == "/32") {
232 newObject.insert("/DefaultStyle", uncompressStyleSheetFeatures(val.toHash()));
233 } else if (keyList.keys().contains(key)) {
234 newObject.insert(keyList.value(key), val);
235 } else {
236 newObject.insert(key, val);
237 }
238 }
239 return newObject;
240}
241
242QVariantHash uncompressKeysStyleSheetSet(const QVariantHash object) {
243 QVariantHash newObject;
244
245 QVariantList resources = object.value("/0").toList();
246 QVariantList newResources;
247
248 Q_FOREACH(QVariant val, resources) {
249 QVariantHash resource = val.toHash().value("/0").toHash();
250 QVariantHash newResource;
251 Q_FOREACH(QString key, resource.keys()) {
252 QMap<QString, QString> keyList {{"/0", "/Name"}, {"/5", "/Parent"}, {"/97", "/UUID"}};
253 QVariant rdVal = resource.value(key);
254 if (key == "/6") {
255 newResource.insert("/Features", uncompressStyleSheetFeatures(rdVal.toHash()));
256 } else if (keyList.keys().contains(key)) {
257 newResource.insert(keyList.value(key), rdVal);
258 } else {
259 newResource.insert(key, rdVal);
260 }
261 }
262
263 newResources.append(QVariantHash({{"/Resource", newResource}}));
264 }
265 newObject.insert("/Resources", newResources);
266 return newObject;
267}
268
269QVariantHash uncompressKeysParagraphSheetSet(const QVariantHash object) {
270 QVariantHash newObject;
271 QVariantList resources = object.value("/0").toList();
272 QVariantList newResources;
273
274 const QMap<QString, QString> keyList {{"/0", "/Name"}, {"/6", "/Parent"}, {"/97", "/UUID"}};
275
276 Q_FOREACH(QVariant val, resources) {
277 QVariantHash resource = val.toHash().value("/0").toHash();
278 QVariantHash newResource;
279 Q_FOREACH(QString key, resource.keys()) {
280 QVariant rdVal = resource.value(key);
281 if (key == "/5") {
282 newResource.insert("/Features", uncompressParagraphSheetFeatures(rdVal.toHash()));
283 } else if (keyList.keys().contains(key)) {
284 newResource.insert(keyList.value(key), rdVal);
285 } else {
286 newResource.insert(key, rdVal);
287 }
288 }
289
290 newResources.append(QVariantHash({{"/Resource", newResource}}));
291 }
292 newObject.insert("/Resources", newResources);
293 return newObject;
294}
295
296QVariantHash uncompressTextFrameData(const QVariantHash object) {
297 QVariantHash newObject;
298 const QMap<QString, QString> keyList {
299 {"/0", "/Type"},
300 {"/1", "/LineOrientation"},
301 {"/2", "/FrameMatrix"},
302 {"/3", "/RowCount"},
303 {"/4", "/ColumnCount"},
304
305 {"/5", "/RowMajorOrder"},
306 {"/6", "/TextOnPathTRange"},
307 {"/7", "/RowGutter"},
308 {"/8", "/ColumnGutter"},
309 {"/9", "/Spacing"},
310
311 {"/10", "/FirstBaseAlignment"},
312 // {"/11", "/PathData"},
313 //{"/12", ""},
314 {"/13", "/_VerticalAlignment"},
315 };
316
317 const QMap<QString, QString> pathDataList {
318 {"/0", "/Flip"},
319 {"/1", "/Effect"},
320 {"/2", "/Alignment"},
321 {"/4", "/_Spacing"},
322 {"/18", "/_Spacing2"},
323 };
324
325 Q_FOREACH(QString key, object.keys()) {
326 QVariant val = object.value(key);
327 if (key == "/11") {
328 QVariantHash data = val.toHash();
329 QVariantHash newData;
330 Q_FOREACH(QString key2, data.keys()) {
331 if (pathDataList.keys().contains(key2)) {
332 newData.insert(pathDataList.value(key2), data.value(key2));
333 } else {
334 newData.insert(key2, data.value(key2));
335 }
336 }
337 newObject.insert("/PathData", newData);
338 } else if (keyList.keys().contains(key)) {
339 newObject.insert(keyList.value(key), val);
340 } else {
341 newObject.insert(key, val);
342 }
343 }
344 return newObject;
345}
346
347QVariantHash uncompressKeysTextFrameSet(const QVariantHash object) {
348 QVariantHash newObject;
349
350 QVariantList resources = object.value("/0").toList();
351 QVariantList newResources;
352 const QMap<QString, QString> keyList {
353 {"/0", "/_Position"},
354 {"/1", "/Bezier"},
355 //{"/2", "/Data"},
356 {"/97", "/UUID"}
357 };
358
359 Q_FOREACH(QVariant val, resources) {
360 QVariantHash resource = val.toHash().value("/0").toHash();
361 QVariantHash newResource;
362 Q_FOREACH(QString key2, resource.keys()) {
363 QVariant rdVal = resource.value(key2);
364 if (key2 == "/5") {
365 newResource.insert("/Features", uncompressStyleSheetFeatures(rdVal.toHash()));
366 } else if (key2 == "/1") {
367 QVariant pList = rdVal.toHash().value("/0");
368
369 newResource.insert("/Bezier", QVariantHash({{"/Points", pList}}));
370 } else if (key2 == "/2") {
371 newResource.insert("/Data", uncompressTextFrameData(rdVal.toHash()));
372 } else if (keyList.keys().contains(key2)) {
373 newResource.insert(keyList.value(key2), rdVal);
374 } else {
375 newResource.insert(key2, rdVal);
376 }
377 }
378
379 newResources.append(QVariantHash({{"/Resource", newResource}}));
380 }
381 newObject.insert("/Resources", newResources);
382 return newObject;
383}
384
385QVariantHash uncompressKeysKinsokuSet(const QVariantHash object) {
386 QVariantHash newObject;
387
388 QVariantList resources = object.value("/0").toList();
389 QVariantList newResources;
390
391 const QMap<QString, QString> keyList {{"/0", "/Name"}, {"/5", "/Data"}};
392 const QMap<QString, QString> idKeyList {{"/0", "/NoStart"}, {"/1", "/NoEnd"}, {"/2", "/Keep"}, {"/3", "/Hanging"}, {"/4", "/PredefinedTag"}};
393
394
395 Q_FOREACH(QVariant val, resources) {
396 QVariantHash resource = val.toHash().value("/0").toHash();
397 QVariantHash newResource;
398 Q_FOREACH(QString key, resource.keys()) {
399 if (key == "/5") {
400 QVariantHash id = resource.value(key).toHash();
401 QVariantHash newId;
402 Q_FOREACH(QString key2, id.keys()) {
403 QVariant idVal = id.value(key2);
404 if (idKeyList.keys().contains(key2)) {
405 newId.insert(idKeyList.value(key2), idVal);
406 } else {
407 newId.insert(key2, idVal);
408 }
409 }
410 newResource.insert("/Data", newId);
411 } else if (keyList.keys().contains(key)) {
412 newResource.insert(keyList.value(key), resource.value(key));
413 } else {
414 newResource.insert(key, resource.value(key));
415 }
416 }
417
418 newResources.append(QVariantHash({{"/Resource", newResource}}));
419 }
420 newObject.insert("/Resources", newResources);
421 return newObject;
422}
423
424QVariantHash uncompressKeysMojiKumiTableSet(const QVariantHash object) {
425 QVariantHash newObject;
426
427 Q_FOREACH(QString key, object.keys()) {
428 QVariant val = object.value(key);
429 newObject.insert(key, val);
430 }
431 return newObject;
432}
433
434QVariantHash uncompressKeysMojiKumiCodeToClassSet(const QVariantHash object) {
435 QVariantHash newObject;
436
437 Q_FOREACH(QString key, object.keys()) {
438 QVariant val = object.value(key);
439 newObject.insert(key, val);
440 }
441 return newObject;
442}
443
444QVariantHash uncompressKeysFontSet(const QVariantHash object) {
445 QVariantHash newObject;
446
447 QVariantList resources = object.value("/0").toList();
448 QVariantList newResources;
449
450 const QMap<QString, QString> keyList {{"/99", "/StreamTag"}, {"/97", "/UUID"}};
451 const QMap<QString, QString> idKeyList {{"/0", "/Name"}, {"/2", "/Type"}, {"/4", "/MMAxis"}, {"/5", "/VersionString"}};
452
453
454 Q_FOREACH(QVariant val, resources) {
455 QVariantHash resource = val.toHash().value("/0").toHash();
456 QVariantHash newResource;
457 Q_FOREACH(QString key, resource.keys()) {
458 if (key == "/0") {
459 QVariantHash id = resource.value(key).toHash();
460 QVariantHash newId;
461 Q_FOREACH(QString key2, id.keys()) {
462 QVariant idVal = id.value(key2);
463 if (idKeyList.keys().contains(key2)) {
464 newId.insert(idKeyList.value(key2), idVal);
465 } else {
466 newId.insert(key2, idVal);
467 }
468 }
469 newResource.insert("/Identifier", newId);
470 } else if (keyList.keys().contains(key)) {
471 newResource.insert(keyList.value(key), resource.value(key));
472 } else {
473 newResource.insert(key, resource.value(key));
474 }
475 }
476
477 newResources.append(QVariantHash({{"/Resource", newResource}}));
478 }
479 newObject.insert("/Resources", newResources);
480 return newObject;
481}
482
483QVariantHash uncompressKeysDocumentResources(const QVariantHash object) {
484 QVariantHash newObject;
485
486 Q_FOREACH(QString key, object.keys()) {
487 QVariant val = object.value(key);
488
489 if (key == "/1") {
490 newObject.insert("/FontSet", uncompressKeysFontSet(val.toHash()));
491 } else if (key == "/2") {
492 newObject.insert("/MojiKumiCodeToClassSet", uncompressKeysMojiKumiCodeToClassSet(val.toHash()));
493 } else if (key == "/3") {
494 newObject.insert("/MojiKumiTableSet", uncompressKeysMojiKumiTableSet(val.toHash()));
495 } else if (key == "/4") {
496 newObject.insert("/KinsokuSet", uncompressKeysKinsokuSet(val.toHash()));
497 } else if (key == "/5") {
498 newObject.insert("/StyleSheetSet", uncompressKeysStyleSheetSet(val.toHash()));
499 } else if (key == "/6") {
500 newObject.insert("/ParagraphSheetSet", uncompressKeysParagraphSheetSet(val.toHash()));
501 } else if (key == "/8") {
502 newObject.insert("/TextFrameSet", uncompressKeysTextFrameSet(val.toHash()));
503 } else if (key == "/9") {
504 newObject.insert("/ListStyleSet", val);
505 } else {
506 newObject.insert(key, val);
507 }
508 }
509 return newObject;
510}
511
512/*------- Document Objects ----------*/
513
514QVariantHash uncompressKeysTextModel(const QVariantHash object) {
515 QVariantHash newObject;
516
517 const QMap<QString, QString> runStyleKeyList {{"/0", "/Name"}, {"/5", "/Parent"}, {"/97", "/UUID"}};
518
519 Q_FOREACH(QString key, object.keys()) {
520 QVariant val = object.value(key);
521
522 if (key == "/0") {
523 newObject.insert("/Text", val);
524 } else if (key == "/5") {
525 QVariantList array = val.toHash().value("/0").toList();
526 QVariantList newArray;
527
528 Q_FOREACH(QVariant run, array) {
529 QVariantHash runDataSheet = run.toHash().value("/0").toHash().value("/0").toHash();
530 QVariantHash newDataSheet;
531
532 Q_FOREACH(QString key2, runDataSheet.keys()) {
533 QVariant rdVal = runDataSheet.value(key2);
534 if (key2 == "/5") {
535 newDataSheet.insert("/Features", uncompressParagraphSheetFeatures(rdVal.toHash()));
536 } else if (key2 == "/6") {
537 newDataSheet.insert("/Parent", rdVal);
538 } else if (runStyleKeyList.keys().contains(key)) {
539 newDataSheet.insert(runStyleKeyList.value(key2), rdVal);
540 } else {
541 newDataSheet.insert(key2, rdVal);
542 }
543 }
544
545 QVariantHash newSheet = {{"/ParagraphSheet", newDataSheet}};
546 QVariantHash newRunData = {{"/RunData", newSheet}};
547 newRunData.insert("/Length", run.toHash().value("/1"));
548 newArray.append(newRunData);
549 }
550 QVariantHash arrayParent = {{"/RunArray", newArray}};
551 newObject.insert("/ParagraphRun", arrayParent);
552 } else if (key == "/6") {
553 QVariantList array = val.toHash().value("/0").toList();
554 QVariantList newArray;
555
556 Q_FOREACH(QVariant run, array) {
557 QVariantHash runDataSheet = run.toHash().value("/0").toHash().value("/0").toHash();
558 QVariantHash newDataSheet;
559
560 Q_FOREACH(QString key2, runDataSheet.keys()) {
561 QVariant rdVal = runDataSheet.value(key2);
562 if (key2 == "/6") {
563 newDataSheet.insert("/Features", uncompressStyleSheetFeatures(rdVal.toHash()));
564 } else if (key2 == "/5") {
565 newDataSheet.insert("/Parent", rdVal);
566 } else if (runStyleKeyList.keys().contains(key)) {
567 newDataSheet.insert(runStyleKeyList.value(key2), rdVal);
568 } else {
569 newDataSheet.insert(key2, rdVal);
570 }
571 }
572
573 QVariantHash newSheet = {{"/StyleSheet", newDataSheet}};
574 QVariantHash newRunData = {{"/RunData", newSheet}};
575 newRunData.insert("/Length", run.toHash().value("/1"));
576 newArray.append(newRunData);
577 }
578 QVariantHash arrayParent = {{"/RunArray", newArray}};
579 newObject.insert("/StyleRun", arrayParent);
580 } else if (key == "/10") {
581 newObject.insert("/StorySheet", val);
582 } else {
583 newObject.insert(key, val);
584 }
585 }
586 return newObject;
587}
588
589QVariantHash uncompressGlyphStrikeDef(const QVariantHash object) {
590 QVariantHash newObject;
591
592 Q_FOREACH(QString key, object.keys()) {
593 QVariant val = object.value(key);
594 // bounds,
595 if (key == "/99") {
596 newObject.insert("/StreamTag", val);
597 } else if (key == "/1") {
598 newObject.insert("/Bounds", val);
599 } else if (key == "/5") {
600 newObject.insert("/Glyphs", val);
601 } else if (key == "/10") {
602 newObject.insert("/GlyphAdjustments", val);
603 } else if (key == "/8") {
604 newObject.insert("/VisualBounds", val);
605 } else if (key == "/9") {
606 newObject.insert("/RenderedBounds", val);
607 } else if (key == "/15") {
608 newObject.insert("/Invalidation", val);
609 } else if (key == "/14") {
610 newObject.insert("/EndsInCR", val);
611 } else if (key == "/12") {
612 newObject.insert("/SelectionAscent", val);
613 } else if (key == "/13") {
614 newObject.insert("/SelectionDescent", val);
615 } else {
616 newObject.insert(key, val);
617 }
618 }
619 return newObject;
620}
621
622QVariantHash uncompressSegmentDef(const QVariantHash object) {
623 QVariantHash newObject;
624
625 Q_FOREACH(QString key, object.keys()) {
626 QVariant val = object.value(key);
627
628 if (key == "/99") {
629 newObject.insert("/StreamTag", val);
630 } else if (key == "/1") {
631 newObject.insert("/Bounds", val);
632 } else if (key == "/5") {
633 newObject.insert("/ChildProcession", val);
634 } else if (key == "/6") {
635 QVariantList array = val.toList();
636 QVariantList newArray;
637 Q_FOREACH(QVariant entry, array) {
638 newArray.append(uncompressGlyphStrikeDef(entry.toHash()));
639 }
640 newObject.insert("/Children", newArray);
641 } else if (key == "/15") {
642 newObject.insert("/Mapping", val);
643 } else if (key == "/20") {
644 newObject.insert("/FirstCharacterIndexInSegment", val);
645 } else {
646 newObject.insert(key, val);
647 }
648 }
649 return newObject;
650}
651
652QVariantHash uncompressLineDef(const QVariantHash object) {
653 QVariantHash newObject;
654
655 Q_FOREACH(QString key, object.keys()) {
656 QVariant val = object.value(key);
657
658 if (key == "/99") {
659 newObject.insert("/StreamTag", val);
660 } else if (key == "/0") {
661 newObject.insert("/Transform", val);
662 } else if (key == "/1") {
663 newObject.insert("/Bounds", val);
664 } else if (key == "/5") {
665 newObject.insert("/ChildProcession", val);
666 } else if (key == "/6") {
667 QVariantList array = val.toList();
668 QVariantList newArray;
669 Q_FOREACH(QVariant entry, array) {
670 newArray.append(uncompressSegmentDef(entry.toHash()));
671 }
672 newObject.insert("/Children", newArray);
673 } else if (key == "/10") {
674 newObject.insert("/Baseline", val);
675 } else if (key == "/14") {
676 newObject.insert("/SelectionAscent", val);
677 } else if (key == "/15") {
678 newObject.insert("/SelectionDescent", val);
679 } else {
680 newObject.insert(key, val);
681 }
682 }
683 return newObject;
684}
685
686QVariantHash uncompressStrikeDef(const QVariantHash object, bool flip = false) {
687 QVariantHash newObject;
688 QString tag = object.contains("/99")? object.value("/99").toString()
689 : object.value("/StreamTag").toString();
690
691 Q_FOREACH(QString key, object.keys()) {
692 QVariant val = object.value(key);
693
694 if (key == "/99") {
695 newObject.insert("/StreamTag", val);
696 } else if ((key == "/0" && !flip) || (key == "/1" && flip)) {
697 newObject.insert("/Bounds", val);
698 } else if ((key == "/1" && !flip) || (key == "/0" && flip)) {
699 newObject.insert("/Transform", val);
700 } else if (key == "/5") {
701 newObject.insert("/ChildProcession", val);
702 } else if (key == "/6") {
703 QVariantList array = val.toList();
704 QVariantList newArray;
705 Q_FOREACH(QVariant entry, array) {
706 QString streamTag = entry.toHash().keys().contains("/99")? entry.toHash().value("/99").toString()
707 : entry.toHash().value("/StreamTag").toString();
708 if (streamTag == "/PC" || streamTag == "/PathSelectGroupCharacter"
709 || streamTag == "/F" || streamTag == "/FrameStrike" || streamTag == "/RowColStrike" || streamTag == "/R") {
710 newArray.append(uncompressStrikeDef(entry.toHash(), true));
711 } else if (streamTag == "/L" || streamTag == "/LineStrike") {
712 newArray.append(uncompressLineDef(entry.toHash()));
713 }
714 }
715 newObject.insert("/Children", newArray);
716 } else if (key == "/10" && (tag == "/F" || tag == "/FrameStrike")) { // only for frame strike.
717 newObject.insert("/Frame", val);
718 } else {
719 newObject.insert(key, val);
720 }
721 }
722 return newObject;
723}
724
725QVariantHash uncompressKeysTextView(const QVariantHash object) {
726 QVariantHash newObject;
727 Q_FOREACH(QString key, object.keys()) {
728 QVariant val = object.value(key);
729
730 if (key == "/0") {
731 QVariantList array = val.toList();
732 QVariantList newArray;
733 Q_FOREACH(QVariant entry, array) {
734 QVariant resource = entry.toHash().value("/0");
735
736 newArray.append(QVariantHash({{"/Resource", resource}}));
737 }
738
739 newObject.insert("/Frames", newArray);
740 } else if (key == "/2") {
741 QVariantList array = val.toList();
742 QVariantList newArray;
743 Q_FOREACH(QVariant entry, array) {
744 newArray.append(uncompressStrikeDef(entry.toHash()));
745 }
746 newObject.insert("/Strikes", newArray);
747 } else {
748 newObject.insert(key, val);
749 }
750 }
751 return newObject;
752}
753
754QVariantHash uncompressKeysTextObject(const QVariantHash object) {
755 QVariantHash newObject;
756
757 Q_FOREACH(QString key, object.keys()) {
758 QVariant val = object.value(key);
759
760 if (key == "/0") {
761 newObject.insert("/Model", uncompressKeysTextModel(val.toHash()));
762 } else if (key == "/1") {
763 newObject.insert("/View", uncompressKeysTextView(val.toHash()));
764 } else {
765 newObject.insert(key, val);
766 }
767 }
768 return newObject;
769}
770
771QVariantHash uncompressSmartQuoteSettings(const QVariantHash object) {
772 QVariantHash newObject;
773 const QMap<QString, QString> keyList {
774 {"/0", "/Language"},
775 {"/1", "/OpenDoubleQuote"},
776 {"/2", "/CloseDoubleQuote"},
777 {"/3", "/OpenSingleQuote"},
778 {"/4", "/CloseSingleQuote"},
779
780 };
781
782 Q_FOREACH(QString key, object.keys()) {
783 QVariant val = object.value(key);
784 if (keyList.keys().contains(key)) {
785 newObject.insert(keyList.value(key), val);
786 } else {
787 newObject.insert(key, val);
788 }
789 }
790 return newObject;
791}
792
793QVariantHash uncompressHiddenGlyphSettings(const QVariantHash object) {
794 QVariantHash newObject;
795
796 if (object.keys().contains("/0")) {
797 newObject.insert("/AlternateGlyphFont", object.value("/0"));
798 }
799 if (object.keys().contains("/1")) {
800 QVariantList array = object.value("/1").toList();
801 QVariantList newArray;
802 Q_FOREACH(QVariant entry, array) {
803 QVariantHash newEntry;
804 newObject.insert("/WhitespaceCharacter", newEntry.value("/0"));
805 newObject.insert("/AlternateCharacter", newEntry.value("/1"));
806 newArray.append(newObject);
807 }
808 newObject.insert("/WhitespaceCharacterMapping", newArray);
809 }
810
811 return newObject;
812}
813
814QVariantHash uncompressKeysDocumentSettings(const QVariantHash object) {
815 QVariantHash newObject;
816 const QMap<QString, QString> keyList {
817 //{"/0", "/HiddenGlyphFont"},
818 {"/1", "/NormalStyleSheet"},
819 {"/2", "/NormalParagraphSheet"},
820 {"/3", "/SuperscriptSize"},
821 {"/4", "/SuperscriptPosition"},
822
823 {"/5", "/SubscriptSize"},
824 {"/6", "/SubscriptPosition"},
825 {"/7", "/SmallCapSize"},
826 {"/8", "/UseSmartQuotes"},
827 //{"/9", "/SmartQuoteSets"},
828
829 //{"/10", ""},
830 {"/11", "/GreekingSize"},
831 //{"/12", ""},
832 //{"/13", ""},
833 //{"/14", ""},
834
835 {"/15", "/LinguisticSettings"},
836 {"/16", "/UseSmartLists"},
837 {"/17", "/DefaultStoryDir"},
838 };
839
840 Q_FOREACH(QString key, object.keys()) {
841 QVariant val = object.value(key);
842 if (key == "/0") {
843 newObject.insert("/HiddenGlyphFont", uncompressHiddenGlyphSettings(val.toHash()));
844 } else if (key == "/9") {
845 QVariantList array = val.toList();
846 QVariantList newArray;
847 Q_FOREACH(QVariant entry, array) {
848 newArray.append(uncompressSmartQuoteSettings(entry.toHash()));
849 }
850 newObject.insert("/SmartQuoteSets", newArray);
851 } else if (keyList.keys().contains(key)) {
852 newObject.insert(keyList.value(key), val);
853 } else {
854 newObject.insert(key, val);
855 }
856 }
857
858 return newObject;
859}
860
861QVariantHash uncompressKeysDocumentObjects(const QVariantHash object) {
862 QVariantHash newObject;
863 Q_FOREACH(QString key, object.keys()) {
864 QVariant val = object.value(key);
865
866 if (key == "/0") {
867 newObject.insert("/DocumentSettings", uncompressKeysDocumentSettings(val.toHash()));
868 } else if (key == "/1") {
869 QVariantList array = val.toList();
870 QVariantList newArray;
871 Q_FOREACH(QVariant entry, array) {
872 newArray.append(uncompressKeysTextObject(entry.toHash()));
873 }
874 newObject.insert("/TextObjects", newArray);
875 } else if (key == "/2") {
876 newObject.insert("/OriginalNormalStyleFeatures", uncompressStyleSheetFeatures(val.toHash()));
877 } else if (key == "/3") {
878 newObject.insert("/OriginalNormalParagraphFeatures", uncompressParagraphSheetFeatures(val.toHash()));
879 } else {
880 newObject.insert(key, val);
881 }
882 }
883
884 return newObject;
885}
886
887QVariantHash KisTxt2Utils::uncompressKeys(QVariantHash doc)
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}
902
903//-------------- Default Txt2 ----------------//
904
905static QVariantHash defaultFill {
906 { "/StreamTag", "/SimplePaint"},
907 {
908 "/Color", QVariantHash{{"/Type", 1}, {"/Values", QVariantList({1.0, 0.0, 0.0, 0.0})}}
909 }
910};
911
912static QVariantHash defaultBGFill {
913 { "/StreamTag", "/SimplePaint"},
914 {
915 "/Color", QVariantHash{{"/Type", 1}, {"/Values", QVariantList({1.0, 1.0, 1.0, 0.0})}}
916 }
917};
918
919static QVariantHash defaultStyle {
920 {"/Font", 1},
921 {"/FontSize", 12.0},
922 {"/FauxBold", false},
923 {"/FauxItalic", false},
924 {"/AutoLeading", true},
925
926 {"/Leading", 0.0},
927 {"/HorizontalScale", 1.0},
928 {"/VerticalScale", 1.0},
929 {"/Tracking", 0},
930 {"/BaselineShift", 0.0},
931
932 {"/CharacterRotation", 0.0},
933 {"/AutoKern", 1},
934 {"/FontCaps", 0},
935 {"/FontBaseline", 0},
936 {"/FontOTPosition", 0},
937
938 {"/StrikethroughPosition", 0},
939 {"/UnderlinePosition", 0},
940 {"/UnderlineOffset", 0.0},
941 {"/Ligatures", true},
942 {"/DiscretionaryLigatures", false},
943
944 {"/ContextualLigatures", false},
945 {"/AlternateLigatures", false},
946 {"/OldStyle", false},
947 {"/Fractions", false},
948 {"/Ordinals", false},
949
950 {"/Swash", false},
951 {"/Titling", false},
952 {"/ConnectionForms", false},
953 {"/StylisticAlternates", false},
954 {"/Ornaments", false},
955
956 {"/FigureStyle", 0},
957 {"/ProportionalMetrics", false},
958 {"/Kana", false},
959 {"/Italics", false},
960 {"/Ruby", false},
961
962 {"/BaselineDirection", 2},
963 {"/Tsume", 0.0},
964 {"/StyleRunAlignment", 0},
965 {"/Language", 0},
966 {"/JapaneseAlternateFeature", 0},
967
968 {"/EnableWariChu", false},
969 {"/WariChuLineCount", 2},
970 {"/WariChuLineGap", 0},
971 {"/WariChuSubLineAmount", QVariantHash({{"/WariChuSubLineScale", 0.5}})},
972 {"/WariChuWidowAmount", 2},
973
974 {"/WariChuOrphanAmount", 2},
975 {"/WariChuJustification", 7},
976 {"/TCYUpDownAdjustment", 0},
977 {"/TCYLeftRightAdjustment", 0},
978 {"/LeftAki", -1.0},
979
980 {"/RightAki", -1.0},
981 {"/JiDori", 0},
982 {"/NoBreak", false},
983 {"/FillColor", defaultFill},
984 {"/StrokeColor", defaultFill},
985
986 {"/Blend", QVariantHash({{"/StreamTag", "/SimpleBlender"}})},
987 {"/FillFlag", true},
988 {"/StrokeFlag", false},
989 {"/FillFirst", false},
990
991 {"/FillOverPrint", false},
992 {"/StrokeOverPrint", false},
993 {"/LineCap", 0},
994 {"/LineJoin", 0},
995 {"/LineWidth", 1.0},
996 {"/MiterLimit", 4.0},
997
998 {"/LineDashOffset", 0.0},
999 {"/LineDashArray", QVariantList()},
1000 {"/Type", QVariantList()},
1001 {"/Kashidas", 0},
1002 {"/DirOverride", 0},
1003
1004 {"/DigitSet", 0},
1005 {"/DiacVPos", 0},
1006 {"/DiacXOffset", 0.0},
1007 {"/DiacYOffset", 0.0},
1008 {"/OverlapSwash", false},
1009
1010 {"/JustificationAlternates", false},
1011 {"/StretchedAlternates", false},
1012 {"/FillVisibleFlag", true},
1013 {"/StrokeVisibleFlag", true},
1014 {"/FillBackgroundColor", defaultBGFill},
1015
1016 {"/FillBackgroundFlag", false},
1017 {"/UnderlineStyle", 0},
1018 {"/DashedUnderlineGapLength", 3.0},
1019 {"/DashedUnderlineDashLength", 3.0},
1020 {"/SlashedZero", false},
1021
1022 {"/StylisticSets", 0},
1023 {"/CustomFeature", QVariantHash({{"/StreamTag", "/SimpleCustomFeature"}})},
1024 {"/MarkYDistFromBaseline", 100.0},
1025};
1026
1027static QVariantHash defaultParagraph {
1028 {"/Justification", 0},
1029 {"/FirstLineIndent", 0.0},
1030 {"/StartIndent", 0.0},
1031 {"/EndIndent", 0.0},
1032 {"/SpaceBefore", 0.0},
1033
1034 {"/SpaceAfter", 0.0},
1035 {"/DropCaps", 1},
1036 {"/AutoLeading", 1.2},
1037 {"/LeadingType", 0},
1038 {"/AutoHyphenate", true},
1039
1040 {"/HyphenatedWordSize", 6},
1041 {"/PreHyphen", 2},
1042 {"/PostHyphen", 2},
1043 {"/ConsecutiveHyphens", 0},
1044 {"/Zone", 36.0},
1045
1046 {"/HyphenateCapitalized", true},
1047 {"/HyphenationPreference", 0.5},
1048 {"/WordSpacing", QVariantList({0.8, 1.0, 1.3})},
1049 {"/LetterSpacing", QVariantList({0.0, 0.0, 0.0})},
1050 {"/GlyphSpacing", QVariantList({1.0, 1.0, 1.0})},
1051
1052 {"/SingleWordJustification", 6},
1053 {"/Hanging", false},
1054 {"/AutoTCY", 0},
1055 {"/KeepTogether", true},
1056 {"/BurasagariType", 0},
1057
1058 {"/KinsokuOrder", 0},
1059 {"/KurikaeshiMojiShori", false},
1060 {"/Kinsoku", "/nil"},
1061 {"/MojiKumiTable", "/nil"},
1062 {"/EveryLineComposer", false},
1063
1064 {"/TabStops", QVariantHash()},
1065 {"/DefaultTabWidth", 36.0},
1066 {"/DefaultStyle", QVariantHash()},
1067 {"/ParagraphDirection", 0},
1068 {"/JustificationMethod", 7},
1069
1070 {"/ComposerEngine", 1},
1071 {"/ListStyle", "/nil"},
1072 {"/ListTier", 0},
1073 {"/ListSkip", false},
1074 {"/ListOffset", 0},
1075
1076 {"/KashidaWidth", 2}
1077};
1078
1079static QVariantHash kinsokuNone {
1080 {"/NoStart", ""},
1081 {"/NoEnd", ""},
1082 {"/Keep", ""},
1083 {"/Hanging", ""},
1084 {"/PredefinedTag", 0}
1085};
1086
1087static QVariantHash kinsokuHard {
1088 {"/NoStart", "!),.:;?]}¢—’”‰℃℉、。々〉》」』】〕ぁぃぅぇぉっゃゅょゎ゛゜ゝゞァィゥェォッャュョヮヵヶ・ーヽヾ!%),.:;?]}"},
1089 {"/NoEnd", "([{£§‘“〈《「『【〒〔#$(@[{¥"},
1090 {"/Keep", "—‥…"},
1091 {"/Hanging", "、。,."},
1092 {"/PredefinedTag", 1}
1093};
1094
1095static QVariantHash kinsokuSoft {
1096 {"/NoStart", "’”、。々〉》」』】〕ゝゞ・ヽヾ!),.:;?]}"},
1097 {"/NoEnd", "‘“〈《「『【〔([{"},
1098 {"/Keep", "—‥…"},
1099 {"/Hanging", "、。,."},
1100 {"/PredefinedTag", 2}
1101};
1102
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}
1261
1262QVariantHash defaultGrid {
1263 {"/GridIsOn", false},
1264 {"/ShowGrid", false},
1265 {"/GridSize", 18.0},
1266 {"/GridLeading", 22.0},
1267 {"/GridColor", QVariantHash{{"/Type", 1}, {"/Values", QVariantList({0.0, 0.0, 0.0, 1.0})}}},
1268 {"/GridLeadingFillColor", QVariantHash{{"/Type", 1}, {"/Values", QVariantList({0.0, 0.0, 0.0, 1.0})}}},
1269 {"/AlignLineHeightToGridFlags", false},
1270};
1271
1273 "/Font",
1274 "/FontSize",
1275 "/FauxBold",
1276 "/FauxItalic",
1277 "/AutoLeading",
1278
1279 "/Leading",
1280 "/HorizontalScale",
1281 "/VerticalScale",
1282 "/Tracking",
1283 "/BaselineShift",
1284
1285 "/FontCaps",
1286 "/FontBaseline",
1287 "/Ligatures",
1288 "/BaselineDirection",
1289 "/Tsume",
1290
1291 "/StyleRunAlignment",
1292 "/Language",
1293 "/NoBreak",
1294 "/FillFlag",
1295 "/StrokeFlag",
1296
1297 "/FillFirst",
1298 "/Kashida",
1299};
1300static QVariantHash simplifyStyleSheet(const QVariantHash complex) {
1301 QVariantHash simple;
1302 Q_FOREACH(const QString key, complex.keys()) {
1303 if (simpleStyleAllowed.contains(key)) {
1304 simple.insert(key, complex.value(key));
1305 }else if (key == "/StrokeColor" || key == "/FillColor") {
1306 simple.insert(key, complex.value(key).toHash().value("/Color"));
1307 } else if (key == "/UnderlinePosition") {
1308 bool val = complex.value(key).toBool();
1309 simple.insert("/Underline", val);
1310 if (complex.value(key).toInt() == 2) {
1311 simple.insert("/YUnderline", 0);
1312 } else {
1313 simple.insert("/YUnderline", 1);
1314 }
1315 } else if (key == "/StrikethroughPosition") {
1316 bool val = complex.value(key).toBool();
1317 simple.insert("/Strikethrough", val);
1318 } else if (key == "/AutoKerning") {
1319 bool val = complex.value(key).toBool();
1320 simple.insert("/AutoKern", val);
1321 } else if (key == "/LineWidth") {
1322 simple.insert("/OutlineWidth", complex.value(key));
1323 } else if (key == "/DiscretionaryLigatures") {
1324 simple.insert("/DLigatures", complex.value(key));
1325 }
1326 }
1327 simple.insert("/Kerning", 0.0);
1328 simple.insert("/HindiNumbers", false);
1329 simple.insert("/DiacriticPos", 2);
1330 return simple;
1331}
1333 "/Justification",
1334 "/FirstLineIndent",
1335 "/StartIndent",
1336 "/EndIndent",
1337 "/SpaceBefore",
1338
1339 "/AutoHyphenate",
1340 "/HyphenatedWordSize",
1341 "/PreHyphen",
1342 "/PostHyphen",
1343 "/Zone",
1344
1345 "/WordSpacing",
1346 "/LetterSpacing",
1347 "/GlyphSpacing",
1348 "/SpaceAfter",
1349 "/AutoLeading",
1350
1351 "/LeadingType",
1352 "/Hanging",
1353 "/Burasagari",
1354 "/KinsokuOrder",
1355 "/EveryLineComposer",
1356};
1357static QVariantHash simplifyParagraphSheet(const QVariantHash complex) {
1358 QVariantHash simple;
1359 Q_FOREACH(const QString key, complex.keys()) {
1360 if (simpleParagraphAllowed.contains(key)) {
1361 simple.insert(key, complex.value(key));
1362 }
1363 }
1364 return simple;
1365}
1366
1367QVariantHash KisTxt2Utils::tyShFromTxt2(const QVariantHash Txt2, const QRectF boundsInPx, int textIndex)
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
float value(const T *src, size_t ch)
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 dat...
static QVariantHash uncompressKeys(QVariantHash doc)
uncompressKeys One of the problems with the Txt2 block is that older versions of photoshop (cs2-cs3 e...
static QVariantHash defaultTxt2()
defaultTxt2 Generate a default txt2 varianthash. This includes stuff like Kinsoku sets default fonts ...
QVariantHash uncompressKeysTextObject(const QVariantHash object)
static QVariantHash kinsokuHard
QVariantHash defaultGrid
QVariantHash uncompressTextFrameData(const QVariantHash object)
QVariantHash uncompressKeysFontSet(const QVariantHash object)
QVariantHash uncompressKeysMojiKumiCodeToClassSet(const QVariantHash object)
static QVariantHash simplifyParagraphSheet(const QVariantHash complex)
QVariantHash uncompressHiddenGlyphSettings(const QVariantHash object)
QVariantHash uncompressStyleSheetFeatures(const QVariantHash object)
QVariantHash uncompressKeysTextModel(const QVariantHash object)
QVariantHash uncompressKeysDocumentObjects(const QVariantHash object)
QVariantHash uncompressLineDef(const QVariantHash object)
static QVariantHash defaultParagraph
QVariantHash uncompressKeysMojiKumiTableSet(const QVariantHash object)
QVariantHash uncompressStrikeDef(const QVariantHash object, bool flip=false)
QVariantHash uncompressSmartQuoteSettings(const QVariantHash object)
QVariantHash uncompressKeysTextFrameSet(const QVariantHash object)
QVariantHash uncompressParagraphSheetFeatures(const QVariantHash object)
QVariantHash uncompressColor(const QVariantHash object)
QVariantHash uncompressKeysParagraphSheetSet(const QVariantHash object)
static QVariantHash kinsokuSoft
static QVariantHash defaultFill
QVariantHash uncompressSegmentDef(const QVariantHash object)
static QVariantHash defaultStyle
QVariantHash uncompressKeysTextView(const QVariantHash object)
QVariantHash uncompressKeysStyleSheetSet(const QVariantHash object)
static QStringList simpleParagraphAllowed
QVariantHash uncompressKeysKinsokuSet(const QVariantHash object)
QVariantHash uncompressKeysDocumentSettings(const QVariantHash object)
static QVariantHash simplifyStyleSheet(const QVariantHash complex)
static QStringList simpleStyleAllowed
QVariantHash uncompressKeysDocumentResources(const QVariantHash object)
static QVariantHash defaultBGFill
QVariantHash uncompressGlyphStrikeDef(const QVariantHash object)
static QVariantHash kinsokuNone