pdfnative 1.0.2 → 1.0.4

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.
@@ -2391,9 +2391,26 @@ function buildStructureTree(root, startObjNum, pageObjToStructParents) {
2391
2391
  totalObjects: nextObj - startObjNum
2392
2392
  };
2393
2393
  }
2394
- function buildXMPMetadata(title, createDate, pdfaPart = 2, pdfaConformance = "B") {
2394
+ function buildPdfMetadata(now = /* @__PURE__ */ new Date()) {
2395
+ const pad2 = (n) => String(n).padStart(2, "0");
2396
+ const yyyy = now.getFullYear();
2397
+ const mm = pad2(now.getMonth() + 1);
2398
+ const dd = pad2(now.getDate());
2399
+ const hh = pad2(now.getHours());
2400
+ const mi = pad2(now.getMinutes());
2401
+ const ss = pad2(now.getSeconds());
2402
+ const tzMinutes = -now.getTimezoneOffset();
2403
+ const tzSign = tzMinutes >= 0 ? "+" : "-";
2404
+ const tzAbs = Math.abs(tzMinutes);
2405
+ const tzH = pad2(Math.floor(tzAbs / 60));
2406
+ const tzM = pad2(tzAbs % 60);
2407
+ const pdfDate = `D:${yyyy}${mm}${dd}${hh}${mi}${ss}${tzSign}${tzH}'${tzM}'`;
2408
+ const xmpDate = `${yyyy}-${mm}-${dd}T${hh}:${mi}:${ss}${tzSign}${tzH}:${tzM}`;
2409
+ return { pdfDate, xmpDate };
2410
+ }
2411
+ function buildXMPMetadata(title, createDate, pdfaPart = 2, pdfaConformance = "B", author) {
2395
2412
  const escapedTitle = escapeXml(title);
2396
- return [
2413
+ const lines = [
2397
2414
  '<?xpacket begin="\xEF\xBB\xBF" id="W5M0MpCehiHzreSzNTczkc9d"?>',
2398
2415
  '<x:xmpmeta xmlns:x="adobe:ns:meta/">',
2399
2416
  ' <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">',
@@ -2402,17 +2419,21 @@ function buildXMPMetadata(title, createDate, pdfaPart = 2, pdfaConformance = "B"
2402
2419
  ' xmlns:pdf="http://ns.adobe.com/pdf/1.3/"',
2403
2420
  ' xmlns:xmp="http://ns.adobe.com/xap/1.0/"',
2404
2421
  ' xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/">',
2405
- ` <dc:title><rdf:Alt><rdf:li xml:lang="x-default">${escapedTitle}</rdf:li></rdf:Alt></dc:title>`,
2406
- " <dc:creator><rdf:Seq><rdf:li>pdfnative</rdf:li></rdf:Seq></dc:creator>",
2422
+ ` <dc:title><rdf:Alt><rdf:li xml:lang="x-default">${escapedTitle}</rdf:li></rdf:Alt></dc:title>`
2423
+ ];
2424
+ lines.push(
2407
2425
  " <pdf:Producer>pdfnative</pdf:Producer>",
2408
2426
  ` <xmp:CreateDate>${createDate}</xmp:CreateDate>`,
2427
+ ` <xmp:ModifyDate>${createDate}</xmp:ModifyDate>`,
2428
+ ` <xmp:MetadataDate>${createDate}</xmp:MetadataDate>`,
2409
2429
  ` <pdfaid:part>${pdfaPart}</pdfaid:part>`,
2410
2430
  ` <pdfaid:conformance>${pdfaConformance}</pdfaid:conformance>`,
2411
2431
  " </rdf:Description>",
2412
2432
  " </rdf:RDF>",
2413
2433
  "</x:xmpmeta>",
2414
2434
  '<?xpacket end="w"?>'
2415
- ].join("\n");
2435
+ );
2436
+ return lines.join("\n");
2416
2437
  }
2417
2438
  function buildOutputIntentDict(iccStreamObjNum, subtype = "GTS_PDFA1") {
2418
2439
  return `<< /Type /OutputIntent /S /${subtype} /OutputConditionIdentifier (sRGB IEC61966-2.1) /RegistryName (http://www.color.org) /DestOutputProfile ${iccStreamObjNum} 0 R >>`;
@@ -2742,6 +2763,205 @@ function parsePdfRgbString(str) {
2742
2763
  }
2743
2764
  return str;
2744
2765
  }
2766
+ var MD5_S = [
2767
+ 7,
2768
+ 12,
2769
+ 17,
2770
+ 22,
2771
+ 7,
2772
+ 12,
2773
+ 17,
2774
+ 22,
2775
+ 7,
2776
+ 12,
2777
+ 17,
2778
+ 22,
2779
+ 7,
2780
+ 12,
2781
+ 17,
2782
+ 22,
2783
+ 5,
2784
+ 9,
2785
+ 14,
2786
+ 20,
2787
+ 5,
2788
+ 9,
2789
+ 14,
2790
+ 20,
2791
+ 5,
2792
+ 9,
2793
+ 14,
2794
+ 20,
2795
+ 5,
2796
+ 9,
2797
+ 14,
2798
+ 20,
2799
+ 4,
2800
+ 11,
2801
+ 16,
2802
+ 23,
2803
+ 4,
2804
+ 11,
2805
+ 16,
2806
+ 23,
2807
+ 4,
2808
+ 11,
2809
+ 16,
2810
+ 23,
2811
+ 4,
2812
+ 11,
2813
+ 16,
2814
+ 23,
2815
+ 6,
2816
+ 10,
2817
+ 15,
2818
+ 21,
2819
+ 6,
2820
+ 10,
2821
+ 15,
2822
+ 21,
2823
+ 6,
2824
+ 10,
2825
+ 15,
2826
+ 21,
2827
+ 6,
2828
+ 10,
2829
+ 15,
2830
+ 21
2831
+ ];
2832
+ var MD5_K = new Uint32Array([
2833
+ 3614090360,
2834
+ 3905402710,
2835
+ 606105819,
2836
+ 3250441966,
2837
+ 4118548399,
2838
+ 1200080426,
2839
+ 2821735955,
2840
+ 4249261313,
2841
+ 1770035416,
2842
+ 2336552879,
2843
+ 4294925233,
2844
+ 2304563134,
2845
+ 1804603682,
2846
+ 4254626195,
2847
+ 2792965006,
2848
+ 1236535329,
2849
+ 4129170786,
2850
+ 3225465664,
2851
+ 643717713,
2852
+ 3921069994,
2853
+ 3593408605,
2854
+ 38016083,
2855
+ 3634488961,
2856
+ 3889429448,
2857
+ 568446438,
2858
+ 3275163606,
2859
+ 4107603335,
2860
+ 1163531501,
2861
+ 2850285829,
2862
+ 4243563512,
2863
+ 1735328473,
2864
+ 2368359562,
2865
+ 4294588738,
2866
+ 2272392833,
2867
+ 1839030562,
2868
+ 4259657740,
2869
+ 2763975236,
2870
+ 1272893353,
2871
+ 4139469664,
2872
+ 3200236656,
2873
+ 681279174,
2874
+ 3936430074,
2875
+ 3572445317,
2876
+ 76029189,
2877
+ 3654602809,
2878
+ 3873151461,
2879
+ 530742520,
2880
+ 3299628645,
2881
+ 4096336452,
2882
+ 1126891415,
2883
+ 2878612391,
2884
+ 4237533241,
2885
+ 1700485571,
2886
+ 2399980690,
2887
+ 4293915773,
2888
+ 2240044497,
2889
+ 1873313359,
2890
+ 4264355552,
2891
+ 2734768916,
2892
+ 1309151649,
2893
+ 4149444226,
2894
+ 3174756917,
2895
+ 718787259,
2896
+ 3951481745
2897
+ ]);
2898
+ function rotl32(x, n) {
2899
+ return (x << n | x >>> 32 - n) >>> 0;
2900
+ }
2901
+ function md5(input) {
2902
+ const len = input.length;
2903
+ const totalBits = len * 8;
2904
+ const padLen = (56 - (len + 1) % 64 + 64) % 64;
2905
+ const padded = new Uint8Array(len + 1 + padLen + 8);
2906
+ padded.set(input);
2907
+ padded[len] = 128;
2908
+ const dv = new DataView(padded.buffer);
2909
+ dv.setUint32(padded.length - 8, totalBits >>> 0, true);
2910
+ dv.setUint32(padded.length - 4, 0, true);
2911
+ let a0 = 1732584193 >>> 0;
2912
+ let b0 = 4023233417 >>> 0;
2913
+ let c0 = 2562383102 >>> 0;
2914
+ let d0 = 271733878 >>> 0;
2915
+ for (let off = 0; off < padded.length; off += 64) {
2916
+ const M = new Uint32Array(16);
2917
+ for (let j = 0; j < 16; j++) {
2918
+ M[j] = dv.getUint32(off + j * 4, true);
2919
+ }
2920
+ let a = a0, b = b0, c = c0, d = d0;
2921
+ for (let i = 0; i < 64; i++) {
2922
+ let f, g;
2923
+ if (i < 16) {
2924
+ f = b & c | ~b & d;
2925
+ g = i;
2926
+ } else if (i < 32) {
2927
+ f = d & b | ~d & c;
2928
+ g = (5 * i + 1) % 16;
2929
+ } else if (i < 48) {
2930
+ f = b ^ c ^ d;
2931
+ g = (3 * i + 5) % 16;
2932
+ } else {
2933
+ f = c ^ (b | ~d);
2934
+ g = 7 * i % 16;
2935
+ }
2936
+ f = f >>> 0;
2937
+ const temp = d;
2938
+ d = c;
2939
+ c = b;
2940
+ b = b + rotl32(a + f + MD5_K[i] + M[g] >>> 0, MD5_S[i]) >>> 0;
2941
+ a = temp;
2942
+ }
2943
+ a0 = a0 + a >>> 0;
2944
+ b0 = b0 + b >>> 0;
2945
+ c0 = c0 + c >>> 0;
2946
+ d0 = d0 + d >>> 0;
2947
+ }
2948
+ const result = new Uint8Array(16);
2949
+ const rv = new DataView(result.buffer);
2950
+ rv.setUint32(0, a0, true);
2951
+ rv.setUint32(4, b0, true);
2952
+ rv.setUint32(8, c0, true);
2953
+ rv.setUint32(12, d0, true);
2954
+ return result;
2955
+ }
2956
+ function hexStr(bytes) {
2957
+ let h = "";
2958
+ for (let i = 0; i < bytes.length; i++) h += bytes[i].toString(16).padStart(2, "0");
2959
+ return h.toUpperCase();
2960
+ }
2961
+ function buildIdArray(docId) {
2962
+ const h = hexStr(docId);
2963
+ return `[<${h}> <${h}>]`;
2964
+ }
2745
2965
 
2746
2966
  // src/core/pdf-assembler.ts
2747
2967
  function createPdfWriter(compress, encState) {
@@ -2774,7 +2994,7 @@ endstream`);
2774
2994
  _offset += d;
2775
2995
  }, objOffsets, parts };
2776
2996
  }
2777
- function writeXrefTrailer(w, totalObjs, infoObjNum, encState) {
2997
+ function writeXrefTrailer(w, totalObjs, infoObjNum, encState, idSeed = "") {
2778
2998
  const xrefOffset = w.offset();
2779
2999
  w.emit("xref\n");
2780
3000
  w.emit(`0 ${totalObjs + 1}
@@ -2786,8 +3006,10 @@ function writeXrefTrailer(w, totalObjs, infoObjNum, encState) {
2786
3006
  `);
2787
3007
  }
2788
3008
  w.emit("trailer\n");
3009
+ const docId = md5(new TextEncoder().encode(`pdfnative|${idSeed}|${totalObjs}`));
3010
+ const idArray = buildIdArray(docId);
2789
3011
  {
2790
- w.emit(`<< /Size ${totalObjs + 1} /Root 1 0 R /Info ${infoObjNum} 0 R >>
3012
+ w.emit(`<< /Size ${totalObjs + 1} /Root 1 0 R /Info ${infoObjNum} 0 R /ID ${idArray} >>
2791
3013
  `);
2792
3014
  }
2793
3015
  w.emit("startxref\n");
@@ -2958,6 +3180,7 @@ function buildPDF(params, layoutOptions) {
2958
3180
  if (totalPages < 1) totalPages = 1;
2959
3181
  const pdfaConfig = resolvePdfAConfig();
2960
3182
  const tagged = pdfaConfig.enabled;
3183
+ const encState = null;
2961
3184
  const wmExtraObjs = 0;
2962
3185
  const mcidAlloc = tagged ? createMCIDAllocator() : void 0;
2963
3186
  const documentChildren = [];
@@ -3162,10 +3385,7 @@ function buildPDF(params, layoutOptions) {
3162
3385
  }
3163
3386
  const baseObjCount = enc.isUnicode ? 4 + fontEntries.length * 5 + wmExtraObjs + totalPages * 2 : 4 + wmExtraObjs + totalPages * 2;
3164
3387
  const infoObjNum = baseObjCount + 1;
3165
- const now = /* @__PURE__ */ new Date();
3166
- const pad2 = (n) => String(n).padStart(2, "0");
3167
- const pdfDate = `D:${now.getFullYear()}${pad2(now.getMonth() + 1)}${pad2(now.getDate())}${pad2(now.getHours())}${pad2(now.getMinutes())}${pad2(now.getSeconds())}`;
3168
- const isoDate = `${now.getFullYear()}-${pad2(now.getMonth() + 1)}-${pad2(now.getDate())}T${pad2(now.getHours())}:${pad2(now.getMinutes())}:${pad2(now.getSeconds())}`;
3388
+ const { pdfDate, xmpDate: isoDate } = buildPdfMetadata();
3169
3389
  const infoTitle = params.docTitle || title || "";
3170
3390
  emitObj(
3171
3391
  infoObjNum,
@@ -3226,7 +3446,7 @@ endobj
3226
3446
  }
3227
3447
  }
3228
3448
  const writer = { emit, emitObj, emitStreamObj, offset: getOffset, adjustOffset, objOffsets, parts };
3229
- writeXrefTrailer(writer, totalObjs, infoObjNum);
3449
+ writeXrefTrailer(writer, totalObjs, infoObjNum, encState, `${infoTitle}|${pdfDate}`);
3230
3450
  return parts.join("");
3231
3451
  }
3232
3452