reamkit 1.32.1 → 1.33.1

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 (165) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +16 -11
  3. package/dist/esm/core/bidi/algorithm.js +2 -2
  4. package/dist/esm/core/bidi/char-types.js +1 -1
  5. package/dist/esm/core/bidi/index.js +3 -3
  6. package/dist/esm/core/bytes.js +1 -1
  7. package/dist/esm/core/converter/facade.js +10 -5
  8. package/dist/esm/core/converter/ream.d.ts +9 -0
  9. package/dist/esm/core/converter/ream.js +40 -10
  10. package/dist/esm/core/crypto/asn1.js +2 -2
  11. package/dist/esm/core/crypto/cms.js +5 -3
  12. package/dist/esm/core/crypto/index.js +2 -1
  13. package/dist/esm/core/crypto/offcrypto.d.ts +2 -5
  14. package/dist/esm/core/crypto/offcrypto.js +9 -15
  15. package/dist/esm/core/crypto/password-error.d.ts +8 -0
  16. package/dist/esm/core/crypto/password-error.js +14 -0
  17. package/dist/esm/core/crypto/primitives.js +16 -16
  18. package/dist/esm/core/document-model/index.d.ts +1 -1
  19. package/dist/esm/core/document-model/types.d.ts +174 -2
  20. package/dist/esm/core/drawingml/chart-geometry.d.ts +24 -6
  21. package/dist/esm/core/drawingml/chart-geometry.js +905 -208
  22. package/dist/esm/core/drawingml/chart-parser.d.ts +5 -1
  23. package/dist/esm/core/drawingml/chart-parser.js +275 -19
  24. package/dist/esm/core/drawingml/chart-text.d.ts +41 -0
  25. package/dist/esm/core/drawingml/chart-text.js +93 -0
  26. package/dist/esm/core/drawingml/colors.js +5 -5
  27. package/dist/esm/core/drawingml/diagram/layout-engine.js +1 -4
  28. package/dist/esm/core/drawingml/diagram/run.js +2 -1
  29. package/dist/esm/core/drawingml/preset-geometry.js +4 -6
  30. package/dist/esm/core/drawingml/shape-render.js +1 -1
  31. package/dist/esm/core/drawingml/text-warp.js +4 -16
  32. package/dist/esm/core/drawingml/theme-parser.js +14 -8
  33. package/dist/esm/core/font/arabic-joining.js +2 -2
  34. package/dist/esm/core/font/binary-reader.js +2 -0
  35. package/dist/esm/core/font/font-registry.js +1 -0
  36. package/dist/esm/core/font/ligatures.js +1 -1
  37. package/dist/esm/core/font/opentype-layout.js +11 -5
  38. package/dist/esm/core/font/ttf-build.js +6 -10
  39. package/dist/esm/core/font/ttf-parser.js +2 -1
  40. package/dist/esm/core/font/ttf-subset.js +8 -8
  41. package/dist/esm/core/fonts/families.js +1 -1
  42. package/dist/esm/core/fonts/remote-fonts.js +4 -4
  43. package/dist/esm/core/hyphenation/index.js +1 -1
  44. package/dist/esm/core/images.js +8 -8
  45. package/dist/esm/core/ir/adapters.d.ts +9 -0
  46. package/dist/esm/core/ir/loss.js +1 -0
  47. package/dist/esm/core/line-breaker/cjk.js +1 -1
  48. package/dist/esm/core/line-breaker/index.js +4 -3
  49. package/dist/esm/core/links.js +1 -1
  50. package/dist/esm/core/lzw.js +1 -1
  51. package/dist/esm/core/metafile/blit.js +1 -1
  52. package/dist/esm/core/metafile/emf.js +5 -7
  53. package/dist/esm/core/metafile/picture.js +1 -1
  54. package/dist/esm/core/metafile/symbol-fonts.js +7 -7
  55. package/dist/esm/core/metafile/wmf.js +5 -7
  56. package/dist/esm/core/number-format.js +4 -6
  57. package/dist/esm/core/numbering/index.js +3 -2
  58. package/dist/esm/core/ole/cfb.js +4 -4
  59. package/dist/esm/core/ole/escher-blip.js +1 -1
  60. package/dist/esm/core/opc/index.js +5 -4
  61. package/dist/esm/core/opc/package.js +3 -1
  62. package/dist/esm/core/opc/xml-entities.js +1 -1
  63. package/dist/esm/core/outline.js +1 -1
  64. package/dist/esm/core/png-encode.js +3 -3
  65. package/dist/esm/core/po-helpers.js +1 -1
  66. package/dist/esm/core/spreadsheet-model/types.d.ts +6 -0
  67. package/dist/esm/core/style-cascade/index.js +4 -3
  68. package/dist/esm/core/tiff.js +3 -1
  69. package/dist/esm/excel/activex-parser.js +1 -1
  70. package/dist/esm/excel/conditional-format.js +7 -7
  71. package/dist/esm/excel/formula/functions.js +8 -4
  72. package/dist/esm/excel/formula/index.js +3 -3
  73. package/dist/esm/excel/formula/lexer.js +2 -2
  74. package/dist/esm/excel/formula/parser.js +4 -3
  75. package/dist/esm/excel/formula/value.js +1 -1
  76. package/dist/esm/excel/index.js +7 -6
  77. package/dist/esm/excel/print-model.d.ts +1 -0
  78. package/dist/esm/excel/print-model.js +7 -32
  79. package/dist/esm/excel/printer-settings.js +6 -7
  80. package/dist/esm/excel/rich-value.js +1 -1
  81. package/dist/esm/excel/sheet-shape-parser.js +4 -2
  82. package/dist/esm/excel/sheet-to-flow.d.ts +8 -0
  83. package/dist/esm/excel/sheet-to-flow.js +14 -11
  84. package/dist/esm/excel/styles-parser.js +5 -3
  85. package/dist/esm/excel/tint.js +5 -5
  86. package/dist/esm/excel/vml-drawing.js +2 -2
  87. package/dist/esm/excel/worksheet-parser.js +5 -5
  88. package/dist/esm/excel/xls/biff-chart.js +1 -3
  89. package/dist/esm/excel/xls/biff-reader.js +10 -11
  90. package/dist/esm/excel/xls/xls-reader.js +1 -1
  91. package/dist/esm/excel/xlsx-reader.js +17 -4
  92. package/dist/esm/excel/xlsx-to-pdf.js +1 -1
  93. package/dist/esm/excel/xlsx-writer.js +2 -2
  94. package/dist/esm/html/html-writer.js +18 -10
  95. package/dist/esm/index.js +2 -1
  96. package/dist/esm/layout/line-paint.js +1 -1
  97. package/dist/esm/layout/math-layout.js +5 -8
  98. package/dist/esm/layout/styled-layout.js +133 -75
  99. package/dist/esm/layout/turned-section.js +2 -2
  100. package/dist/esm/markdown/markdown-writer.js +50 -9
  101. package/dist/esm/pdf/encryption.js +9 -9
  102. package/dist/esm/pdf/icc-profile.js +2 -2
  103. package/dist/esm/pdf/index.js +3 -2
  104. package/dist/esm/pdf/objects.js +7 -0
  105. package/dist/esm/pdf/serialize.js +1 -1
  106. package/dist/esm/pdf/struct-tree.js +3 -1
  107. package/dist/esm/pdf/styled-page-emitter.js +23 -15
  108. package/dist/esm/pdf/styled-page-renderer.js +9 -5
  109. package/dist/esm/pdf-reader/annot-draw.js +3 -3
  110. package/dist/esm/pdf-reader/ccitt.js +2 -1
  111. package/dist/esm/pdf-reader/cff-outline.js +1 -4
  112. package/dist/esm/pdf-reader/content.js +13 -15
  113. package/dist/esm/pdf-reader/decrypt.d.ts +18 -6
  114. package/dist/esm/pdf-reader/decrypt.js +90 -45
  115. package/dist/esm/pdf-reader/document.d.ts +7 -1
  116. package/dist/esm/pdf-reader/document.js +18 -4
  117. package/dist/esm/pdf-reader/encodings.js +1 -1
  118. package/dist/esm/pdf-reader/flow-build.js +4 -6
  119. package/dist/esm/pdf-reader/font.js +3 -3
  120. package/dist/esm/pdf-reader/function.js +8 -7
  121. package/dist/esm/pdf-reader/icc.js +1 -1
  122. package/dist/esm/pdf-reader/images.js +1 -1
  123. package/dist/esm/pdf-reader/jbig2.js +36 -38
  124. package/dist/esm/pdf-reader/jpeg.js +14 -13
  125. package/dist/esm/pdf-reader/layout.js +12 -9
  126. package/dist/esm/pdf-reader/lexer.js +2 -1
  127. package/dist/esm/pdf-reader/math-rows.js +2 -2
  128. package/dist/esm/pdf-reader/optional-content.js +1 -1
  129. package/dist/esm/pdf-reader/page-numbers.js +1 -1
  130. package/dist/esm/pdf-reader/pattern-tint.js +1 -2
  131. package/dist/esm/pdf-reader/reader.d.ts +5 -1
  132. package/dist/esm/pdf-reader/reader.js +83 -16
  133. package/dist/esm/pdf-reader/struct-tree.js +1 -1
  134. package/dist/esm/pdf-reader/tagged.js +3 -2
  135. package/dist/esm/pdf-reader/text.js +2 -2
  136. package/dist/esm/pdf-reader/type1-outline.js +1 -3
  137. package/dist/esm/pptx/embedded-fonts.js +3 -5
  138. package/dist/esm/pptx/placeholder-cascade.js +1 -1
  139. package/dist/esm/pptx/ppt/ppt-reader.js +5 -4
  140. package/dist/esm/pptx/ppt/ppt-text.js +9 -10
  141. package/dist/esm/pptx/pptx-reader.js +6 -5
  142. package/dist/esm/pptx/preset-table-styles.js +1 -1
  143. package/dist/esm/pptx/slide-parser.js +6 -4
  144. package/dist/esm/pptx/sp-helpers.js +1 -1
  145. package/dist/esm/pptx/table-style.js +2 -1
  146. package/dist/esm/svg/svg-writer.js +1 -1
  147. package/dist/esm/word/doc/doc-reader.js +2 -2
  148. package/dist/esm/word/doc/doc-text.js +20 -22
  149. package/dist/esm/word/document-parser.js +26 -21
  150. package/dist/esm/word/docx-reader.js +2 -2
  151. package/dist/esm/word/docx-to-pdf.js +3 -3
  152. package/dist/esm/word/docx-writer.js +10 -6
  153. package/dist/esm/word/drawing-parser.js +18 -18
  154. package/dist/esm/word/font-table.js +1 -1
  155. package/dist/esm/word/index.js +6 -5
  156. package/dist/esm/word/numbering-parser.js +4 -3
  157. package/dist/esm/word/omml-parser.js +1 -1
  158. package/dist/esm/word/paragraph-properties.js +11 -10
  159. package/dist/esm/word/run-properties.js +4 -4
  160. package/dist/esm/word/settings-parser.js +2 -1
  161. package/dist/esm/word/shading.js +1 -1
  162. package/dist/esm/word/styles-parser.js +5 -4
  163. package/dist/esm/word/table-parser.js +4 -4
  164. package/dist/esm/word/theme-fonts.js +1 -1
  165. package/package.json +9 -3
@@ -348,7 +348,7 @@ function assembleStyledPdf(laid, options, doc) {
348
348
  });
349
349
  if (pageRefs.length === 0) {
350
350
  const fallback = sectionCtxs[0] ?? defaultPageCtx();
351
- const contentsRef = doc.add(stream({}, new Uint8Array(0)));
351
+ const contentsRef = doc.add(stream({}, /* @__PURE__ */ new Uint8Array(0)));
352
352
  const fallbackDict = dict({
353
353
  Type: name("Page"),
354
354
  Parent: ref(pagesRef.id),
@@ -372,17 +372,23 @@ function assembleStyledPdf(laid, options, doc) {
372
372
  Type: name("Catalog"),
373
373
  Pages: ref(pagesRef.id)
374
374
  };
375
- if (pdfaProfile) catalogEntries["OutputIntents"] = [ref(doc.add(dict({
376
- Type: name("OutputIntent"),
377
- S: name("GTS_PDFA1"),
378
- OutputConditionIdentifier: "sRGB",
379
- Info: "sRGB IEC61966-2.1",
380
- DestOutputProfile: ref(pdfaIccRef.id)
381
- })).id)];
382
- if (pdfaProfile || options.pdfUA) catalogEntries["Metadata"] = ref(doc.add(stream({
383
- Type: name("Metadata"),
384
- Subtype: name("XML")
385
- }, buildXmpPacket(xmpFromInfo(docInfo, pdfaProfile, options.pdfUA === true)))).id);
375
+ if (pdfaProfile) {
376
+ const outputIntentRef = doc.add(dict({
377
+ Type: name("OutputIntent"),
378
+ S: name("GTS_PDFA1"),
379
+ OutputConditionIdentifier: "sRGB",
380
+ Info: "sRGB IEC61966-2.1",
381
+ DestOutputProfile: ref(pdfaIccRef.id)
382
+ }));
383
+ catalogEntries["OutputIntents"] = [ref(outputIntentRef.id)];
384
+ }
385
+ if (pdfaProfile || options.pdfUA) {
386
+ const xmpRef = doc.add(stream({
387
+ Type: name("Metadata"),
388
+ Subtype: name("XML")
389
+ }, buildXmpPacket(xmpFromInfo(docInfo, pdfaProfile, options.pdfUA === true))));
390
+ catalogEntries["Metadata"] = ref(xmpRef.id);
391
+ }
386
392
  if (tagged && structBuilder) {
387
393
  const structRootRef = structBuilder.emit(doc, pageRefs);
388
394
  catalogEntries["MarkInfo"] = dict({ Marked: true });
@@ -399,7 +405,8 @@ function assembleStyledPdf(laid, options, doc) {
399
405
  const sorted = [...embedded].sort((a, b) => a.file.name < b.file.name ? -1 : a.file.name > b.file.name ? 1 : 0);
400
406
  const names = [];
401
407
  for (const e of sorted) names.push(e.file.name, ref(e.ref.id));
402
- namesTreeEntries["EmbeddedFiles"] = ref(doc.add(dict({ Names: names })).id);
408
+ const embeddedFilesRef = doc.add(dict({ Names: names }));
409
+ namesTreeEntries["EmbeddedFiles"] = ref(embeddedFilesRef.id);
403
410
  }
404
411
  const bookmarkDests = laid.pdf.bookmarks;
405
412
  const destNames = [...referencedAnchors].filter((n) => bookmarkDests.has(n)).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
@@ -415,7 +422,8 @@ function assembleStyledPdf(laid, options, doc) {
415
422
  pos.yTopPt
416
423
  ]);
417
424
  }
418
- namesTreeEntries["Dests"] = ref(doc.add(dict({ Names: names })).id);
425
+ const destsRef = doc.add(dict({ Names: names }));
426
+ namesTreeEntries["Dests"] = ref(destsRef.id);
419
427
  }
420
428
  if (Object.keys(namesTreeEntries).length > 0) catalogEntries["Names"] = dict(namesTreeEntries);
421
429
  if (options.signaturePlaceholder && firstPageDict) {
@@ -655,7 +663,7 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
655
663
  const commands = page.commands;
656
664
  const links = [];
657
665
  if (commands.length === 0) return {
658
- content: new Uint8Array(0),
666
+ content: /* @__PURE__ */ new Uint8Array(0),
659
667
  links
660
668
  };
661
669
  const H = page.height;
@@ -1,6 +1,6 @@
1
1
  import { PdfDocument } from "./writer.js";
2
- import "../layout/page-doc.js";
3
- import { layoutStyledDocument } from "../layout/styled-layout.js";
2
+ import { pageItemBounds, pageLayers, paintPlan } from "../layout/page-doc.js";
3
+ import { GLUE_SHRINK_RATIO, layoutStyledDocument } from "../layout/styled-layout.js";
4
4
  import { emitStyledPdf, emitStyledPdfEncrypted } from "./styled-page-emitter.js";
5
5
  //#region src/pdf/styled-page-renderer.ts
6
6
  /**
@@ -12,7 +12,9 @@ import { emitStyledPdf, emitStyledPdfEncrypted } from "./styled-page-emitter.js"
12
12
  */
13
13
  function renderStyledPdf(body, options) {
14
14
  if (options.encrypt) throw new Error("PDF encryption requires the async conversion path (WebCrypto)");
15
- return emitStyledPdf(layoutStyledDocument(body, options), options, new PdfDocument());
15
+ const laid = layoutStyledDocument(body, options);
16
+ const doc = new PdfDocument();
17
+ return emitStyledPdf(laid, options, doc);
16
18
  }
17
19
  /**
18
20
  * The encrypting variant of {@link renderStyledPdf} (ISO 32000 §7.6; async
@@ -37,7 +39,9 @@ async function renderStyledPdfEncrypted(body, options) {
37
39
  contentAccessibility: true
38
40
  }
39
41
  } : encrypt;
40
- return emitStyledPdfEncrypted(layoutStyledDocument(body, options), options, new PdfDocument(), effective);
42
+ const laid = layoutStyledDocument(body, options);
43
+ const doc = new PdfDocument();
44
+ return emitStyledPdfEncrypted(laid, options, doc, effective);
41
45
  }
42
46
  //#endregion
43
- export { renderStyledPdf, renderStyledPdfEncrypted };
47
+ export { GLUE_SHRINK_RATIO, layoutStyledDocument, pageItemBounds, pageLayers, paintPlan, renderStyledPdf, renderStyledPdfEncrypted };
@@ -167,7 +167,7 @@ function drawnResources(file, annot) {
167
167
  const subtype = file.get(annot, "Subtype");
168
168
  if (subtype instanceof PdfName && subtype.value === "FreeText") {
169
169
  const text = freeTextContents(file, annot);
170
- return text === void 0 ? void 0 : new Map([["Font", new Map([[FREE_TEXT_FONT, spelledFace(text)]])]]);
170
+ return text === void 0 ? void 0 : /* @__PURE__ */ new Map([["Font", /* @__PURE__ */ new Map([[FREE_TEXT_FONT, spelledFace(text)]])]]);
171
171
  }
172
172
  if (!(subtype instanceof PdfName) || subtype.value !== "Widget") return void 0;
173
173
  const acro = file.get(file.catalog, "AcroForm");
@@ -296,11 +296,11 @@ function spelledFace(text) {
296
296
  const cp = ch.codePointAt(0) ?? 32;
297
297
  differences.push(new PdfName(`uni${cp.toString(16).toUpperCase().padStart(4, "0")}`));
298
298
  }
299
- return new Map([
299
+ return /* @__PURE__ */ new Map([
300
300
  ["Type", new PdfName("Font")],
301
301
  ["Subtype", new PdfName("Type1")],
302
302
  ["BaseFont", new PdfName("Helvetica")],
303
- ["Encoding", new Map([["Differences", differences]])]
303
+ ["Encoding", /* @__PURE__ */ new Map([["Differences", differences]])]
304
304
  ]);
305
305
  }
306
306
  /** §12.7.4.3 — the field is a multi-line text box (bit 13 of `/Ff`). */
@@ -164,6 +164,7 @@ function readCode(reader, table) {
164
164
  return -1;
165
165
  }
166
166
  var BitReader = class {
167
+ data;
167
168
  bytePos = 0;
168
169
  bitPos = 0;
169
170
  constructor(data) {
@@ -502,4 +503,4 @@ var WHITE = buildRunTable(WHITE_CODES, SHARED_MAKEUP);
502
503
  var BLACK = buildRunTable(BLACK_CODES, SHARED_MAKEUP);
503
504
  var MODES = new Map(MODE_CODES.map(([bits, m]) => [bits.length << 8 | parseInt(bits, 2), m]));
504
505
  //#endregion
505
- export { decodeCcitt, decodeCcittPlanes };
506
+ export { BLACK_CODES, MODE_CODES, SHARED_MAKEUP, WHITE_CODES, decodeCcitt, decodeCcittPlanes };
@@ -1022,9 +1022,7 @@ function runGlyph(font, gid, part = false) {
1022
1022
  stack.length = 0;
1023
1023
  break;
1024
1024
  }
1025
- default:
1026
- stack.length = 0;
1027
- break;
1025
+ default: stack.length = 0;
1028
1026
  }
1029
1027
  }
1030
1028
  return true;
@@ -1118,7 +1116,6 @@ function runEscape(op, stack, trans) {
1118
1116
  stack.push(b, a);
1119
1117
  break;
1120
1118
  }
1121
- default: break;
1122
1119
  }
1123
1120
  }
1124
1121
  /**
@@ -416,11 +416,17 @@ function interpretContent(bytes, fonts, initialCtm = IDENTITY, shadings = /* @__
416
416
  });
417
417
  };
418
418
  const showString = (operand) => {
419
- emitAt(multiply(tm, state.ctm), consume(operand), multiply(tm, state.ctm));
419
+ const origin = multiply(tm, state.ctm);
420
+ const text = consume(operand);
421
+ emitAt(origin, text, multiply(tm, state.ctm));
420
422
  };
421
423
  const showArray = (arr) => {
422
424
  for (const el of arr) if (typeof el === "number") tm = multiply(translation(-el / 1e3 * state.fontSize * state.hScale, 0), tm);
423
- else if (typeof el === "string" || el instanceof PdfHexString) emitAt(multiply(tm, state.ctm), consume(el), multiply(tm, state.ctm));
425
+ else if (typeof el === "string" || el instanceof PdfHexString) {
426
+ const origin = multiply(tm, state.ctm);
427
+ const text = consume(el);
428
+ emitAt(origin, text, multiply(tm, state.ctm));
429
+ }
424
430
  };
425
431
  const exec = (op) => {
426
432
  switch (op) {
@@ -696,10 +702,7 @@ function interpretContent(bytes, fonts, initialCtm = IDENTITY, shadings = /* @__
696
702
  break;
697
703
  }
698
704
  case "W":
699
- case "W*":
700
- pendingClip = true;
701
- break;
702
- default: break;
705
+ case "W*": pendingClip = true;
703
706
  }
704
707
  };
705
708
  for (;;) {
@@ -741,9 +744,7 @@ function interpretContent(bytes, fonts, initialCtm = IDENTITY, shadings = /* @__
741
744
  } else exec(tok.value);
742
745
  operands = [];
743
746
  break;
744
- default:
745
- operands = [];
746
- break;
747
+ default: operands = [];
747
748
  }
748
749
  }
749
750
  return {
@@ -863,7 +864,7 @@ function toBytes(operand) {
863
864
  for (let i = 0; i < operand.length; i++) out[i] = operand.charCodeAt(i) & 255;
864
865
  return out;
865
866
  }
866
- return new Uint8Array(0);
867
+ return /* @__PURE__ */ new Uint8Array(0);
867
868
  }
868
869
  function splitCodes(bytes, bytesPerCode) {
869
870
  const out = [];
@@ -897,10 +898,7 @@ function readArray(lexer) {
897
898
  case "dictOpen":
898
899
  out.push(readDict(lexer));
899
900
  break;
900
- case "keyword":
901
- if (tok.value === "true" || tok.value === "false") out.push(tok.value === "true");
902
- break;
903
- default: break;
901
+ case "keyword": if (tok.value === "true" || tok.value === "false") out.push(tok.value === "true");
904
902
  }
905
903
  }
906
904
  return out;
@@ -1048,4 +1046,4 @@ function inlineLength(dict) {
1048
1046
  return ((w * comps * bpc + 7) / 8 | 0) * h;
1049
1047
  }
1050
1048
  //#endregion
1051
- export { IDENTITY, interpretContent, isRightToLeft, multiply };
1049
+ export { IDENTITY, interpretContent, isRightToLeft, multiply, statesACharacter };
@@ -7,16 +7,28 @@ export interface Decryptor {
7
7
  */
8
8
  decrypt: (value: PdfValue, objNum: number, gen: number) => PdfValue;
9
9
  }
10
+ /**
11
+ * What {@link buildDecryptor} makes of a file: the decryptor, or why there is
12
+ * none — the password opens it as neither its user nor its owner, or the file is
13
+ * locked by a handler this does not implement.
14
+ */
15
+ export type DecryptorResult = {
16
+ readonly decryptor: Decryptor;
17
+ } | {
18
+ readonly refused: 'password' | 'handler';
19
+ };
10
20
  /**
11
21
  * Build a {@link Decryptor} from the `/Encrypt` dictionary and the file `/ID`
12
- * (ISO 32000 §7.6.3 / ISO 32000-2 §7.6.4). Derives the file key for the
13
- * handler's revision — R6/V5 via `/UE` (AES-256), else the legacy MD5 key — and
22
+ * (ISO 32000 §7.6.3 / ISO 32000-2 §7.6.4). Authenticates the password as the
23
+ * user's and then as the owner's, derives the file key for the handler's
24
+ * revision — R6/V5 via `/UE` or `/OE` (AES-256), else the legacy MD5 key — and
14
25
  * picks the cipher (RC4, AES-128 `/AESV2`, AES-256 `/AESV3`).
15
26
  *
16
27
  * @param encrypt The `/Encrypt` dictionary.
17
28
  * @param idArray The trailer `/ID` array (its first element seeds the legacy key).
18
- * @param password The user password (EP14); the empty string opens permissions-only encryption.
19
- * @returns A decryptor, or `undefined` for a non-Standard filter, an unencrypting
20
- * crypt filter, or a password that fails key validation.
29
+ * @param password The password (EP14), the user's or the owner's; the empty
30
+ * string opens permissions-only encryption.
31
+ * @returns The decryptor, or why there is none: a password the file's own
32
+ * verifiers refuse, or a non-Standard filter or unencrypting crypt filter.
21
33
  */
22
- export declare function buildDecryptor(encrypt: PdfDict, idArray: PdfValue | undefined, password?: string): Decryptor | undefined;
34
+ export declare function buildDecryptor(encrypt: PdfDict, idArray: PdfValue | undefined, password?: string): DecryptorResult;
@@ -41,64 +41,96 @@ var AES_SALT = Uint8Array.from([
41
41
  108,
42
42
  84
43
43
  ]);
44
- var ZERO16 = new Uint8Array(16);
45
- var EMPTY = new Uint8Array(0);
44
+ var ZERO16 = /* @__PURE__ */ new Uint8Array(16);
45
+ var EMPTY = /* @__PURE__ */ new Uint8Array(0);
46
46
  /**
47
47
  * Build a {@link Decryptor} from the `/Encrypt` dictionary and the file `/ID`
48
- * (ISO 32000 §7.6.3 / ISO 32000-2 §7.6.4). Derives the file key for the
49
- * handler's revision — R6/V5 via `/UE` (AES-256), else the legacy MD5 key — and
48
+ * (ISO 32000 §7.6.3 / ISO 32000-2 §7.6.4). Authenticates the password as the
49
+ * user's and then as the owner's, derives the file key for the handler's
50
+ * revision — R6/V5 via `/UE` or `/OE` (AES-256), else the legacy MD5 key — and
50
51
  * picks the cipher (RC4, AES-128 `/AESV2`, AES-256 `/AESV3`).
51
52
  *
52
53
  * @param encrypt The `/Encrypt` dictionary.
53
54
  * @param idArray The trailer `/ID` array (its first element seeds the legacy key).
54
- * @param password The user password (EP14); the empty string opens permissions-only encryption.
55
- * @returns A decryptor, or `undefined` for a non-Standard filter, an unencrypting
56
- * crypt filter, or a password that fails key validation.
55
+ * @param password The password (EP14), the user's or the owner's; the empty
56
+ * string opens permissions-only encryption.
57
+ * @returns The decryptor, or why there is none: a password the file's own
58
+ * verifiers refuse, or a non-Standard filter or unencrypting crypt filter.
57
59
  */
58
60
  function buildDecryptor(encrypt, idArray, password = "") {
59
61
  const filter = encrypt.get("Filter");
60
- if (!(filter instanceof PdfName) || filter.value !== "Standard") return void 0;
62
+ if (!(filter instanceof PdfName) || filter.value !== "Standard") return { refused: "handler" };
61
63
  const v = numOf(encrypt.get("V"));
62
64
  const r = numOf(encrypt.get("R"));
65
+ const o = strBytes(encrypt.get("O"));
66
+ const u = strBytes(encrypt.get("U"));
67
+ const methods = cryptMethods(encrypt, v, r);
68
+ if (methods.stream === "none" && methods.string === "none") return { decryptor: { decrypt: (value) => value } };
63
69
  let fileKey;
64
- let method;
65
- if (r >= 5 || v >= 5) {
66
- fileKey = deriveKeyR6(strBytes(encrypt.get("U")), strBytes(encrypt.get("UE")), password);
67
- method = "aesv3";
68
- } else {
69
- const keyLen = (numOf(encrypt.get("Length")) || 40) / 8;
70
+ if (r >= 5 || v >= 5) fileKey = userKeyR6(u, strBytes(encrypt.get("UE")), password) ?? ownerKeyR6(o, u, strBytes(encrypt.get("OE")), password);
71
+ else {
72
+ const keyLen = Math.max(5, Math.min(16, (numOf(encrypt.get("Length")) || 40) / 8));
70
73
  const id0 = Array.isArray(idArray) ? strBytes(idArray[0]) : EMPTY;
71
- fileKey = deriveKeyLegacy(strBytes(encrypt.get("O")), numOf(encrypt.get("P")) | 0, id0, r, Math.max(5, Math.min(16, keyLen)), encrypt.get("EncryptMetadata") !== false, password);
72
- const m = cipherMethod(encrypt, v);
73
- if (m === void 0) return void 0;
74
- method = m;
74
+ const keyFor = (padded) => {
75
+ const key = deriveKeyLegacy(o, numOf(encrypt.get("P")) | 0, id0, r, keyLen, encrypt.get("EncryptMetadata") !== false, padded);
76
+ return userKeyMatches(key, r, id0, u) ? key : void 0;
77
+ };
78
+ fileKey = keyFor(padPassword(password)) ?? keyFor(userPasswordFromOwner(password, o, r, keyLen));
75
79
  }
76
- if (!fileKey) return void 0;
80
+ if (!fileKey) return { refused: "password" };
77
81
  const key = fileKey;
78
- return { decrypt: (value, objNum, gen) => decryptValue(value, objNum, gen, key, method) };
82
+ return { decryptor: { decrypt: (value, objNum, gen) => decryptValue(value, objNum, gen, key, methods) } };
79
83
  }
80
- function deriveKeyLegacy(o, p, id0, r, keyLen, encryptMetadata, password) {
84
+ function deriveKeyLegacy(o, p, id0, r, keyLen, encryptMetadata, padded) {
81
85
  const tail = r >= 4 && !encryptMetadata ? Uint8Array.from([
82
86
  255,
83
87
  255,
84
88
  255,
85
89
  255
86
90
  ]) : EMPTY;
87
- let hash = md5(concat(padPassword(password), o.subarray(0, 32), p32le(p), id0, tail));
91
+ let hash = md5(concat(padded, o.subarray(0, 32), p32le(p), id0, tail));
88
92
  if (r >= 3) for (let i = 0; i < 50; i++) hash = md5(hash.subarray(0, keyLen));
89
93
  return hash.subarray(0, keyLen);
90
94
  }
91
- function deriveKeyR6(u, ue, password) {
95
+ function userKeyMatches(key, r, id0, u) {
96
+ if (r <= 2) return u.length < 32 || equal(rc4(key, PAD), u.subarray(0, 32));
97
+ if (u.length < 16) return true;
98
+ let x = rc4(key, md5(concat(PAD, id0)));
99
+ for (let i = 1; i <= 19; i++) x = rc4(xorKey(key, i), x);
100
+ return equal(x, u.subarray(0, 16));
101
+ }
102
+ function userPasswordFromOwner(owner, o, r, keyLen) {
103
+ let hash = md5(padPassword(owner));
104
+ if (r >= 3) for (let i = 0; i < 50; i++) hash = md5(hash);
105
+ const key = hash.subarray(0, r >= 3 ? keyLen : 5);
106
+ let x = o.subarray(0, 32);
107
+ if (r <= 2) return rc4(key, x);
108
+ for (let i = 19; i >= 0; i--) x = rc4(xorKey(key, i), x);
109
+ return x;
110
+ }
111
+ function xorKey(key, i) {
112
+ return key.map((b) => b ^ i);
113
+ }
114
+ function userKeyR6(u, ue, password) {
92
115
  if (u.length < 48 || ue.length < 32) return void 0;
93
116
  const pw = passwordBytes(password);
94
117
  const validationSalt = u.subarray(32, 40);
95
118
  const keySalt = u.subarray(40, 48);
96
119
  if (!equal(hash2B(pw, validationSalt, EMPTY), u.subarray(0, 32))) return void 0;
97
- return aesCbcDecrypt(hash2B(pw, keySalt, EMPTY), ZERO16, ue.subarray(0, 32), false);
120
+ const intermediate = hash2B(pw, keySalt, EMPTY);
121
+ return aesCbcDecrypt(intermediate, ZERO16, ue.subarray(0, 32), false);
122
+ }
123
+ function ownerKeyR6(o, u, oe, password) {
124
+ if (o.length < 48 || u.length < 48 || oe.length < 32) return void 0;
125
+ const pw = passwordBytes(password);
126
+ const udata = u.subarray(0, 48);
127
+ if (!equal(hash2B(pw, o.subarray(32, 40), udata), o.subarray(0, 32))) return void 0;
128
+ const intermediate = hash2B(pw, o.subarray(40, 48), udata);
129
+ return aesCbcDecrypt(intermediate, ZERO16, oe.subarray(0, 32), false);
98
130
  }
99
131
  function padPassword(password) {
100
132
  const raw = strToBytes(password);
101
- const out = new Uint8Array(32);
133
+ const out = /* @__PURE__ */ new Uint8Array(32);
102
134
  const n = Math.min(raw.length, 32);
103
135
  out.set(raw.subarray(0, n), 0);
104
136
  out.set(PAD.subarray(0, 32 - n), n);
@@ -122,19 +154,31 @@ function hash2B(pw, salt, udata) {
122
154
  }
123
155
  return k.subarray(0, 32);
124
156
  }
125
- function cipherMethod(encrypt, v) {
126
- if (v < 4) return "rc4";
127
- const stmf = encrypt.get("StmF");
128
- const cfName = stmf instanceof PdfName ? stmf.value : "StdCF";
129
- if (cfName === "Identity") return void 0;
130
- const cf = encrypt.get("CF");
131
- const cfDict = cf instanceof Map ? cf.get(cfName) : void 0;
132
- const cfm = cfDict instanceof Map ? cfDict.get("CFM") : void 0;
133
- if (cfm instanceof PdfName) {
134
- if (cfm.value === "AESV2") return "aesv2";
135
- if (cfm.value === "AESV3") return "aesv3";
136
- }
137
- return "rc4";
157
+ function cryptMethods(encrypt, v, r) {
158
+ if (v < 4) return {
159
+ stream: "rc4",
160
+ string: "rc4"
161
+ };
162
+ const fallback = r >= 5 || v >= 5 ? "aesv3" : "rc4";
163
+ const methodOf = (key) => {
164
+ const named = encrypt.get(key);
165
+ const cfName = named instanceof PdfName ? named.value : "StdCF";
166
+ if (cfName === "Identity") return "none";
167
+ const cf = encrypt.get("CF");
168
+ const cfDict = cf instanceof Map ? cf.get(cfName) : void 0;
169
+ const cfm = cfDict instanceof Map ? cfDict.get("CFM") : void 0;
170
+ if (cfm instanceof PdfName) {
171
+ if (cfm.value === "AESV2") return "aesv2";
172
+ if (cfm.value === "AESV3") return "aesv3";
173
+ if (cfm.value === "V2") return "rc4";
174
+ if (cfm.value === "None") return "none";
175
+ }
176
+ return fallback;
177
+ };
178
+ return {
179
+ stream: methodOf("StmF"),
180
+ string: methodOf("StrF")
181
+ };
138
182
  }
139
183
  function objectKey(fileKey, objNum, gen, aes) {
140
184
  const extra = aes ? AES_SALT : EMPTY;
@@ -149,6 +193,7 @@ function objectKey(fileKey, objNum, gen, aes) {
149
193
  return md5(seed).subarray(0, Math.min(fileKey.length + 5, 16));
150
194
  }
151
195
  function decryptBytes(data, objNum, gen, fileKey, method) {
196
+ if (method === "none") return data;
152
197
  if (method === "aesv3") {
153
198
  if (data.length < 16) return data;
154
199
  return aesCbcDecrypt(fileKey, data.subarray(0, 16), data.subarray(16), true);
@@ -160,18 +205,18 @@ function decryptBytes(data, objNum, gen, fileKey, method) {
160
205
  }
161
206
  return rc4(key, data);
162
207
  }
163
- function decryptValue(value, objNum, gen, fileKey, method) {
164
- if (typeof value === "string") return latin1(decryptBytes(strToBytes(value), objNum, gen, fileKey, method));
165
- if (value instanceof PdfHexString) return new PdfHexString(decryptBytes(value.bytes, objNum, gen, fileKey, method));
208
+ function decryptValue(value, objNum, gen, fileKey, methods) {
209
+ if (typeof value === "string") return latin1(decryptBytes(strToBytes(value), objNum, gen, fileKey, methods.string));
210
+ if (value instanceof PdfHexString) return new PdfHexString(decryptBytes(value.bytes, objNum, gen, fileKey, methods.string));
166
211
  if (value instanceof PdfStream) {
167
- const dict = decryptValue(value.dict, objNum, gen, fileKey, method);
168
- const data = decryptBytes(value.data, objNum, gen, fileKey, method);
212
+ const dict = decryptValue(value.dict, objNum, gen, fileKey, methods);
213
+ const data = decryptBytes(value.data, objNum, gen, fileKey, methods.stream);
169
214
  return new PdfStream(dict instanceof Map ? dict : value.dict, data);
170
215
  }
171
- if (Array.isArray(value)) return value.map((v) => decryptValue(v, objNum, gen, fileKey, method));
216
+ if (Array.isArray(value)) return value.map((v) => decryptValue(v, objNum, gen, fileKey, methods));
172
217
  if (value instanceof Map) {
173
218
  const out = /* @__PURE__ */ new Map();
174
- for (const [k, v] of value) out.set(k, decryptValue(v, objNum, gen, fileKey, method));
219
+ for (const [k, v] of value) out.set(k, decryptValue(v, objNum, gen, fileKey, methods));
175
220
  return out;
176
221
  }
177
222
  return value;
@@ -35,6 +35,7 @@ export declare class PdfFile {
35
35
  private readonly cache;
36
36
  private readonly objStmCache;
37
37
  private decryptor;
38
+ private refused;
38
39
  private encryptObjNum;
39
40
  private constructor();
40
41
  /**
@@ -71,9 +72,14 @@ export declare class PdfFile {
71
72
  get catalog(): PdfDict;
72
73
  /**
73
74
  * The document is encrypted but no decryptor could be built (an unsupported
74
- * handler, or a wrong/missing user password) — its content is unreadable.
75
+ * handler, or a refused password) — its content is unreadable.
75
76
  */
76
77
  get encryptionUnsupported(): boolean;
78
+ /**
79
+ * §7.6.3.4 — the document is encrypted and the password it was opened with is
80
+ * neither its user's nor its owner's, by the verifiers the file itself stores.
81
+ */
82
+ get passwordRefused(): boolean;
77
83
  /** The leaf pages, in document order, each with its inherited `/MediaBox` and `/Resources`. */
78
84
  pages(): Array<PdfPage>;
79
85
  /**
@@ -24,9 +24,14 @@ var MAX_OBJSTM_N = 2e5;
24
24
  * object scan recovers files whose xref is broken. Construct via {@link PdfFile.parse}.
25
25
  */
26
26
  var PdfFile = class PdfFile {
27
+ buf;
28
+ xref;
29
+ trailer;
30
+ filters;
27
31
  cache = /* @__PURE__ */ new Map();
28
32
  objStmCache = /* @__PURE__ */ new Map();
29
33
  decryptor;
34
+ refused;
30
35
  encryptObjNum = -1;
31
36
  constructor(buf, xref, trailer, filters = {}) {
32
37
  this.buf = buf;
@@ -81,7 +86,9 @@ var PdfFile = class PdfFile {
81
86
  const enc = this.resolve(encVal);
82
87
  if (!(enc instanceof Map)) return;
83
88
  const id = this.trailer.get("ID");
84
- this.decryptor = buildDecryptor(enc, Array.isArray(id) ? id : void 0, password);
89
+ const built = buildDecryptor(enc, Array.isArray(id) ? id : void 0, password);
90
+ if ("decryptor" in built) this.decryptor = built.decryptor;
91
+ else this.refused = built.refused;
85
92
  }
86
93
  /** Resolve a stream's `/Length` when it is an indirect reference. */
87
94
  lengthResolver = (r) => {
@@ -143,11 +150,18 @@ var PdfFile = class PdfFile {
143
150
  }
144
151
  /**
145
152
  * The document is encrypted but no decryptor could be built (an unsupported
146
- * handler, or a wrong/missing user password) — its content is unreadable.
153
+ * handler, or a refused password) — its content is unreadable.
147
154
  */
148
155
  get encryptionUnsupported() {
149
156
  return this.trailer.get("Encrypt") !== void 0 && this.decryptor === void 0;
150
157
  }
158
+ /**
159
+ * §7.6.3.4 — the document is encrypted and the password it was opened with is
160
+ * neither its user's nor its owner's, by the verifiers the file itself stores.
161
+ */
162
+ get passwordRefused() {
163
+ return this.refused === "password";
164
+ }
151
165
  /** The leaf pages, in document order, each with its inherited `/MediaBox` and `/Resources`. */
152
166
  pages() {
153
167
  const out = [];
@@ -265,7 +279,7 @@ var GENERAL_FILTERS = {
265
279
  RunLengthDecode: runLengthDecode,
266
280
  RL: runLengthDecode
267
281
  };
268
- var PASSTHROUGH_FILTERS = new Set([
282
+ var PASSTHROUGH_FILTERS = /* @__PURE__ */ new Set([
269
283
  "DCTDecode",
270
284
  "DCT",
271
285
  "JPXDecode",
@@ -401,7 +415,7 @@ function inflateStream(stream, unknown, filters = {}) {
401
415
  if (f.value === "FlateDecode" || f.value === "Fl") try {
402
416
  data = unzlibSync(data);
403
417
  } catch {
404
- return new Uint8Array(0);
418
+ return /* @__PURE__ */ new Uint8Array(0);
405
419
  }
406
420
  else if (!PASSTHROUGH_FILTERS.has(f.value)) {
407
421
  const decoded = runFilter(filters[f.value], data);
@@ -61,7 +61,7 @@ function baseEncodingTable(name) {
61
61
  function standardEncodingTable() {
62
62
  return STANDARD;
63
63
  }
64
- var STANDARD_LATIN_FACES = new Set([
64
+ var STANDARD_LATIN_FACES = /* @__PURE__ */ new Set([
65
65
  "courier",
66
66
  "courier-bold",
67
67
  "courier-oblique",
@@ -538,7 +538,7 @@ function floatOntoSheet(el, sheetWidth) {
538
538
  }
539
539
  };
540
540
  };
541
- const quarter = (rotation60k) => ((rotation60k ?? 0) + 90 * 6e4) % (360 * 6e4);
541
+ const quarter = (rotation60k) => ((rotation60k ?? 0) + 54e5) % 216e5;
542
542
  if (el.kind === "image" && el.image.float) {
543
543
  const float = onto(el.image.float, el.image.width, el.image.height);
544
544
  if (!float) return el;
@@ -605,8 +605,6 @@ var DEEPEST_MARGIN = .5;
605
605
  * rest of it.
606
606
  */
607
607
  var GUESSED_MARGIN = 1 / 3;
608
- /** The narrowest measure a sheet's own lines may leave, as a share of the sheet. */
609
- var NARROWEST_MEASURE = .2;
610
608
  /**
611
609
  * The lines a sheet's runs stand on — baselines further apart than half the
612
610
  * size of the type on them — and how many of them END at the sheet's right
@@ -660,7 +658,7 @@ var ASCENDER = BASELINE_AT * NATURAL_LINE_EM;
660
658
  * face's descender instead, bug1337429.pdf's last line did not fit the sheet
661
659
  * it was drawn on and went to a second one.
662
660
  */
663
- var DESCENDER = (1 - BASELINE_AT) * 1.5;
661
+ var DESCENDER = .29999999999999993;
664
662
  /**
665
663
  * How small, against the document's own text, type may be set and still be
666
664
  * read as text rather than as a mark the producer left on the sheet.
@@ -780,7 +778,7 @@ function withMeasuredMargins(section, shown, pageRuns, pageMarks = [], foot = []
780
778
  const floor = inked.length > 0 ? footTop + textSize * FOOT_CLEAR_EM : Infinity;
781
779
  const left = clamp(Math.min(...lefts), width);
782
780
  const voters = rights.filter((r) => r.full);
783
- const farthest = voters.length > 0 && voters.every((r) => r.edged) ? Math.max(width * GUESSED_MARGIN, width * (1 - NARROWEST_MEASURE) - left) : width * GUESSED_MARGIN;
781
+ const farthest = voters.length > 0 && voters.every((r) => r.edged) ? Math.max(width * GUESSED_MARGIN, width * .8 - left) : width * GUESSED_MARGIN;
784
782
  return {
785
783
  ...section,
786
784
  margins: {
@@ -918,4 +916,4 @@ var RECONSTRUCTION_SHEET = {
918
916
  defaultParagraphProperties: { widowControl: false }
919
917
  };
920
918
  //#endregion
921
- export { ASCENDER, BASELINE_AT, CARRIER_LINE_PT, GUESSED_MARGIN, NATURAL_LINE_EM, buildFlowDoc, dedupeLosses, figureBlock, floatOntoSheet, imageBlock, imageMember, labelMember, membersBox, paragraphBlock, paragraphFromRuns, positionedText, sectionFromPdfPages, sectionOnSheet, shapeBlock, spaceAfter, textSizeOf, tooSmallToRead, vectorMember, withMeasuredMargins };
919
+ export { ASCENDER, BASELINE_AT, CARRIER_LINE_PT, FLOAT_CARRIER, GUESSED_MARGIN, NATURAL_LINE_EM, buildFlowDoc, dedupeLosses, figureBlock, floatOntoSheet, imageBlock, imageMember, labelMember, membersBox, paragraphBlock, paragraphFromRuns, positionedText, sectionFromPdfPages, sectionOnSheet, shapeBlock, spaceAfter, textSizeOf, tooSmallToRead, typesetRuns, typesetting, vectorMember, withMeasuredMargins };
@@ -149,7 +149,7 @@ function lettersOf(text) {
149
149
  }
150
150
  var LIGATURE = /[\uFB00-\uFB06]/u;
151
151
  var LIGATURES = /[\uFB00-\uFB06]/gu;
152
- var LATIN_LIGATURES = new Map([
152
+ var LATIN_LIGATURES = /* @__PURE__ */ new Map([
153
153
  ["ff", "ff"],
154
154
  ["fi", "fi"],
155
155
  ["fl", "fl"],
@@ -231,7 +231,7 @@ function coreGlyphOrder(file, fontDict) {
231
231
  return out;
232
232
  }
233
233
  /** The core faces whose first glyphs stand in the standard Macintosh order. */
234
- var CORE_FACES = new Set([
234
+ var CORE_FACES = /* @__PURE__ */ new Set([
235
235
  "arial",
236
236
  "timesnewroman",
237
237
  "couriernew",
@@ -1230,4 +1230,4 @@ function asNumber(v, dflt) {
1230
1230
  return typeof v === "number" ? v : dflt;
1231
1231
  }
1232
1232
  //#endregion
1233
- export { buildContentFont, collectFaceFamilies };
1233
+ export { buildContentFont, collectFaceFamilies, familyOfFace };