ag-psd 32.0.0 → 34.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/.v8-cache/v24.7.0-x64-ef5a0af0/03e19709 +0 -0
  2. package/.v8-cache/v24.7.0-x64-ef5a0af0/05135617 +0 -0
  3. package/.v8-cache/v24.7.0-x64-ef5a0af0/1130885f +0 -0
  4. package/.v8-cache/v24.7.0-x64-ef5a0af0/226e2801 +0 -0
  5. package/.v8-cache/v24.7.0-x64-ef5a0af0/2a19133e +0 -0
  6. package/.v8-cache/v24.7.0-x64-ef5a0af0/4511bacf +0 -0
  7. package/.v8-cache/v24.7.0-x64-ef5a0af0/68416cb2 +0 -0
  8. package/.v8-cache/v24.7.0-x64-ef5a0af0/71df9cb3 +0 -0
  9. package/.v8-cache/v24.7.0-x64-ef5a0af0/7ea06cea +0 -0
  10. package/.v8-cache/v24.7.0-x64-ef5a0af0/87cf2209 +0 -0
  11. package/.v8-cache/v24.7.0-x64-ef5a0af0/932f0770 +0 -0
  12. package/.v8-cache/v24.7.0-x64-ef5a0af0/acc36e66 +0 -0
  13. package/.v8-cache/v24.7.0-x64-ef5a0af0/b3c2fab7 +0 -0
  14. package/.v8-cache/v24.7.0-x64-ef5a0af0/c0b789d2 +0 -0
  15. package/.v8-cache/v24.7.0-x64-ef5a0af0/c314aece +0 -0
  16. package/.v8-cache/v24.7.0-x64-ef5a0af0/cfc49f4f +0 -0
  17. package/.v8-cache/v24.7.0-x64-ef5a0af0/cff9434a +0 -0
  18. package/.v8-cache/v24.7.0-x64-ef5a0af0/d13d7610 +0 -0
  19. package/.v8-cache/v24.7.0-x64-ef5a0af0/dc86f000 +0 -0
  20. package/.v8-cache/v24.7.0-x64-ef5a0af0/e03e2acd +0 -0
  21. package/.v8-cache/v24.7.0-x64-ef5a0af0/e6745c2b +0 -0
  22. package/.v8-cache/v24.7.0-x64-ef5a0af0/e6b99945 +0 -0
  23. package/.v8-cache/v24.7.0-x64-ef5a0af0/eeeebdfe +0 -0
  24. package/.v8-cache/v24.7.0-x64-ef5a0af0/f6fd8125 +0 -0
  25. package/CHANGELOG.md +100 -0
  26. package/LICENSE +5 -0
  27. package/README.md +4 -7
  28. package/README_PSD.md +261 -84
  29. package/TODO.md +13 -84
  30. package/dist/abr.d.ts +11 -4
  31. package/dist/abr.js +362 -230
  32. package/dist/abr.js.map +1 -1
  33. package/dist/additionalInfo.d.ts +56 -2
  34. package/dist/additionalInfo.js +828 -361
  35. package/dist/additionalInfo.js.map +1 -1
  36. package/dist/ase.d.ts +6 -1
  37. package/dist/ase.js +61 -61
  38. package/dist/ase.js.map +1 -1
  39. package/dist/bundle.js +3321 -1364
  40. package/dist/descriptor.d.ts +28 -13
  41. package/dist/descriptor.js +295 -241
  42. package/dist/descriptor.js.map +1 -1
  43. package/dist/helpers.d.ts +7 -1
  44. package/dist/helpers.js +246 -4
  45. package/dist/helpers.js.map +1 -1
  46. package/dist/imageResources.d.ts +15 -3
  47. package/dist/imageResources.js +586 -144
  48. package/dist/imageResources.js.map +1 -1
  49. package/dist/index.d.ts +1 -0
  50. package/dist/index.js +1 -0
  51. package/dist/index.js.map +1 -1
  52. package/dist/jpeg.js +8 -8
  53. package/dist/jpeg.js.map +1 -1
  54. package/dist/psd.d.ts +292 -19
  55. package/dist/psd.js.map +1 -1
  56. package/dist/psdReader.d.ts +10 -0
  57. package/dist/psdReader.js +424 -216
  58. package/dist/psdReader.js.map +1 -1
  59. package/dist/psdWriter.d.ts +2 -0
  60. package/dist/psdWriter.js +373 -113
  61. package/dist/psdWriter.js.map +1 -1
  62. package/dist/text.d.ts +32 -1
  63. package/dist/text.js +75 -6
  64. package/dist/text.js.map +1 -1
  65. package/dist/utf8.js +0 -3
  66. package/dist/utf8.js.map +1 -1
  67. package/dist-es/abr.d.ts +11 -4
  68. package/dist-es/abr.js +362 -230
  69. package/dist-es/abr.js.map +1 -1
  70. package/dist-es/additionalInfo.d.ts +56 -2
  71. package/dist-es/additionalInfo.js +828 -361
  72. package/dist-es/additionalInfo.js.map +1 -1
  73. package/dist-es/ase.d.ts +6 -1
  74. package/dist-es/ase.js +61 -61
  75. package/dist-es/ase.js.map +1 -1
  76. package/dist-es/descriptor.d.ts +28 -13
  77. package/dist-es/descriptor.js +295 -241
  78. package/dist-es/descriptor.js.map +1 -1
  79. package/dist-es/helpers.d.ts +7 -1
  80. package/dist-es/helpers.js +246 -4
  81. package/dist-es/helpers.js.map +1 -1
  82. package/dist-es/imageResources.d.ts +15 -3
  83. package/dist-es/imageResources.js +586 -144
  84. package/dist-es/imageResources.js.map +1 -1
  85. package/dist-es/index.d.ts +1 -0
  86. package/dist-es/index.js +1 -0
  87. package/dist-es/index.js.map +1 -1
  88. package/dist-es/jpeg.js +8 -8
  89. package/dist-es/jpeg.js.map +1 -1
  90. package/dist-es/psd.d.ts +292 -19
  91. package/dist-es/psd.js.map +1 -1
  92. package/dist-es/psdReader.d.ts +10 -0
  93. package/dist-es/psdReader.js +424 -216
  94. package/dist-es/psdReader.js.map +1 -1
  95. package/dist-es/psdWriter.d.ts +2 -0
  96. package/dist-es/psdWriter.js +373 -113
  97. package/dist-es/psdWriter.js.map +1 -1
  98. package/dist-es/text.d.ts +32 -1
  99. package/dist-es/text.js +75 -6
  100. package/dist-es/text.js.map +1 -1
  101. package/dist-es/utf8.js +0 -3
  102. package/dist-es/utf8.js.map +1 -1
  103. package/package.json +2 -2
  104. package/perf.js +312 -9
  105. package/src/abr.ts +382 -235
  106. package/src/additionalInfo.ts +1071 -482
  107. package/src/ase.ts +66 -61
  108. package/src/descriptor.ts +291 -242
  109. package/src/helpers.ts +266 -3
  110. package/src/imageResources.ts +736 -169
  111. package/src/index.ts +1 -0
  112. package/src/jpeg.ts +8 -8
  113. package/src/psd.ts +271 -32
  114. package/src/psdReader.ts +440 -221
  115. package/src/psdWriter.ts +402 -110
  116. package/src/text.ts +93 -7
  117. package/src/utf8.ts +0 -4
package/src/text.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { TextStyle, LayerTextData, ParagraphStyle, Font, AntiAlias, TextGridInfo, Justification, Color, TextPath } from './psd';
1
+ import type { TextStyle, LayerTextData, ParagraphStyle, Font, AntiAlias, TextGridInfo, Justification, Color, TextPath, TextStyleRun } from './psd';
2
2
  import { clamp } from './helpers';
3
3
 
4
4
  interface Adjustments {
@@ -274,7 +274,16 @@ const styleKeys: (keyof TextStyle)[] = [
274
274
  'kashida', 'diacriticPos',
275
275
  ];
276
276
 
277
- const antialias: AntiAlias[] = ['none', 'crisp', 'strong', 'smooth', 'sharp'];
277
+ const antialias: (AntiAlias | undefined)[] = [
278
+ 'none', // 0
279
+ 'crisp', // 1
280
+ 'strong', // 2
281
+ 'smooth', // 3
282
+ 'sharp', // 4
283
+ undefined, // 5 - unknown
284
+ 'platformLCD', // 6
285
+ 'platform', // 7
286
+ ];
278
287
  const justification: Justification[] = [
279
288
  'left', // 0
280
289
  'right', // 1
@@ -360,8 +369,9 @@ function objectsEqual(a: any, b: any) {
360
369
  }
361
370
 
362
371
  function findOrAddFont(fonts: Font[], font: Font) {
372
+ // Photoshop writes separate entries for the same font with different synthetic (faux bold/italic) styles
363
373
  for (let i = 0; i < fonts.length; i++) {
364
- if (fonts[i].name === font.name) return i;
374
+ if (fonts[i].name === font.name && (fonts[i].synthetic || 0) === (font.synthetic || 0)) return i;
365
375
  }
366
376
 
367
377
  fonts.push(font);
@@ -578,7 +588,8 @@ export function decodeEngineData(engineData: EngineData) {
578
588
  }
579
589
 
580
590
  for (let counter = removedCharacters; result.paragraphStyleRuns.length && counter > 0; counter--) {
581
- if (--result.paragraphStyleRuns[result.paragraphStyleRuns.length - 1].length === 0) {
591
+ // keep 0 length run if it's for empty last paragraph, otherwise we lose its style
592
+ if (--result.paragraphStyleRuns[result.paragraphStyleRuns.length - 1].length === 0 && result.paragraphStyleRuns.length === 1) {
582
593
  result.paragraphStyleRuns.pop();
583
594
  }
584
595
  }
@@ -622,6 +633,81 @@ export function decodeEngineData(engineData: EngineData) {
622
633
  return result;
623
634
  }
624
635
 
636
+ // type tool info from Photoshop 5.0 and 5.5 ('tySh')
637
+ export interface LegacyTextData {
638
+ transform: number[];
639
+ faces: { mark: number; name: string; familyName: string; styleName: string; script: number; }[];
640
+ styles: {
641
+ mark: number; faceMark: number; size: number; tracking: number; kerning: number; leading: number;
642
+ baselineShift: number; autoKerning: boolean;
643
+ }[];
644
+ lines: { orientation: number; alignment: number; chars: { code: number; style: number; }[]; }[];
645
+ color: Color;
646
+ antiAlias: boolean;
647
+ }
648
+
649
+ const fixed = (value: number) => value / 0x10000; // 16.16 fixed point value
650
+
651
+ export function decodeLegacyTextData(data: LegacyTextData): LayerTextData {
652
+ const styleRuns: { length: number; mark: number; }[] = [];
653
+ let text = '';
654
+
655
+ for (const line of data.lines) {
656
+ for (const { code, style } of line.chars) {
657
+ text += String.fromCharCode(code);
658
+ const last = styleRuns[styleRuns.length - 1];
659
+
660
+ if (last && last.mark === style) {
661
+ last.length++;
662
+ } else {
663
+ styleRuns.push({ length: 1, mark: style });
664
+ }
665
+ }
666
+ }
667
+
668
+ // remove one trailing new line (Photoshop always appends it)
669
+ if (text.endsWith('\r')) {
670
+ text = text.slice(0, -1);
671
+ if (--styleRuns[styleRuns.length - 1].length === 0) styleRuns.pop();
672
+ }
673
+
674
+ const runs: TextStyleRun[] = styleRuns.map(({ length, mark }) => {
675
+ const s = data.styles.find(s => s.mark === mark) ?? data.styles[0];
676
+ const face = s && (data.faces.find(f => f.mark === s.faceMark) ?? data.faces[0]);
677
+ const style: TextStyle = {};
678
+
679
+ if (face) style.font = { name: face.name, script: face.script };
680
+
681
+ if (s) {
682
+ style.fontSize = fixed(s.size);
683
+ style.autoLeading = s.leading === 0;
684
+ if (s.leading) style.leading = fixed(s.leading);
685
+ style.tracking = Math.round(fixed(s.tracking) * 1000); // stored in ems
686
+ style.autoKerning = s.autoKerning;
687
+ style.kerning = Math.round(fixed(s.kerning) * 1000); // stored in ems
688
+ style.baselineShift = fixed(s.baselineShift);
689
+ }
690
+
691
+ style.fillColor = data.color;
692
+ return { length, style };
693
+ });
694
+
695
+ const result: LayerTextData = {
696
+ text: text.replace(/\r/g, '\n'),
697
+ transform: data.transform,
698
+ antiAlias: data.antiAlias ? 'smooth' : 'none',
699
+ orientation: data.lines[0]?.orientation === 1 ? 'vertical' : 'horizontal',
700
+ paragraphStyle: { justification: justification[data.lines[0]?.alignment ?? 0] ?? 'left' },
701
+ style: {},
702
+ styleRuns: runs,
703
+ };
704
+
705
+ deduplicateValues(result.style!, result.styleRuns!, styleKeys);
706
+ if (!result.styleRuns!.length) delete result.styleRuns;
707
+
708
+ return result;
709
+ }
710
+
625
711
  // Adjusts run lengths (specified in terms of the original text) for characters removed from the text
626
712
  // (\r characters of \r\n pairs that are collapsed into single \r)
627
713
  function adjustRunLengths<T extends { length: number; }>(runs: T[] | undefined, removed: number[]): T[] | undefined {
@@ -671,14 +757,14 @@ export function encodeEngineData(data: LayerTextData) {
671
757
  let runLength = Math.min(run.length, leftLength);
672
758
  leftLength -= runLength;
673
759
 
674
- if (!runLength) continue; // ignore 0 size runs
675
-
676
- // extend last run if it's only for trailing \r
760
+ // extend last run if it's only for trailing \r (last run has 0 length if it's for empty last paragraph)
677
761
  if (leftLength === 1 && run === paragraphRuns[paragraphRuns.length - 1]) {
678
762
  runLength++;
679
763
  leftLength--;
680
764
  }
681
765
 
766
+ if (!runLength) continue; // ignore 0 size runs
767
+
682
768
  paragraphRunLengthArray.push(runLength);
683
769
  paragraphRunArray.push({
684
770
  ParagraphSheet: {
package/src/utf8.ts CHANGED
@@ -113,10 +113,6 @@ export function encodeString(value: string): Uint8Array {
113
113
  // UTF-8 decoder implementing the WHATWG Encoding Standard's non-fatal error handling,
114
114
  // so malformed byte sequences are replaced with U+FFFD instead of throwing, matching TextDecoder.
115
115
  export function decodeString(value: Uint8Array): string {
116
- if (value.byteLength > 1000 && typeof TextDecoder !== 'undefined') {
117
- return (new TextDecoder()).decode(value);
118
- }
119
-
120
116
  const result: string[] = [];
121
117
 
122
118
  function pushCodePoint(code: number) {