ag-psd 31.0.3 → 33.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.
- package/.v8-cache/v24.7.0-x64-ef5a0af0/00d0e0b4 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/03e19709 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/05135617 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/0cc76730 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/1130885f +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/20729831 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/214a593b +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/226e2801 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/25f8b84a +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/27518289 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/2a19133e +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/330ef2d9 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/37ff16b8 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/3f72a97c +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/4511bacf +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/68416cb2 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/71df9cb3 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/75efccd4 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/762f9305 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/7bcfc50a +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/7ea06cea +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/825e9a05 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/87372817 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/87cf2209 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/891a7c73 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/8b68a3a2 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/932f0770 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/a1d12a93 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/a7e80865 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/ac317c9c +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/acc36e66 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/b3c2fab7 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/b8569d6b +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/b8b073c4 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/bb489c89 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/c0b789d2 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/c314aece +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/c46725e1 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/c794cb34 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/cd4ae980 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/cfc49f4f +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/cff9434a +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/d02dd6f7 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/dc86f000 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/e03e2acd +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/e6735171 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/e6745c2b +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/e6b99945 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/eeeebdfe +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/f5417276 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/f6fd8125 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/f74d3518 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/f886deac +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/fd0a2987 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/fe349423 +0 -0
- package/CHANGELOG.md +107 -0
- package/LICENSE +5 -0
- package/README.md +3 -6
- package/README_PSD.md +242 -81
- package/dist/abr.d.ts +11 -4
- package/dist/abr.js +363 -229
- package/dist/abr.js.map +1 -1
- package/dist/additionalInfo.d.ts +56 -2
- package/dist/additionalInfo.js +600 -364
- package/dist/additionalInfo.js.map +1 -1
- package/dist/ase.d.ts +6 -1
- package/dist/ase.js +61 -61
- package/dist/ase.js.map +1 -1
- package/dist/bundle.js +3096 -1541
- package/dist/descriptor.d.ts +25 -6
- package/dist/descriptor.js +380 -135
- package/dist/descriptor.js.map +1 -1
- package/dist/effectsHelpers.js +12 -12
- package/dist/effectsHelpers.js.map +1 -1
- package/dist/engineData.d.ts +3 -1
- package/dist/engineData.js +34 -13
- package/dist/engineData.js.map +1 -1
- package/dist/engineData2.js +50 -21
- package/dist/engineData2.js.map +1 -1
- package/dist/helpers.d.ts +6 -3
- package/dist/helpers.js +22 -6
- package/dist/helpers.js.map +1 -1
- package/dist/imageResources.d.ts +15 -3
- package/dist/imageResources.js +529 -144
- package/dist/imageResources.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/jpeg.js +30 -10
- package/dist/jpeg.js.map +1 -1
- package/dist/psd.d.ts +154 -18
- package/dist/psd.js.map +1 -1
- package/dist/psdReader.d.ts +12 -2
- package/dist/psdReader.js +720 -421
- package/dist/psdReader.js.map +1 -1
- package/dist/psdWriter.d.ts +3 -0
- package/dist/psdWriter.js +167 -130
- package/dist/psdWriter.js.map +1 -1
- package/dist/text.js +143 -29
- package/dist/text.js.map +1 -1
- package/dist/utf8.js +36 -18
- package/dist/utf8.js.map +1 -1
- package/dist-es/abr.d.ts +11 -4
- package/dist-es/abr.js +363 -229
- package/dist-es/abr.js.map +1 -1
- package/dist-es/additionalInfo.d.ts +56 -2
- package/dist-es/additionalInfo.js +600 -364
- package/dist-es/additionalInfo.js.map +1 -1
- package/dist-es/ase.d.ts +6 -1
- package/dist-es/ase.js +61 -61
- package/dist-es/ase.js.map +1 -1
- package/dist-es/descriptor.d.ts +25 -6
- package/dist-es/descriptor.js +380 -135
- package/dist-es/descriptor.js.map +1 -1
- package/dist-es/effectsHelpers.js +12 -12
- package/dist-es/effectsHelpers.js.map +1 -1
- package/dist-es/engineData.d.ts +3 -1
- package/dist-es/engineData.js +34 -13
- package/dist-es/engineData.js.map +1 -1
- package/dist-es/engineData2.js +50 -21
- package/dist-es/engineData2.js.map +1 -1
- package/dist-es/helpers.d.ts +6 -3
- package/dist-es/helpers.js +22 -6
- package/dist-es/helpers.js.map +1 -1
- package/dist-es/imageResources.d.ts +15 -3
- package/dist-es/imageResources.js +529 -144
- package/dist-es/imageResources.js.map +1 -1
- package/dist-es/index.js +1 -0
- package/dist-es/index.js.map +1 -1
- package/dist-es/jpeg.js +30 -10
- package/dist-es/jpeg.js.map +1 -1
- package/dist-es/psd.d.ts +154 -18
- package/dist-es/psd.js.map +1 -1
- package/dist-es/psdReader.d.ts +12 -2
- package/dist-es/psdReader.js +720 -421
- package/dist-es/psdReader.js.map +1 -1
- package/dist-es/psdWriter.d.ts +3 -0
- package/dist-es/psdWriter.js +167 -130
- package/dist-es/psdWriter.js.map +1 -1
- package/dist-es/text.js +143 -29
- package/dist-es/text.js.map +1 -1
- package/dist-es/utf8.js +36 -18
- package/dist-es/utf8.js.map +1 -1
- package/package.json +2 -2
- package/src/abr.ts +380 -232
- package/src/additionalInfo.ts +781 -477
- package/src/ase.ts +66 -61
- package/src/descriptor.ts +386 -142
- package/src/effectsHelpers.ts +9 -9
- package/src/engineData.ts +36 -13
- package/src/engineData2.ts +468 -432
- package/src/helpers.ts +23 -5
- package/src/imageResources.ts +658 -167
- package/src/index.ts +1 -0
- package/src/jpeg.ts +27 -12
- package/src/psd.ts +158 -30
- package/src/psdReader.ts +732 -414
- package/src/psdWriter.ts +186 -132
- package/src/text.ts +139 -18
- package/src/utf8.ts +35 -21
package/dist-es/descriptor.js
CHANGED
|
@@ -11,12 +11,15 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
return t;
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.
|
|
15
|
-
exports.presetKindType = exports.prjM = exports.FlMd = void 0;
|
|
14
|
+
exports.Drct = exports.WndM = exports.CntE = exports.FlCl = exports.ExtR = exports.ExtT = exports.DfsM = exports.blurType = exports.Lns = exports.MztT = exports.Chnl = exports.Dstr = exports.ZZTy = exports.Wvtp = exports.SphM = exports.RplS = exports.Cnvr = exports.UndA = exports.DspM = exports.SmBQ = exports.SmBM = exports.BlrQ = exports.BlrM = exports.strokeStyleLineAlignment = exports.strokeStyleLineJoinType = exports.strokeStyleLineCapType = exports.ESliceBGColorType = exports.ESliceOrigin = exports.ESliceVertAlign = exports.ESliceHorzAlign = exports.ESliceType = exports.FrFl = exports.FStl = exports.ClrS = exports.Clry = exports.gradientInterpolationMethodType = exports.stdTrackID = exports.animInterpStyleEnum = exports.GrdT = exports.IGSr = exports.BETE = exports.BESs = exports.bvlT = exports.BESl = exports.BlnM = exports.warpStyle = exports.Annt = exports.Ornt = exports.textGridding = exports.outputSettingsRoot = void 0;
|
|
15
|
+
exports.presetKindType = exports.prjM = exports.FlMd = exports.IntC = exports.IntE = void 0;
|
|
16
16
|
exports.setLogErrors = setLogErrors;
|
|
17
17
|
exports.readAsciiStringOrClassId = readAsciiStringOrClassId;
|
|
18
|
+
exports.writeAsciiStringOrClassId = writeAsciiStringOrClassId;
|
|
18
19
|
exports.readDescriptorStructure = readDescriptorStructure;
|
|
19
20
|
exports.writeDescriptorStructure = writeDescriptorStructure;
|
|
21
|
+
exports.pathSelectionStateToReference = pathSelectionStateToReference;
|
|
22
|
+
exports.writeClassStructure = writeClassStructure;
|
|
20
23
|
exports.readVersionAndDescriptor = readVersionAndDescriptor;
|
|
21
24
|
exports.writeVersionAndDescriptor = writeVersionAndDescriptor;
|
|
22
25
|
exports.horzVrtcToXY = horzVrtcToXY;
|
|
@@ -155,12 +158,15 @@ const fieldToExtType = {
|
|
|
155
158
|
origFXRefPoint: nullType,
|
|
156
159
|
FXRefPoint: nullType,
|
|
157
160
|
ClMg: makeType('', 'ClMg'),
|
|
161
|
+
interpretation: makeType('', 'footageInterpretation'),
|
|
162
|
+
bgColor: makeType('', 'NativeQuad'),
|
|
158
163
|
};
|
|
159
164
|
const fieldToArrayExtType = {
|
|
160
165
|
'Crv ': makeType('', 'CrPt'),
|
|
161
166
|
Clrs: makeType('', 'Clrt'),
|
|
162
167
|
Trns: makeType('', 'TrnS'),
|
|
163
168
|
keyDescriptorList: nullType,
|
|
169
|
+
keyRootDescriptorList: nullType,
|
|
164
170
|
solidFillMulti: makeType('', 'SoFi'),
|
|
165
171
|
gradientFillMulti: makeType('', 'GrFl'),
|
|
166
172
|
dropShadowMulti: makeType('', 'DrSh'),
|
|
@@ -188,20 +194,29 @@ const fieldToArrayExtType = {
|
|
|
188
194
|
layerSettings: nullType,
|
|
189
195
|
list: nullType,
|
|
190
196
|
Adjs: makeType('', 'CrvA'),
|
|
197
|
+
vertices: makeType('', 'Pnt '),
|
|
198
|
+
warpedVertices: makeType('', 'Pnt '),
|
|
199
|
+
quads: makeType('', 'quadIndices'),
|
|
191
200
|
};
|
|
192
201
|
const typeToField = {
|
|
193
202
|
'TEXT': [
|
|
194
|
-
'Txt ', 'printerName', 'Nm ', 'Idnt', 'blackAndWhitePresetFileName', 'LUT3DFileName',
|
|
203
|
+
'Txt ', 'printerName', 'Nm ', 'Idnt', 'blackAndWhitePresetFileName', 'LUT3DFileName', 'exportOption', 'scaleSettings',
|
|
204
|
+
'BackgroundImagePath', 'ImageSubfolderName',
|
|
195
205
|
'presetFileName', 'curvesPresetFileName', 'mixerPresetFileName', 'placed', 'description', 'reason',
|
|
196
206
|
'artboardPresetName', 'json', 'clipID', 'relPath', 'fullPath', 'mediaDescriptor', 'Msge',
|
|
197
|
-
'altTag', 'url', 'cellText', 'preset', 'KnNm', 'FPth', 'comment', 'originalPath',
|
|
207
|
+
'altTag', 'url', 'cellText', 'preset', 'KnNm', 'FPth', 'comment', 'originalPath', 'Bk ', 'pathUnicodeName',
|
|
198
208
|
],
|
|
199
209
|
'tdta': [
|
|
200
210
|
'EngineData', 'LUT3DFileData', 'indexArray', 'originalVertexArray', 'deformedVertexArray',
|
|
201
|
-
'LqMe',
|
|
211
|
+
'LqMe', 'bookKey',
|
|
202
212
|
],
|
|
203
213
|
'long': [
|
|
204
|
-
'TextIndex', 'RndS', 'Mdpn', 'Smth', 'Lctn', 'strokeStyleVersion', 'LaID', 'Vrsn', 'Cnt ',
|
|
214
|
+
'TextIndex', 'RndS', 'Mdpn', 'Smth', 'Lctn', 'strokeStyleVersion', 'LaID', 'Vrsn', 'Cnt ', 'bookID',
|
|
215
|
+
'cropRectBottom', 'cropRectLeft', 'cropRectRight', 'cropRectTop',
|
|
216
|
+
// save for web output settings
|
|
217
|
+
'Version', 'BackgroundColorBlue', 'BackgroundColorGreen', 'BackgroundColorRed', 'BackgroundColorState', 'AttributeCase', 'Encoding',
|
|
218
|
+
'DuplicateFileNameBehavior', 'ImageMapLocation', 'ImageMapType', 'Indent', 'LineEndings', 'SpacersEmptyCells',
|
|
219
|
+
'SpacersHorizontal', 'SpacersVertical', 'StylesFormat', 'TDWidthHeight', 'TagCase', 'ColorPolicy', 'MetadataPolicy',
|
|
205
220
|
'Brgh', 'Cntr', 'means', 'vibrance', 'Strt', 'bwPresetKind', 'comp', 'compID', 'originalCompID',
|
|
206
221
|
'curvesPresetKind', 'mixerPresetKind', 'uOrder', 'vOrder', 'PgNm', 'totalPages', 'Crop',
|
|
207
222
|
'numerator', 'denominator', 'frameCount', 'Annt', 'keyOriginType', 'unitValueQuadVersion',
|
|
@@ -213,6 +228,7 @@ const typeToField = {
|
|
|
213
228
|
'meshExpansion', 'meshRigidity', 'VrsM', 'VrsN', 'NmbG', 'WLMn', 'WLMx', 'AmMn', 'AmMx', 'SclH', 'SclV',
|
|
214
229
|
'Lvl ', 'TlNm', 'TlOf', 'FlRs', 'Thsh', 'ShrS', 'ShrE', 'FlRs', 'Vrnc', 'Strg', 'ExtS', 'ExtD',
|
|
215
230
|
'HrzS', 'VrtS', 'NmbR', 'EdgF', 'Ang1', 'Ang2', 'Ang3', 'Ang4', 'lastAppliedComp', 'capturedInfo',
|
|
231
|
+
'pixelSourceType',
|
|
216
232
|
],
|
|
217
233
|
'enum': [
|
|
218
234
|
'textGridding', 'Ornt', 'warpStyle', 'warpRotate', 'Inte', 'Bltn', 'ClrS', 'BlrQ',
|
|
@@ -222,7 +238,8 @@ const typeToField = {
|
|
|
222
238
|
'tableOrder', 'enableCompCore', 'enableCompCoreGPU', 'compCoreSupport', 'compCoreGPUSupport', 'Engn',
|
|
223
239
|
'enableCompCoreThreads', 'gs99', 'FrDs', 'trackID', 'animInterpStyle', 'horzAlign',
|
|
224
240
|
'vertAlign', 'bgColorType', 'shapeOperation', 'UndA', 'Wvtp', 'Drct', 'WndM', 'Edg ', 'FlCl', 'IntE',
|
|
225
|
-
'IntC', 'Cnvr', 'Fl ', 'Dstr', 'MztT', 'Lns ', 'ExtT', 'DspM', 'ExtR', 'ZZTy', 'SphM', 'SmBQ', 'placedLayerOCIOConversion', 'gradientsInterpolationMethod',
|
|
241
|
+
'IntC', 'Cnvr', 'Fl ', 'Dstr', 'MztT', 'Lns ', 'ExtT', 'DspM', 'ExtR', 'ZZTy', 'SphM', 'SmBQ', 'placedLayerOCIOConversion', 'gradientsInterpolationMethod', 'pathSymmetryMode',
|
|
242
|
+
'interpretAlpha',
|
|
226
243
|
],
|
|
227
244
|
'bool': [
|
|
228
245
|
'PstS', 'printSixteenBit', 'masterFXSwitch', 'enab', 'uglg', 'antialiasGloss',
|
|
@@ -235,14 +252,15 @@ const typeToField = {
|
|
|
235
252
|
'materialsDisclosed', 'hasMotion', 'muted', 'Effc', 'selected', 'autoScope', 'fillCanvas',
|
|
236
253
|
'cellTextIsHTML', 'Smoo', 'Clsp', 'validAtPosition', 'rigidType', 'hasoptions', 'filterMaskEnable',
|
|
237
254
|
'filterMaskLinked', 'filterMaskExtendWithWhite', 'removeJPEGArtifact', 'Mnch', 'ExtF', 'ExtM',
|
|
238
|
-
'moreAccurate', 'GpuY', 'LIWy', 'Cnty',
|
|
255
|
+
'moreAccurate', 'GpuY', 'LIWy', 'Cnty', 'Lnkd', 'showAlteredVideo', 'lightingOn',
|
|
239
256
|
],
|
|
240
257
|
'doub': [
|
|
241
|
-
'warpValue', 'warpPerspective', 'warpPerspectiveOther', 'Intr', 'Wdth', 'Hght',
|
|
258
|
+
'warpValue', 'warpPerspective', 'warpPerspectiveOther', 'Intr', 'Wdth', 'Hght', 'Gmm ',
|
|
242
259
|
'strokeStyleMiterLimit', 'strokeStyleResolution', 'layerTime', 'keyOriginResolution',
|
|
243
260
|
'xx', 'xy', 'yx', 'yy', 'tx', 'ty', 'FrGA', 'frameRate', 'audioLevel', 'rotation',
|
|
244
261
|
'X ', 'Y ', 'redFloat', 'greenFloat', 'blueFloat', 'imageResolution',
|
|
245
|
-
'PuX0', 'PuX1', 'PuX2', 'PuX3', 'PuY0', 'PuY1', 'PuY2', 'PuY3'
|
|
262
|
+
'PuX0', 'PuX1', 'PuX2', 'PuX3', 'PuY0', 'PuY1', 'PuY2', 'PuY3',
|
|
263
|
+
'stylization', 'cleanliness', 'brushScale', 'microBrush', 'specularity',
|
|
246
264
|
],
|
|
247
265
|
'UntF': [
|
|
248
266
|
'sdwO', 'hglO', 'lagl', 'Lald', 'srgR', 'blur', 'Sftn', 'Opct', 'Dstn', 'Angl',
|
|
@@ -251,29 +269,60 @@ const typeToField = {
|
|
|
251
269
|
'topRight', 'topLeft', 'bottomLeft', 'bottomRight', 'ClNs', 'Shrp',
|
|
252
270
|
],
|
|
253
271
|
'VlLs': [
|
|
254
|
-
'Crv ', 'Clrs', 'Mnm ', 'Mxm ', 'Trns', 'pathList', 'strokeStyleLineDashSet', 'FrLs', 'slices',
|
|
272
|
+
'Crv ', 'Clrs', 'Mnm ', 'Mxm ', 'Trns', 'pathList', 'keyRootDescriptorList', 'strokeStyleLineDashSet', 'FrLs', 'slices',
|
|
255
273
|
'LaSt', 'Trnf', 'nonAffineTransform', 'keyDescriptorList', 'guideIndeces', 'gradientFillMulti',
|
|
256
274
|
'solidFillMulti', 'frameFXMulti', 'innerShadowMulti', 'dropShadowMulti', 'FrIn', 'FSts', 'FsFr',
|
|
257
275
|
'sheetTimelineOptions', 'audioClipList', 'trackList', 'globalTrackList', 'keyList', 'audioClipList',
|
|
258
276
|
'warpValues', 'selectedPin', 'Pts ', 'SbpL', 'pathComponents', 'pinOffsets', 'posFinalPins',
|
|
259
277
|
'pinVertexIndices', 'PinP', 'PnRt', 'PnOv', 'PnDp', 'filterFXList', 'puppetShapeList', 'ShrP',
|
|
260
278
|
'channelDenoise', 'Mtrx', 'layerSettings', 'list', 'compList', 'Adjs',
|
|
279
|
+
'vertices', 'warpedVertices', 'quads', 'indices', 'Mpng',
|
|
261
280
|
],
|
|
262
281
|
'ObAr': ['meshPoints', 'quiltSliceX', 'quiltSliceY'],
|
|
263
282
|
'obj ': ['null', 'Chnl'],
|
|
264
283
|
'Pth ': ['DspF'],
|
|
284
|
+
'alis': ['alis'],
|
|
265
285
|
};
|
|
266
286
|
const channels = [
|
|
267
287
|
'Rd ', 'Grn ', 'Bl ', 'Yllw', 'Ylw ', 'Cyn ', 'Mgnt', 'Blck', 'Gry ', 'Lmnc', 'A ', 'B ',
|
|
268
288
|
];
|
|
289
|
+
// color classes whose channel values are written as doubles ('GRYC' and 'LABC' are kept for backwards compatibility)
|
|
290
|
+
const doubleColorClasses = ['Grsc', 'LbCl', 'GRYC', 'LABC'];
|
|
291
|
+
// fallback for unknown keys, based on the type of the value
|
|
292
|
+
function guessOSType(value) {
|
|
293
|
+
if (typeof value === 'boolean')
|
|
294
|
+
return 'bool';
|
|
295
|
+
if (typeof value === 'number' && !Number.isInteger(value))
|
|
296
|
+
return 'doub';
|
|
297
|
+
if (Array.isArray(value))
|
|
298
|
+
return 'VlLs';
|
|
299
|
+
if (value && typeof value === 'object') {
|
|
300
|
+
if (typeof value._classID === 'string')
|
|
301
|
+
return 'Objc';
|
|
302
|
+
if (typeof value.classID === 'string')
|
|
303
|
+
return 'type'; // class read from 'type' or 'GlbC'
|
|
304
|
+
if (typeof value.low === 'number' && typeof value.high === 'number')
|
|
305
|
+
return 'comp';
|
|
306
|
+
if (typeof value.units === 'string' && typeof value.value === 'number')
|
|
307
|
+
return 'UntF';
|
|
308
|
+
}
|
|
309
|
+
return undefined;
|
|
310
|
+
}
|
|
269
311
|
const fieldToArrayType = {
|
|
270
312
|
'Mnm ': 'long',
|
|
271
313
|
'Mxm ': 'long',
|
|
314
|
+
HtmlFileNameComponents: 'long', // save for web output settings
|
|
315
|
+
SavingFileNameComponents: 'long',
|
|
316
|
+
SliceFileNameComponents: 'long',
|
|
317
|
+
Inpt: 'long', // levels filter
|
|
318
|
+
Otpt: 'long', // levels filter
|
|
272
319
|
FrLs: 'long',
|
|
273
320
|
strokeStyleLineDashSet: 'UntF',
|
|
274
321
|
Trnf: 'doub',
|
|
275
322
|
nonAffineTransform: 'doub',
|
|
276
323
|
keyDescriptorList: 'Objc',
|
|
324
|
+
keyRootDescriptorList: 'Objc',
|
|
325
|
+
pathList: 'Objc',
|
|
277
326
|
gradientFillMulti: 'Objc',
|
|
278
327
|
solidFillMulti: 'Objc',
|
|
279
328
|
frameFXMulti: 'Objc',
|
|
@@ -305,6 +354,8 @@ const fieldToArrayType = {
|
|
|
305
354
|
Mtrx: 'long',
|
|
306
355
|
compList: 'long',
|
|
307
356
|
Chnl: 'enum',
|
|
357
|
+
indices: 'long',
|
|
358
|
+
Mpng: 'long',
|
|
308
359
|
};
|
|
309
360
|
const fieldToType = {};
|
|
310
361
|
for (const type of Object.keys(typeToField)) {
|
|
@@ -319,6 +370,7 @@ for (const field of Object.keys(fieldToExtType)) {
|
|
|
319
370
|
for (const field of Object.keys(fieldToArrayExtType)) {
|
|
320
371
|
fieldToArrayType[field] = 'Objc';
|
|
321
372
|
}
|
|
373
|
+
const pixelSourceOriginRoot = 'PixelSource.origin';
|
|
322
374
|
function getTypeByKey(key, value, root, parent) {
|
|
323
375
|
if (key === 'presetKind') {
|
|
324
376
|
return typeof value === 'string' ? 'enum' : 'long';
|
|
@@ -338,7 +390,7 @@ function getTypeByKey(key, value, root, parent) {
|
|
|
338
390
|
else if (key === 'AntA') {
|
|
339
391
|
return typeof value === 'string' ? 'enum' : 'bool';
|
|
340
392
|
}
|
|
341
|
-
else if ((key === 'Hrzn' || key === 'Vrtc') && (parent.Type === 'keyType.Pstn' || parent._classID === 'Ofst')) {
|
|
393
|
+
else if ((key === 'Hrzn' || key === 'Vrtc') && (parent.Type === 'keyType.Pstn' || parent._classID === 'Ofst' || root === pixelSourceOriginRoot)) {
|
|
342
394
|
return 'long';
|
|
343
395
|
}
|
|
344
396
|
else if (key === 'Hrzn' || key === 'Vrtc' || key === 'Top ' || key === 'Left' || key === 'Btom' || key === 'Rght') {
|
|
@@ -355,6 +407,24 @@ function getTypeByKey(key, value, root, parent) {
|
|
|
355
407
|
else if (key === 'Trnf') {
|
|
356
408
|
return Array.isArray(value) ? 'VlLs' : 'Objc';
|
|
357
409
|
}
|
|
410
|
+
else if (key === 'alpha' && root === 'slices') {
|
|
411
|
+
return 'long';
|
|
412
|
+
}
|
|
413
|
+
else if ((key === 'Inpt' || key === 'Otpt') && parent._classID === 'HsbP') {
|
|
414
|
+
return 'enum';
|
|
415
|
+
}
|
|
416
|
+
else if ((key === 'Inpt' || key === 'Otpt') && parent._classID === 'LvlA') {
|
|
417
|
+
return 'VlLs';
|
|
418
|
+
}
|
|
419
|
+
else if (key === 'Intr' && typeof value === 'boolean') {
|
|
420
|
+
return 'bool'; // interpolation in print style
|
|
421
|
+
}
|
|
422
|
+
else if (key === 'PgPs') {
|
|
423
|
+
return 'enum';
|
|
424
|
+
}
|
|
425
|
+
else if (key === 'LghD' && parent._classID === 'oilPaint') {
|
|
426
|
+
return 'long';
|
|
427
|
+
}
|
|
358
428
|
else {
|
|
359
429
|
return fieldToType[key];
|
|
360
430
|
}
|
|
@@ -364,7 +434,7 @@ function readAsciiStringOrClassId(reader) {
|
|
|
364
434
|
return (0, psdReader_1.readAsciiString)(reader, length || 4);
|
|
365
435
|
}
|
|
366
436
|
function writeAsciiStringOrClassId(writer, value) {
|
|
367
|
-
if (value.length === 4 && value !== 'warp' && value !== 'time' && value !== 'hold' && value !== 'list') {
|
|
437
|
+
if (value.length === 4 && value !== 'warp' && value !== 'time' && value !== 'hold' && value !== 'list' && value !== 'json') {
|
|
368
438
|
// write classId
|
|
369
439
|
(0, psdWriter_1.writeInt32)(writer, 0);
|
|
370
440
|
(0, psdWriter_1.writeSignature)(writer, value);
|
|
@@ -392,29 +462,36 @@ function readDescriptorStructure(reader, includeClass) {
|
|
|
392
462
|
}
|
|
393
463
|
return object;
|
|
394
464
|
}
|
|
465
|
+
exports.outputSettingsRoot = 'outputSettings';
|
|
395
466
|
function writeDescriptorStructure(writer, name, classId, value, root) {
|
|
396
467
|
if (logErrors && !classId)
|
|
397
468
|
console.log('Missing classId for: ', name, classId, value);
|
|
398
469
|
// write class structure
|
|
399
470
|
(0, psdWriter_1.writeUnicodeStringWithPadding)(writer, name);
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
471
|
+
if (root === exports.outputSettingsRoot && classId === 'null') {
|
|
472
|
+
// Photoshop writes 'null' class id as 4 character string in save for web output settings
|
|
473
|
+
(0, psdWriter_1.writeInt32)(writer, 4);
|
|
474
|
+
(0, psdWriter_1.writeSignature)(writer, classId);
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
writeAsciiStringOrClassId(writer, classId);
|
|
478
|
+
}
|
|
479
|
+
const allKeys = Object.keys(value);
|
|
480
|
+
const keys = allKeys.filter(key => key !== '_name' && key !== '_classID' && value[key] !== undefined);
|
|
481
|
+
(0, psdWriter_1.writeUint32)(writer, keys.length);
|
|
408
482
|
for (const key of keys) {
|
|
409
|
-
if (key === '_name' || key === '_classID')
|
|
410
|
-
continue;
|
|
411
483
|
let type = getTypeByKey(key, value[key], root, value);
|
|
484
|
+
let childRoot = root;
|
|
412
485
|
let extType = fieldToExtType[key];
|
|
413
486
|
if (key === 'bounds' && root === 'text') {
|
|
414
487
|
extType = makeType('', 'bounds');
|
|
415
488
|
}
|
|
416
489
|
else if (key === 'origin') {
|
|
417
490
|
type = root === 'slices' ? 'enum' : 'Objc';
|
|
491
|
+
if (classId === 'PixelSource') {
|
|
492
|
+
extType = nullType; // stored as 'null' class with integer Hrzn/Vrtc
|
|
493
|
+
childRoot = pixelSourceOriginRoot;
|
|
494
|
+
}
|
|
418
495
|
}
|
|
419
496
|
else if ((key === 'Cyn ' || key === 'Mgnt' || key === 'Ylw ' || key === 'Blck') && value._classID === 'CMYC') {
|
|
420
497
|
type = 'doub';
|
|
@@ -482,10 +559,14 @@ function writeDescriptorStructure(writer, name, classId, value, root) {
|
|
|
482
559
|
extType = nullType;
|
|
483
560
|
}
|
|
484
561
|
else if (channels.indexOf(key) !== -1) {
|
|
485
|
-
type = (classId === 'RGBC' && root !== 'artd') ? 'doub' : 'long';
|
|
562
|
+
type = ((classId === 'RGBC' && root !== 'artd') || doubleColorClasses.indexOf(classId) !== -1) ? 'doub' : 'long';
|
|
486
563
|
}
|
|
487
564
|
else if (key === 'profile') {
|
|
488
|
-
type = classId === 'printOutput' ? 'TEXT' : 'tdta';
|
|
565
|
+
type = (classId === 'printOutput' || classId === 'proofSetup') ? 'TEXT' : 'tdta';
|
|
566
|
+
}
|
|
567
|
+
else if (key === 'alis' && typeof value[key] === 'string') {
|
|
568
|
+
// 'alis' is read as a binary string (one char per byte), strings with wider chars can only be stored as TEXT
|
|
569
|
+
type = /[^\x00-\xff]/.test(value[key]) ? 'TEXT' : 'alis';
|
|
489
570
|
}
|
|
490
571
|
else if (key === 'strokeStyleContent') {
|
|
491
572
|
if (value[key]['Clr ']) {
|
|
@@ -504,14 +585,22 @@ function writeDescriptorStructure(writer, name, classId, value, root) {
|
|
|
504
585
|
else if (key === 'bounds' && root === 'quiltWarp') {
|
|
505
586
|
extType = makeType('', 'classFloatRect');
|
|
506
587
|
}
|
|
588
|
+
// guess color class from its fields (colors created by serializeColor always have _classID set)
|
|
507
589
|
if (extType && extType.classID === 'RGBC') {
|
|
508
590
|
if ('H ' in value[key])
|
|
509
591
|
extType = { classID: 'HSBC', name: '' };
|
|
510
|
-
|
|
592
|
+
else if ('Cyn ' in value[key])
|
|
593
|
+
extType = { classID: 'CMYC', name: '' };
|
|
594
|
+
else if ('Lmnc' in value[key])
|
|
595
|
+
extType = { classID: 'LbCl', name: '' };
|
|
596
|
+
else if ('Gry ' in value[key])
|
|
597
|
+
extType = { classID: 'Grsc', name: '' };
|
|
511
598
|
}
|
|
599
|
+
if (!type)
|
|
600
|
+
type = guessOSType(value[key]);
|
|
512
601
|
writeAsciiStringOrClassId(writer, key);
|
|
513
602
|
(0, psdWriter_1.writeSignature)(writer, type || 'long');
|
|
514
|
-
writeOSType(writer, type || 'long', value[key], key, extType,
|
|
603
|
+
writeOSType(writer, type || 'long', value[key], key, extType, childRoot);
|
|
515
604
|
if (logErrors && !type)
|
|
516
605
|
console.log(`Missing descriptor field type for: '${key}' in`, value);
|
|
517
606
|
}
|
|
@@ -579,7 +668,7 @@ function readOSType(reader, type, includeClass) {
|
|
|
579
668
|
case 'ObAr': { // Object array
|
|
580
669
|
(0, psdReader_1.readInt32)(reader); // version: 16
|
|
581
670
|
(0, psdReader_1.readUnicodeString)(reader); // name: ''
|
|
582
|
-
readAsciiStringOrClassId(reader); // 'rationalPoint'
|
|
671
|
+
readAsciiStringOrClassId(reader); // classID: 'rationalPoint'
|
|
583
672
|
const length = (0, psdReader_1.readInt32)(reader);
|
|
584
673
|
const items = [];
|
|
585
674
|
for (let i = 0; i < length; i++) {
|
|
@@ -613,6 +702,7 @@ const ObArTypes = {
|
|
|
613
702
|
quiltSliceY: 'UntF',
|
|
614
703
|
};
|
|
615
704
|
function writeOSType(writer, type, value, key, extType, root) {
|
|
705
|
+
var _a;
|
|
616
706
|
switch (type) {
|
|
617
707
|
case 'obj ': // Reference
|
|
618
708
|
writeReferenceStructure(writer, key, value);
|
|
@@ -621,9 +711,9 @@ function writeOSType(writer, type, value, key, extType, root) {
|
|
|
621
711
|
case 'GlbO': { // GlobalObject same as Descriptor
|
|
622
712
|
if (typeof value !== 'object')
|
|
623
713
|
throw new Error(`Invalid struct value: ${JSON.stringify(value)}, key: ${key}`);
|
|
624
|
-
if (!extType)
|
|
714
|
+
if (!extType && !value._classID)
|
|
625
715
|
throw new Error(`Missing ext type for: '${key}' (${JSON.stringify(value)})`);
|
|
626
|
-
const name = value._name || extType.name;
|
|
716
|
+
const name = value._name || (extType === null || extType === void 0 ? void 0 : extType.name) || '';
|
|
627
717
|
const classID = value._classID || extType.classID;
|
|
628
718
|
writeDescriptorStructure(writer, name, classID, value, root);
|
|
629
719
|
break;
|
|
@@ -633,7 +723,7 @@ function writeOSType(writer, type, value, key, extType, root) {
|
|
|
633
723
|
throw new Error(`Invalid list value: ${JSON.stringify(value)}, key: ${key}`);
|
|
634
724
|
(0, psdWriter_1.writeInt32)(writer, value.length);
|
|
635
725
|
for (let i = 0; i < value.length; i++) {
|
|
636
|
-
const type = fieldToArrayType[key];
|
|
726
|
+
const type = (_a = fieldToArrayType[key]) !== null && _a !== void 0 ? _a : guessOSType(value[i]);
|
|
637
727
|
(0, psdWriter_1.writeSignature)(writer, type || 'long');
|
|
638
728
|
writeOSType(writer, type || 'long', value[i], `${key}[]`, fieldToArrayExtType[key], root);
|
|
639
729
|
if (logErrors && !type)
|
|
@@ -671,20 +761,35 @@ function writeOSType(writer, type, value, key, extType, root) {
|
|
|
671
761
|
case 'long': // Integer
|
|
672
762
|
if (typeof value !== 'number')
|
|
673
763
|
throw new Error(`Invalid integer value: ${JSON.stringify(value)}, key: ${key}`);
|
|
674
|
-
(0, psdWriter_1.writeInt32)(writer, value);
|
|
764
|
+
(0, psdWriter_1.writeInt32)(writer, Math.round(value)); // round instead of truncating fractional values
|
|
765
|
+
break;
|
|
766
|
+
case 'comp': // Large Integer
|
|
767
|
+
if (!value || typeof value !== 'object')
|
|
768
|
+
throw new Error(`Invalid large integer value: ${JSON.stringify(value)}, key: ${key}`);
|
|
769
|
+
(0, psdWriter_1.writeUint32)(writer, value.low >>> 0);
|
|
770
|
+
(0, psdWriter_1.writeUint32)(writer, value.high >>> 0);
|
|
675
771
|
break;
|
|
676
|
-
// case 'comp': // Large Integer
|
|
677
|
-
// writeLargeInteger(reader);
|
|
678
772
|
case 'bool': // Boolean
|
|
679
773
|
if (typeof value !== 'boolean')
|
|
680
774
|
throw new Error(`Invalid boolean value: ${JSON.stringify(value)}, key: ${key}`);
|
|
681
775
|
(0, psdWriter_1.writeUint8)(writer, value ? 1 : 0);
|
|
682
776
|
break;
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
777
|
+
case 'type': // Class
|
|
778
|
+
case 'GlbC': // Class
|
|
779
|
+
if (!value || typeof value !== 'object')
|
|
780
|
+
throw new Error(`Invalid class value: ${JSON.stringify(value)}, key: ${key}`);
|
|
781
|
+
(0, psdWriter_1.writeUnicodeStringWithPadding)(writer, value.name || '');
|
|
782
|
+
writeAsciiStringOrClassId(writer, value.classID);
|
|
783
|
+
break;
|
|
784
|
+
case 'alis': { // Alias (read as a binary string, one char per byte)
|
|
785
|
+
if (typeof value !== 'string')
|
|
786
|
+
throw new Error(`Invalid alias value: ${JSON.stringify(value)}, key: ${key}`);
|
|
787
|
+
(0, psdWriter_1.writeInt32)(writer, value.length);
|
|
788
|
+
for (let i = 0; i < value.length; i++) {
|
|
789
|
+
(0, psdWriter_1.writeUint8)(writer, value.charCodeAt(i) & 0xff);
|
|
790
|
+
}
|
|
791
|
+
break;
|
|
792
|
+
}
|
|
688
793
|
case 'tdta': // Raw Data
|
|
689
794
|
(0, psdWriter_1.writeInt32)(writer, value.byteLength);
|
|
690
795
|
(0, psdWriter_1.writeBytes)(writer, value);
|
|
@@ -709,97 +814,127 @@ function writeOSType(writer, type, value, key, extType, root) {
|
|
|
709
814
|
break;
|
|
710
815
|
}
|
|
711
816
|
case 'Pth ': { // File path
|
|
712
|
-
const
|
|
817
|
+
const path = value.path + '\0'; // Photoshop stores trailing null character (stripped when reading)
|
|
818
|
+
const length = 4 + 4 + 4 + path.length * 2;
|
|
713
819
|
(0, psdWriter_1.writeInt32)(writer, length);
|
|
714
820
|
(0, psdWriter_1.writeSignature)(writer, value.sig);
|
|
715
821
|
(0, psdWriter_1.writeInt32LE)(writer, length);
|
|
716
|
-
(0, psdWriter_1.writeInt32LE)(writer,
|
|
717
|
-
(0, psdWriter_1.writeUnicodeStringWithoutLengthLE)(writer,
|
|
822
|
+
(0, psdWriter_1.writeInt32LE)(writer, path.length);
|
|
823
|
+
(0, psdWriter_1.writeUnicodeStringWithoutLengthLE)(writer, path);
|
|
718
824
|
break;
|
|
719
825
|
}
|
|
720
826
|
default:
|
|
721
827
|
throw new Error(`Not implemented descriptor OSType: ${type}`);
|
|
722
828
|
}
|
|
723
829
|
}
|
|
830
|
+
const referenceTypes = ['prop', 'Clss', 'Enmr', 'rele', 'Idnt', 'indx', 'name'];
|
|
831
|
+
function isReferenceItem(value) {
|
|
832
|
+
return !!value && typeof value === 'object' && referenceTypes.indexOf(value.type) !== -1;
|
|
833
|
+
}
|
|
724
834
|
function readReferenceStructure(reader) {
|
|
725
835
|
const itemsCount = (0, psdReader_1.readInt32)(reader);
|
|
726
836
|
const items = [];
|
|
727
837
|
for (let i = 0; i < itemsCount; i++) {
|
|
728
838
|
const type = (0, psdReader_1.readSignature)(reader);
|
|
729
839
|
switch (type) {
|
|
730
|
-
case 'prop':
|
|
840
|
+
case 'prop': // Property
|
|
731
841
|
readClassStructure(reader);
|
|
732
|
-
|
|
733
|
-
items.push(keyID);
|
|
842
|
+
items.push(readAsciiStringOrClassId(reader));
|
|
734
843
|
break;
|
|
735
|
-
}
|
|
736
844
|
case 'Clss': // Class
|
|
737
845
|
items.push(readClassStructure(reader));
|
|
738
846
|
break;
|
|
739
847
|
case 'Enmr': { // Enumerated Reference
|
|
740
848
|
readClassStructure(reader);
|
|
741
849
|
const typeID = readAsciiStringOrClassId(reader);
|
|
742
|
-
const
|
|
743
|
-
items.push(`${typeID}.${
|
|
850
|
+
const enumValue = readAsciiStringOrClassId(reader);
|
|
851
|
+
items.push(`${typeID}.${enumValue}`);
|
|
744
852
|
break;
|
|
745
853
|
}
|
|
746
|
-
case 'rele':
|
|
747
|
-
// const { name, classID } =
|
|
854
|
+
case 'rele': // Offset
|
|
748
855
|
readClassStructure(reader);
|
|
749
856
|
items.push((0, psdReader_1.readUint32)(reader));
|
|
750
857
|
break;
|
|
751
|
-
}
|
|
752
858
|
case 'Idnt': // Identifier
|
|
753
|
-
items.push((0, psdReader_1.readInt32)(reader));
|
|
754
|
-
break;
|
|
755
859
|
case 'indx': // Index
|
|
756
860
|
items.push((0, psdReader_1.readInt32)(reader));
|
|
757
861
|
break;
|
|
758
|
-
case 'name':
|
|
862
|
+
case 'name': // Name
|
|
759
863
|
readClassStructure(reader);
|
|
760
864
|
items.push((0, psdReader_1.readUnicodeString)(reader));
|
|
761
865
|
break;
|
|
762
|
-
}
|
|
763
866
|
default:
|
|
764
867
|
throw new Error(`Invalid descriptor reference type: ${type}`);
|
|
765
868
|
}
|
|
766
869
|
}
|
|
767
870
|
return items;
|
|
768
871
|
}
|
|
872
|
+
function guessReferenceItem(value) {
|
|
873
|
+
if (typeof value === 'string') {
|
|
874
|
+
// enumerated references are read as `${typeID}.${enumValue}` where typeID is a 4 character ID or a string ID
|
|
875
|
+
// (values like 'My.Path' or 'Logo.v2' can't be typeID/enum value, so they are written as name references)
|
|
876
|
+
const match = /^([a-z ]{4}|[a-z]{5,})\.([a-z ]+)$/i.exec(value);
|
|
877
|
+
if (match) {
|
|
878
|
+
return { type: 'Enmr', _name: '', _classID: match[1], typeID: match[1], enumValue: match[2] };
|
|
879
|
+
}
|
|
880
|
+
else {
|
|
881
|
+
return { type: 'name', _name: '', _classID: 'Lyr ', value };
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
else if (typeof value === 'number') {
|
|
885
|
+
return { type: 'Idnt', value };
|
|
886
|
+
}
|
|
887
|
+
else if (value && typeof value === 'object' && typeof value.classID === 'string') {
|
|
888
|
+
return { type: 'Clss', _name: value.name || '', _classID: value.classID };
|
|
889
|
+
}
|
|
890
|
+
else {
|
|
891
|
+
throw new Error(`Invalid descriptor reference value: ${JSON.stringify(value)}`);
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
// path selection state (image resource 1088) is a reference to paths, enumerated references there use 'Path' class
|
|
895
|
+
// (name references use 'Lyr ' class, they reference layer of the vector mask)
|
|
896
|
+
function pathSelectionStateToReference(items) {
|
|
897
|
+
return items.map(value => {
|
|
898
|
+
const item = guessReferenceItem(value);
|
|
899
|
+
if (item.type === 'Enmr')
|
|
900
|
+
item._classID = 'Path';
|
|
901
|
+
return item;
|
|
902
|
+
});
|
|
903
|
+
}
|
|
769
904
|
function writeReferenceStructure(writer, _key, items) {
|
|
905
|
+
if (!Array.isArray(items))
|
|
906
|
+
throw new Error(`Invalid reference value: ${JSON.stringify(items)}, key: ${_key}`);
|
|
770
907
|
(0, psdWriter_1.writeInt32)(writer, items.length);
|
|
771
|
-
for (
|
|
772
|
-
const
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
else {
|
|
779
|
-
type = 'name';
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
(0, psdWriter_1.writeSignature)(writer, type);
|
|
783
|
-
switch (type) {
|
|
784
|
-
// case 'prop': // Property
|
|
785
|
-
// case 'Clss': // Class
|
|
786
|
-
case 'Enmr': { // Enumerated Reference
|
|
787
|
-
const [typeID, enumValue] = value.split('.');
|
|
788
|
-
writeClassStructure(writer, '\0', typeID);
|
|
789
|
-
writeAsciiStringOrClassId(writer, typeID);
|
|
790
|
-
writeAsciiStringOrClassId(writer, enumValue);
|
|
908
|
+
for (const value of items) {
|
|
909
|
+
const item = isReferenceItem(value) ? value : guessReferenceItem(value);
|
|
910
|
+
(0, psdWriter_1.writeSignature)(writer, item.type);
|
|
911
|
+
switch (item.type) {
|
|
912
|
+
case 'prop': // Property
|
|
913
|
+
writeClassStructure(writer, item._name || '', item._classID);
|
|
914
|
+
writeAsciiStringOrClassId(writer, item.keyID);
|
|
791
915
|
break;
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
(
|
|
916
|
+
case 'Clss': // Class
|
|
917
|
+
writeClassStructure(writer, item._name || '', item._classID);
|
|
918
|
+
break;
|
|
919
|
+
case 'Enmr': // Enumerated Reference
|
|
920
|
+
writeClassStructure(writer, item._name || '', item._classID);
|
|
921
|
+
writeAsciiStringOrClassId(writer, item.typeID);
|
|
922
|
+
writeAsciiStringOrClassId(writer, item.enumValue);
|
|
923
|
+
break;
|
|
924
|
+
case 'rele': // Offset
|
|
925
|
+
writeClassStructure(writer, item._name || '', item._classID);
|
|
926
|
+
(0, psdWriter_1.writeUint32)(writer, item.value);
|
|
927
|
+
break;
|
|
928
|
+
case 'Idnt': // Identifier
|
|
929
|
+
case 'indx': // Index
|
|
930
|
+
(0, psdWriter_1.writeInt32)(writer, item.value);
|
|
931
|
+
break;
|
|
932
|
+
case 'name': // Name
|
|
933
|
+
writeClassStructure(writer, item._name || '', item._classID);
|
|
934
|
+
(0, psdWriter_1.writeUnicodeStringWithPadding)(writer, `${item.value}`);
|
|
799
935
|
break;
|
|
800
|
-
}
|
|
801
936
|
default:
|
|
802
|
-
throw new Error(`Invalid descriptor reference type: ${type}`);
|
|
937
|
+
throw new Error(`Invalid descriptor reference type: ${item.type}`);
|
|
803
938
|
}
|
|
804
939
|
}
|
|
805
940
|
return items;
|
|
@@ -810,7 +945,7 @@ function readClassStructure(reader) {
|
|
|
810
945
|
return { name, classID };
|
|
811
946
|
}
|
|
812
947
|
function writeClassStructure(writer, name, classID) {
|
|
813
|
-
(0, psdWriter_1.
|
|
948
|
+
(0, psdWriter_1.writeUnicodeStringWithPadding)(writer, name);
|
|
814
949
|
writeAsciiStringOrClassId(writer, classID);
|
|
815
950
|
}
|
|
816
951
|
function readVersionAndDescriptor(reader, includeClass = false) {
|
|
@@ -854,7 +989,7 @@ function parseFxObject(fx) {
|
|
|
854
989
|
fillType: exports.FrFl.decode(fx.PntT),
|
|
855
990
|
blendMode: exports.BlnM.decode(fx['Md ']),
|
|
856
991
|
opacity: parsePercent(fx.Opct),
|
|
857
|
-
size:
|
|
992
|
+
size: parseUnitsOrNumber(fx['Sz ']), // stored as number (pixels) in old versions
|
|
858
993
|
};
|
|
859
994
|
if (fx.present !== undefined)
|
|
860
995
|
stroke.present = fx.present;
|
|
@@ -942,9 +1077,11 @@ function serializeEffects(e, log, multi) {
|
|
|
942
1077
|
info.numModifyingFX = 0;
|
|
943
1078
|
for (const key of Object.keys(e)) {
|
|
944
1079
|
const value = e[key];
|
|
1080
|
+
if (value == null || typeof value !== 'object')
|
|
1081
|
+
continue;
|
|
945
1082
|
if (Array.isArray(value)) {
|
|
946
1083
|
for (const effect of value) {
|
|
947
|
-
if (effect.enabled)
|
|
1084
|
+
if (effect === null || effect === void 0 ? void 0 : effect.enabled)
|
|
948
1085
|
info.numModifyingFX++;
|
|
949
1086
|
}
|
|
950
1087
|
}
|
|
@@ -957,11 +1094,11 @@ function serializeEffects(e, log, multi) {
|
|
|
957
1094
|
}
|
|
958
1095
|
function parseEffects(info, log) {
|
|
959
1096
|
const effects = {};
|
|
960
|
-
const { masterFXSwitch, DrSh, dropShadowMulti, IrSh, innerShadowMulti, OrGl, IrGl, ebbl, SoFi, solidFillMulti, patternFill, GrFl, gradientFillMulti, ChFX, FrFX, frameFXMulti, numModifyingFX } =
|
|
1097
|
+
const _a = info, { _name, _classID, 'Scl ': scale, masterFXSwitch, DrSh, dropShadowMulti, IrSh, innerShadowMulti, OrGl, IrGl, ebbl, SoFi, solidFillMulti, patternFill, GrFl, gradientFillMulti, ChFX, FrFX, frameFXMulti, numModifyingFX } = _a, rest = __rest(_a, ["_name", "_classID", 'Scl ', "masterFXSwitch", "DrSh", "dropShadowMulti", "IrSh", "innerShadowMulti", "OrGl", "IrGl", "ebbl", "SoFi", "solidFillMulti", "patternFill", "GrFl", "gradientFillMulti", "ChFX", "FrFX", "frameFXMulti", "numModifyingFX"]);
|
|
961
1098
|
if (!masterFXSwitch)
|
|
962
1099
|
effects.disabled = true;
|
|
963
|
-
if (
|
|
964
|
-
effects.scale = parsePercent(
|
|
1100
|
+
if (scale)
|
|
1101
|
+
effects.scale = parsePercent(scale);
|
|
965
1102
|
if (DrSh)
|
|
966
1103
|
effects.dropShadow = [parseEffectObject(DrSh, log)];
|
|
967
1104
|
if (dropShadowMulti)
|
|
@@ -975,7 +1112,7 @@ function parseEffects(info, log) {
|
|
|
975
1112
|
if (IrGl)
|
|
976
1113
|
effects.innerGlow = parseEffectObject(IrGl, log);
|
|
977
1114
|
if (ebbl)
|
|
978
|
-
effects.bevel = parseEffectObject(ebbl, log);
|
|
1115
|
+
effects.bevel = parseEffectObject(ebbl, log, 'bevel');
|
|
979
1116
|
if (SoFi)
|
|
980
1117
|
effects.solidFill = [parseEffectObject(SoFi, log)];
|
|
981
1118
|
if (solidFillMulti)
|
|
@@ -992,7 +1129,7 @@ function parseEffects(info, log) {
|
|
|
992
1129
|
effects.stroke = [parseFxObject(FrFX)];
|
|
993
1130
|
if (frameFXMulti)
|
|
994
1131
|
effects.stroke = frameFXMulti.map(i => parseFxObject(i));
|
|
995
|
-
if (log && Object.keys(rest).length
|
|
1132
|
+
if (log && Object.keys(rest).length)
|
|
996
1133
|
console.log('Unhandled effect keys:', rest);
|
|
997
1134
|
return effects;
|
|
998
1135
|
}
|
|
@@ -1093,7 +1230,7 @@ function serializeTrackList(tracks) {
|
|
|
1093
1230
|
const t = tracks[i];
|
|
1094
1231
|
trackList.push(Object.assign(Object.assign({ trackID: exports.stdTrackID.encode(t.type), Vrsn: 1, enab: !!t.enabled, Effc: !!t.effectParams }, (t.effectParams ? {
|
|
1095
1232
|
effectParams: {
|
|
1096
|
-
keyList: serializeKeyList(t.keys),
|
|
1233
|
+
keyList: serializeKeyList(t.effectParams.keys),
|
|
1097
1234
|
fillCanvas: t.effectParams.fillCanvas,
|
|
1098
1235
|
zoomOrigin: t.effectParams.zoomOrigin,
|
|
1099
1236
|
}
|
|
@@ -1101,7 +1238,7 @@ function serializeTrackList(tracks) {
|
|
|
1101
1238
|
}
|
|
1102
1239
|
return trackList;
|
|
1103
1240
|
}
|
|
1104
|
-
function parseEffectObject(obj, reportErrors) {
|
|
1241
|
+
function parseEffectObject(obj, reportErrors, objName) {
|
|
1105
1242
|
const result = {};
|
|
1106
1243
|
for (const key of Object.keys(obj)) {
|
|
1107
1244
|
const val = obj[key];
|
|
@@ -1166,7 +1303,8 @@ function parseEffectObject(obj, reportErrors) {
|
|
|
1166
1303
|
case 'Type':
|
|
1167
1304
|
result.type = exports.GrdT.decode(val);
|
|
1168
1305
|
break;
|
|
1169
|
-
case 'gs99':
|
|
1306
|
+
case 'gs99': // gradient overlay
|
|
1307
|
+
case 'gradientsInterpolationMethod': // glows
|
|
1170
1308
|
result.interpolationMethod = exports.gradientInterpolationMethodType.decode(val);
|
|
1171
1309
|
break;
|
|
1172
1310
|
case 'Opct':
|
|
@@ -1218,18 +1356,26 @@ function parseEffectObject(obj, reportErrors) {
|
|
|
1218
1356
|
result.pattern = { name: val['Nm '], id: val.Idnt };
|
|
1219
1357
|
break;
|
|
1220
1358
|
case 'phase':
|
|
1221
|
-
result.phase =
|
|
1359
|
+
result.phase = parsePhase(val);
|
|
1222
1360
|
break;
|
|
1223
1361
|
case 'Ofst':
|
|
1224
1362
|
result.offset = { x: parsePercent(val.Hrzn), y: parsePercent(val.Vrtc) };
|
|
1225
1363
|
break;
|
|
1226
1364
|
case 'MpgS':
|
|
1227
|
-
case 'TrnS':
|
|
1228
|
-
|
|
1365
|
+
case 'TrnS': {
|
|
1366
|
+
const contour = {
|
|
1229
1367
|
name: val['Nm '],
|
|
1230
1368
|
curve: val['Crv '].map(p => ({ x: p.Hrzn, y: p.Vrtc })),
|
|
1231
1369
|
};
|
|
1370
|
+
// bevel can have both: gloss contour (TrnS) and contour of the shape (MpgS)
|
|
1371
|
+
if (objName === 'bevel' && key === 'MpgS') {
|
|
1372
|
+
result.shapeContour = contour;
|
|
1373
|
+
}
|
|
1374
|
+
else {
|
|
1375
|
+
result.contour = contour;
|
|
1376
|
+
}
|
|
1232
1377
|
break;
|
|
1378
|
+
}
|
|
1233
1379
|
case 'Grad':
|
|
1234
1380
|
result.gradient = parseGradient(val);
|
|
1235
1381
|
break;
|
|
@@ -1324,7 +1470,7 @@ function serializeEffectObject(obj, objName, reportErrors) {
|
|
|
1324
1470
|
result.Type = exports.GrdT.encode(val);
|
|
1325
1471
|
break;
|
|
1326
1472
|
case 'interpolationMethod':
|
|
1327
|
-
result
|
|
1473
|
+
result[(objName === 'outerGlow' || objName === 'innerGlow') ? 'gradientsInterpolationMethod' : 'gs99'] = exports.gradientInterpolationMethodType.encode(val);
|
|
1328
1474
|
break;
|
|
1329
1475
|
case 'opacity':
|
|
1330
1476
|
result.Opct = unitsPercent(val);
|
|
@@ -1336,7 +1482,7 @@ function serializeEffectObject(obj, objName, reportErrors) {
|
|
|
1336
1482
|
result.sdwO = unitsPercent(val);
|
|
1337
1483
|
break;
|
|
1338
1484
|
case 'angle':
|
|
1339
|
-
if (objName === 'gradientOverlay' || objName === '
|
|
1485
|
+
if (objName === 'gradientOverlay' || objName === 'patternOverlay') {
|
|
1340
1486
|
result.Angl = unitsAngle(val);
|
|
1341
1487
|
}
|
|
1342
1488
|
else {
|
|
@@ -1380,15 +1526,14 @@ function serializeEffectObject(obj, objName, reportErrors) {
|
|
|
1380
1526
|
result.phase = { Hrzn: val.x, Vrtc: val.y };
|
|
1381
1527
|
break;
|
|
1382
1528
|
case 'offset':
|
|
1383
|
-
result.Ofst = { Hrzn:
|
|
1529
|
+
result.Ofst = { Hrzn: unitsPercentF(val.x), Vrtc: unitsPercentF(val.y) };
|
|
1384
1530
|
break;
|
|
1385
|
-
case 'contour':
|
|
1386
|
-
result[objName === 'satin' ? 'MpgS' : 'TrnS'] =
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1531
|
+
case 'contour':
|
|
1532
|
+
result[objName === 'satin' ? 'MpgS' : 'TrnS'] = serializeContour(val);
|
|
1533
|
+
break;
|
|
1534
|
+
case 'shapeContour':
|
|
1535
|
+
result.MpgS = serializeContour(val);
|
|
1390
1536
|
break;
|
|
1391
|
-
}
|
|
1392
1537
|
case 'gradient':
|
|
1393
1538
|
result.Grad = serializeGradient(val);
|
|
1394
1539
|
break;
|
|
@@ -1406,18 +1551,36 @@ function serializeEffectObject(obj, objName, reportErrors) {
|
|
|
1406
1551
|
}
|
|
1407
1552
|
return result;
|
|
1408
1553
|
}
|
|
1554
|
+
function serializeContour(contour) {
|
|
1555
|
+
return {
|
|
1556
|
+
'Nm ': contour.name,
|
|
1557
|
+
'Crv ': contour.curve.map(p => ({ Hrzn: p.x, Vrtc: p.y })),
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1409
1560
|
function parseGradient(grad) {
|
|
1410
1561
|
if (grad.GrdF === 'GrdF.CstS') {
|
|
1411
|
-
|
|
1562
|
+
// stop locations are always in 0..4096 range, independent of smoothness (Intr)
|
|
1563
|
+
const samples = 4096;
|
|
1412
1564
|
return {
|
|
1413
1565
|
type: 'solid',
|
|
1414
1566
|
name: grad['Nm '],
|
|
1415
1567
|
smoothness: grad.Intr / 4096,
|
|
1416
|
-
colorStops: grad.Clrs.map(s =>
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1568
|
+
colorStops: grad.Clrs.map(s => {
|
|
1569
|
+
const stop = {
|
|
1570
|
+
color: s['Clr '] ? parseColor(s['Clr ']) : { r: 0, g: 0, b: 0 },
|
|
1571
|
+
location: s.Lctn / samples,
|
|
1572
|
+
midpoint: s.Mdpn / 100,
|
|
1573
|
+
};
|
|
1574
|
+
if (s.Type) {
|
|
1575
|
+
try {
|
|
1576
|
+
const type = exports.Clry.decode(s.Type);
|
|
1577
|
+
if (type !== 'user')
|
|
1578
|
+
stop.type = type;
|
|
1579
|
+
}
|
|
1580
|
+
catch (_a) { } // unknown stop type, read as user color
|
|
1581
|
+
}
|
|
1582
|
+
return stop;
|
|
1583
|
+
}),
|
|
1421
1584
|
opacityStops: grad.Trns.map(s => ({
|
|
1422
1585
|
opacity: parsePercent(s.Opct),
|
|
1423
1586
|
location: s.Lctn / samples,
|
|
@@ -1442,24 +1605,25 @@ function parseGradient(grad) {
|
|
|
1442
1605
|
function serializeGradient(grad) {
|
|
1443
1606
|
var _a, _b;
|
|
1444
1607
|
if (grad.type === 'solid') {
|
|
1445
|
-
|
|
1608
|
+
// stop locations are always in 0..4096 range, independent of smoothness (Intr)
|
|
1609
|
+
const samples = 4096;
|
|
1446
1610
|
return {
|
|
1447
1611
|
'Nm ': grad.name || '',
|
|
1448
1612
|
GrdF: 'GrdF.CstS',
|
|
1449
|
-
Intr:
|
|
1613
|
+
Intr: Math.round(((_a = grad.smoothness) !== null && _a !== void 0 ? _a : 1) * 4096),
|
|
1450
1614
|
Clrs: grad.colorStops.map(s => {
|
|
1451
|
-
var _a;
|
|
1615
|
+
var _a, _b;
|
|
1452
1616
|
return ({
|
|
1453
1617
|
'Clr ': serializeColor(s.color),
|
|
1454
|
-
Type:
|
|
1618
|
+
Type: exports.Clry.encode((_a = s.type) !== null && _a !== void 0 ? _a : 'user'),
|
|
1455
1619
|
Lctn: Math.round(s.location * samples),
|
|
1456
|
-
Mdpn: Math.round(((
|
|
1620
|
+
Mdpn: Math.round(((_b = s.midpoint) !== null && _b !== void 0 ? _b : 0.5) * 100),
|
|
1457
1621
|
});
|
|
1458
1622
|
}),
|
|
1459
1623
|
Trns: grad.opacityStops.map(s => {
|
|
1460
1624
|
var _a;
|
|
1461
1625
|
return ({
|
|
1462
|
-
Opct:
|
|
1626
|
+
Opct: unitsPercentF(s.opacity),
|
|
1463
1627
|
Lctn: Math.round(s.location * samples),
|
|
1464
1628
|
Mdpn: Math.round(((_a = s.midpoint) !== null && _a !== void 0 ? _a : 0.5) * 100),
|
|
1465
1629
|
});
|
|
@@ -1475,8 +1639,8 @@ function serializeGradient(grad) {
|
|
|
1475
1639
|
ClrS: exports.ClrS.encode(grad.colorModel),
|
|
1476
1640
|
RndS: grad.randomSeed || 0,
|
|
1477
1641
|
Smth: Math.round(((_b = grad.roughness) !== null && _b !== void 0 ? _b : 1) * 4096),
|
|
1478
|
-
'Mnm ': (grad.min || [0, 0, 0, 0]).map(x => x * 100),
|
|
1479
|
-
'Mxm ': (grad.max || [1, 1, 1, 1]).map(x => x * 100),
|
|
1642
|
+
'Mnm ': (grad.min || [0, 0, 0, 0]).map(x => Math.round(x * 100)),
|
|
1643
|
+
'Mxm ': (grad.max || [1, 1, 1, 1]).map(x => Math.round(x * 100)),
|
|
1480
1644
|
};
|
|
1481
1645
|
}
|
|
1482
1646
|
}
|
|
@@ -1503,6 +1667,13 @@ function parseGradientContent(descriptor) {
|
|
|
1503
1667
|
}
|
|
1504
1668
|
return result;
|
|
1505
1669
|
}
|
|
1670
|
+
// phase is usually stored as plain numbers, but some files store it as unit values
|
|
1671
|
+
function parsePhase({ Hrzn, Vrtc }) {
|
|
1672
|
+
return {
|
|
1673
|
+
x: typeof Hrzn === 'number' ? Hrzn : Hrzn.value,
|
|
1674
|
+
y: typeof Vrtc === 'number' ? Vrtc : Vrtc.value,
|
|
1675
|
+
};
|
|
1676
|
+
}
|
|
1506
1677
|
function parsePatternContent(descriptor) {
|
|
1507
1678
|
const result = {
|
|
1508
1679
|
name: descriptor.Ptrn['Nm '],
|
|
@@ -1511,7 +1682,11 @@ function parsePatternContent(descriptor) {
|
|
|
1511
1682
|
if (descriptor.Lnkd !== undefined)
|
|
1512
1683
|
result.linked = descriptor.Lnkd;
|
|
1513
1684
|
if (descriptor.phase !== undefined)
|
|
1514
|
-
result.phase =
|
|
1685
|
+
result.phase = parsePhase(descriptor.phase);
|
|
1686
|
+
if (descriptor['Scl '] !== undefined)
|
|
1687
|
+
result.scale = parsePercent(descriptor['Scl ']);
|
|
1688
|
+
if (descriptor.Angl !== undefined)
|
|
1689
|
+
result.angle = parseAngle(descriptor.Angl);
|
|
1515
1690
|
return result;
|
|
1516
1691
|
}
|
|
1517
1692
|
function parseVectorContent(descriptor) {
|
|
@@ -1542,11 +1717,11 @@ function serializeGradientContent(content) {
|
|
|
1542
1717
|
if (content.align !== undefined)
|
|
1543
1718
|
result.Algn = content.align;
|
|
1544
1719
|
if (content.scale !== undefined)
|
|
1545
|
-
result['Scl '] =
|
|
1720
|
+
result['Scl '] = unitsPercentF(content.scale);
|
|
1546
1721
|
if (content.offset) {
|
|
1547
1722
|
result.Ofst = {
|
|
1548
|
-
Hrzn:
|
|
1549
|
-
Vrtc:
|
|
1723
|
+
Hrzn: unitsPercentF(content.offset.x),
|
|
1724
|
+
Vrtc: unitsPercentF(content.offset.y),
|
|
1550
1725
|
};
|
|
1551
1726
|
}
|
|
1552
1727
|
result.Grad = serializeGradient(content);
|
|
@@ -1563,6 +1738,10 @@ function serializePatternContent(content) {
|
|
|
1563
1738
|
result.Lnkd = !!content.linked;
|
|
1564
1739
|
if (content.phase !== undefined)
|
|
1565
1740
|
result.phase = { Hrzn: content.phase.x, Vrtc: content.phase.y };
|
|
1741
|
+
if (content.scale !== undefined)
|
|
1742
|
+
result['Scl '] = unitsPercentF(content.scale);
|
|
1743
|
+
if (content.angle !== undefined)
|
|
1744
|
+
result.Angl = unitsAngle(content.angle);
|
|
1566
1745
|
return result;
|
|
1567
1746
|
}
|
|
1568
1747
|
function serializeVectorContent(content) {
|
|
@@ -1576,25 +1755,68 @@ function serializeVectorContent(content) {
|
|
|
1576
1755
|
return { key: 'GdFl', descriptor: serializeGradientContent(content) };
|
|
1577
1756
|
}
|
|
1578
1757
|
}
|
|
1758
|
+
// Descriptor color values: HSB saturation/brightness 0..100, CMYK 0..100, Gray 0..100, Lab L 0..100, a/b -128..127
|
|
1759
|
+
// Color values (see psd.ts): HSB 0..1, CMYK 0..255, Gray 0..255, Lab L 0..1, a/b -1..1 (same as readColor/writeColor)
|
|
1760
|
+
const colorConversions = {
|
|
1761
|
+
// key: [descriptor -> color, color -> descriptor]
|
|
1762
|
+
'H ': [x => x / 360, x => x * 360], // angle
|
|
1763
|
+
Strt: [x => x / 100, x => x * 100],
|
|
1764
|
+
Brgh: [x => x / 100, x => x * 100],
|
|
1765
|
+
'Cyn ': [x => x * 255 / 100, x => x * 100 / 255],
|
|
1766
|
+
Mgnt: [x => x * 255 / 100, x => x * 100 / 255],
|
|
1767
|
+
'Ylw ': [x => x * 255 / 100, x => x * 100 / 255],
|
|
1768
|
+
Blck: [x => x * 255 / 100, x => x * 100 / 255],
|
|
1769
|
+
'Gry ': [x => x * 255 / 100, x => x * 100 / 255],
|
|
1770
|
+
Lmnc: [x => x / 100, x => x * 100],
|
|
1771
|
+
'A ': [helpers_1.normalizeLabAB, helpers_1.denormalizeLabAB],
|
|
1772
|
+
'B ': [helpers_1.normalizeLabAB, helpers_1.denormalizeLabAB],
|
|
1773
|
+
};
|
|
1774
|
+
function colorToDescriptorValue(key, value) {
|
|
1775
|
+
const conversion = colorConversions[key];
|
|
1776
|
+
if (!conversion)
|
|
1777
|
+
return value;
|
|
1778
|
+
const [from, to] = conversion;
|
|
1779
|
+
const result = to(value);
|
|
1780
|
+
if (!isFinite(result))
|
|
1781
|
+
return result;
|
|
1782
|
+
// prefer shortest number that converts back to the same value (avoids values like 30.200000000000003)
|
|
1783
|
+
for (let precision = 1; precision < 17; precision++) {
|
|
1784
|
+
const candidate = +result.toPrecision(precision);
|
|
1785
|
+
if (from(candidate) === value)
|
|
1786
|
+
return candidate;
|
|
1787
|
+
}
|
|
1788
|
+
return result;
|
|
1789
|
+
}
|
|
1790
|
+
function isBookColor(color) {
|
|
1791
|
+
return color._classID === 'BkCl' || 'Bk ' in color || 'bookID' in color;
|
|
1792
|
+
}
|
|
1579
1793
|
function parseColor(color) {
|
|
1580
1794
|
if ('H ' in color) {
|
|
1581
|
-
return { h: parsePercentOrAngle(color['H ']), s: color.Strt, b: color.Brgh };
|
|
1795
|
+
return { h: parsePercentOrAngle(color['H ']), s: color.Strt / 100, b: color.Brgh / 100 };
|
|
1582
1796
|
}
|
|
1583
1797
|
else if ('Rd ' in color) {
|
|
1584
1798
|
return { r: color['Rd '], g: color['Grn '], b: color['Bl '] };
|
|
1585
1799
|
}
|
|
1586
1800
|
else if ('Cyn ' in color) {
|
|
1587
|
-
return {
|
|
1801
|
+
return {
|
|
1802
|
+
c: color['Cyn '] * 255 / 100,
|
|
1803
|
+
m: color.Mgnt * 255 / 100,
|
|
1804
|
+
y: color['Ylw '] * 255 / 100,
|
|
1805
|
+
k: color.Blck * 255 / 100,
|
|
1806
|
+
};
|
|
1588
1807
|
}
|
|
1589
1808
|
else if ('Gry ' in color) {
|
|
1590
|
-
return { k: color['Gry '] };
|
|
1809
|
+
return { k: color['Gry '] * 255 / 100 };
|
|
1591
1810
|
}
|
|
1592
1811
|
else if ('Lmnc' in color) {
|
|
1593
|
-
return { l: color.Lmnc, a: color['A '], b: color['B '] };
|
|
1812
|
+
return { l: color.Lmnc / 100, a: (0, helpers_1.normalizeLabAB)(color['A ']), b: (0, helpers_1.normalizeLabAB)(color['B ']) };
|
|
1594
1813
|
}
|
|
1595
1814
|
else if ('redFloat' in color) {
|
|
1596
1815
|
return { fr: color.redFloat, fg: color.greenFloat, fb: color.blueFloat };
|
|
1597
1816
|
}
|
|
1817
|
+
else if (isBookColor(color)) {
|
|
1818
|
+
return { r: 0, g: 0, b: 0 }; // book (Pantone) colors are not supported
|
|
1819
|
+
}
|
|
1598
1820
|
else {
|
|
1599
1821
|
throw new Error('Unsupported color descriptor');
|
|
1600
1822
|
}
|
|
@@ -1610,16 +1832,32 @@ function serializeColor(color) {
|
|
|
1610
1832
|
return { _name: '', _classID: 'RGBC', redFloat: color.fr, greenFloat: color.fg, blueFloat: color.fb };
|
|
1611
1833
|
}
|
|
1612
1834
|
else if ('h' in color) {
|
|
1613
|
-
return {
|
|
1835
|
+
return {
|
|
1836
|
+
_name: '', _classID: 'HSBC',
|
|
1837
|
+
'H ': unitsAngle(colorToDescriptorValue('H ', color.h || 0)),
|
|
1838
|
+
Strt: colorToDescriptorValue('Strt', color.s || 0),
|
|
1839
|
+
Brgh: colorToDescriptorValue('Brgh', color.b || 0),
|
|
1840
|
+
};
|
|
1614
1841
|
}
|
|
1615
1842
|
else if ('c' in color) {
|
|
1616
|
-
return {
|
|
1843
|
+
return {
|
|
1844
|
+
_name: '', _classID: 'CMYC',
|
|
1845
|
+
'Cyn ': colorToDescriptorValue('Cyn ', color.c || 0),
|
|
1846
|
+
Mgnt: colorToDescriptorValue('Mgnt', color.m || 0),
|
|
1847
|
+
'Ylw ': colorToDescriptorValue('Ylw ', color.y || 0),
|
|
1848
|
+
Blck: colorToDescriptorValue('Blck', color.k || 0),
|
|
1849
|
+
};
|
|
1617
1850
|
}
|
|
1618
1851
|
else if ('l' in color) {
|
|
1619
|
-
return {
|
|
1852
|
+
return {
|
|
1853
|
+
_name: '', _classID: 'LbCl',
|
|
1854
|
+
Lmnc: colorToDescriptorValue('Lmnc', color.l || 0),
|
|
1855
|
+
'A ': colorToDescriptorValue('A ', color.a || 0),
|
|
1856
|
+
'B ': colorToDescriptorValue('B ', color.b || 0),
|
|
1857
|
+
};
|
|
1620
1858
|
}
|
|
1621
1859
|
else if ('k' in color) {
|
|
1622
|
-
return { _name: '', _classID: '
|
|
1860
|
+
return { _name: '', _classID: 'Grsc', 'Gry ': colorToDescriptorValue('Gry ', color.k || 0) };
|
|
1623
1861
|
}
|
|
1624
1862
|
else {
|
|
1625
1863
|
throw new Error('Invalid color value');
|
|
@@ -1650,7 +1888,8 @@ function parsePercentOrAngle(x) {
|
|
|
1650
1888
|
}
|
|
1651
1889
|
function parseUnits({ units, value }) {
|
|
1652
1890
|
if (units !== 'Pixels' && units !== 'Millimeters' && units !== 'Points' && units !== 'None' &&
|
|
1653
|
-
units !== 'Picas' && units !== 'Inches' && units !== 'Centimeters' && units !== 'Density'
|
|
1891
|
+
units !== 'Picas' && units !== 'Inches' && units !== 'Centimeters' && units !== 'Density' &&
|
|
1892
|
+
units !== 'Distance') {
|
|
1654
1893
|
throw new Error(`Invalid units: ${JSON.stringify({ units, value })}`);
|
|
1655
1894
|
}
|
|
1656
1895
|
return { value, units };
|
|
@@ -1683,7 +1922,8 @@ function unitsValue(x, key) {
|
|
|
1683
1922
|
if (typeof value !== 'number')
|
|
1684
1923
|
throw new Error(`Invalid value in ${JSON.stringify(x)} (key: ${key})`);
|
|
1685
1924
|
if (units !== 'Pixels' && units !== 'Millimeters' && units !== 'Points' && units !== 'None' &&
|
|
1686
|
-
units !== 'Picas' && units !== 'Inches' && units !== 'Centimeters' && units !== 'Density'
|
|
1925
|
+
units !== 'Picas' && units !== 'Inches' && units !== 'Centimeters' && units !== 'Density' &&
|
|
1926
|
+
units !== 'Distance') {
|
|
1687
1927
|
throw new Error(`Invalid units in ${JSON.stringify(x)} (key: ${key})`);
|
|
1688
1928
|
}
|
|
1689
1929
|
return { units, value };
|
|
@@ -1811,6 +2051,11 @@ exports.gradientInterpolationMethodType = (0, helpers_1.createEnum)('gradientInt
|
|
|
1811
2051
|
smooth: 'Smoo',
|
|
1812
2052
|
// TODO: stripes
|
|
1813
2053
|
});
|
|
2054
|
+
exports.Clry = (0, helpers_1.createEnum)('Clry', 'user', {
|
|
2055
|
+
user: 'UsrS',
|
|
2056
|
+
foreground: 'FrgC',
|
|
2057
|
+
background: 'BckC',
|
|
2058
|
+
});
|
|
1814
2059
|
exports.ClrS = (0, helpers_1.createEnum)('ClrS', 'rgb', {
|
|
1815
2060
|
rgb: 'RGBC',
|
|
1816
2061
|
hsb: 'HSBl',
|