@pdfme/pdf-lib 1.18.1 → 1.18.3

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 (138) hide show
  1. package/cjs/api/PDFDocument.js +195 -225
  2. package/cjs/api/PDFDocument.js.map +1 -1
  3. package/cjs/api/PDFEmbeddedFile.js +30 -33
  4. package/cjs/api/PDFEmbeddedFile.js.map +1 -1
  5. package/cjs/api/PDFEmbeddedPage.js +5 -7
  6. package/cjs/api/PDFEmbeddedPage.js.map +1 -1
  7. package/cjs/api/PDFFont.js +6 -8
  8. package/cjs/api/PDFFont.js.map +1 -1
  9. package/cjs/api/PDFImage.js +14 -16
  10. package/cjs/api/PDFImage.js.map +1 -1
  11. package/cjs/api/PDFJavaScript.js +19 -22
  12. package/cjs/api/PDFJavaScript.js.map +1 -1
  13. package/cjs/api/PDFPage.d.ts.map +1 -1
  14. package/cjs/api/PDFPage.js +26 -16
  15. package/cjs/api/PDFPage.js.map +1 -1
  16. package/cjs/api/PDFPageOptions.d.ts +14 -8
  17. package/cjs/api/PDFPageOptions.d.ts.map +1 -1
  18. package/cjs/api/PDFPageOptions.js.map +1 -1
  19. package/cjs/api/form/PDFField.js +1 -1
  20. package/cjs/api/form/PDFField.js.map +1 -1
  21. package/cjs/api/form/PDFForm.js +1 -1
  22. package/cjs/api/form/PDFForm.js.map +1 -1
  23. package/cjs/api/form/appearances.js +56 -16
  24. package/cjs/api/form/appearances.js.map +1 -1
  25. package/cjs/api/operations.d.ts +15 -0
  26. package/cjs/api/operations.d.ts.map +1 -1
  27. package/cjs/api/operations.js +22 -0
  28. package/cjs/api/operations.js.map +1 -1
  29. package/cjs/api/svg.d.ts +7 -1
  30. package/cjs/api/svg.d.ts.map +1 -1
  31. package/cjs/api/svg.js +332 -1016
  32. package/cjs/api/svg.js.map +1 -1
  33. package/cjs/core/PDFContext.js +11 -2
  34. package/cjs/core/PDFContext.js.map +1 -1
  35. package/cjs/core/embedders/CustomFontEmbedder.js +62 -74
  36. package/cjs/core/embedders/CustomFontEmbedder.js.map +1 -1
  37. package/cjs/core/embedders/CustomFontSubsetEmbedder.js +3 -5
  38. package/cjs/core/embedders/CustomFontSubsetEmbedder.js.map +1 -1
  39. package/cjs/core/embedders/FileEmbedder.js +30 -32
  40. package/cjs/core/embedders/FileEmbedder.js.map +1 -1
  41. package/cjs/core/embedders/JavaScriptEmbedder.js +12 -14
  42. package/cjs/core/embedders/JavaScriptEmbedder.js.map +1 -1
  43. package/cjs/core/embedders/JpegEmbedder.js +54 -59
  44. package/cjs/core/embedders/JpegEmbedder.js.map +1 -1
  45. package/cjs/core/embedders/PDFPageEmbedder.js +22 -26
  46. package/cjs/core/embedders/PDFPageEmbedder.js.map +1 -1
  47. package/cjs/core/embedders/PngEmbedder.js +20 -25
  48. package/cjs/core/embedders/PngEmbedder.js.map +1 -1
  49. package/cjs/core/parser/PDFObjectStreamParser.js +15 -17
  50. package/cjs/core/parser/PDFObjectStreamParser.js.map +1 -1
  51. package/cjs/core/parser/PDFParser.js +66 -74
  52. package/cjs/core/parser/PDFParser.js.map +1 -1
  53. package/cjs/core/writers/PDFStreamWriter.js +53 -55
  54. package/cjs/core/writers/PDFStreamWriter.js.map +1 -1
  55. package/cjs/core/writers/PDFWriter.js +62 -66
  56. package/cjs/core/writers/PDFWriter.js.map +1 -1
  57. package/cjs/types/index.d.ts +4 -4
  58. package/cjs/types/index.d.ts.map +1 -1
  59. package/dist/pdf-lib.esm.js +1123 -2589
  60. package/dist/pdf-lib.esm.js.map +1 -1
  61. package/dist/pdf-lib.esm.min.js +1 -15
  62. package/dist/pdf-lib.esm.min.js.map +1 -1
  63. package/dist/pdf-lib.js +1123 -2589
  64. package/dist/pdf-lib.js.map +1 -1
  65. package/dist/pdf-lib.min.js +1 -15
  66. package/dist/pdf-lib.min.js.map +1 -1
  67. package/es/api/PDFDocument.js +195 -226
  68. package/es/api/PDFDocument.js.map +1 -1
  69. package/es/api/PDFEmbeddedFile.js +30 -33
  70. package/es/api/PDFEmbeddedFile.js.map +1 -1
  71. package/es/api/PDFEmbeddedPage.js +5 -8
  72. package/es/api/PDFEmbeddedPage.js.map +1 -1
  73. package/es/api/PDFFont.js +6 -9
  74. package/es/api/PDFFont.js.map +1 -1
  75. package/es/api/PDFImage.js +14 -17
  76. package/es/api/PDFImage.js.map +1 -1
  77. package/es/api/PDFJavaScript.js +19 -22
  78. package/es/api/PDFJavaScript.js.map +1 -1
  79. package/es/api/PDFPage.d.ts.map +1 -1
  80. package/es/api/PDFPage.js +26 -17
  81. package/es/api/PDFPage.js.map +1 -1
  82. package/es/api/PDFPageOptions.d.ts +14 -8
  83. package/es/api/PDFPageOptions.d.ts.map +1 -1
  84. package/es/api/PDFPageOptions.js.map +1 -1
  85. package/es/api/form/PDFField.js +1 -1
  86. package/es/api/form/PDFField.js.map +1 -1
  87. package/es/api/form/PDFForm.js +1 -1
  88. package/es/api/form/PDFForm.js.map +1 -1
  89. package/es/api/form/appearances.js +56 -16
  90. package/es/api/form/appearances.js.map +1 -1
  91. package/es/api/operations.d.ts +15 -0
  92. package/es/api/operations.d.ts.map +1 -1
  93. package/es/api/operations.js +23 -1
  94. package/es/api/operations.js.map +1 -1
  95. package/es/api/svg.d.ts +7 -1
  96. package/es/api/svg.d.ts.map +1 -1
  97. package/es/api/svg.js +333 -1017
  98. package/es/api/svg.js.map +1 -1
  99. package/es/core/PDFContext.js +11 -2
  100. package/es/core/PDFContext.js.map +1 -1
  101. package/es/core/embedders/CustomFontEmbedder.js +62 -75
  102. package/es/core/embedders/CustomFontEmbedder.js.map +1 -1
  103. package/es/core/embedders/CustomFontSubsetEmbedder.js +3 -6
  104. package/es/core/embedders/CustomFontSubsetEmbedder.js.map +1 -1
  105. package/es/core/embedders/FileEmbedder.js +30 -33
  106. package/es/core/embedders/FileEmbedder.js.map +1 -1
  107. package/es/core/embedders/JavaScriptEmbedder.js +12 -15
  108. package/es/core/embedders/JavaScriptEmbedder.js.map +1 -1
  109. package/es/core/embedders/JpegEmbedder.js +54 -59
  110. package/es/core/embedders/JpegEmbedder.js.map +1 -1
  111. package/es/core/embedders/PDFPageEmbedder.js +22 -27
  112. package/es/core/embedders/PDFPageEmbedder.js.map +1 -1
  113. package/es/core/embedders/PngEmbedder.js +20 -25
  114. package/es/core/embedders/PngEmbedder.js.map +1 -1
  115. package/es/core/parser/PDFObjectStreamParser.js +15 -18
  116. package/es/core/parser/PDFObjectStreamParser.js.map +1 -1
  117. package/es/core/parser/PDFParser.js +66 -75
  118. package/es/core/parser/PDFParser.js.map +1 -1
  119. package/es/core/writers/PDFStreamWriter.js +53 -56
  120. package/es/core/writers/PDFStreamWriter.js.map +1 -1
  121. package/es/core/writers/PDFWriter.js +62 -67
  122. package/es/core/writers/PDFWriter.js.map +1 -1
  123. package/es/types/index.d.ts +4 -4
  124. package/es/types/index.d.ts.map +1 -1
  125. package/package.json +1 -1
  126. package/src/api/PDFPage.ts +12 -0
  127. package/src/api/PDFPageOptions.ts +14 -8
  128. package/src/api/operations.ts +45 -3
  129. package/src/api/svg.ts +305 -1086
  130. package/src/types/index.ts +6 -1
  131. package/ts3.4/cjs/api/PDFPageOptions.d.ts +14 -8
  132. package/ts3.4/cjs/api/operations.d.ts +15 -0
  133. package/ts3.4/cjs/api/svg.d.ts +7 -1
  134. package/ts3.4/cjs/types/index.d.ts +4 -4
  135. package/ts3.4/es/api/PDFPageOptions.d.ts +14 -8
  136. package/ts3.4/es/api/operations.d.ts +15 -0
  137. package/ts3.4/es/api/svg.d.ts +7 -1
  138. package/ts3.4/es/types/index.d.ts +4 -4
@@ -16043,13 +16043,22 @@ class PDFContext {
16043
16043
  return PDFRawStream.of(this.obj(dict), typedArrayFor(contents));
16044
16044
  }
16045
16045
  flateStream(contents, dict = {}) {
16046
- return this.stream(pako_1$1.deflate(typedArrayFor(contents)), Object.assign(Object.assign({}, dict), { Filter: 'FlateDecode' }));
16046
+ return this.stream(pako_1$1.deflate(typedArrayFor(contents)), {
16047
+ ...dict,
16048
+ Filter: 'FlateDecode',
16049
+ });
16047
16050
  }
16048
16051
  contentStream(operators, dict = {}) {
16049
16052
  return PDFContentStream.of(this.obj(dict), operators);
16050
16053
  }
16051
16054
  formXObject(operators, dict = {}) {
16052
- return this.contentStream(operators, Object.assign(Object.assign({ BBox: this.obj([0, 0, 0, 0]), Matrix: this.obj([1, 0, 0, 1, 0, 0]) }, dict), { Type: 'XObject', Subtype: 'Form' }));
16055
+ return this.contentStream(operators, {
16056
+ BBox: this.obj([0, 0, 0, 0]),
16057
+ Matrix: this.obj([1, 0, 0, 1, 0, 0]),
16058
+ ...dict,
16059
+ Type: 'XObject',
16060
+ Subtype: 'Form',
16061
+ });
16053
16062
  }
16054
16063
  /*
16055
16064
  * Reference to PDFContentStream that contains a single PDFOperator: `q`.
@@ -16384,43 +16393,6 @@ class PDFObjectCopier {
16384
16393
  }
16385
16394
  PDFObjectCopier.for = (src, dest) => new PDFObjectCopier(src, dest);
16386
16395
 
16387
- /*! *****************************************************************************
16388
- Copyright (c) Microsoft Corporation.
16389
-
16390
- Permission to use, copy, modify, and/or distribute this software for any
16391
- purpose with or without fee is hereby granted.
16392
-
16393
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
16394
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
16395
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16396
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16397
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16398
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16399
- PERFORMANCE OF THIS SOFTWARE.
16400
- ***************************************************************************** */
16401
-
16402
- function __rest(s, e) {
16403
- var t = {};
16404
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
16405
- t[p] = s[p];
16406
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
16407
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
16408
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
16409
- t[p[i]] = s[p[i]];
16410
- }
16411
- return t;
16412
- }
16413
-
16414
- function __awaiter(thisArg, _arguments, P, generator) {
16415
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
16416
- return new (P || (P = Promise))(function (resolve, reject) {
16417
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16418
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16419
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
16420
- step((generator = generator.apply(thisArg, _arguments || [])).next());
16421
- });
16422
- }
16423
-
16424
16396
  /**
16425
16397
  * Entries should be added using the [[addEntry]] and [[addDeletedEntry]]
16426
16398
  * methods **in order of ascending object number**.
@@ -16666,52 +16638,50 @@ class PDFWriter {
16666
16638
  this.context = context;
16667
16639
  this.objectsPerTick = objectsPerTick;
16668
16640
  }
16669
- serializeToBuffer() {
16670
- return __awaiter(this, void 0, void 0, function* () {
16671
- const { size, header, indirectObjects, xref, trailerDict, trailer } = yield this.computeBufferSize();
16672
- let offset = 0;
16673
- const buffer = new Uint8Array(size);
16674
- offset += header.copyBytesInto(buffer, offset);
16641
+ async serializeToBuffer() {
16642
+ const { size, header, indirectObjects, xref, trailerDict, trailer } = await this.computeBufferSize();
16643
+ let offset = 0;
16644
+ const buffer = new Uint8Array(size);
16645
+ offset += header.copyBytesInto(buffer, offset);
16646
+ buffer[offset++] = CharCodes$1.Newline;
16647
+ buffer[offset++] = CharCodes$1.Newline;
16648
+ for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
16649
+ const [ref, object] = indirectObjects[idx];
16650
+ const objectNumber = String(ref.objectNumber);
16651
+ offset += copyStringIntoBuffer(objectNumber, buffer, offset);
16652
+ buffer[offset++] = CharCodes$1.Space;
16653
+ const generationNumber = String(ref.generationNumber);
16654
+ offset += copyStringIntoBuffer(generationNumber, buffer, offset);
16655
+ buffer[offset++] = CharCodes$1.Space;
16656
+ buffer[offset++] = CharCodes$1.o;
16657
+ buffer[offset++] = CharCodes$1.b;
16658
+ buffer[offset++] = CharCodes$1.j;
16675
16659
  buffer[offset++] = CharCodes$1.Newline;
16660
+ offset += object.copyBytesInto(buffer, offset);
16676
16661
  buffer[offset++] = CharCodes$1.Newline;
16677
- for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
16678
- const [ref, object] = indirectObjects[idx];
16679
- const objectNumber = String(ref.objectNumber);
16680
- offset += copyStringIntoBuffer(objectNumber, buffer, offset);
16681
- buffer[offset++] = CharCodes$1.Space;
16682
- const generationNumber = String(ref.generationNumber);
16683
- offset += copyStringIntoBuffer(generationNumber, buffer, offset);
16684
- buffer[offset++] = CharCodes$1.Space;
16685
- buffer[offset++] = CharCodes$1.o;
16686
- buffer[offset++] = CharCodes$1.b;
16687
- buffer[offset++] = CharCodes$1.j;
16688
- buffer[offset++] = CharCodes$1.Newline;
16689
- offset += object.copyBytesInto(buffer, offset);
16690
- buffer[offset++] = CharCodes$1.Newline;
16691
- buffer[offset++] = CharCodes$1.e;
16692
- buffer[offset++] = CharCodes$1.n;
16693
- buffer[offset++] = CharCodes$1.d;
16694
- buffer[offset++] = CharCodes$1.o;
16695
- buffer[offset++] = CharCodes$1.b;
16696
- buffer[offset++] = CharCodes$1.j;
16697
- buffer[offset++] = CharCodes$1.Newline;
16698
- buffer[offset++] = CharCodes$1.Newline;
16699
- const n = object instanceof PDFObjectStream ? object.getObjectsCount() : 1;
16700
- if (this.shouldWaitForTick(n))
16701
- yield waitForTick();
16702
- }
16703
- if (xref) {
16704
- offset += xref.copyBytesInto(buffer, offset);
16705
- buffer[offset++] = CharCodes$1.Newline;
16706
- }
16707
- if (trailerDict) {
16708
- offset += trailerDict.copyBytesInto(buffer, offset);
16709
- buffer[offset++] = CharCodes$1.Newline;
16710
- buffer[offset++] = CharCodes$1.Newline;
16711
- }
16712
- offset += trailer.copyBytesInto(buffer, offset);
16713
- return buffer;
16714
- });
16662
+ buffer[offset++] = CharCodes$1.e;
16663
+ buffer[offset++] = CharCodes$1.n;
16664
+ buffer[offset++] = CharCodes$1.d;
16665
+ buffer[offset++] = CharCodes$1.o;
16666
+ buffer[offset++] = CharCodes$1.b;
16667
+ buffer[offset++] = CharCodes$1.j;
16668
+ buffer[offset++] = CharCodes$1.Newline;
16669
+ buffer[offset++] = CharCodes$1.Newline;
16670
+ const n = object instanceof PDFObjectStream ? object.getObjectsCount() : 1;
16671
+ if (this.shouldWaitForTick(n))
16672
+ await waitForTick();
16673
+ }
16674
+ if (xref) {
16675
+ offset += xref.copyBytesInto(buffer, offset);
16676
+ buffer[offset++] = CharCodes$1.Newline;
16677
+ }
16678
+ if (trailerDict) {
16679
+ offset += trailerDict.copyBytesInto(buffer, offset);
16680
+ buffer[offset++] = CharCodes$1.Newline;
16681
+ buffer[offset++] = CharCodes$1.Newline;
16682
+ }
16683
+ offset += trailer.copyBytesInto(buffer, offset);
16684
+ return buffer;
16715
16685
  }
16716
16686
  computeIndirectObjectSize([ref, object]) {
16717
16687
  const refSize = ref.sizeInBytes() + 3; // 'R' -> 'obj\n'
@@ -16727,28 +16697,26 @@ class PDFWriter {
16727
16697
  ID: this.context.trailerInfo.ID,
16728
16698
  });
16729
16699
  }
16730
- computeBufferSize() {
16731
- return __awaiter(this, void 0, void 0, function* () {
16732
- const header = PDFHeader.forVersion(1, 7);
16733
- let size = header.sizeInBytes() + 2;
16734
- const xref = PDFCrossRefSection.create();
16735
- const indirectObjects = this.context.enumerateIndirectObjects();
16736
- for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
16737
- const indirectObject = indirectObjects[idx];
16738
- const [ref] = indirectObject;
16739
- xref.addEntry(ref, size);
16740
- size += this.computeIndirectObjectSize(indirectObject);
16741
- if (this.shouldWaitForTick(1))
16742
- yield waitForTick();
16743
- }
16744
- const xrefOffset = size;
16745
- size += xref.sizeInBytes() + 1; // '\n'
16746
- const trailerDict = PDFTrailerDict.of(this.createTrailerDict());
16747
- size += trailerDict.sizeInBytes() + 2; // '\n\n'
16748
- const trailer = PDFTrailer.forLastCrossRefSectionOffset(xrefOffset);
16749
- size += trailer.sizeInBytes();
16750
- return { size, header, indirectObjects, xref, trailerDict, trailer };
16751
- });
16700
+ async computeBufferSize() {
16701
+ const header = PDFHeader.forVersion(1, 7);
16702
+ let size = header.sizeInBytes() + 2;
16703
+ const xref = PDFCrossRefSection.create();
16704
+ const indirectObjects = this.context.enumerateIndirectObjects();
16705
+ for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
16706
+ const indirectObject = indirectObjects[idx];
16707
+ const [ref] = indirectObject;
16708
+ xref.addEntry(ref, size);
16709
+ size += this.computeIndirectObjectSize(indirectObject);
16710
+ if (this.shouldWaitForTick(1))
16711
+ await waitForTick();
16712
+ }
16713
+ const xrefOffset = size;
16714
+ size += xref.sizeInBytes() + 1; // '\n'
16715
+ const trailerDict = PDFTrailerDict.of(this.createTrailerDict());
16716
+ size += trailerDict.sizeInBytes() + 2; // '\n\n'
16717
+ const trailer = PDFTrailer.forLastCrossRefSectionOffset(xrefOffset);
16718
+ size += trailer.sizeInBytes();
16719
+ return { size, header, indirectObjects, xref, trailerDict, trailer };
16752
16720
  }
16753
16721
  }
16754
16722
  PDFWriter.forContext = (context, objectsPerTick) => new PDFWriter(context, objectsPerTick);
@@ -16953,63 +16921,61 @@ class PDFStreamWriter extends PDFWriter {
16953
16921
  this.encodeStreams = encodeStreams;
16954
16922
  this.objectsPerStream = objectsPerStream;
16955
16923
  }
16956
- computeBufferSize() {
16957
- return __awaiter(this, void 0, void 0, function* () {
16958
- let objectNumber = this.context.largestObjectNumber + 1;
16959
- const header = PDFHeader.forVersion(1, 7);
16960
- let size = header.sizeInBytes() + 2;
16961
- const xrefStream = PDFCrossRefStream.create(this.createTrailerDict(), this.encodeStreams);
16962
- const uncompressedObjects = [];
16963
- const compressedObjects = [];
16964
- const objectStreamRefs = [];
16965
- const indirectObjects = this.context.enumerateIndirectObjects();
16966
- for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
16967
- const indirectObject = indirectObjects[idx];
16968
- const [ref, object] = indirectObject;
16969
- const shouldNotCompress = ref === this.context.trailerInfo.Encrypt ||
16970
- object instanceof PDFStream ||
16971
- object instanceof PDFInvalidObject ||
16972
- ref.generationNumber !== 0;
16973
- if (shouldNotCompress) {
16974
- uncompressedObjects.push(indirectObject);
16975
- xrefStream.addUncompressedEntry(ref, size);
16976
- size += this.computeIndirectObjectSize(indirectObject);
16977
- if (this.shouldWaitForTick(1))
16978
- yield waitForTick();
16979
- }
16980
- else {
16981
- let chunk = last(compressedObjects);
16982
- let objectStreamRef = last(objectStreamRefs);
16983
- if (!chunk || chunk.length % this.objectsPerStream === 0) {
16984
- chunk = [];
16985
- compressedObjects.push(chunk);
16986
- objectStreamRef = PDFRef.of(objectNumber++);
16987
- objectStreamRefs.push(objectStreamRef);
16988
- }
16989
- xrefStream.addCompressedEntry(ref, objectStreamRef, chunk.length);
16990
- chunk.push(indirectObject);
16991
- }
16992
- }
16993
- for (let idx = 0, len = compressedObjects.length; idx < len; idx++) {
16994
- const chunk = compressedObjects[idx];
16995
- const ref = objectStreamRefs[idx];
16996
- const objectStream = PDFObjectStream.withContextAndObjects(this.context, chunk, this.encodeStreams);
16924
+ async computeBufferSize() {
16925
+ let objectNumber = this.context.largestObjectNumber + 1;
16926
+ const header = PDFHeader.forVersion(1, 7);
16927
+ let size = header.sizeInBytes() + 2;
16928
+ const xrefStream = PDFCrossRefStream.create(this.createTrailerDict(), this.encodeStreams);
16929
+ const uncompressedObjects = [];
16930
+ const compressedObjects = [];
16931
+ const objectStreamRefs = [];
16932
+ const indirectObjects = this.context.enumerateIndirectObjects();
16933
+ for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
16934
+ const indirectObject = indirectObjects[idx];
16935
+ const [ref, object] = indirectObject;
16936
+ const shouldNotCompress = ref === this.context.trailerInfo.Encrypt ||
16937
+ object instanceof PDFStream ||
16938
+ object instanceof PDFInvalidObject ||
16939
+ ref.generationNumber !== 0;
16940
+ if (shouldNotCompress) {
16941
+ uncompressedObjects.push(indirectObject);
16997
16942
  xrefStream.addUncompressedEntry(ref, size);
16998
- size += this.computeIndirectObjectSize([ref, objectStream]);
16999
- uncompressedObjects.push([ref, objectStream]);
17000
- if (this.shouldWaitForTick(chunk.length))
17001
- yield waitForTick();
17002
- }
17003
- const xrefStreamRef = PDFRef.of(objectNumber++);
17004
- xrefStream.dict.set(PDFName.of('Size'), PDFNumber.of(objectNumber));
17005
- xrefStream.addUncompressedEntry(xrefStreamRef, size);
17006
- const xrefOffset = size;
17007
- size += this.computeIndirectObjectSize([xrefStreamRef, xrefStream]);
17008
- uncompressedObjects.push([xrefStreamRef, xrefStream]);
17009
- const trailer = PDFTrailer.forLastCrossRefSectionOffset(xrefOffset);
17010
- size += trailer.sizeInBytes();
17011
- return { size, header, indirectObjects: uncompressedObjects, trailer };
17012
- });
16943
+ size += this.computeIndirectObjectSize(indirectObject);
16944
+ if (this.shouldWaitForTick(1))
16945
+ await waitForTick();
16946
+ }
16947
+ else {
16948
+ let chunk = last(compressedObjects);
16949
+ let objectStreamRef = last(objectStreamRefs);
16950
+ if (!chunk || chunk.length % this.objectsPerStream === 0) {
16951
+ chunk = [];
16952
+ compressedObjects.push(chunk);
16953
+ objectStreamRef = PDFRef.of(objectNumber++);
16954
+ objectStreamRefs.push(objectStreamRef);
16955
+ }
16956
+ xrefStream.addCompressedEntry(ref, objectStreamRef, chunk.length);
16957
+ chunk.push(indirectObject);
16958
+ }
16959
+ }
16960
+ for (let idx = 0, len = compressedObjects.length; idx < len; idx++) {
16961
+ const chunk = compressedObjects[idx];
16962
+ const ref = objectStreamRefs[idx];
16963
+ const objectStream = PDFObjectStream.withContextAndObjects(this.context, chunk, this.encodeStreams);
16964
+ xrefStream.addUncompressedEntry(ref, size);
16965
+ size += this.computeIndirectObjectSize([ref, objectStream]);
16966
+ uncompressedObjects.push([ref, objectStream]);
16967
+ if (this.shouldWaitForTick(chunk.length))
16968
+ await waitForTick();
16969
+ }
16970
+ const xrefStreamRef = PDFRef.of(objectNumber++);
16971
+ xrefStream.dict.set(PDFName.of('Size'), PDFNumber.of(objectNumber));
16972
+ xrefStream.addUncompressedEntry(xrefStreamRef, size);
16973
+ const xrefOffset = size;
16974
+ size += this.computeIndirectObjectSize([xrefStreamRef, xrefStream]);
16975
+ uncompressedObjects.push([xrefStreamRef, xrefStream]);
16976
+ const trailer = PDFTrailer.forLastCrossRefSectionOffset(xrefOffset);
16977
+ size += trailer.sizeInBytes();
16978
+ return { size, header, indirectObjects: uncompressedObjects, trailer };
17013
16979
  }
17014
16980
  }
17015
16981
  PDFStreamWriter.forContext = (context, objectsPerTick, encodeStreams = true, objectsPerStream = 50) => new PDFStreamWriter(context, objectsPerTick, encodeStreams, objectsPerStream);
@@ -17380,11 +17346,9 @@ class CustomFontEmbedder {
17380
17346
  this.baseFontName = '';
17381
17347
  this.glyphCache = Cache.populatedBy(this.allGlyphsInFontSortedById);
17382
17348
  }
17383
- static for(fontkit, fontData, customName, fontFeatures) {
17384
- return __awaiter(this, void 0, void 0, function* () {
17385
- const font = yield fontkit.create(fontData);
17386
- return new CustomFontEmbedder(font, fontData, customName, fontFeatures);
17387
- });
17349
+ static async for(fontkit, fontData, customName, fontFeatures) {
17350
+ const font = await fontkit.create(fontData);
17351
+ return new CustomFontEmbedder(font, fontData, customName, fontFeatures);
17388
17352
  }
17389
17353
  /**
17390
17354
  * Encode the JavaScript string into this font. (JavaScript encodes strings in
@@ -17430,85 +17394,75 @@ class CustomFontEmbedder {
17430
17394
  this.customName || context.addRandomSuffix(this.fontName);
17431
17395
  return this.embedFontDict(context, ref);
17432
17396
  }
17433
- embedFontDict(context, ref) {
17434
- return __awaiter(this, void 0, void 0, function* () {
17435
- const cidFontDictRef = yield this.embedCIDFontDict(context);
17436
- const unicodeCMapRef = this.embedUnicodeCmap(context);
17437
- const fontDict = context.obj({
17438
- Type: 'Font',
17439
- Subtype: 'Type0',
17440
- BaseFont: this.baseFontName,
17441
- Encoding: 'Identity-H',
17442
- DescendantFonts: [cidFontDictRef],
17443
- ToUnicode: unicodeCMapRef,
17444
- });
17445
- if (ref) {
17446
- context.assign(ref, fontDict);
17447
- return ref;
17448
- }
17449
- else {
17450
- return context.register(fontDict);
17451
- }
17397
+ async embedFontDict(context, ref) {
17398
+ const cidFontDictRef = await this.embedCIDFontDict(context);
17399
+ const unicodeCMapRef = this.embedUnicodeCmap(context);
17400
+ const fontDict = context.obj({
17401
+ Type: 'Font',
17402
+ Subtype: 'Type0',
17403
+ BaseFont: this.baseFontName,
17404
+ Encoding: 'Identity-H',
17405
+ DescendantFonts: [cidFontDictRef],
17406
+ ToUnicode: unicodeCMapRef,
17452
17407
  });
17408
+ if (ref) {
17409
+ context.assign(ref, fontDict);
17410
+ return ref;
17411
+ }
17412
+ else {
17413
+ return context.register(fontDict);
17414
+ }
17453
17415
  }
17454
17416
  isCFF() {
17455
17417
  return this.font.cff;
17456
17418
  }
17457
- embedCIDFontDict(context) {
17458
- return __awaiter(this, void 0, void 0, function* () {
17459
- const fontDescriptorRef = yield this.embedFontDescriptor(context);
17460
- const cidFontDict = context.obj({
17461
- Type: 'Font',
17462
- Subtype: this.isCFF() ? 'CIDFontType0' : 'CIDFontType2',
17463
- CIDToGIDMap: 'Identity',
17464
- BaseFont: this.baseFontName,
17465
- CIDSystemInfo: {
17466
- Registry: PDFString.of('Adobe'),
17467
- Ordering: PDFString.of('Identity'),
17468
- Supplement: 0,
17469
- },
17470
- FontDescriptor: fontDescriptorRef,
17471
- W: this.computeWidths(),
17472
- });
17473
- return context.register(cidFontDict);
17419
+ async embedCIDFontDict(context) {
17420
+ const fontDescriptorRef = await this.embedFontDescriptor(context);
17421
+ const cidFontDict = context.obj({
17422
+ Type: 'Font',
17423
+ Subtype: this.isCFF() ? 'CIDFontType0' : 'CIDFontType2',
17424
+ CIDToGIDMap: 'Identity',
17425
+ BaseFont: this.baseFontName,
17426
+ CIDSystemInfo: {
17427
+ Registry: PDFString.of('Adobe'),
17428
+ Ordering: PDFString.of('Identity'),
17429
+ Supplement: 0,
17430
+ },
17431
+ FontDescriptor: fontDescriptorRef,
17432
+ W: this.computeWidths(),
17474
17433
  });
17475
- }
17476
- embedFontDescriptor(context) {
17477
- return __awaiter(this, void 0, void 0, function* () {
17478
- const fontStreamRef = yield this.embedFontStream(context);
17479
- const { scale } = this;
17480
- const { italicAngle, ascent, descent, capHeight, xHeight } = this.font;
17481
- const { minX, minY, maxX, maxY } = this.font.bbox;
17482
- const fontDescriptor = context.obj({
17483
- Type: 'FontDescriptor',
17484
- FontName: this.baseFontName,
17485
- Flags: deriveFontFlags(this.font),
17486
- FontBBox: [minX * scale, minY * scale, maxX * scale, maxY * scale],
17487
- ItalicAngle: italicAngle,
17488
- Ascent: ascent * scale,
17489
- Descent: descent * scale,
17490
- CapHeight: (capHeight || ascent) * scale,
17491
- XHeight: (xHeight || 0) * scale,
17492
- // Not sure how to compute/find this, nor is anybody else really:
17493
- // https://stackoverflow.com/questions/35485179/stemv-value-of-the-truetype-font
17494
- StemV: 0,
17495
- [this.isCFF() ? 'FontFile3' : 'FontFile2']: fontStreamRef,
17496
- });
17497
- return context.register(fontDescriptor);
17434
+ return context.register(cidFontDict);
17435
+ }
17436
+ async embedFontDescriptor(context) {
17437
+ const fontStreamRef = await this.embedFontStream(context);
17438
+ const { scale } = this;
17439
+ const { italicAngle, ascent, descent, capHeight, xHeight } = this.font;
17440
+ const { minX, minY, maxX, maxY } = this.font.bbox;
17441
+ const fontDescriptor = context.obj({
17442
+ Type: 'FontDescriptor',
17443
+ FontName: this.baseFontName,
17444
+ Flags: deriveFontFlags(this.font),
17445
+ FontBBox: [minX * scale, minY * scale, maxX * scale, maxY * scale],
17446
+ ItalicAngle: italicAngle,
17447
+ Ascent: ascent * scale,
17448
+ Descent: descent * scale,
17449
+ CapHeight: (capHeight || ascent) * scale,
17450
+ XHeight: (xHeight || 0) * scale,
17451
+ // Not sure how to compute/find this, nor is anybody else really:
17452
+ // https://stackoverflow.com/questions/35485179/stemv-value-of-the-truetype-font
17453
+ StemV: 0,
17454
+ [this.isCFF() ? 'FontFile3' : 'FontFile2']: fontStreamRef,
17498
17455
  });
17456
+ return context.register(fontDescriptor);
17499
17457
  }
17500
- serializeFont() {
17501
- return __awaiter(this, void 0, void 0, function* () {
17502
- return this.fontData;
17503
- });
17458
+ async serializeFont() {
17459
+ return this.fontData;
17504
17460
  }
17505
- embedFontStream(context) {
17506
- return __awaiter(this, void 0, void 0, function* () {
17507
- const fontStream = context.flateStream(yield this.serializeFont(), {
17508
- Subtype: this.isCFF() ? 'CIDFontType0C' : undefined,
17509
- });
17510
- return context.register(fontStream);
17461
+ async embedFontStream(context) {
17462
+ const fontStream = context.flateStream(await this.serializeFont(), {
17463
+ Subtype: this.isCFF() ? 'CIDFontType0C' : undefined,
17511
17464
  });
17465
+ return context.register(fontStream);
17512
17466
  }
17513
17467
  embedUnicodeCmap(context) {
17514
17468
  const cmap = createCmap(this.glyphCache.access(), this.glyphId.bind(this));
@@ -17555,11 +17509,9 @@ class CustomFontSubsetEmbedder extends CustomFontEmbedder {
17555
17509
  this.glyphCache = Cache.populatedBy(() => this.glyphs);
17556
17510
  this.glyphIdMap = new Map();
17557
17511
  }
17558
- static for(fontkit, fontData, customFontName, fontFeatures) {
17559
- return __awaiter(this, void 0, void 0, function* () {
17560
- const font = yield fontkit.create(fontData);
17561
- return new CustomFontSubsetEmbedder(font, fontData, customFontName, fontFeatures);
17562
- });
17512
+ static async for(fontkit, fontData, customFontName, fontFeatures) {
17513
+ const font = await fontkit.create(fontData);
17514
+ return new CustomFontSubsetEmbedder(font, fontData, customFontName, fontFeatures);
17563
17515
  }
17564
17516
  encodeText(text) {
17565
17517
  const { glyphs } = this.font.layout(text, this.fontFeatures);
@@ -17630,39 +17582,37 @@ class FileEmbedder {
17630
17582
  static for(bytes, fileName, options = {}) {
17631
17583
  return new FileEmbedder(bytes, fileName, options);
17632
17584
  }
17633
- embedIntoContext(context, ref) {
17634
- return __awaiter(this, void 0, void 0, function* () {
17635
- const { mimeType, description, creationDate, modificationDate, afRelationship, } = this.options;
17636
- const embeddedFileStream = context.flateStream(this.fileData, {
17637
- Type: 'EmbeddedFile',
17638
- Subtype: mimeType !== null && mimeType !== void 0 ? mimeType : undefined,
17639
- Params: {
17640
- Size: this.fileData.length,
17641
- CreationDate: creationDate
17642
- ? PDFString.fromDate(creationDate)
17643
- : undefined,
17644
- ModDate: modificationDate
17645
- ? PDFString.fromDate(modificationDate)
17646
- : undefined,
17647
- },
17648
- });
17649
- const embeddedFileStreamRef = context.register(embeddedFileStream);
17650
- const fileSpecDict = context.obj({
17651
- Type: 'Filespec',
17652
- F: PDFString.of(this.fileName),
17653
- UF: PDFHexString.fromText(this.fileName),
17654
- EF: { F: embeddedFileStreamRef },
17655
- Desc: description ? PDFHexString.fromText(description) : undefined,
17656
- AFRelationship: afRelationship !== null && afRelationship !== void 0 ? afRelationship : undefined,
17657
- });
17658
- if (ref) {
17659
- context.assign(ref, fileSpecDict);
17660
- return ref;
17661
- }
17662
- else {
17663
- return context.register(fileSpecDict);
17664
- }
17585
+ async embedIntoContext(context, ref) {
17586
+ const { mimeType, description, creationDate, modificationDate, afRelationship, } = this.options;
17587
+ const embeddedFileStream = context.flateStream(this.fileData, {
17588
+ Type: 'EmbeddedFile',
17589
+ Subtype: mimeType !== null && mimeType !== void 0 ? mimeType : undefined,
17590
+ Params: {
17591
+ Size: this.fileData.length,
17592
+ CreationDate: creationDate
17593
+ ? PDFString.fromDate(creationDate)
17594
+ : undefined,
17595
+ ModDate: modificationDate
17596
+ ? PDFString.fromDate(modificationDate)
17597
+ : undefined,
17598
+ },
17599
+ });
17600
+ const embeddedFileStreamRef = context.register(embeddedFileStream);
17601
+ const fileSpecDict = context.obj({
17602
+ Type: 'Filespec',
17603
+ F: PDFString.of(this.fileName),
17604
+ UF: PDFHexString.fromText(this.fileName),
17605
+ EF: { F: embeddedFileStreamRef },
17606
+ Desc: description ? PDFHexString.fromText(description) : undefined,
17607
+ AFRelationship: afRelationship !== null && afRelationship !== void 0 ? afRelationship : undefined,
17665
17608
  });
17609
+ if (ref) {
17610
+ context.assign(ref, fileSpecDict);
17611
+ return ref;
17612
+ }
17613
+ else {
17614
+ return context.register(fileSpecDict);
17615
+ }
17666
17616
  }
17667
17617
  }
17668
17618
 
@@ -17698,67 +17648,63 @@ class JpegEmbedder {
17698
17648
  this.height = height;
17699
17649
  this.colorSpace = colorSpace;
17700
17650
  }
17701
- static for(imageData) {
17702
- return __awaiter(this, void 0, void 0, function* () {
17703
- const dataView = new DataView(imageData.buffer);
17704
- const soi = dataView.getUint16(0);
17705
- if (soi !== 0xffd8)
17706
- throw new Error('SOI not found in JPEG');
17707
- let pos = 2;
17708
- let marker;
17709
- while (pos < dataView.byteLength) {
17710
- marker = dataView.getUint16(pos);
17711
- pos += 2;
17712
- if (MARKERS.includes(marker))
17713
- break;
17714
- pos += dataView.getUint16(pos);
17715
- }
17716
- if (!MARKERS.includes(marker))
17717
- throw new Error('Invalid JPEG');
17718
- pos += 2;
17719
- const bitsPerComponent = dataView.getUint8(pos++);
17720
- const height = dataView.getUint16(pos);
17651
+ static async for(imageData) {
17652
+ const dataView = new DataView(imageData.buffer);
17653
+ const soi = dataView.getUint16(0);
17654
+ if (soi !== 0xffd8)
17655
+ throw new Error('SOI not found in JPEG');
17656
+ let pos = 2;
17657
+ let marker;
17658
+ while (pos < dataView.byteLength) {
17659
+ marker = dataView.getUint16(pos);
17721
17660
  pos += 2;
17722
- const width = dataView.getUint16(pos);
17723
- pos += 2;
17724
- const channelByte = dataView.getUint8(pos++);
17725
- const channelName = ChannelToColorSpace[channelByte];
17726
- if (!channelName)
17727
- throw new Error('Unknown JPEG channel.');
17728
- const colorSpace = channelName;
17729
- return new JpegEmbedder(imageData, bitsPerComponent, width, height, colorSpace);
17730
- });
17731
- }
17732
- embedIntoContext(context, ref) {
17733
- return __awaiter(this, void 0, void 0, function* () {
17734
- const xObject = context.stream(this.imageData, {
17735
- Type: 'XObject',
17736
- Subtype: 'Image',
17737
- BitsPerComponent: this.bitsPerComponent,
17738
- Width: this.width,
17739
- Height: this.height,
17740
- ColorSpace: this.colorSpace,
17741
- Filter: 'DCTDecode',
17742
- // CMYK JPEG streams in PDF are typically stored complemented,
17743
- // with 1 as 'off' and 0 as 'on' (PDF 32000-1:2008, 8.6.4.4).
17744
- //
17745
- // Standalone CMYK JPEG (usually exported by Photoshop) are
17746
- // stored inverse, with 0 as 'off' and 1 as 'on', like RGB.
17747
- //
17748
- // Applying a swap here as a hedge that most bytes passing
17749
- // through this method will benefit from it.
17750
- Decode: this.colorSpace === ColorSpace.DeviceCMYK
17751
- ? [1, 0, 1, 0, 1, 0, 1, 0]
17752
- : undefined,
17753
- });
17754
- if (ref) {
17755
- context.assign(ref, xObject);
17756
- return ref;
17757
- }
17758
- else {
17759
- return context.register(xObject);
17760
- }
17661
+ if (MARKERS.includes(marker))
17662
+ break;
17663
+ pos += dataView.getUint16(pos);
17664
+ }
17665
+ if (!MARKERS.includes(marker))
17666
+ throw new Error('Invalid JPEG');
17667
+ pos += 2;
17668
+ const bitsPerComponent = dataView.getUint8(pos++);
17669
+ const height = dataView.getUint16(pos);
17670
+ pos += 2;
17671
+ const width = dataView.getUint16(pos);
17672
+ pos += 2;
17673
+ const channelByte = dataView.getUint8(pos++);
17674
+ const channelName = ChannelToColorSpace[channelByte];
17675
+ if (!channelName)
17676
+ throw new Error('Unknown JPEG channel.');
17677
+ const colorSpace = channelName;
17678
+ return new JpegEmbedder(imageData, bitsPerComponent, width, height, colorSpace);
17679
+ }
17680
+ async embedIntoContext(context, ref) {
17681
+ const xObject = context.stream(this.imageData, {
17682
+ Type: 'XObject',
17683
+ Subtype: 'Image',
17684
+ BitsPerComponent: this.bitsPerComponent,
17685
+ Width: this.width,
17686
+ Height: this.height,
17687
+ ColorSpace: this.colorSpace,
17688
+ Filter: 'DCTDecode',
17689
+ // CMYK JPEG streams in PDF are typically stored complemented,
17690
+ // with 1 as 'off' and 0 as 'on' (PDF 32000-1:2008, 8.6.4.4).
17691
+ //
17692
+ // Standalone CMYK JPEG (usually exported by Photoshop) are
17693
+ // stored inverse, with 0 as 'off' and 1 as 'on', like RGB.
17694
+ //
17695
+ // Applying a swap here as a hedge that most bytes passing
17696
+ // through this method will benefit from it.
17697
+ Decode: this.colorSpace === ColorSpace.DeviceCMYK
17698
+ ? [1, 0, 1, 0, 1, 0, 1, 0]
17699
+ : undefined,
17761
17700
  });
17701
+ if (ref) {
17702
+ context.assign(ref, xObject);
17703
+ return ref;
17704
+ }
17705
+ else {
17706
+ return context.register(xObject);
17707
+ }
17762
17708
  }
17763
17709
  }
17764
17710
 
@@ -25644,32 +25590,28 @@ class PngEmbedder {
25644
25590
  this.height = png.height;
25645
25591
  this.colorSpace = 'DeviceRGB';
25646
25592
  }
25647
- static for(imageData) {
25648
- return __awaiter(this, void 0, void 0, function* () {
25649
- const png = PNG.load(imageData);
25650
- return new PngEmbedder(png);
25651
- });
25593
+ static async for(imageData) {
25594
+ const png = PNG.load(imageData);
25595
+ return new PngEmbedder(png);
25652
25596
  }
25653
- embedIntoContext(context, ref) {
25654
- return __awaiter(this, void 0, void 0, function* () {
25655
- const SMask = this.embedAlphaChannel(context);
25656
- const xObject = context.flateStream(this.image.rgbChannel, {
25657
- Type: 'XObject',
25658
- Subtype: 'Image',
25659
- BitsPerComponent: this.image.bitsPerComponent,
25660
- Width: this.image.width,
25661
- Height: this.image.height,
25662
- ColorSpace: this.colorSpace,
25663
- SMask,
25664
- });
25665
- if (ref) {
25666
- context.assign(ref, xObject);
25667
- return ref;
25668
- }
25669
- else {
25670
- return context.register(xObject);
25671
- }
25597
+ async embedIntoContext(context, ref) {
25598
+ const SMask = this.embedAlphaChannel(context);
25599
+ const xObject = context.flateStream(this.image.rgbChannel, {
25600
+ Type: 'XObject',
25601
+ Subtype: 'Image',
25602
+ BitsPerComponent: this.image.bitsPerComponent,
25603
+ Width: this.image.width,
25604
+ Height: this.image.height,
25605
+ ColorSpace: this.colorSpace,
25606
+ SMask,
25672
25607
  });
25608
+ if (ref) {
25609
+ context.assign(ref, xObject);
25610
+ return ref;
25611
+ }
25612
+ else {
25613
+ return context.register(xObject);
25614
+ }
25673
25615
  }
25674
25616
  embedAlphaChannel(context) {
25675
25617
  if (!this.image.alphaChannel)
@@ -26657,34 +26599,30 @@ class PDFPageEmbedder {
26657
26599
  this.transformationMatrix =
26658
26600
  transformationMatrix !== null && transformationMatrix !== void 0 ? transformationMatrix : boundingBoxAdjustedMatrix(bb);
26659
26601
  }
26660
- static for(page, boundingBox, transformationMatrix) {
26661
- return __awaiter(this, void 0, void 0, function* () {
26662
- return new PDFPageEmbedder(page, boundingBox, transformationMatrix);
26663
- });
26602
+ static async for(page, boundingBox, transformationMatrix) {
26603
+ return new PDFPageEmbedder(page, boundingBox, transformationMatrix);
26664
26604
  }
26665
- embedIntoContext(context, ref) {
26666
- return __awaiter(this, void 0, void 0, function* () {
26667
- const { Contents, Resources } = this.page.normalizedEntries();
26668
- if (!Contents)
26669
- throw new MissingPageContentsEmbeddingError();
26670
- const decodedContents = this.decodeContents(Contents);
26671
- const { left, bottom, right, top } = this.boundingBox;
26672
- const xObject = context.flateStream(decodedContents, {
26673
- Type: 'XObject',
26674
- Subtype: 'Form',
26675
- FormType: 1,
26676
- BBox: [left, bottom, right, top],
26677
- Matrix: this.transformationMatrix,
26678
- Resources,
26679
- });
26680
- if (ref) {
26681
- context.assign(ref, xObject);
26682
- return ref;
26683
- }
26684
- else {
26685
- return context.register(xObject);
26686
- }
26605
+ async embedIntoContext(context, ref) {
26606
+ const { Contents, Resources } = this.page.normalizedEntries();
26607
+ if (!Contents)
26608
+ throw new MissingPageContentsEmbeddingError();
26609
+ const decodedContents = this.decodeContents(Contents);
26610
+ const { left, bottom, right, top } = this.boundingBox;
26611
+ const xObject = context.flateStream(decodedContents, {
26612
+ Type: 'XObject',
26613
+ Subtype: 'Form',
26614
+ FormType: 1,
26615
+ BBox: [left, bottom, right, top],
26616
+ Matrix: this.transformationMatrix,
26617
+ Resources,
26687
26618
  });
26619
+ if (ref) {
26620
+ context.assign(ref, xObject);
26621
+ return ref;
26622
+ }
26623
+ else {
26624
+ return context.register(xObject);
26625
+ }
26688
26626
  }
26689
26627
  // `contents` is an array of streams which are merged to include them in the XObject.
26690
26628
  // This methods extracts each stream and joins them with a newline character.
@@ -29136,23 +29074,21 @@ class PDFObjectStreamParser extends PDFObjectParser {
29136
29074
  this.firstOffset = dict.lookup(PDFName.of('First'), PDFNumber).asNumber();
29137
29075
  this.objectCount = dict.lookup(PDFName.of('N'), PDFNumber).asNumber();
29138
29076
  }
29139
- parseIntoContext() {
29140
- return __awaiter(this, void 0, void 0, function* () {
29141
- if (this.alreadyParsed) {
29142
- throw new ReparseError('PDFObjectStreamParser', 'parseIntoContext');
29143
- }
29144
- this.alreadyParsed = true;
29145
- const offsetsAndObjectNumbers = this.parseOffsetsAndObjectNumbers();
29146
- for (let idx = 0, len = offsetsAndObjectNumbers.length; idx < len; idx++) {
29147
- const { objectNumber, offset } = offsetsAndObjectNumbers[idx];
29148
- this.bytes.moveTo(this.firstOffset + offset);
29149
- const ref = PDFRef.of(objectNumber, 0);
29150
- const object = this.parseObject(ref);
29151
- this.context.assign(ref, object);
29152
- if (this.shouldWaitForTick())
29153
- yield waitForTick();
29154
- }
29155
- });
29077
+ async parseIntoContext() {
29078
+ if (this.alreadyParsed) {
29079
+ throw new ReparseError('PDFObjectStreamParser', 'parseIntoContext');
29080
+ }
29081
+ this.alreadyParsed = true;
29082
+ const offsetsAndObjectNumbers = this.parseOffsetsAndObjectNumbers();
29083
+ for (let idx = 0, len = offsetsAndObjectNumbers.length; idx < len; idx++) {
29084
+ const { objectNumber, offset } = offsetsAndObjectNumbers[idx];
29085
+ this.bytes.moveTo(this.firstOffset + offset);
29086
+ const ref = PDFRef.of(objectNumber, 0);
29087
+ const object = this.parseObject(ref);
29088
+ this.context.assign(ref, object);
29089
+ if (this.shouldWaitForTick())
29090
+ await waitForTick();
29091
+ }
29156
29092
  }
29157
29093
  parseOffsetsAndObjectNumbers() {
29158
29094
  const offsetsAndObjectNumbers = [];
@@ -29260,29 +29196,27 @@ class PDFParser extends PDFObjectParser {
29260
29196
  this.throwOnInvalidObject = throwOnInvalidObject;
29261
29197
  this.context.isDecrypted = !!(cryptoFactory === null || cryptoFactory === void 0 ? void 0 : cryptoFactory.encryptionKey);
29262
29198
  }
29263
- parseDocument() {
29264
- return __awaiter(this, void 0, void 0, function* () {
29265
- if (this.alreadyParsed) {
29266
- throw new ReparseError('PDFParser', 'parseDocument');
29267
- }
29268
- this.alreadyParsed = true;
29269
- this.context.header = this.parseHeader();
29270
- let prevOffset;
29271
- while (!this.bytes.done()) {
29272
- yield this.parseDocumentSection();
29273
- const offset = this.bytes.offset();
29274
- if (offset === prevOffset) {
29275
- throw new StalledParserError(this.bytes.position());
29276
- }
29277
- prevOffset = offset;
29278
- }
29279
- this.maybeRecoverRoot();
29280
- if (this.context.lookup(PDFRef.of(0))) {
29281
- console.warn('Removing parsed object: 0 0 R');
29282
- this.context.delete(PDFRef.of(0));
29199
+ async parseDocument() {
29200
+ if (this.alreadyParsed) {
29201
+ throw new ReparseError('PDFParser', 'parseDocument');
29202
+ }
29203
+ this.alreadyParsed = true;
29204
+ this.context.header = this.parseHeader();
29205
+ let prevOffset;
29206
+ while (!this.bytes.done()) {
29207
+ await this.parseDocumentSection();
29208
+ const offset = this.bytes.offset();
29209
+ if (offset === prevOffset) {
29210
+ throw new StalledParserError(this.bytes.position());
29283
29211
  }
29284
- return this.context;
29285
- });
29212
+ prevOffset = offset;
29213
+ }
29214
+ this.maybeRecoverRoot();
29215
+ if (this.context.lookup(PDFRef.of(0))) {
29216
+ console.warn('Removing parsed object: 0 0 R');
29217
+ this.context.delete(PDFRef.of(0));
29218
+ }
29219
+ return this.context;
29286
29220
  }
29287
29221
  maybeRecoverRoot() {
29288
29222
  const isValidCatalog = (obj) => obj instanceof PDFDict &&
@@ -29334,30 +29268,28 @@ class PDFParser extends PDFObjectParser {
29334
29268
  return false;
29335
29269
  }
29336
29270
  }
29337
- parseIndirectObject() {
29338
- return __awaiter(this, void 0, void 0, function* () {
29339
- const ref = this.parseIndirectObjectHeader();
29340
- this.skipWhitespaceAndComments();
29341
- const object = this.parseObject(ref);
29342
- this.skipWhitespaceAndComments();
29343
- // if (!this.matchKeyword(Keywords.endobj)) {
29344
- // throw new MissingKeywordError(this.bytes.position(), Keywords.endobj);
29345
- // }
29346
- // TODO: Log a warning if this fails...
29347
- this.matchKeyword(Keywords.endobj);
29348
- if (object instanceof PDFRawStream &&
29349
- object.dict.lookup(PDFName.of('Type')) === PDFName.of('ObjStm')) {
29350
- yield PDFObjectStreamParser.forStream(object, this.shouldWaitForTick).parseIntoContext();
29351
- }
29352
- else if (object instanceof PDFRawStream &&
29353
- object.dict.lookup(PDFName.of('Type')) === PDFName.of('XRef')) {
29354
- PDFXRefStreamParser.forStream(object).parseIntoContext();
29355
- }
29356
- else {
29357
- this.context.assign(ref, object);
29358
- }
29359
- return ref;
29360
- });
29271
+ async parseIndirectObject() {
29272
+ const ref = this.parseIndirectObjectHeader();
29273
+ this.skipWhitespaceAndComments();
29274
+ const object = this.parseObject(ref);
29275
+ this.skipWhitespaceAndComments();
29276
+ // if (!this.matchKeyword(Keywords.endobj)) {
29277
+ // throw new MissingKeywordError(this.bytes.position(), Keywords.endobj);
29278
+ // }
29279
+ // TODO: Log a warning if this fails...
29280
+ this.matchKeyword(Keywords.endobj);
29281
+ if (object instanceof PDFRawStream &&
29282
+ object.dict.lookup(PDFName.of('Type')) === PDFName.of('ObjStm')) {
29283
+ await PDFObjectStreamParser.forStream(object, this.shouldWaitForTick).parseIntoContext();
29284
+ }
29285
+ else if (object instanceof PDFRawStream &&
29286
+ object.dict.lookup(PDFName.of('Type')) === PDFName.of('XRef')) {
29287
+ PDFXRefStreamParser.forStream(object).parseIntoContext();
29288
+ }
29289
+ else {
29290
+ this.context.assign(ref, object);
29291
+ }
29292
+ return ref;
29361
29293
  }
29362
29294
  // TODO: Improve and clean this up
29363
29295
  tryToParseInvalidIndirectObject() {
@@ -29386,26 +29318,24 @@ class PDFParser extends PDFObjectParser {
29386
29318
  this.context.assign(ref, object);
29387
29319
  return ref;
29388
29320
  }
29389
- parseIndirectObjects() {
29390
- return __awaiter(this, void 0, void 0, function* () {
29391
- this.skipWhitespaceAndComments();
29392
- while (!this.bytes.done() && IsDigit[this.bytes.peek()]) {
29393
- const initialOffset = this.bytes.offset();
29394
- try {
29395
- yield this.parseIndirectObject();
29396
- }
29397
- catch (e) {
29398
- // TODO: Add tracing/logging mechanism to track when this happens!
29399
- this.bytes.moveTo(initialOffset);
29400
- this.tryToParseInvalidIndirectObject();
29401
- }
29402
- this.skipWhitespaceAndComments();
29403
- // TODO: Can this be done only when needed, to avoid harming performance?
29404
- this.skipJibberish();
29405
- if (this.shouldWaitForTick())
29406
- yield waitForTick();
29321
+ async parseIndirectObjects() {
29322
+ this.skipWhitespaceAndComments();
29323
+ while (!this.bytes.done() && IsDigit[this.bytes.peek()]) {
29324
+ const initialOffset = this.bytes.offset();
29325
+ try {
29326
+ await this.parseIndirectObject();
29407
29327
  }
29408
- });
29328
+ catch (e) {
29329
+ // TODO: Add tracing/logging mechanism to track when this happens!
29330
+ this.bytes.moveTo(initialOffset);
29331
+ this.tryToParseInvalidIndirectObject();
29332
+ }
29333
+ this.skipWhitespaceAndComments();
29334
+ // TODO: Can this be done only when needed, to avoid harming performance?
29335
+ this.skipJibberish();
29336
+ if (this.shouldWaitForTick())
29337
+ await waitForTick();
29338
+ }
29409
29339
  }
29410
29340
  maybeParseCrossRefSection() {
29411
29341
  this.skipWhitespaceAndComments();
@@ -29465,15 +29395,13 @@ class PDFParser extends PDFObjectParser {
29465
29395
  this.skipWhitespaceAndComments();
29466
29396
  return PDFTrailer.forLastCrossRefSectionOffset(offset);
29467
29397
  }
29468
- parseDocumentSection() {
29469
- return __awaiter(this, void 0, void 0, function* () {
29470
- yield this.parseIndirectObjects();
29471
- this.maybeParseCrossRefSection();
29472
- this.maybeParseTrailerDict();
29473
- this.maybeParseTrailer();
29474
- // TODO: Can this be done only when needed, to avoid harming performance?
29475
- this.skipJibberish();
29476
- });
29398
+ async parseDocumentSection() {
29399
+ await this.parseIndirectObjects();
29400
+ this.maybeParseCrossRefSection();
29401
+ this.maybeParseTrailerDict();
29402
+ this.maybeParseTrailer();
29403
+ // TODO: Can this be done only when needed, to avoid harming performance?
29404
+ this.skipJibberish();
29477
29405
  }
29478
29406
  /**
29479
29407
  * This operation is not necessary for valid PDF files. But some invalid PDFs
@@ -32196,6 +32124,16 @@ const segmentToBezier = (cx1, cy1, th0, th1, rx, ry, sinTh, cosTh) => {
32196
32124
  };
32197
32125
  const svgPathToOperators = (path) => apply(parse(path));
32198
32126
 
32127
+ const clipSpace = ({ topLeft, topRight, bottomRight, bottomLeft }) => [
32128
+ moveTo(topLeft.x, topLeft.y),
32129
+ lineTo(topRight.x, topRight.y),
32130
+ lineTo(bottomRight.x, bottomRight.y),
32131
+ lineTo(bottomLeft.x, bottomLeft.y),
32132
+ closePath(),
32133
+ clip(),
32134
+ endPath(),
32135
+ ];
32136
+ const clipSpaces = (spaces) => spaces.flatMap(clipSpace);
32199
32137
  const drawText = (line, options) => [
32200
32138
  pushGraphicsState(),
32201
32139
  options.graphicsState && setGraphicsState(options.graphicsState),
@@ -32211,6 +32149,8 @@ const drawLinesOfText = (lines, options) => {
32211
32149
  const operators = [
32212
32150
  pushGraphicsState(),
32213
32151
  options.graphicsState && setGraphicsState(options.graphicsState),
32152
+ ...(options.clipSpaces ? clipSpaces(options.clipSpaces) : []),
32153
+ options.matrix && concatTransformationMatrix(...options.matrix),
32214
32154
  beginText(),
32215
32155
  setFillingColor(options.color),
32216
32156
  setFontAndSize(options.font, options.size),
@@ -32226,6 +32166,8 @@ const drawLinesOfText = (lines, options) => {
32226
32166
  const drawImage = (name, options) => [
32227
32167
  pushGraphicsState(),
32228
32168
  options.graphicsState && setGraphicsState(options.graphicsState),
32169
+ ...(options.clipSpaces ? clipSpaces(options.clipSpaces) : []),
32170
+ options.matrix && concatTransformationMatrix(...options.matrix),
32229
32171
  translate(options.x, options.y),
32230
32172
  rotateRadians(toRadians(options.rotate)),
32231
32173
  scale(options.width, options.height),
@@ -32248,6 +32190,8 @@ const drawLine = (options) => {
32248
32190
  return [
32249
32191
  pushGraphicsState(),
32250
32192
  options.graphicsState && setGraphicsState(options.graphicsState),
32193
+ ...(options.clipSpaces ? clipSpaces(options.clipSpaces) : []),
32194
+ options.matrix && concatTransformationMatrix(...options.matrix),
32251
32195
  options.color && setStrokingColor(options.color),
32252
32196
  setLineWidth(options.thickness),
32253
32197
  setDashPattern((_a = options.dashArray) !== null && _a !== void 0 ? _a : [], (_b = options.dashPhase) !== null && _b !== void 0 ? _b : 0),
@@ -32269,6 +32213,8 @@ const drawRectangle = (options) => {
32269
32213
  setLineWidth(options.borderWidth),
32270
32214
  options.borderLineCap && setLineCap(options.borderLineCap),
32271
32215
  setDashPattern((_a = options.borderDashArray) !== null && _a !== void 0 ? _a : [], (_b = options.borderDashPhase) !== null && _b !== void 0 ? _b : 0),
32216
+ ...(options.clipSpaces ? clipSpaces(options.clipSpaces) : []),
32217
+ options.matrix && concatTransformationMatrix(...options.matrix),
32272
32218
  translate(options.x, options.y),
32273
32219
  rotateRadians(toRadians(options.rotate)),
32274
32220
  skewRadians(toRadians(options.xSkew), toRadians(options.ySkew)),
@@ -32340,6 +32286,8 @@ const drawEllipse = (options) => {
32340
32286
  options.graphicsState && setGraphicsState(options.graphicsState),
32341
32287
  options.color && setFillingColor(options.color),
32342
32288
  options.borderColor && setStrokingColor(options.borderColor),
32289
+ ...(options.clipSpaces ? clipSpaces(options.clipSpaces) : []),
32290
+ options.matrix && concatTransformationMatrix(...options.matrix),
32343
32291
  setLineWidth(options.borderWidth),
32344
32292
  options.borderLineCap && setLineCap(options.borderLineCap),
32345
32293
  setDashPattern((_a = options.borderDashArray) !== null && _a !== void 0 ? _a : [], (_b = options.borderDashPhase) !== null && _b !== void 0 ? _b : 0),
@@ -32372,6 +32320,8 @@ const drawSvgPath = (path, options) => {
32372
32320
  return [
32373
32321
  pushGraphicsState(),
32374
32322
  options.graphicsState && setGraphicsState(options.graphicsState),
32323
+ ...(options.clipSpaces ? clipSpaces(options.clipSpaces) : []),
32324
+ options.matrix && concatTransformationMatrix(...options.matrix),
32375
32325
  translate(options.x, options.y),
32376
32326
  rotateRadians(toRadians((_a = options.rotate) !== null && _a !== void 0 ? _a : degrees(0))),
32377
32327
  options.scale && scale(options.scale, options.scale),
@@ -33033,7 +32983,7 @@ const defaultCheckBoxAppearanceProvider = (checkBox, widget) => {
33033
32983
  const borderWidth = (_a = bs === null || bs === void 0 ? void 0 : bs.getWidth()) !== null && _a !== void 0 ? _a : 0;
33034
32984
  const rotation = reduceRotation(ap === null || ap === void 0 ? void 0 : ap.getRotation());
33035
32985
  const { width, height } = adjustDimsForRotation(rectangle, rotation);
33036
- const rotate = rotateInPlace(Object.assign(Object.assign({}, rectangle), { rotation }));
32986
+ const rotate = rotateInPlace({ ...rectangle, rotation });
33037
32987
  const black = rgb(0, 0, 0);
33038
32988
  const borderColor = (_b = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBorderColor())) !== null && _b !== void 0 ? _b : black;
33039
32989
  const normalBackgroundColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBackgroundColor());
@@ -33060,21 +33010,37 @@ const defaultCheckBoxAppearanceProvider = (checkBox, widget) => {
33060
33010
  normal: {
33061
33011
  on: [
33062
33012
  ...rotate,
33063
- ...drawCheckBox(Object.assign(Object.assign({}, options), { color: normalBackgroundColor, filled: true })),
33013
+ ...drawCheckBox({
33014
+ ...options,
33015
+ color: normalBackgroundColor,
33016
+ filled: true,
33017
+ }),
33064
33018
  ],
33065
33019
  off: [
33066
33020
  ...rotate,
33067
- ...drawCheckBox(Object.assign(Object.assign({}, options), { color: normalBackgroundColor, filled: false })),
33021
+ ...drawCheckBox({
33022
+ ...options,
33023
+ color: normalBackgroundColor,
33024
+ filled: false,
33025
+ }),
33068
33026
  ],
33069
33027
  },
33070
33028
  down: {
33071
33029
  on: [
33072
33030
  ...rotate,
33073
- ...drawCheckBox(Object.assign(Object.assign({}, options), { color: downBackgroundColor, filled: true })),
33031
+ ...drawCheckBox({
33032
+ ...options,
33033
+ color: downBackgroundColor,
33034
+ filled: true,
33035
+ }),
33074
33036
  ],
33075
33037
  off: [
33076
33038
  ...rotate,
33077
- ...drawCheckBox(Object.assign(Object.assign({}, options), { color: downBackgroundColor, filled: false })),
33039
+ ...drawCheckBox({
33040
+ ...options,
33041
+ color: downBackgroundColor,
33042
+ filled: false,
33043
+ }),
33078
33044
  ],
33079
33045
  },
33080
33046
  };
@@ -33090,7 +33056,7 @@ const defaultRadioGroupAppearanceProvider = (radioGroup, widget) => {
33090
33056
  const borderWidth = (_a = bs === null || bs === void 0 ? void 0 : bs.getWidth()) !== null && _a !== void 0 ? _a : 0;
33091
33057
  const rotation = reduceRotation(ap === null || ap === void 0 ? void 0 : ap.getRotation());
33092
33058
  const { width, height } = adjustDimsForRotation(rectangle, rotation);
33093
- const rotate = rotateInPlace(Object.assign(Object.assign({}, rectangle), { rotation }));
33059
+ const rotate = rotateInPlace({ ...rectangle, rotation });
33094
33060
  const black = rgb(0, 0, 0);
33095
33061
  const borderColor = (_b = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBorderColor())) !== null && _b !== void 0 ? _b : black;
33096
33062
  const normalBackgroundColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBackgroundColor());
@@ -33116,21 +33082,37 @@ const defaultRadioGroupAppearanceProvider = (radioGroup, widget) => {
33116
33082
  normal: {
33117
33083
  on: [
33118
33084
  ...rotate,
33119
- ...drawRadioButton(Object.assign(Object.assign({}, options), { color: normalBackgroundColor, filled: true })),
33085
+ ...drawRadioButton({
33086
+ ...options,
33087
+ color: normalBackgroundColor,
33088
+ filled: true,
33089
+ }),
33120
33090
  ],
33121
33091
  off: [
33122
33092
  ...rotate,
33123
- ...drawRadioButton(Object.assign(Object.assign({}, options), { color: normalBackgroundColor, filled: false })),
33093
+ ...drawRadioButton({
33094
+ ...options,
33095
+ color: normalBackgroundColor,
33096
+ filled: false,
33097
+ }),
33124
33098
  ],
33125
33099
  },
33126
33100
  down: {
33127
33101
  on: [
33128
33102
  ...rotate,
33129
- ...drawRadioButton(Object.assign(Object.assign({}, options), { color: downBackgroundColor, filled: true })),
33103
+ ...drawRadioButton({
33104
+ ...options,
33105
+ color: downBackgroundColor,
33106
+ filled: true,
33107
+ }),
33130
33108
  ],
33131
33109
  off: [
33132
33110
  ...rotate,
33133
- ...drawRadioButton(Object.assign(Object.assign({}, options), { color: downBackgroundColor, filled: false })),
33111
+ ...drawRadioButton({
33112
+ ...options,
33113
+ color: downBackgroundColor,
33114
+ filled: false,
33115
+ }),
33134
33116
  ],
33135
33117
  },
33136
33118
  };
@@ -33151,7 +33133,7 @@ const defaultButtonAppearanceProvider = (button, widget, font) => {
33151
33133
  const borderWidth = (_d = bs === null || bs === void 0 ? void 0 : bs.getWidth()) !== null && _d !== void 0 ? _d : 0;
33152
33134
  const rotation = reduceRotation(ap === null || ap === void 0 ? void 0 : ap.getRotation());
33153
33135
  const { width, height } = adjustDimsForRotation(rectangle, rotation);
33154
- const rotate = rotateInPlace(Object.assign(Object.assign({}, rectangle), { rotation }));
33136
+ const rotate = rotateInPlace({ ...rectangle, rotation });
33155
33137
  const black = rgb(0, 0, 0);
33156
33138
  const borderColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBorderColor());
33157
33139
  const normalBackgroundColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBackgroundColor());
@@ -33197,11 +33179,19 @@ const defaultButtonAppearanceProvider = (button, widget, font) => {
33197
33179
  return {
33198
33180
  normal: [
33199
33181
  ...rotate,
33200
- ...drawButton(Object.assign(Object.assign({}, options), { color: normalBackgroundColor, textLines: [normalLayout.line] })),
33182
+ ...drawButton({
33183
+ ...options,
33184
+ color: normalBackgroundColor,
33185
+ textLines: [normalLayout.line],
33186
+ }),
33201
33187
  ],
33202
33188
  down: [
33203
33189
  ...rotate,
33204
- ...drawButton(Object.assign(Object.assign({}, options), { color: downBackgroundColor, textLines: [downLayout.line] })),
33190
+ ...drawButton({
33191
+ ...options,
33192
+ color: downBackgroundColor,
33193
+ textLines: [downLayout.line],
33194
+ }),
33205
33195
  ],
33206
33196
  };
33207
33197
  };
@@ -33219,7 +33209,7 @@ const defaultTextFieldAppearanceProvider = (textField, widget, font) => {
33219
33209
  const borderWidth = (_b = bs === null || bs === void 0 ? void 0 : bs.getWidth()) !== null && _b !== void 0 ? _b : 0;
33220
33210
  const rotation = reduceRotation(ap === null || ap === void 0 ? void 0 : ap.getRotation());
33221
33211
  const { width, height } = adjustDimsForRotation(rectangle, rotation);
33222
- const rotate = rotateInPlace(Object.assign(Object.assign({}, rectangle), { rotation }));
33212
+ const rotate = rotateInPlace({ ...rectangle, rotation });
33223
33213
  const black = rgb(0, 0, 0);
33224
33214
  const borderColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBorderColor());
33225
33215
  const normalBackgroundColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBackgroundColor());
@@ -33300,7 +33290,7 @@ const defaultDropdownAppearanceProvider = (dropdown, widget, font) => {
33300
33290
  const borderWidth = (_b = bs === null || bs === void 0 ? void 0 : bs.getWidth()) !== null && _b !== void 0 ? _b : 0;
33301
33291
  const rotation = reduceRotation(ap === null || ap === void 0 ? void 0 : ap.getRotation());
33302
33292
  const { width, height } = adjustDimsForRotation(rectangle, rotation);
33303
- const rotate = rotateInPlace(Object.assign(Object.assign({}, rectangle), { rotation }));
33293
+ const rotate = rotateInPlace({ ...rectangle, rotation });
33304
33294
  const black = rgb(0, 0, 0);
33305
33295
  const borderColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBorderColor());
33306
33296
  const normalBackgroundColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBackgroundColor());
@@ -33354,7 +33344,7 @@ const defaultOptionListAppearanceProvider = (optionList, widget, font) => {
33354
33344
  const borderWidth = (_a = bs === null || bs === void 0 ? void 0 : bs.getWidth()) !== null && _a !== void 0 ? _a : 0;
33355
33345
  const rotation = reduceRotation(ap === null || ap === void 0 ? void 0 : ap.getRotation());
33356
33346
  const { width, height } = adjustDimsForRotation(rectangle, rotation);
33357
- const rotate = rotateInPlace(Object.assign(Object.assign({}, rectangle), { rotation }));
33347
+ const rotate = rotateInPlace({ ...rectangle, rotation });
33358
33348
  const black = rgb(0, 0, 0);
33359
33349
  const borderColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBorderColor());
33360
33350
  const normalBackgroundColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBackgroundColor());
@@ -33472,13 +33462,11 @@ class PDFEmbeddedPage {
33472
33462
  *
33473
33463
  * @returns Resolves when the embedding is complete.
33474
33464
  */
33475
- embed() {
33476
- return __awaiter(this, void 0, void 0, function* () {
33477
- if (!this.alreadyEmbedded) {
33478
- yield this.embedder.embedIntoContext(this.doc.context, this.ref);
33479
- this.alreadyEmbedded = true;
33480
- }
33481
- });
33465
+ async embed() {
33466
+ if (!this.alreadyEmbedded) {
33467
+ await this.embedder.embedIntoContext(this.doc.context, this.ref);
33468
+ this.alreadyEmbedded = true;
33469
+ }
33482
33470
  }
33483
33471
  }
33484
33472
  /**
@@ -33597,14 +33585,12 @@ class PDFFont {
33597
33585
  *
33598
33586
  * @returns Resolves when the embedding is complete.
33599
33587
  */
33600
- embed() {
33601
- return __awaiter(this, void 0, void 0, function* () {
33602
- // TODO: Cleanup orphan embedded objects if a font is embedded multiple times...
33603
- if (this.modified) {
33604
- yield this.embedder.embedIntoContext(this.doc.context, this.ref);
33605
- this.modified = false;
33606
- }
33607
- });
33588
+ async embed() {
33589
+ // TODO: Cleanup orphan embedded objects if a font is embedded multiple times...
33590
+ if (this.modified) {
33591
+ await this.embedder.embedIntoContext(this.doc.context, this.ref);
33592
+ this.modified = false;
33593
+ }
33608
33594
  }
33609
33595
  }
33610
33596
  /**
@@ -33703,22 +33689,20 @@ class PDFImage {
33703
33689
  *
33704
33690
  * @returns Resolves when the embedding is complete.
33705
33691
  */
33706
- embed() {
33707
- return __awaiter(this, void 0, void 0, function* () {
33708
- if (!this.embedder)
33709
- return;
33710
- // The image should only be embedded once. If there's a pending embed
33711
- // operation then wait on it. Otherwise we need to start the embed.
33712
- if (!this.embedTask) {
33713
- const { doc, ref } = this;
33714
- this.embedTask = this.embedder.embedIntoContext(doc.context, ref);
33715
- }
33716
- yield this.embedTask;
33717
- // We clear `this.embedder` so that the indirectly referenced image data
33718
- // can be garbage collected, thus avoiding a memory leak.
33719
- // See https://github.com/Hopding/pdf-lib/pull/1032/files.
33720
- this.embedder = undefined;
33721
- });
33692
+ async embed() {
33693
+ if (!this.embedder)
33694
+ return;
33695
+ // The image should only be embedded once. If there's a pending embed
33696
+ // operation then wait on it. Otherwise we need to start the embed.
33697
+ if (!this.embedTask) {
33698
+ const { doc, ref } = this;
33699
+ this.embedTask = this.embedder.embedIntoContext(doc.context, ref);
33700
+ }
33701
+ await this.embedTask;
33702
+ // We clear `this.embedder` so that the indirectly referenced image data
33703
+ // can be garbage collected, thus avoiding a memory leak.
33704
+ // See https://github.com/Hopding/pdf-lib/pull/1032/files.
33705
+ this.embedder = undefined;
33722
33706
  }
33723
33707
  }
33724
33708
  /**
@@ -34063,7 +34047,7 @@ class PDFField {
34063
34047
  const bs = widget.getBorderStyle();
34064
34048
  const borderWidth = (_a = bs === null || bs === void 0 ? void 0 : bs.getWidth()) !== null && _a !== void 0 ? _a : 0;
34065
34049
  const rotation = reduceRotation(ap === null || ap === void 0 ? void 0 : ap.getRotation());
34066
- const rotate = rotateInPlace(Object.assign(Object.assign({}, rectangle), { rotation }));
34050
+ const rotate = rotateInPlace({ ...rectangle, rotation });
34067
34051
  const adj = adjustDimsForRotation(rectangle, rotation);
34068
34052
  const imageDims = image.scaleToFit(adj.width - borderWidth * 2, adj.height - borderWidth * 2);
34069
34053
  // Support borders on images and maybe other properties
@@ -36984,7 +36968,7 @@ class PDFForm {
36984
36968
  const operators = [
36985
36969
  pushGraphicsState(),
36986
36970
  translate(rectangle.x, rectangle.y),
36987
- ...rotateInPlace(Object.assign(Object.assign({}, rectangle), { rotation: 0 })),
36971
+ ...rotateInPlace({ ...rectangle, rotation: 0 }),
36988
36972
  drawObject(xObjectKey),
36989
36973
  popGraphicsState(),
36990
36974
  ].filter(Boolean);
@@ -37329,39 +37313,37 @@ class PDFEmbeddedFile {
37329
37313
  *
37330
37314
  * @returns Resolves when the embedding is complete.
37331
37315
  */
37332
- embed() {
37333
- return __awaiter(this, void 0, void 0, function* () {
37334
- if (!this.alreadyEmbedded) {
37335
- const ref = yield this.embedder.embedIntoContext(this.doc.context, this.ref);
37336
- if (!this.doc.catalog.has(PDFName.of('Names'))) {
37337
- this.doc.catalog.set(PDFName.of('Names'), this.doc.context.obj({}));
37338
- }
37339
- const Names = this.doc.catalog.lookup(PDFName.of('Names'), PDFDict);
37340
- if (!Names.has(PDFName.of('EmbeddedFiles'))) {
37341
- Names.set(PDFName.of('EmbeddedFiles'), this.doc.context.obj({}));
37342
- }
37343
- const EmbeddedFiles = Names.lookup(PDFName.of('EmbeddedFiles'), PDFDict);
37344
- if (!EmbeddedFiles.has(PDFName.of('Names'))) {
37345
- EmbeddedFiles.set(PDFName.of('Names'), this.doc.context.obj([]));
37346
- }
37347
- const EFNames = EmbeddedFiles.lookup(PDFName.of('Names'), PDFArray);
37348
- EFNames.push(PDFHexString.fromText(this.embedder.fileName));
37349
- EFNames.push(ref);
37350
- /**
37351
- * The AF-Tag is needed to achieve PDF-A3 compliance for embedded files
37352
- *
37353
- * The following document outlines the uses cases of the associated files (AF) tag.
37354
- * See:
37355
- * https://www.pdfa.org/wp-content/uploads/2018/10/PDF20_AN002-AF.pdf
37356
- */
37357
- if (!this.doc.catalog.has(PDFName.of('AF'))) {
37358
- this.doc.catalog.set(PDFName.of('AF'), this.doc.context.obj([]));
37359
- }
37360
- const AF = this.doc.catalog.lookup(PDFName.of('AF'), PDFArray);
37361
- AF.push(ref);
37362
- this.alreadyEmbedded = true;
37316
+ async embed() {
37317
+ if (!this.alreadyEmbedded) {
37318
+ const ref = await this.embedder.embedIntoContext(this.doc.context, this.ref);
37319
+ if (!this.doc.catalog.has(PDFName.of('Names'))) {
37320
+ this.doc.catalog.set(PDFName.of('Names'), this.doc.context.obj({}));
37363
37321
  }
37364
- });
37322
+ const Names = this.doc.catalog.lookup(PDFName.of('Names'), PDFDict);
37323
+ if (!Names.has(PDFName.of('EmbeddedFiles'))) {
37324
+ Names.set(PDFName.of('EmbeddedFiles'), this.doc.context.obj({}));
37325
+ }
37326
+ const EmbeddedFiles = Names.lookup(PDFName.of('EmbeddedFiles'), PDFDict);
37327
+ if (!EmbeddedFiles.has(PDFName.of('Names'))) {
37328
+ EmbeddedFiles.set(PDFName.of('Names'), this.doc.context.obj([]));
37329
+ }
37330
+ const EFNames = EmbeddedFiles.lookup(PDFName.of('Names'), PDFArray);
37331
+ EFNames.push(PDFHexString.fromText(this.embedder.fileName));
37332
+ EFNames.push(ref);
37333
+ /**
37334
+ * The AF-Tag is needed to achieve PDF-A3 compliance for embedded files
37335
+ *
37336
+ * The following document outlines the uses cases of the associated files (AF) tag.
37337
+ * See:
37338
+ * https://www.pdfa.org/wp-content/uploads/2018/10/PDF20_AN002-AF.pdf
37339
+ */
37340
+ if (!this.doc.catalog.has(PDFName.of('AF'))) {
37341
+ this.doc.catalog.set(PDFName.of('AF'), this.doc.context.obj([]));
37342
+ }
37343
+ const AF = this.doc.catalog.lookup(PDFName.of('AF'), PDFArray);
37344
+ AF.push(ref);
37345
+ this.alreadyEmbedded = true;
37346
+ }
37365
37347
  }
37366
37348
  }
37367
37349
  /**
@@ -37396,28 +37378,26 @@ class PDFJavaScript {
37396
37378
  *
37397
37379
  * @returns Resolves when the embedding is complete.
37398
37380
  */
37399
- embed() {
37400
- return __awaiter(this, void 0, void 0, function* () {
37401
- if (!this.alreadyEmbedded) {
37402
- const { catalog, context } = this.doc;
37403
- const ref = yield this.embedder.embedIntoContext(this.doc.context, this.ref);
37404
- if (!catalog.has(PDFName.of('Names'))) {
37405
- catalog.set(PDFName.of('Names'), context.obj({}));
37406
- }
37407
- const Names = catalog.lookup(PDFName.of('Names'), PDFDict);
37408
- if (!Names.has(PDFName.of('JavaScript'))) {
37409
- Names.set(PDFName.of('JavaScript'), context.obj({}));
37410
- }
37411
- const Javascript = Names.lookup(PDFName.of('JavaScript'), PDFDict);
37412
- if (!Javascript.has(PDFName.of('Names'))) {
37413
- Javascript.set(PDFName.of('Names'), context.obj([]));
37414
- }
37415
- const JSNames = Javascript.lookup(PDFName.of('Names'), PDFArray);
37416
- JSNames.push(PDFHexString.fromText(this.embedder.scriptName));
37417
- JSNames.push(ref);
37418
- this.alreadyEmbedded = true;
37381
+ async embed() {
37382
+ if (!this.alreadyEmbedded) {
37383
+ const { catalog, context } = this.doc;
37384
+ const ref = await this.embedder.embedIntoContext(this.doc.context, this.ref);
37385
+ if (!catalog.has(PDFName.of('Names'))) {
37386
+ catalog.set(PDFName.of('Names'), context.obj({}));
37419
37387
  }
37420
- });
37388
+ const Names = catalog.lookup(PDFName.of('Names'), PDFDict);
37389
+ if (!Names.has(PDFName.of('JavaScript'))) {
37390
+ Names.set(PDFName.of('JavaScript'), context.obj({}));
37391
+ }
37392
+ const Javascript = Names.lookup(PDFName.of('JavaScript'), PDFDict);
37393
+ if (!Javascript.has(PDFName.of('Names'))) {
37394
+ Javascript.set(PDFName.of('Names'), context.obj([]));
37395
+ }
37396
+ const JSNames = Javascript.lookup(PDFName.of('Names'), PDFArray);
37397
+ JSNames.push(PDFHexString.fromText(this.embedder.scriptName));
37398
+ JSNames.push(ref);
37399
+ this.alreadyEmbedded = true;
37400
+ }
37421
37401
  }
37422
37402
  }
37423
37403
  /**
@@ -37441,21 +37421,19 @@ class JavaScriptEmbedder {
37441
37421
  static for(script, scriptName) {
37442
37422
  return new JavaScriptEmbedder(script, scriptName);
37443
37423
  }
37444
- embedIntoContext(context, ref) {
37445
- return __awaiter(this, void 0, void 0, function* () {
37446
- const jsActionDict = context.obj({
37447
- Type: 'Action',
37448
- S: 'JavaScript',
37449
- JS: PDFHexString.fromText(this.script),
37450
- });
37451
- if (ref) {
37452
- context.assign(ref, jsActionDict);
37453
- return ref;
37454
- }
37455
- else {
37456
- return context.register(jsActionDict);
37457
- }
37424
+ async embedIntoContext(context, ref) {
37425
+ const jsActionDict = context.obj({
37426
+ Type: 'Action',
37427
+ S: 'JavaScript',
37428
+ JS: PDFHexString.fromText(this.script),
37458
37429
  });
37430
+ if (ref) {
37431
+ context.assign(ref, jsActionDict);
37432
+ return ref;
37433
+ }
37434
+ else {
37435
+ return context.register(jsActionDict);
37436
+ }
37459
37437
  }
37460
37438
  }
37461
37439
 
@@ -39189,42 +39167,38 @@ class PDFDocument {
39189
39167
  * @param options The options to be used when loading the document.
39190
39168
  * @returns Resolves with a document loaded from the input.
39191
39169
  */
39192
- static load(pdf, options = {}) {
39193
- return __awaiter(this, void 0, void 0, function* () {
39194
- const { ignoreEncryption = false, parseSpeed = ParseSpeeds.Slow, throwOnInvalidObject = false, updateMetadata = true, capNumbers = false, password, } = options;
39195
- assertIs(pdf, 'pdf', ['string', Uint8Array, ArrayBuffer]);
39196
- assertIs(ignoreEncryption, 'ignoreEncryption', ['boolean']);
39197
- assertIs(parseSpeed, 'parseSpeed', ['number']);
39198
- assertIs(throwOnInvalidObject, 'throwOnInvalidObject', ['boolean']);
39199
- assertIs(password, 'password', ['string', 'undefined']);
39200
- const bytes = toUint8Array(pdf);
39201
- const context = yield PDFParser.forBytesWithOptions(bytes, parseSpeed, throwOnInvalidObject, capNumbers).parseDocument();
39202
- if (!!context.lookup(context.trailerInfo.Encrypt) && password !== undefined) {
39203
- // Decrypt
39204
- const fileIds = context.lookup(context.trailerInfo.ID, PDFArray);
39205
- const encryptDict = context.lookup(context.trailerInfo.Encrypt, PDFDict);
39206
- const decryptedContext = yield PDFParser.forBytesWithOptions(bytes, parseSpeed, throwOnInvalidObject, capNumbers, new CipherTransformFactory(encryptDict, fileIds.get(0).asBytes(), password)).parseDocument();
39207
- return new PDFDocument(decryptedContext, true, updateMetadata);
39208
- }
39209
- else {
39210
- return new PDFDocument(context, ignoreEncryption, updateMetadata);
39211
- }
39212
- });
39170
+ static async load(pdf, options = {}) {
39171
+ const { ignoreEncryption = false, parseSpeed = ParseSpeeds.Slow, throwOnInvalidObject = false, updateMetadata = true, capNumbers = false, password, } = options;
39172
+ assertIs(pdf, 'pdf', ['string', Uint8Array, ArrayBuffer]);
39173
+ assertIs(ignoreEncryption, 'ignoreEncryption', ['boolean']);
39174
+ assertIs(parseSpeed, 'parseSpeed', ['number']);
39175
+ assertIs(throwOnInvalidObject, 'throwOnInvalidObject', ['boolean']);
39176
+ assertIs(password, 'password', ['string', 'undefined']);
39177
+ const bytes = toUint8Array(pdf);
39178
+ const context = await PDFParser.forBytesWithOptions(bytes, parseSpeed, throwOnInvalidObject, capNumbers).parseDocument();
39179
+ if (!!context.lookup(context.trailerInfo.Encrypt) && password !== undefined) {
39180
+ // Decrypt
39181
+ const fileIds = context.lookup(context.trailerInfo.ID, PDFArray);
39182
+ const encryptDict = context.lookup(context.trailerInfo.Encrypt, PDFDict);
39183
+ const decryptedContext = await PDFParser.forBytesWithOptions(bytes, parseSpeed, throwOnInvalidObject, capNumbers, new CipherTransformFactory(encryptDict, fileIds.get(0).asBytes(), password)).parseDocument();
39184
+ return new PDFDocument(decryptedContext, true, updateMetadata);
39185
+ }
39186
+ else {
39187
+ return new PDFDocument(context, ignoreEncryption, updateMetadata);
39188
+ }
39213
39189
  }
39214
39190
  /**
39215
39191
  * Create a new [[PDFDocument]].
39216
39192
  * @returns Resolves with the newly created document.
39217
39193
  */
39218
- static create(options = {}) {
39219
- return __awaiter(this, void 0, void 0, function* () {
39220
- const { updateMetadata = true } = options;
39221
- const context = PDFContext.create();
39222
- const pageTree = PDFPageTree.withContext(context);
39223
- const pageTreeRef = context.register(pageTree);
39224
- const catalog = PDFCatalog.withContextAndPages(context, pageTreeRef);
39225
- context.trailerInfo.Root = context.register(catalog);
39226
- return new PDFDocument(context, false, updateMetadata);
39227
- });
39194
+ static async create(options = {}) {
39195
+ const { updateMetadata = true } = options;
39196
+ const context = PDFContext.create();
39197
+ const pageTree = PDFPageTree.withContext(context);
39198
+ const pageTreeRef = context.register(pageTree);
39199
+ const catalog = PDFCatalog.withContextAndPages(context, pageTreeRef);
39200
+ context.trailerInfo.Root = context.register(catalog);
39201
+ return new PDFDocument(context, false, updateMetadata);
39228
39202
  }
39229
39203
  /**
39230
39204
  * Register a fontkit instance. This must be done before custom fonts can
@@ -39708,22 +39682,20 @@ class PDFDocument {
39708
39682
  * @param indices The indices of the pages that should be copied.
39709
39683
  * @returns Resolves with an array of pages copied into this document.
39710
39684
  */
39711
- copyPages(srcDoc, indices) {
39712
- return __awaiter(this, void 0, void 0, function* () {
39713
- assertIs(srcDoc, 'srcDoc', [[PDFDocument, 'PDFDocument']]);
39714
- assertIs(indices, 'indices', [Array]);
39715
- yield srcDoc.flush();
39716
- const copier = PDFObjectCopier.for(srcDoc.context, this.context);
39717
- const srcPages = srcDoc.getPages();
39718
- const copiedPages = new Array(indices.length);
39719
- for (let idx = 0, len = indices.length; idx < len; idx++) {
39720
- const srcPage = srcPages[indices[idx]];
39721
- const copiedPage = copier.copy(srcPage.node);
39722
- const ref = this.context.register(copiedPage);
39723
- copiedPages[idx] = PDFPage.of(copiedPage, ref, this);
39724
- }
39725
- return copiedPages;
39726
- });
39685
+ async copyPages(srcDoc, indices) {
39686
+ assertIs(srcDoc, 'srcDoc', [[PDFDocument, 'PDFDocument']]);
39687
+ assertIs(indices, 'indices', [Array]);
39688
+ await srcDoc.flush();
39689
+ const copier = PDFObjectCopier.for(srcDoc.context, this.context);
39690
+ const srcPages = srcDoc.getPages();
39691
+ const copiedPages = new Array(indices.length);
39692
+ for (let idx = 0, len = indices.length; idx < len; idx++) {
39693
+ const srcPage = srcPages[indices[idx]];
39694
+ const copiedPage = copier.copy(srcPage.node);
39695
+ const ref = this.context.register(copiedPage);
39696
+ copiedPages[idx] = PDFPage.of(copiedPage, ref, this);
39697
+ }
39698
+ return copiedPages;
39727
39699
  }
39728
39700
  /**
39729
39701
  * Get a copy of this document.
@@ -39739,42 +39711,40 @@ class PDFDocument {
39739
39711
  *
39740
39712
  * @returns Resolves with a copy this document.
39741
39713
  */
39742
- copy() {
39743
- return __awaiter(this, void 0, void 0, function* () {
39744
- const pdfCopy = yield PDFDocument.create();
39745
- const contentPages = yield pdfCopy.copyPages(this, this.getPageIndices());
39746
- for (let idx = 0, len = contentPages.length; idx < len; idx++) {
39747
- pdfCopy.addPage(contentPages[idx]);
39748
- }
39749
- if (this.getAuthor() !== undefined) {
39750
- pdfCopy.setAuthor(this.getAuthor());
39751
- }
39752
- if (this.getCreationDate() !== undefined) {
39753
- pdfCopy.setCreationDate(this.getCreationDate());
39754
- }
39755
- if (this.getCreator() !== undefined) {
39756
- pdfCopy.setCreator(this.getCreator());
39757
- }
39758
- if (this.getModificationDate() !== undefined) {
39759
- pdfCopy.setModificationDate(this.getModificationDate());
39760
- }
39761
- if (this.getProducer() !== undefined) {
39762
- pdfCopy.setProducer(this.getProducer());
39763
- }
39764
- if (this.getSubject() !== undefined) {
39765
- pdfCopy.setSubject(this.getSubject());
39766
- }
39767
- if (this.getTitle() !== undefined) {
39768
- pdfCopy.setTitle(this.getTitle());
39769
- }
39770
- pdfCopy.defaultWordBreaks = this.defaultWordBreaks;
39771
- return pdfCopy;
39772
- });
39773
- }
39774
- /**
39775
- * Add JavaScript to this document. The supplied `script` is executed when the
39776
- * document is opened. The `script` can be used to perform some operation
39777
- * when the document is opened (e.g. logging to the console), or it can be
39714
+ async copy() {
39715
+ const pdfCopy = await PDFDocument.create();
39716
+ const contentPages = await pdfCopy.copyPages(this, this.getPageIndices());
39717
+ for (let idx = 0, len = contentPages.length; idx < len; idx++) {
39718
+ pdfCopy.addPage(contentPages[idx]);
39719
+ }
39720
+ if (this.getAuthor() !== undefined) {
39721
+ pdfCopy.setAuthor(this.getAuthor());
39722
+ }
39723
+ if (this.getCreationDate() !== undefined) {
39724
+ pdfCopy.setCreationDate(this.getCreationDate());
39725
+ }
39726
+ if (this.getCreator() !== undefined) {
39727
+ pdfCopy.setCreator(this.getCreator());
39728
+ }
39729
+ if (this.getModificationDate() !== undefined) {
39730
+ pdfCopy.setModificationDate(this.getModificationDate());
39731
+ }
39732
+ if (this.getProducer() !== undefined) {
39733
+ pdfCopy.setProducer(this.getProducer());
39734
+ }
39735
+ if (this.getSubject() !== undefined) {
39736
+ pdfCopy.setSubject(this.getSubject());
39737
+ }
39738
+ if (this.getTitle() !== undefined) {
39739
+ pdfCopy.setTitle(this.getTitle());
39740
+ }
39741
+ pdfCopy.defaultWordBreaks = this.defaultWordBreaks;
39742
+ return pdfCopy;
39743
+ }
39744
+ /**
39745
+ * Add JavaScript to this document. The supplied `script` is executed when the
39746
+ * document is opened. The `script` can be used to perform some operation
39747
+ * when the document is opened (e.g. logging to the console), or it can be
39778
39748
  * used to define a function that can be referenced later in a JavaScript
39779
39749
  * action. For example:
39780
39750
  * ```js
@@ -39858,23 +39828,21 @@ class PDFDocument {
39858
39828
  * @param name The name of the file to be attached.
39859
39829
  * @returns Resolves when the attachment is complete.
39860
39830
  */
39861
- attach(attachment, name, options = {}) {
39862
- return __awaiter(this, void 0, void 0, function* () {
39863
- assertIs(attachment, 'attachment', ['string', Uint8Array, ArrayBuffer]);
39864
- assertIs(name, 'name', ['string']);
39865
- assertOrUndefined(options.mimeType, 'mimeType', ['string']);
39866
- assertOrUndefined(options.description, 'description', ['string']);
39867
- assertOrUndefined(options.creationDate, 'options.creationDate', [Date]);
39868
- assertOrUndefined(options.modificationDate, 'options.modificationDate', [
39869
- Date,
39870
- ]);
39871
- assertIsOneOfOrUndefined(options.afRelationship, 'options.afRelationship', AFRelationship);
39872
- const bytes = toUint8Array(attachment);
39873
- const embedder = FileEmbedder.for(bytes, name, options);
39874
- const ref = this.context.nextRef();
39875
- const embeddedFile = PDFEmbeddedFile.of(ref, this, embedder);
39876
- this.embeddedFiles.push(embeddedFile);
39877
- });
39831
+ async attach(attachment, name, options = {}) {
39832
+ assertIs(attachment, 'attachment', ['string', Uint8Array, ArrayBuffer]);
39833
+ assertIs(name, 'name', ['string']);
39834
+ assertOrUndefined(options.mimeType, 'mimeType', ['string']);
39835
+ assertOrUndefined(options.description, 'description', ['string']);
39836
+ assertOrUndefined(options.creationDate, 'options.creationDate', [Date]);
39837
+ assertOrUndefined(options.modificationDate, 'options.modificationDate', [
39838
+ Date,
39839
+ ]);
39840
+ assertIsOneOfOrUndefined(options.afRelationship, 'options.afRelationship', AFRelationship);
39841
+ const bytes = toUint8Array(attachment);
39842
+ const embedder = FileEmbedder.for(bytes, name, options);
39843
+ const ref = this.context.nextRef();
39844
+ const embeddedFile = PDFEmbeddedFile.of(ref, this, embedder);
39845
+ this.embeddedFiles.push(embeddedFile);
39878
39846
  }
39879
39847
  /**
39880
39848
  * Embed a font into this document. The input data can be provided in multiple
@@ -39911,30 +39879,28 @@ class PDFDocument {
39911
39879
  * @param options The options to be used when embedding the font.
39912
39880
  * @returns Resolves with the embedded font.
39913
39881
  */
39914
- embedFont(font, options = {}) {
39915
- return __awaiter(this, void 0, void 0, function* () {
39916
- const { subset = false, customName, features } = options;
39917
- assertIs(font, 'font', ['string', Uint8Array, ArrayBuffer]);
39918
- assertIs(subset, 'subset', ['boolean']);
39919
- let embedder;
39920
- if (isStandardFont(font)) {
39921
- embedder = StandardFontEmbedder.for(font, customName);
39922
- }
39923
- else if (canBeConvertedToUint8Array(font)) {
39924
- const bytes = toUint8Array(font);
39925
- const fontkit = this.assertFontkit();
39926
- embedder = subset
39927
- ? yield CustomFontSubsetEmbedder.for(fontkit, bytes, customName, features)
39928
- : yield CustomFontEmbedder.for(fontkit, bytes, customName, features);
39929
- }
39930
- else {
39931
- throw new TypeError('`font` must be one of `StandardFonts | string | Uint8Array | ArrayBuffer`');
39932
- }
39933
- const ref = this.context.nextRef();
39934
- const pdfFont = PDFFont.of(ref, this, embedder);
39935
- this.fonts.push(pdfFont);
39936
- return pdfFont;
39937
- });
39882
+ async embedFont(font, options = {}) {
39883
+ const { subset = false, customName, features } = options;
39884
+ assertIs(font, 'font', ['string', Uint8Array, ArrayBuffer]);
39885
+ assertIs(subset, 'subset', ['boolean']);
39886
+ let embedder;
39887
+ if (isStandardFont(font)) {
39888
+ embedder = StandardFontEmbedder.for(font, customName);
39889
+ }
39890
+ else if (canBeConvertedToUint8Array(font)) {
39891
+ const bytes = toUint8Array(font);
39892
+ const fontkit = this.assertFontkit();
39893
+ embedder = subset
39894
+ ? await CustomFontSubsetEmbedder.for(fontkit, bytes, customName, features)
39895
+ : await CustomFontEmbedder.for(fontkit, bytes, customName, features);
39896
+ }
39897
+ else {
39898
+ throw new TypeError('`font` must be one of `StandardFonts | string | Uint8Array | ArrayBuffer`');
39899
+ }
39900
+ const ref = this.context.nextRef();
39901
+ const pdfFont = PDFFont.of(ref, this, embedder);
39902
+ this.fonts.push(pdfFont);
39903
+ return pdfFont;
39938
39904
  }
39939
39905
  /**
39940
39906
  * Embed a standard font into this document.
@@ -39988,16 +39954,14 @@ class PDFDocument {
39988
39954
  * @param jpg The input data for a JPEG image.
39989
39955
  * @returns Resolves with the embedded image.
39990
39956
  */
39991
- embedJpg(jpg) {
39992
- return __awaiter(this, void 0, void 0, function* () {
39993
- assertIs(jpg, 'jpg', ['string', Uint8Array, ArrayBuffer]);
39994
- const bytes = toUint8Array(jpg);
39995
- const embedder = yield JpegEmbedder.for(bytes);
39996
- const ref = this.context.nextRef();
39997
- const pdfImage = PDFImage.of(ref, this, embedder);
39998
- this.images.push(pdfImage);
39999
- return pdfImage;
40000
- });
39957
+ async embedJpg(jpg) {
39958
+ assertIs(jpg, 'jpg', ['string', Uint8Array, ArrayBuffer]);
39959
+ const bytes = toUint8Array(jpg);
39960
+ const embedder = await JpegEmbedder.for(bytes);
39961
+ const ref = this.context.nextRef();
39962
+ const pdfImage = PDFImage.of(ref, this, embedder);
39963
+ this.images.push(pdfImage);
39964
+ return pdfImage;
40001
39965
  }
40002
39966
  /**
40003
39967
  * Embed a PNG image into this document. The input data can be provided in
@@ -40029,16 +39993,14 @@ class PDFDocument {
40029
39993
  * @param png The input data for a PNG image.
40030
39994
  * @returns Resolves with the embedded image.
40031
39995
  */
40032
- embedPng(png) {
40033
- return __awaiter(this, void 0, void 0, function* () {
40034
- assertIs(png, 'png', ['string', Uint8Array, ArrayBuffer]);
40035
- const bytes = toUint8Array(png);
40036
- const embedder = yield PngEmbedder.for(bytes);
40037
- const ref = this.context.nextRef();
40038
- const pdfImage = PDFImage.of(ref, this, embedder);
40039
- this.images.push(pdfImage);
40040
- return pdfImage;
40041
- });
39996
+ async embedPng(png) {
39997
+ assertIs(png, 'png', ['string', Uint8Array, ArrayBuffer]);
39998
+ const bytes = toUint8Array(png);
39999
+ const embedder = await PngEmbedder.for(bytes);
40000
+ const ref = this.context.nextRef();
40001
+ const pdfImage = PDFImage.of(ref, this, embedder);
40002
+ this.images.push(pdfImage);
40003
+ return pdfImage;
40042
40004
  }
40043
40005
  /**
40044
40006
  * Embed one or more PDF pages into this document.
@@ -40060,19 +40022,17 @@ class PDFDocument {
40060
40022
  * @param indices The indices of the pages that should be embedded.
40061
40023
  * @returns Resolves with an array of the embedded pages.
40062
40024
  */
40063
- embedPdf(pdf, indices = [0]) {
40064
- return __awaiter(this, void 0, void 0, function* () {
40065
- assertIs(pdf, 'pdf', [
40066
- 'string',
40067
- Uint8Array,
40068
- ArrayBuffer,
40069
- [PDFDocument, 'PDFDocument'],
40070
- ]);
40071
- assertIs(indices, 'indices', [Array]);
40072
- const srcDoc = pdf instanceof PDFDocument ? pdf : yield PDFDocument.load(pdf);
40073
- const srcPages = pluckIndices(srcDoc.getPages(), indices);
40074
- return this.embedPages(srcPages);
40075
- });
40025
+ async embedPdf(pdf, indices = [0]) {
40026
+ assertIs(pdf, 'pdf', [
40027
+ 'string',
40028
+ Uint8Array,
40029
+ ArrayBuffer,
40030
+ [PDFDocument, 'PDFDocument'],
40031
+ ]);
40032
+ assertIs(indices, 'indices', [Array]);
40033
+ const srcDoc = pdf instanceof PDFDocument ? pdf : await PDFDocument.load(pdf);
40034
+ const srcPages = pluckIndices(srcDoc.getPages(), indices);
40035
+ return this.embedPages(srcPages);
40076
40036
  }
40077
40037
  /**
40078
40038
  * Embed a single PDF page into this document.
@@ -40106,12 +40066,10 @@ class PDFDocument {
40106
40066
  * page anywhere it is drawn.
40107
40067
  * @returns Resolves with the embedded pdf page.
40108
40068
  */
40109
- embedPage(page, boundingBox, transformationMatrix) {
40110
- return __awaiter(this, void 0, void 0, function* () {
40111
- assertIs(page, 'page', [[PDFPage, 'PDFPage']]);
40112
- const [embeddedPage] = yield this.embedPages([page], [boundingBox], [transformationMatrix]);
40113
- return embeddedPage;
40114
- });
40069
+ async embedPage(page, boundingBox, transformationMatrix) {
40070
+ assertIs(page, 'page', [[PDFPage, 'PDFPage']]);
40071
+ const [embeddedPage] = await this.embedPages([page], [boundingBox], [transformationMatrix]);
40072
+ return embeddedPage;
40115
40073
  }
40116
40074
  /**
40117
40075
  * Embed one or more PDF pages into this document.
@@ -40141,34 +40099,32 @@ class PDFDocument {
40141
40099
  * (each page's transformation will apply anywhere it is drawn).
40142
40100
  * @returns Resolves with an array of the embedded pdf pages.
40143
40101
  */
40144
- embedPages(pages, boundingBoxes = [], transformationMatrices = []) {
40145
- return __awaiter(this, void 0, void 0, function* () {
40146
- if (pages.length === 0)
40147
- return [];
40148
- // Assert all pages have the same context
40149
- for (let idx = 0, len = pages.length - 1; idx < len; idx++) {
40150
- const currPage = pages[idx];
40151
- const nextPage = pages[idx + 1];
40152
- if (currPage.node.context !== nextPage.node.context) {
40153
- throw new PageEmbeddingMismatchedContextError();
40154
- }
40155
- }
40156
- const context = pages[0].node.context;
40157
- const maybeCopyPage = context === this.context
40158
- ? (p) => p
40159
- : PDFObjectCopier.for(context, this.context).copy;
40160
- const embeddedPages = new Array(pages.length);
40161
- for (let idx = 0, len = pages.length; idx < len; idx++) {
40162
- const page = maybeCopyPage(pages[idx].node);
40163
- const box = boundingBoxes[idx];
40164
- const matrix = transformationMatrices[idx];
40165
- const embedder = yield PDFPageEmbedder.for(page, box, matrix);
40166
- const ref = this.context.nextRef();
40167
- embeddedPages[idx] = PDFEmbeddedPage.of(ref, this, embedder);
40168
- }
40169
- this.embeddedPages.push(...embeddedPages);
40170
- return embeddedPages;
40171
- });
40102
+ async embedPages(pages, boundingBoxes = [], transformationMatrices = []) {
40103
+ if (pages.length === 0)
40104
+ return [];
40105
+ // Assert all pages have the same context
40106
+ for (let idx = 0, len = pages.length - 1; idx < len; idx++) {
40107
+ const currPage = pages[idx];
40108
+ const nextPage = pages[idx + 1];
40109
+ if (currPage.node.context !== nextPage.node.context) {
40110
+ throw new PageEmbeddingMismatchedContextError();
40111
+ }
40112
+ }
40113
+ const context = pages[0].node.context;
40114
+ const maybeCopyPage = context === this.context
40115
+ ? (p) => p
40116
+ : PDFObjectCopier.for(context, this.context).copy;
40117
+ const embeddedPages = new Array(pages.length);
40118
+ for (let idx = 0, len = pages.length; idx < len; idx++) {
40119
+ const page = maybeCopyPage(pages[idx].node);
40120
+ const box = boundingBoxes[idx];
40121
+ const matrix = transformationMatrices[idx];
40122
+ const embedder = await PDFPageEmbedder.for(page, box, matrix);
40123
+ const ref = this.context.nextRef();
40124
+ embeddedPages[idx] = PDFEmbeddedPage.of(ref, this, embedder);
40125
+ }
40126
+ this.embeddedPages.push(...embeddedPages);
40127
+ return embeddedPages;
40172
40128
  }
40173
40129
  /**
40174
40130
  * > **NOTE:** You shouldn't need to call this method directly. The [[save]]
@@ -40180,14 +40136,12 @@ class PDFDocument {
40180
40136
  *
40181
40137
  * @returns Resolves when the flush is complete.
40182
40138
  */
40183
- flush() {
40184
- return __awaiter(this, void 0, void 0, function* () {
40185
- yield this.embedAll(this.fonts);
40186
- yield this.embedAll(this.images);
40187
- yield this.embedAll(this.embeddedPages);
40188
- yield this.embedAll(this.embeddedFiles);
40189
- yield this.embedAll(this.javaScripts);
40190
- });
40139
+ async flush() {
40140
+ await this.embedAll(this.fonts);
40141
+ await this.embedAll(this.images);
40142
+ await this.embedAll(this.embeddedPages);
40143
+ await this.embedAll(this.embeddedFiles);
40144
+ await this.embedAll(this.javaScripts);
40191
40145
  }
40192
40146
  /**
40193
40147
  * Serialize this document to an array of bytes making up a PDF file.
@@ -40205,24 +40159,22 @@ class PDFDocument {
40205
40159
  * @param options The options to be used when saving the document.
40206
40160
  * @returns Resolves with the bytes of the serialized document.
40207
40161
  */
40208
- save(options = {}) {
40209
- return __awaiter(this, void 0, void 0, function* () {
40210
- const { useObjectStreams = true, addDefaultPage = true, objectsPerTick = 50, updateFieldAppearances = true, } = options;
40211
- assertIs(useObjectStreams, 'useObjectStreams', ['boolean']);
40212
- assertIs(addDefaultPage, 'addDefaultPage', ['boolean']);
40213
- assertIs(objectsPerTick, 'objectsPerTick', ['number']);
40214
- assertIs(updateFieldAppearances, 'updateFieldAppearances', ['boolean']);
40215
- if (addDefaultPage && this.getPageCount() === 0)
40216
- this.addPage();
40217
- if (updateFieldAppearances) {
40218
- const form = this.formCache.getValue();
40219
- if (form)
40220
- form.updateFieldAppearances();
40221
- }
40222
- yield this.flush();
40223
- const Writer = useObjectStreams ? PDFStreamWriter : PDFWriter;
40224
- return Writer.forContext(this.context, objectsPerTick).serializeToBuffer();
40225
- });
40162
+ async save(options = {}) {
40163
+ const { useObjectStreams = true, addDefaultPage = true, objectsPerTick = 50, updateFieldAppearances = true, } = options;
40164
+ assertIs(useObjectStreams, 'useObjectStreams', ['boolean']);
40165
+ assertIs(addDefaultPage, 'addDefaultPage', ['boolean']);
40166
+ assertIs(objectsPerTick, 'objectsPerTick', ['number']);
40167
+ assertIs(updateFieldAppearances, 'updateFieldAppearances', ['boolean']);
40168
+ if (addDefaultPage && this.getPageCount() === 0)
40169
+ this.addPage();
40170
+ if (updateFieldAppearances) {
40171
+ const form = this.formCache.getValue();
40172
+ if (form)
40173
+ form.updateFieldAppearances();
40174
+ }
40175
+ await this.flush();
40176
+ const Writer = useObjectStreams ? PDFStreamWriter : PDFWriter;
40177
+ return Writer.forContext(this.context, objectsPerTick).serializeToBuffer();
40226
40178
  }
40227
40179
  /**
40228
40180
  * Serialize this document to a base64 encoded string or data URI making up a
@@ -40239,14 +40191,12 @@ class PDFDocument {
40239
40191
  * @returns Resolves with a base64 encoded string or data URI of the
40240
40192
  * serialized document.
40241
40193
  */
40242
- saveAsBase64(options = {}) {
40243
- return __awaiter(this, void 0, void 0, function* () {
40244
- const { dataUri = false } = options, otherOptions = __rest(options, ["dataUri"]);
40245
- assertIs(dataUri, 'dataUri', ['boolean']);
40246
- const bytes = yield this.save(otherOptions);
40247
- const base64 = encodeToBase64(bytes);
40248
- return dataUri ? `data:application/pdf;base64,${base64}` : base64;
40249
- });
40194
+ async saveAsBase64(options = {}) {
40195
+ const { dataUri = false, ...otherOptions } = options;
40196
+ assertIs(dataUri, 'dataUri', ['boolean']);
40197
+ const bytes = await this.save(otherOptions);
40198
+ const base64 = encodeToBase64(bytes);
40199
+ return dataUri ? `data:application/pdf;base64,${base64}` : base64;
40250
40200
  }
40251
40201
  findPageForAnnotationRef(ref) {
40252
40202
  const pages = this.getPages();
@@ -40259,12 +40209,10 @@ class PDFDocument {
40259
40209
  }
40260
40210
  return undefined;
40261
40211
  }
40262
- embedAll(embeddables) {
40263
- return __awaiter(this, void 0, void 0, function* () {
40264
- for (let idx = 0, len = embeddables.length; idx < len; idx++) {
40265
- yield embeddables[idx].embed();
40266
- }
40267
- });
40212
+ async embedAll(embeddables) {
40213
+ for (let idx = 0, len = embeddables.length; idx < len; idx++) {
40214
+ await embeddables[idx].embed();
40215
+ }
40268
40216
  }
40269
40217
  updateInfoDict() {
40270
40218
  const pdfLib = `pdf-lib (https://github.com/Hopding/pdf-lib)`;
@@ -41628,772 +41576,70 @@ exports.isBlock = isBlock;
41628
41576
 
41629
41577
  var index = /*@__PURE__*/unwrapExports(dist);
41630
41578
 
41631
- /** This value represents the precision we accept for float values */
41632
- const FLOAT_APPROXIMATION = 0.000001;
41633
- /** Calculates the distance between 2 points */
41634
- const distance = (A, B) => norm(vector(A, B));
41635
- const distanceCoords = (A, B) => norm(minus(B, A));
41636
- /** Calculates the distance denoted by a vector */
41637
- const norm = (vect) => Math.sqrt(vect.x * vect.x + vect.y * vect.y);
41638
- /** Calculates the orthogonal vector of provided vector */
41639
- const orthogonal = ({ x, y }) => ({
41640
- x: -y,
41641
- y: x,
41642
- });
41643
- /** Check if 2 vectors are proportional */
41644
- const isColinear = ({ x: ux, y: uy }, { x: vx, y: vy }) => isEqual(ux * vy, uy * vx);
41645
- /** Check if 2 floating values can be considered equals */
41646
- const isEqual = (a, b) => Math.round(Math.abs(a - b) / FLOAT_APPROXIMATION) === 0;
41647
- /** Calculate the scalar product between 2 vectors */
41648
- const scalar = ({ x: ux, y: uy }, { x: vx, y: vy }) => ux * vx + uy * vy;
41649
- /** Calculate the sum of 2 vectors */
41650
- const plus = ({ x: ux, y: uy }, { x: vx, y: vy }) => ({ x: ux + vx, y: uy + vy });
41651
- /** Calculate the vector multiplied by a scalar */
41652
- const times = ({ x, y }, k = 1) => ({
41653
- x: k * x,
41654
- y: k * y,
41655
- });
41656
- /** Calculate the difference of 2 vectors */
41657
- const minus = (u, v) => plus(u, times(v, -1));
41658
- /** Returns the vector between 2 points. */
41659
- const vector = (A, B) => minus(B.toCoords(), A.toCoords());
41660
- /**
41661
- * Returns the angle between the vector and the horizontal axis (Ox).
41662
- * The return value is between -PI and PI.
41663
- * @returns {number} angle in radian between -Pi and Pi
41664
- */
41665
- const orientation = ({ x, y }) => {
41666
- const alpha = Math.acos(x / Math.sqrt(x * x + y * y));
41667
- return y > 0 ? alpha : -alpha;
41668
- };
41669
- /** Returns the unit vector associated to the provided vector,
41670
- * or the Null vector (0, 0) if the vector is null
41671
- */
41672
- const unitVector = (u) => {
41673
- const l = norm(u);
41674
- return l > 0 ? times(u, 1 / l) : u;
41675
- };
41676
- /** Returns the angle from u to v in radian */
41677
- const angle = (u, v, previousAngle = 0) => {
41678
- let sweep = orientation(v) - orientation(u);
41679
- // If the angle has the same sign as the arc orientation, we return the angle as is
41680
- // Otherwise, we need to correct the value, adding or removing 2π
41681
- while (Math.abs(previousAngle - sweep) > Math.PI) {
41682
- sweep += Math.sign(previousAngle - sweep) * 2 * Math.PI;
41683
- }
41684
- return sweep;
41685
- };
41686
- /** Returns the angle between the lines (BA) and (BC) in radian
41687
- * @returns {number} the angle in radian, between -Pi and Pi
41688
- */
41689
- const angleABC = (A, B, C, previousAngle = 0) => angle(vector(B, A), vector(B, C), previousAngle);
41690
- /** Rotate the vector by an angle in radian */
41691
- const rotate = (vect, teta) => {
41692
- const { x, y } = vect;
41693
- const nx = x * Math.cos(teta) - y * Math.sin(teta);
41694
- const ny = y * Math.cos(teta) + x * Math.sin(teta);
41695
- return { x: nx, y: ny };
41696
- };
41697
-
41698
- class GraphElement {
41699
- distance(P) {
41700
- const H = this.orthoProjection(P);
41701
- return distance(H, P);
41702
- }
41703
- }
41704
-
41705
- class Point extends GraphElement {
41706
- constructor(coords = { x: 0, y: 0 }) {
41707
- super();
41708
- this.x = coords.x;
41709
- this.y = coords.y;
41710
- }
41711
- toCoords() {
41712
- return { x: this.x, y: this.y };
41713
- }
41714
- isEqual(element) {
41715
- if (!(element instanceof Point))
41716
- return false;
41717
- const A = this.toCoords();
41718
- const B = element.toCoords();
41719
- return isEqual(A.x, B.x) && isEqual(A.y, B.y);
41720
- }
41721
- orthoProjection() {
41722
- return new Point(this.toCoords());
41723
- }
41724
- plus(vect) {
41725
- const P = new Point(plus(this.toCoords(), vect));
41726
- return P;
41727
- }
41728
- }
41729
- Point.type = 'PointFixed';
41730
-
41731
- class Circle extends GraphElement {
41732
- constructor(O = new Point(), r = 1) {
41733
- super();
41734
- this.O = O;
41735
- this.r = r;
41736
- }
41737
- ray() {
41738
- return this.r;
41739
- }
41740
- center() {
41741
- return this.O;
41742
- }
41743
- /** This is used to standardize type Circle | Arc */
41744
- getCircle() {
41745
- return this;
41746
- }
41747
- isEqual(element) {
41748
- return (element instanceof Circle &&
41749
- this.center().isEqual(element.center()) &&
41750
- isEqual(this.ray(), element.ray()));
41751
- }
41752
- includes(P) {
41753
- return isEqual(distance(this.center(), P), this.ray());
41754
- }
41755
- orthoProjection(P) {
41756
- const center = this.center().toCoords();
41757
- const coords = P.toCoords();
41758
- if (distanceCoords(coords, center) < this.ray())
41759
- return P;
41760
- const vect = times(unitVector(minus(coords, center)), this.ray());
41761
- return new Point(plus(center, vect));
41762
- }
41763
- }
41579
+ const identityMatrix = [1, 0, 0, 1, 0, 0];
41764
41580
 
41765
- class Arc extends GraphElement {
41766
- constructor(O = new Point(), A = new Point(), B = new Point(), lastSweep = 0) {
41767
- super();
41768
- this.O = O;
41769
- this.A = A;
41770
- this.B = B;
41771
- this.lastSweep = lastSweep;
41772
- }
41773
- center() {
41774
- return this.O;
41775
- }
41776
- origin() {
41777
- return this.A;
41778
- }
41779
- destination() {
41780
- return this.getCircle().orthoProjection(this.B);
41781
- }
41782
- sweep() {
41783
- this.lastSweep = angleABC(this.origin(), this.center(), this.destination(), this.lastSweep);
41784
- return this.lastSweep;
41785
- }
41786
- ray() {
41787
- return distance(this.center(), this.origin());
41788
- }
41789
- isEqual(element) {
41790
- if (!(element instanceof Arc))
41791
- return false;
41792
- const dest = this.destination();
41793
- const o = this.origin();
41794
- const eDest = element.destination();
41795
- const eO = element.origin();
41796
- return (this.getCircle().isEqual(element.getCircle()) &&
41797
- ((dest.isEqual(eDest) && o.isEqual(eO)) ||
41798
- (dest.isEqual(eO) && o.isEqual(eDest))));
41799
- }
41800
- getCircle() {
41801
- const circle = new Circle(this.center(), this.ray());
41802
- return circle;
41803
- }
41804
- originVect() {
41805
- return vector(this.center(), this.origin());
41806
- }
41807
- middle() {
41808
- const halfSweep = this.sweep() / 2;
41809
- const mid = this.center().plus(rotate(vector(this.center(), this.origin()), halfSweep));
41810
- return mid;
41811
- }
41812
- includes(P) {
41813
- // As angles are returned between -π and π, we need the middle of the arc
41814
- return (this.getCircle().includes(P) &&
41815
- Math.abs(angleABC(this.middle(), this.center(), P)) <=
41816
- Math.abs(this.sweep() / 2));
41817
- }
41818
- orthoProjection(P) {
41819
- const H = this.getCircle().orthoProjection(P);
41820
- if (this.includes(H))
41821
- return H;
41822
- else {
41823
- const origin = this.origin().toCoords();
41824
- const destination = this.destination().toCoords();
41825
- // Returns the closest between origin and destination
41826
- const coords = distanceCoords(H.toCoords(), origin) <
41827
- distanceCoords(H.toCoords(), destination)
41828
- ? origin
41829
- : destination;
41830
- return new Point(coords);
41581
+ const combineMatrix = ([a, b, c, d, e, f], [a2, b2, c2, d2, e2, f2]) => [
41582
+ a * a2 + c * b2,
41583
+ b * a2 + d * b2,
41584
+ a * c2 + c * d2,
41585
+ b * c2 + d * d2,
41586
+ a * e2 + c * f2 + e,
41587
+ b * e2 + d * f2 + f,
41588
+ ];
41589
+ const applyTransformation = ([a, b, c, d, e, f], { x, y }) => ({
41590
+ x: a * x + c * y + e,
41591
+ y: b * x + d * y + f
41592
+ });
41593
+ const transformationToMatrix = (name, args) => {
41594
+ switch (name) {
41595
+ case 'scale':
41596
+ case 'scaleX':
41597
+ case 'scaleY': {
41598
+ // [sx 0 0 sy 0 0]
41599
+ const [sx, sy = sx] = args;
41600
+ return [name === 'scaleY' ? 1 : sx, 0, 0, name === 'scaleX' ? 1 : sy, 0, 0];
41831
41601
  }
41832
- }
41833
- }
41834
-
41835
- class Plot extends GraphElement {
41836
- constructor(points = []) {
41837
- super();
41838
- this.points = points;
41839
- }
41840
- getPoints() {
41841
- return [...this.points];
41842
- }
41843
- translate(translationVector) {
41844
- this.points = this.points.map((point) => plus(point, translationVector));
41845
- }
41846
- isEqual(element) {
41847
- if (!(element instanceof Plot))
41848
- return false;
41849
- const points = this.getPoints().map((coord) => new Point(coord));
41850
- const points2 = element.getPoints().map((coord) => new Point(coord));
41851
- return (points.every((point, i) => point.isEqual(points2[i])) ||
41852
- points.reverse().every((point, i) => point.isEqual(points2[i])));
41853
- }
41854
- orthoProjection(P) {
41855
- const points = this.getPoints();
41856
- const orthos = points
41857
- .slice(0, -1)
41858
- .map((pt, i) => new Segment(new Point(pt), new Point(points[i + 1])))
41859
- .map((seg) => seg.orthoProjection(P));
41860
- let min = Number.POSITIVE_INFINITY;
41861
- let closest = new Point(points[0]);
41862
- orthos.forEach((ortho) => {
41863
- const d = ortho.distance(P);
41864
- if (d < min) {
41865
- min = d;
41866
- closest = ortho;
41867
- }
41868
- });
41869
- return closest;
41870
- }
41871
- }
41872
-
41873
- class Rectangle extends GraphElement {
41874
- constructor(start = new Point(), end = new Point()) {
41875
- super();
41876
- this.start = start;
41877
- this.end = end;
41878
- }
41879
- getSize() {
41880
- const start = this.start.toCoords();
41881
- const end = this.end.toCoords();
41882
- return {
41883
- width: Math.abs(start.x - end.x),
41884
- height: Math.abs(start.y - end.y),
41885
- };
41886
- }
41887
- getCoords() {
41888
- const start = this.start.toCoords();
41889
- const end = this.end.toCoords();
41890
- return {
41891
- x: Math.min(start.x, end.x),
41892
- y: Math.max(start.y, end.y),
41893
- };
41894
- }
41895
- getStart() {
41896
- const start = new Point(this.getCoords());
41897
- return start;
41898
- }
41899
- getEnd() {
41900
- const { width, height } = this.getSize();
41901
- const end = new Point(this.getStart()).plus({ x: width, y: -height });
41902
- return end;
41903
- }
41904
- center() {
41905
- const center = new Segment(this.getStart(), this.getEnd()).middle();
41906
- return center;
41907
- }
41908
- isEqual(element) {
41909
- return (element instanceof Rectangle &&
41910
- this.getStart().isEqual(element.getStart()) &&
41911
- this.getEnd().isEqual(element.getEnd()));
41912
- }
41913
- orthoProjection(P) {
41914
- const { x, y } = this.getCoords();
41915
- const end = this.getEnd().toCoords();
41916
- const { x: Px, y: Py } = P.toCoords();
41917
- const Hx = Px < x ? x : Px > end.x ? end.x : Px;
41918
- const Hy = Py > y ? y : Py < end.y ? end.y : Py;
41919
- return new Point({ x: Hx, y: Hy });
41920
- }
41921
- }
41922
- Rectangle.type = 'Rectangle';
41923
-
41924
- function intersections(A, B) {
41925
- if (A instanceof Point || B instanceof Point)
41926
- return [];
41927
- else if (A instanceof Text || B instanceof Text)
41928
- return [];
41929
- else if (A instanceof Image || B instanceof Image)
41930
- return [];
41931
- // TODO: calculate the coords of the intersection: https://www.emathzone.com/tutorials/geometry/intersection-of-line-and-ellipse.html
41932
- else if (A instanceof Line)
41933
- return intersectionsLine(A, B);
41934
- else if (A instanceof Segment) {
41935
- return intersectionsLine(A.getLine(), B).filter((P) => A.includes(new Point(P)));
41936
- }
41937
- else if (A instanceof Circle)
41938
- return intersectionsCircle(A, B);
41939
- else if (A instanceof Arc) {
41940
- return intersectionsCircle(A.getCircle(), B).filter((P) => A.includes(new Point(P)));
41941
- }
41942
- else if (A instanceof Plot)
41943
- return intersectionsPlot(A, B);
41944
- else if (A instanceof Rectangle)
41945
- return intersectionsRectangle(A, B);
41946
- else if (A instanceof Ellipse)
41947
- return intersectionsEllipse(A, B);
41948
- return A;
41949
- }
41950
- function intersectionsLine(A, B) {
41951
- if (B instanceof Line)
41952
- return intersectionLine(A, B);
41953
- else if (B instanceof Segment) {
41954
- return intersectionLine(A, B.getLine()).filter((P) => B.includes(new Point(P)));
41955
- }
41956
- else if (B instanceof Circle)
41957
- return intersectionCircleLine(B, A);
41958
- else if (B instanceof Arc) {
41959
- return intersectionsCircle(B.getCircle(), A).filter((P) => B.includes(new Point(P)));
41960
- }
41961
- else if (B instanceof Plot)
41962
- return intersectionsPlot(B, A);
41963
- else if (B instanceof Rectangle)
41964
- return intersectionsRectangle(B, A);
41965
- else if (B instanceof Ellipse)
41966
- return intersectionsEllipse(B, A);
41967
- return B;
41968
- }
41969
- function intersectionsEllipse(A, B) {
41970
- if (B instanceof Line)
41971
- return intersectionsLineAndEllipse(A, B);
41972
- else if (B instanceof Segment) {
41973
- return intersectionsEllipse(A, B.getLine()).filter((P) => B.includes(new Point(P)));
41974
- }
41975
- // TODO:
41976
- // else if (B instanceof Circle) return intersectionEllipseCircle(B, A)
41977
- else if (B instanceof Circle)
41978
- return [];
41979
- // TODO:
41980
- // else if (B instanceof Ellipse) return intersectionEllipseEllipse(B, A)
41981
- else if (B instanceof Ellipse)
41982
- return [];
41983
- else if (B instanceof Arc) {
41984
- return intersectionsEllipse(A, B.getCircle()).filter((P) => B.includes(new Point(P)));
41985
- }
41986
- else if (B instanceof Plot)
41987
- return intersectionsPlot(B, A);
41988
- else if (B instanceof Rectangle)
41989
- return intersectionsRectangle(B, A);
41990
- return B;
41991
- }
41992
- function intersectionsLineAndEllipse(A, B) {
41993
- const center = A.center().toCoords();
41994
- const a = A.a();
41995
- const b = A.b();
41996
- const rotation = A.rotation();
41997
- const isLineParallel2YAxis = isEqual(B.dirVect().x, 0);
41998
- // this is a dummy value to represent a point on the line
41999
- const p1Y = isLineParallel2YAxis ? 1 : B.y(1);
42000
- const p1X = isLineParallel2YAxis ? B.origin().toCoords().x : 1;
42001
- const p1 = { x: p1X, y: p1Y };
42002
- // this is a dummy value to represent a point on the line
42003
- const p2Y = isLineParallel2YAxis ? 2 : B.y(2);
42004
- const p2X = isLineParallel2YAxis ? B.origin().toCoords().x : 2;
42005
- const p2 = { x: p2X, y: p2Y };
42006
- const p1Normalized = rotate({ x: p1.x - center.x, y: p1.y - center.y }, -rotation);
42007
- const p2Normalized = rotate({ x: p2.x - center.x, y: p2.y - center.y }, -rotation);
42008
- const angular = (p1Normalized.y - p2Normalized.y) / (p1Normalized.x - p2Normalized.x);
42009
- const linear = p1Normalized.y - angular * p1Normalized.x;
42010
- const lineY = (x) => angular * x + linear;
42011
- const denormalize = (coord) => {
42012
- const rotated = rotate(coord, rotation);
42013
- return {
42014
- x: rotated.x + center.x,
42015
- y: rotated.y + center.y,
42016
- };
42017
- };
42018
- // Intersection with vertical line
42019
- if (isEqual(p1Normalized.x - p2Normalized.x, 0)) {
42020
- const x = p1Normalized.x;
42021
- const delta = b ** 2 - (x ** 2 * b ** 2) / a ** 2;
42022
- if (delta < 0)
42023
- return [];
42024
- else if (delta === 0) {
42025
- return [{ x, y: 0 }].map(denormalize);
41602
+ case 'translate':
41603
+ case 'translateX':
41604
+ case 'translateY': {
41605
+ // [1 0 0 1 tx ty]
41606
+ const [tx, ty = tx] = args;
41607
+ // -ty is necessary because the pdf's y axis is inverted
41608
+ return [1, 0, 0, 1, name === 'translateY' ? 0 : tx, name === 'translateX' ? 0 : -ty];
42026
41609
  }
42027
- else {
42028
- const y1 = Math.sqrt((b ** 2 * (a ** 2 - x ** 2)) / a ** 2);
42029
- const y2 = -y1;
42030
- return [
42031
- { x, y: y1 },
42032
- { x, y: y2 },
42033
- ].map(denormalize);
42034
- }
42035
- }
42036
- // Intersection with any line
42037
- // the quadratic equation is:
42038
- // alpha * x ** 2 + beta * x + gamma = 0
42039
- const alpha = a ** 2 * angular ** 2 + b ** 2;
42040
- const beta = 2 * a ** 2 * (angular * linear);
42041
- const gamma = a ** 2 * (linear ** 2 - b ** 2);
42042
- const delta = beta ** 2 - 4 * alpha * gamma;
42043
- if (delta < 0)
42044
- return [];
42045
- else if (delta === 0) {
42046
- const x = -(beta ** 2) / (2 * alpha);
42047
- const y = lineY(x);
42048
- return [{ x, y }].map(denormalize);
42049
- }
42050
- else {
42051
- const x1 = (-beta + Math.sqrt(delta)) / (2 * alpha);
42052
- const y1 = lineY(x1);
42053
- const x2 = (-beta - Math.sqrt(delta)) / (2 * alpha);
42054
- const y2 = lineY(x2);
42055
- return [
42056
- { x: x1, y: y1 },
42057
- { x: x2, y: y2 },
42058
- ].map(denormalize);
42059
- }
42060
- }
42061
- function intersectionLine(A, B) {
42062
- if (isColinear(A.dirVect(), B.dirVect()))
42063
- return [];
42064
- else {
42065
- const { x: ux, y: uy } = A.dirVect();
42066
- const { x: vx, y: vy } = B.dirVect();
42067
- const { x: xA, y: yA } = A.origin().toCoords();
42068
- const { x: xB, y: yB } = B.origin().toCoords();
42069
- const x = (ux * (vx * (yA - yB) + vy * xB) - uy * vx * xA) / (ux * vy - uy * vx);
42070
- const y = (uy * (vy * (xA - xB) + vx * yB) - ux * vy * yA) / (uy * vx - ux * vy);
42071
- return [{ x, y }];
42072
- }
42073
- }
42074
- function intersectionsPlot(A, B) {
42075
- const points = A.getPoints().map((pt) => new Point(pt));
42076
- const head = points.pop();
42077
- const segments = points.map((pt, i) => new Segment(pt, points[i + 1] || head));
42078
- // @ts-ignore
42079
- const inters = segments.map((s) => intersections(s, B)).flat();
42080
- return inters;
42081
- }
42082
- function intersectionsRectangle(A, B) {
42083
- const P1 = A.getCoords();
42084
- const P3 = A.getEnd();
42085
- const P2 = { x: P1.x, y: P3.y };
42086
- const P4 = { x: P3.x, y: P1.y };
42087
- return intersections(new Plot([P1, P2, P3, P4, P1]), B);
42088
- }
42089
- function intersectionCircleLine(A, B) {
42090
- const rA = A.ray();
42091
- const O = A.center();
42092
- const H = B.orthoProjection(O);
42093
- const OH = distance(O, H);
42094
- // The line is tangeant
42095
- if (isEqual(OH, rA))
42096
- return [H];
42097
- // The line is too far from the circle
42098
- else if (OH > A.ray())
42099
- return [];
42100
- // The line cut the circle in 2 points
42101
- else {
42102
- // Pythagore
42103
- const HP = Math.sqrt(rA * rA - OH * OH);
42104
- const vect = unitVector(B.dirVect());
42105
- return [H.plus(times(vect, HP)), H.plus(times(vect, -HP))];
42106
- }
42107
- }
42108
- function intersectionCircle(A, B) {
42109
- const oA = A.center();
42110
- const oB = B.center();
42111
- const rA = A.ray();
42112
- const rB = B.ray();
42113
- const axis = vector(oA, oB);
42114
- const CC = norm(axis);
42115
- // The circles are tangeant
42116
- if (isEqual(CC, rA + rB))
42117
- return [A.orthoProjection(oB).toCoords()];
42118
- // The circles are too far from eachother
42119
- else if (CC > rA + rB)
42120
- return [];
42121
- // The intersections belong to an orthogonal axis
42122
- else {
42123
- const ratio = 1 / 2 + (rA * rA - rB * rB) / (CC * CC) / 2;
42124
- const H = oA.plus(times(axis, ratio));
42125
- return intersectionCircleLine(A, new Line(H, H.plus(orthogonal(axis))));
42126
- }
42127
- }
42128
- function intersectionsCircle(A, B) {
42129
- if (B instanceof Circle)
42130
- return intersectionCircle(A, B);
42131
- else if (B instanceof Line)
42132
- return intersectionCircleLine(A, B);
42133
- else if (B instanceof Segment) {
42134
- return intersectionCircleLine(A, B.getLine()).filter((P) => B.includes(new Point(P)));
42135
- }
42136
- else if (B instanceof Arc) {
42137
- return intersectionCircle(A, B.getCircle()).filter((P) => B.includes(new Point(P)));
42138
- }
42139
- else if (B instanceof Plot)
42140
- return intersectionsPlot(B, A);
42141
- else if (B instanceof Rectangle)
42142
- return intersectionsRectangle(B, A);
42143
- else if (B instanceof Ellipse)
42144
- return intersectionsEllipse(B, A);
42145
- return B;
42146
- }
42147
- function getIntersections(elements) {
42148
- const checked = [];
42149
- const inters = [];
42150
- elements.forEach((elt) => {
42151
- checked.forEach((e) => inters.push(...intersections(e, elt)));
42152
- checked.push(elt);
42153
- });
42154
- return inters;
42155
- }
42156
-
42157
- class Line extends GraphElement {
42158
- constructor(A = new Point(), B = new Point()) {
42159
- super();
42160
- this.A = A;
42161
- this.B = B;
42162
- }
42163
- origin() {
42164
- return this.A;
42165
- }
42166
- dirVect() {
42167
- return vector(this.A, this.B);
42168
- }
42169
- /** Line equation */
42170
- y(x) {
42171
- const a = this.a();
42172
- const b = this.b();
42173
- return a * x + b;
42174
- }
42175
- /** The slope */
42176
- a() {
42177
- const dirVect = this.dirVect();
42178
- return dirVect.y / dirVect.x;
42179
- }
42180
- /** Origin y coordinate */
42181
- b() {
42182
- const O = this.origin().toCoords();
42183
- const a = this.a();
42184
- return O.y - a * O.x;
42185
- }
42186
- isEqual(element) {
42187
- const vect = this.dirVect();
42188
- return (element instanceof Line &&
42189
- isColinear(vect, element.dirVect()) &&
42190
- (isEqual(vect.x, 0)
42191
- ? // We need to take care of the case of the vertical line
42192
- isEqual(this.origin().toCoords().x, element.origin().toCoords().x)
42193
- : isEqual(this.b(), element.b())));
42194
- }
42195
- /** Reversed line equation */
42196
- x(y) {
42197
- const dirVect = this.dirVect();
42198
- return ((y - this.b()) * dirVect.x) / dirVect.y;
42199
- }
42200
- includes(P) {
42201
- const { x, y } = P.toCoords();
42202
- const vect = this.dirVect();
42203
- return isEqual(vect.x, 0)
42204
- ? isEqual(this.origin().toCoords().x, x)
42205
- : isEqual(this.y(x), y);
42206
- }
42207
- /** This is used to standarsize type Segment | HalfLine | Line */
42208
- getLine() {
42209
- const line = new Line(this.origin(), this.B);
42210
- return line;
42211
- }
42212
- orthoProjection(P) {
42213
- const vectOrtho = orthogonal(this.dirVect());
42214
- const A = new Point(P.toCoords());
42215
- const ortho = new Line(A, A.plus(vectOrtho));
42216
- const H = intersectionLine(this, ortho)[0];
42217
- return new Point(H);
42218
- }
42219
- }
42220
-
42221
- class Segment extends GraphElement {
42222
- constructor(A = new Point(), B = new Point()) {
42223
- super();
42224
- this.A = A;
42225
- this.B = B;
42226
- }
42227
- origin() {
42228
- return this.A;
42229
- }
42230
- destination() {
42231
- return this.B;
42232
- }
42233
- dirVect() {
42234
- return vector(this.origin(), this.destination());
42235
- }
42236
- length() {
42237
- return distance(this.destination(), this.origin());
42238
- }
42239
- isEqual(element) {
42240
- if (!(element instanceof Segment))
42241
- return false;
42242
- const o = this.origin();
42243
- const dest = this.destination();
42244
- const oE = element.origin();
42245
- const destE = element.destination();
42246
- return (element instanceof Segment &&
42247
- ((o.isEqual(oE) && dest.isEqual(destE)) ||
42248
- (o.isEqual(destE) && dest.isEqual(oE))));
42249
- }
42250
- /** Returns an equivalent line object */
42251
- getLine() {
42252
- const line = new Line(this.origin(), this.destination());
42253
- return line;
42254
- }
42255
- includes(P) {
42256
- const vect = this.dirVect();
42257
- const otherVect = vector(this.origin(), P);
42258
- // The vectors are not even colinear
42259
- if (!isColinear(vect, otherVect))
42260
- return false;
42261
- // The point is behind the origin
42262
- else if (scalar(vect, otherVect) < 0)
42263
- return false;
42264
- // The point is after the destination
42265
- else if (norm(vect) < norm(otherVect))
42266
- return false;
42267
- else
42268
- return true;
42269
- }
42270
- middle() {
42271
- const mid = new Point(plus(this.origin().toCoords(), times(this.dirVect(), 0.5)));
42272
- return mid;
42273
- }
42274
- orthoProjection(P) {
42275
- const H = this.getLine().orthoProjection(P);
42276
- const vect = this.dirVect();
42277
- const origin = this.origin().toCoords();
42278
- const destination = this.destination().toCoords();
42279
- const otherVect = vector(this.origin(), H);
42280
- // The point is before the origin
42281
- if (scalar(vect, otherVect) < 0)
42282
- return new Point(origin);
42283
- // The point is after the destination
42284
- else if (norm(vect) < norm(otherVect))
42285
- return new Point(destination);
42286
- // The point is within the segment
42287
- else
42288
- return H;
42289
- }
42290
- }
42291
- Segment.type = 'Segment';
42292
-
42293
- class Ellipse extends GraphElement {
42294
- constructor(A = new Point(), B = new Point(), C = new Point()) {
42295
- super();
42296
- this.A = A;
42297
- this.B = B;
42298
- this.C = C;
42299
- }
42300
- center() {
42301
- const center = this.axis().middle();
42302
- return center;
42303
- }
42304
- axis() {
42305
- const axis = new Segment(this.A, this.B);
42306
- return axis;
42307
- }
42308
- a() {
42309
- const axis = this.axis();
42310
- return Math.max(axis.length() / 2, axis.distance(this.C));
42311
- }
42312
- b() {
42313
- const axis = this.axis();
42314
- return Math.min(axis.length() / 2, axis.distance(this.C));
42315
- }
42316
- rotation() {
42317
- const axis = this.axis();
42318
- return axis.length() / 2 > axis.distance(this.C)
42319
- ? orientation(axis.dirVect())
42320
- : orientation(orthogonal(axis.dirVect()));
42321
- }
42322
- getSize() {
42323
- return { width: 2 * this.a(), height: 2 * this.b() };
42324
- }
42325
- isEqual(element) {
42326
- if (!(element instanceof Ellipse))
42327
- return false;
42328
- const a = this.a();
42329
- const b = this.b();
42330
- const rotation = this.rotation();
42331
- const eltA = element.a();
42332
- const eltB = element.b();
42333
- const eltRotation = element.rotation();
42334
- // If the main axis is the same on both ellipse
42335
- if (eltA < eltB === a < b) {
42336
- // The rotation is equivalent module PI as the element is symetrical
42337
- return (isEqual(eltA, a) &&
42338
- isEqual(eltB, b) &&
42339
- isEqual(rotation + (Math.PI % Math.PI), eltRotation + (Math.PI % Math.PI)));
42340
- }
42341
- // If the small axis is different
42342
- else {
42343
- // We add a rotation of PI / 2 to emulate the fact that the main axis are actually orthogonal
42344
- return (isEqual(eltA, b) &&
42345
- isEqual(eltB, a) &&
42346
- isEqual(rotation + (Math.PI % Math.PI), eltRotation + (((3 * Math.PI) / 2) % Math.PI)));
42347
- }
42348
- }
42349
- includes(P) {
42350
- const { x, y } = P.toCoords();
42351
- const { x: cx, y: cy } = this.center().toCoords();
42352
- const teta = this.rotation();
42353
- return isEqual(Math.pow(((x - cx) * Math.cos(teta) + (y - cy) * Math.sin(teta)) / this.a(), 2) +
42354
- Math.pow(((x - cx) * Math.sin(teta) - (y - cy) * Math.cos(teta)) / this.b(), 2), 1);
42355
- }
42356
- orthoProjection(P) {
42357
- // We will consider that the parametric projection is a correct approximation of the distance for the current case, even if it is not orthogonal
42358
- const C = this.center();
42359
- const axis = this.axis();
42360
- const CP = vector(C, P);
42361
- const teta = angle(axis.dirVect(), vector(C, P));
42362
- const ray = this.polarRay(teta);
42363
- if (distance(P, this.center()) < ray)
42364
- return P;
42365
- const vect = times(unitVector(CP), ray);
42366
- return new Point(this.center().plus(vect).toCoords());
42367
- }
42368
- polarRay(teta) {
42369
- const a = this.a();
42370
- const b = this.b();
42371
- const excentricity = Math.sqrt(Math.abs(a * a - b * b)) / Math.max(a, b);
42372
- return (Math.min(a, b) / Math.sqrt(1 - Math.pow(excentricity * Math.cos(teta), 2)));
42373
- }
42374
- }
42375
-
42376
- /**
42377
- * take an array of T and turn it into an 2D-array where each sub array has n elements
42378
- * ex: [1,2,3,4] -> [[1,2], [3, 4]]
42379
- * @param arr the array of elements
42380
- * @param n the size of each sub array
42381
- */
42382
- const groupBy = (arr, n) => {
42383
- if (arr.length <= n)
42384
- return [arr];
42385
- return arr === null || arr === void 0 ? void 0 : arr.reduce((acc, curr, i) => {
42386
- const index = Math.floor(i / n);
42387
- if (i % n) {
42388
- acc[index].push(curr);
41610
+ case 'rotate': {
41611
+ // [cos(a) sin(a) -sin(a) cos(a) 0 0]
41612
+ const [a, x = 0, y = 0] = args;
41613
+ const t1 = transformationToMatrix('translate', [x, y]);
41614
+ const t2 = transformationToMatrix('translate', [-x, -y]);
41615
+ // -args[0] -> the '-' operator is necessary because the pdf rotation system is inverted
41616
+ const aRadians = degreesToRadians(-a);
41617
+ const r = [Math.cos(aRadians), Math.sin(aRadians), -Math.sin(aRadians), Math.cos(aRadians), 0, 0];
41618
+ // rotation around a point is the combination of: translate * rotate * (-translate)
41619
+ return combineMatrix(combineMatrix(t1, r), t2);
41620
+ }
41621
+ case 'skewY':
41622
+ case 'skewX': {
41623
+ // [1 tan(a) 0 1 0 0]
41624
+ // [1 0 tan(a) 1 0 0]
41625
+ // -args[0] -> the '-' operator is necessary because the pdf rotation system is inverted
41626
+ const a = degreesToRadians(-args[0]);
41627
+ const skew = Math.tan(a);
41628
+ const skewX = name === 'skewX' ? skew : 0;
41629
+ const skewY = name === 'skewY' ? skew : 0;
41630
+ return [1, skewY, skewX, 1, 0, 0];
42389
41631
  }
42390
- else {
42391
- acc.push([curr]);
41632
+ case 'matrix': {
41633
+ const [a, b, c, d, e, f] = args;
41634
+ const r = transformationToMatrix('scale', [1, -1]);
41635
+ const m = [a, b, c, d, e, f];
41636
+ return combineMatrix(combineMatrix(r, m), r);
42392
41637
  }
42393
- return acc;
42394
- }, []);
41638
+ default:
41639
+ return identityMatrix;
41640
+ }
42395
41641
  };
42396
- const isCoordinateInsideTheRect = (dot, rect) => isEqual(0, distance(dot, rect.orthoProjection(dot)));
41642
+ const combineTransformation = (matrix, name, args) => combineMatrix(matrix, transformationToMatrix(name, args));
42397
41643
  const StrokeLineCapMap = {
42398
41644
  butt: LineCapStyle.Butt,
42399
41645
  round: LineCapStyle.Round,
@@ -42408,662 +41654,144 @@ const StrokeLineJoinMap = {
42408
41654
  miter: LineJoinStyle.Miter,
42409
41655
  round: LineJoinStyle.Round,
42410
41656
  };
42411
- const getInnerSegment = (start, end, rect) => {
42412
- const isStartInside = isCoordinateInsideTheRect(start, rect);
42413
- const isEndInside = isCoordinateInsideTheRect(end, rect);
42414
- let resultLineStart = start;
42415
- let resultLineEnd = end;
42416
- // it means that the segment is already inside the rect
42417
- if (isEndInside && isStartInside)
42418
- return new Segment(start, end);
42419
- const line = new Segment(start, end);
42420
- const intersection = getIntersections([rect, line]);
42421
- // if there's no intersection it means that the line doesn't intersects the svgRect and isn't visible
42422
- if (intersection.length === 0)
42423
- return;
42424
- if (!isStartInside) {
42425
- // replace the line start point by the nearest intersection
42426
- const nearestPoint = intersection.sort((p1, p2) => distanceCoords(start, p1) - distanceCoords(start, p2))[0];
42427
- resultLineStart = new Point(nearestPoint);
42428
- }
42429
- if (!isEndInside) {
42430
- // replace the line start point by the nearest intersection
42431
- const nearestPoint = intersection.sort((p1, p2) => distanceCoords(end, p1) - distanceCoords(end, p2))[0];
42432
- resultLineEnd = new Point(nearestPoint);
42433
- }
42434
- return new Segment(resultLineStart, resultLineEnd);
42435
- };
42436
- const cropSvgElement = (svgRect, element) => {
42437
- var _a, _b;
42438
- switch (element.tagName) {
42439
- case 'text': {
42440
- const fontSize = element.svgAttributes.fontSize || 12;
42441
- // TODO: compute the right font boundaries to know which characters should be drawn
42442
- // this is an workaround to draw text that are just a little outside the viewbox boundaries
42443
- const start = new Point({
42444
- x: element.svgAttributes.x || 0,
42445
- y: element.svgAttributes.y || 0,
42446
- });
42447
- const paddingRect = new Rectangle(new Point({
42448
- x: svgRect.start.x - fontSize,
42449
- y: svgRect.start.y + fontSize,
42450
- }), new Point({ x: svgRect.end.x + fontSize, y: svgRect.end.y - fontSize }));
42451
- if (!isCoordinateInsideTheRect(start, paddingRect)) {
42452
- element.set_content('');
42453
- }
42454
- break;
42455
- }
42456
- case 'line': {
42457
- const start = new Point({
42458
- x: element.svgAttributes.x1,
42459
- y: element.svgAttributes.y1,
42460
- });
42461
- const end = new Point({
42462
- x: element.svgAttributes.x2,
42463
- y: element.svgAttributes.y2,
42464
- });
42465
- const line = getInnerSegment(start, end, svgRect);
42466
- element.svgAttributes.x1 = line ? line.A.x : 0;
42467
- element.svgAttributes.x2 = line ? line.B.x : 0;
42468
- element.svgAttributes.y1 = line ? line.A.y : 0;
42469
- element.svgAttributes.y2 = line ? line.B.y : 0;
42470
- break;
42471
- }
42472
- case 'path': {
42473
- // the path origin coordinate
42474
- const basePoint = new Point({
42475
- x: element.svgAttributes.x || 0,
42476
- y: element.svgAttributes.y || 0,
42477
- });
42478
- const normalizePoint = (p) => new Point({ x: p.x - basePoint.x, y: p.y - basePoint.y });
42479
- /**
42480
- *
42481
- * @param origin is the origin of the current drawing in the page coordinate system
42482
- * @param command the path instruction
42483
- * @param params the instruction params
42484
- * @returns the point where the next instruction starts and the new instruction text
42485
- */
42486
- const handlePath = (origin, command, params) => {
42487
- switch (command) {
42488
- case 'm':
42489
- case 'M': {
42490
- const isLocalInstruction = command === command.toLocaleLowerCase();
42491
- const nextPoint = new Point({
42492
- x: (isLocalInstruction ? origin.x : basePoint.x) + params[0],
42493
- y: (isLocalInstruction ? origin.y : basePoint.y) + params[1],
42494
- });
42495
- return {
42496
- point: nextPoint,
42497
- command: `${command}${params[0]},${params[1]}`,
42498
- };
42499
- }
42500
- case 'v':
42501
- case 'V':
42502
- case 'h':
42503
- case 'H':
42504
- case 'l':
42505
- case 'L': {
42506
- const isLocalInstruction = ['l', 'v', 'h'].includes(command);
42507
- const getNextPoint = () => {
42508
- switch (command.toLocaleLowerCase()) {
42509
- case 'l':
42510
- return new Point({
42511
- x: (isLocalInstruction ? origin.x : basePoint.x) + params[0],
42512
- y: (isLocalInstruction ? origin.y : basePoint.y) + params[1],
42513
- });
42514
- case 'v':
42515
- return new Point({
42516
- x: origin.x,
42517
- y: (isLocalInstruction ? origin.y : basePoint.y) + params[0],
42518
- });
42519
- case 'h':
42520
- return new Point({
42521
- x: (isLocalInstruction ? origin.x : basePoint.x) + params[0],
42522
- y: origin.y,
42523
- });
42524
- default:
42525
- return new Point({
42526
- x: 0,
42527
- y: 0,
42528
- });
42529
- }
42530
- };
42531
- const nextPoint = getNextPoint();
42532
- const normalizedNext = normalizePoint(nextPoint);
42533
- let endPoint = new Point({ x: nextPoint.x, y: nextPoint.y });
42534
- let startPoint = new Point({ x: origin.x, y: origin.y });
42535
- const result = getInnerSegment(startPoint, endPoint, svgRect);
42536
- if (!result) {
42537
- return {
42538
- point: nextPoint,
42539
- command: `M${normalizedNext.x},${normalizedNext.y}`,
42540
- };
42541
- }
42542
- // if the point wasn't moved it means that it's inside the rect
42543
- const isStartInside = result.A.isEqual(startPoint);
42544
- const isEndInside = result.B.isEqual(endPoint);
42545
- // the intersection points are referencing the pdf coordinates, it's necessary to convert these points to the path's origin point
42546
- endPoint = normalizePoint(new Point(result.B.toCoords()));
42547
- startPoint = normalizePoint(new Point(result.A.toCoords()));
42548
- const startInstruction = isStartInside
42549
- ? ''
42550
- : `M${startPoint.x},${startPoint.y}`;
42551
- const endInstruction = isEndInside
42552
- ? ''
42553
- : `M${normalizedNext.x},${normalizedNext.y}`;
42554
- return {
42555
- point: nextPoint,
42556
- command: `${startInstruction} L${endPoint.x},${endPoint.y} ${endInstruction} `,
42557
- };
42558
- }
42559
- case 'a':
42560
- case 'A': {
42561
- const isLocalInstruction = command === 'a';
42562
- const [, , , , , x, y] = params;
42563
- const nextPoint = new Point({
42564
- x: (isLocalInstruction ? origin.x : basePoint.x) + x,
42565
- y: (isLocalInstruction ? origin.y : basePoint.y) + y,
42566
- });
42567
- // TODO: implement the code to fit the Elliptical Arc Curve instructions into the viewbox
42568
- return {
42569
- point: nextPoint,
42570
- command: `${command} ${params.map((p) => `${p}`).join()}`,
42571
- };
42572
- }
42573
- case 'c':
42574
- case 'C': {
42575
- const isLocalInstruction = command === 'c';
42576
- let x = 0;
42577
- let y = 0;
42578
- for (let pendingParams = params; pendingParams.length > 0; pendingParams = pendingParams.slice(6)) {
42579
- const [, , , , pendingX, pendingY] = pendingParams;
42580
- if (isLocalInstruction) {
42581
- x += pendingX;
42582
- y += pendingY;
42583
- }
42584
- else {
42585
- x = pendingX;
42586
- y = pendingY;
42587
- }
42588
- }
42589
- const nextPoint = new Point({
42590
- x: (isLocalInstruction ? origin.x : basePoint.x) + x,
42591
- y: (isLocalInstruction ? origin.y : basePoint.y) + y,
42592
- });
42593
- // TODO: implement the code to fit the Cubic Bézier Curve instructions into the viewbox
42594
- return {
42595
- point: nextPoint,
42596
- command: `${command} ${params.map((p) => `${p}`).join()}`,
42597
- };
42598
- }
42599
- case 's':
42600
- case 'S':
42601
- const isLocalInstruction = command === 's';
42602
- let x = 0;
42603
- let y = 0;
42604
- for (let pendingParams = params; pendingParams.length > 0; pendingParams = pendingParams.slice(4)) {
42605
- const [, , pendingX, pendingY] = pendingParams;
42606
- x += pendingX;
42607
- y += pendingY;
42608
- }
42609
- const nextPoint = new Point({
42610
- x: (isLocalInstruction ? origin.x : basePoint.x) + x,
42611
- y: (isLocalInstruction ? origin.y : basePoint.y) + y,
42612
- });
42613
- return {
42614
- point: nextPoint,
42615
- command: `${command} ${params.map((p) => `${p}`).join()}`,
42616
- };
42617
- case 'q':
42618
- case 'Q': {
42619
- const isLocalInstruction = command === 'q';
42620
- const [, , x, y] = params;
42621
- const nextPoint = new Point({
42622
- x: (isLocalInstruction ? origin.x : basePoint.x) + x,
42623
- y: (isLocalInstruction ? origin.y : basePoint.y) + y,
42624
- });
42625
- // TODO: implement the code to fit the Quadratic Bézier Curve instructions into the viewbox
42626
- return {
42627
- point: nextPoint,
42628
- command: `${command} ${params.map((p) => `${p}`).join()}`,
42629
- };
42630
- }
42631
- // TODO: Handle the remaining svg instructions: t,q
42632
- default:
42633
- return {
42634
- point: origin,
42635
- command: `${command} ${params.map((p) => `${p}`).join()}`,
42636
- };
42637
- }
42638
- };
42639
- const commands = (_a = element.svgAttributes.d) === null || _a === void 0 ? void 0 : _a.match(/(v|h|a|l|t|m|q|c|s|z)([0-9,e\s.-]*)/gi);
42640
- let currentPoint = new Point({ x: basePoint.x, y: basePoint.y });
42641
- const newPath = commands === null || commands === void 0 ? void 0 : commands.map((command) => {
42642
- var _a, _b;
42643
- const letter = (_a = command.match(/[a-z]/i)) === null || _a === void 0 ? void 0 : _a[0];
42644
- const params = (_b = command
42645
- .match(/(-?[0-9]+\.[0-9]+(e[+-]?[0-9]+)?)|(-?\.[0-9]+(e[+-]?[0-9]+)?)|(-?[0-9]+)/gi)) === null || _b === void 0 ? void 0 : _b.filter((m) => m !== '').map((v) => parseFloat(v));
42646
- if (letter && params) {
42647
- const result = handlePath(currentPoint, letter, params);
42648
- if (result) {
42649
- currentPoint = result.point;
42650
- return result.command;
42651
- }
42652
- }
42653
- return command;
42654
- }).join(' ');
42655
- element.svgAttributes.d = newPath;
42656
- break;
42657
- }
42658
- case 'ellipse':
42659
- case 'circle': {
42660
- if (element.svgAttributes.cx === undefined ||
42661
- element.svgAttributes.cy === undefined ||
42662
- element.svgAttributes.rx === undefined ||
42663
- element.svgAttributes.ry === undefined) {
42664
- break;
42665
- }
42666
- const { cx = 0, cy = 0, rx = 0, ry = 0 } = element.svgAttributes;
42667
- const center = new Point({
42668
- x: cx,
42669
- y: cy,
42670
- });
42671
- const rotation = ((_b = element.svgAttributes.rotation) === null || _b === void 0 ? void 0 : _b.angle) || 0;
42672
- // these points are relative to the ellipse's center
42673
- const a = new Point(rotate({ x: -rx, y: 0 }, degreesToRadians(rotation)));
42674
- const b = new Point(rotate({ x: rx, y: 0 }, degreesToRadians(rotation)));
42675
- const c = new Point(rotate({ x: 0, y: ry }, degreesToRadians(rotation)));
42676
- // these points are relative to the real coordinate system
42677
- const A = center.plus(a);
42678
- const B = center.plus(b);
42679
- const C = center.plus(c);
42680
- const ellipse = new Ellipse(A, B, C);
42681
- const intersections = getIntersections([svgRect, ellipse]);
42682
- const isCenterInsideRect = isCoordinateInsideTheRect(center, svgRect);
42683
- /**
42684
- * if there are less than 2 intersection, there are two possibilities:
42685
- * - the ellipse is outside the viewbox and therefore isn't visible
42686
- * - the ellipse is inside the viewbox and don't need to be cropped
42687
- */
42688
- if (intersections.length < 2) {
42689
- !isCenterInsideRect && element.setAttribute('rx', '0');
42690
- !isCenterInsideRect && (element.svgAttributes.rx = 0);
42691
- !isCenterInsideRect && element.setAttribute('ry', '0');
42692
- !isCenterInsideRect && (element.svgAttributes.ry = 0);
42693
- break;
42694
- }
42695
- // viewbox rectangle coordinates
42696
- const P1 = new Point(svgRect.getCoords());
42697
- const P3 = new Point(svgRect.getEnd());
42698
- const P2 = new Point({ x: P3.x, y: P1.y });
42699
- const P4 = new Point({ x: P1.x, y: P3.y });
42700
- const top = new Segment(P1, P2);
42701
- const right = new Segment(P2, P3);
42702
- const bottom = new Segment(P3, P4);
42703
- const left = new Segment(P4, P1);
42704
- // Warning: keep the order of the segments, it's important when building the path that will represent the ellipse
42705
- const rectSegments = [top, right, bottom, left];
42706
- const isPointInsideEllipse = (P) => (P.x - cx) ** 2 / rx ** 2 + (P.y - cy) ** 2 / ry ** 2 <= 1;
42707
- // check if the rect boundaries are inside the circle
42708
- const isRectInsideEllipse = isPointInsideEllipse(P1) &&
42709
- isPointInsideEllipse(P2) &&
42710
- isPointInsideEllipse(P3) &&
42711
- isPointInsideEllipse(P4);
42712
- // the segments that are intersecting the circle. And, therefore, are lines that are cropping the drawing
42713
- const circleSegments = isRectInsideEllipse
42714
- ? rectSegments
42715
- : rectSegments.map((segment, i) => {
42716
- const [p1, p2] = getIntersections([segment, ellipse])
42717
- // it's important to sort the segment's point because it impacts the angle of the arc, the points are sorted on clockwise direction
42718
- .sort((p1, p2) => {
42719
- // top
42720
- if (i === 0) {
42721
- return p1.x - p2.x;
42722
- // right
42723
- }
42724
- else if (i === 1) {
42725
- return p2.y - p1.y;
42726
- // bottom
42727
- }
42728
- else if (i === 2) {
42729
- return p2.x - p1.x;
42730
- // left
42731
- }
42732
- else {
42733
- return p1.y - p2.y;
42734
- }
42735
- });
42736
- if (p1 && p2) {
42737
- return new Segment(new Point(p1), new Point(p2));
42738
- // if the other point isn't inside the circle it means that the circle isn't cropped by the segment
42739
- }
42740
- else if (p1 &&
42741
- (isPointInsideEllipse(segment.A) ||
42742
- isPointInsideEllipse(segment.B))) {
42743
- const intersectionPoint = new Point(p1);
42744
- const innerPoint = isPointInsideEllipse(segment.A)
42745
- ? segment.A
42746
- : segment.B;
42747
- // ensures that the segment is always following the clockwise direction
42748
- const start = innerPoint.isEqual(segment.A)
42749
- ? innerPoint
42750
- : intersectionPoint;
42751
- const end = innerPoint.isEqual(segment.A)
42752
- ? intersectionPoint
42753
- : innerPoint;
42754
- return new Segment(start, end);
42755
- // if there's no intersection and the segment's points are inside the Ellipse it means that the segment should be drawn as part of the ellipse
42756
- }
42757
- else if (!(p1 && p2) &&
42758
- isPointInsideEllipse(segment.A) &&
42759
- isPointInsideEllipse(segment.B)) {
42760
- return segment;
42761
- }
42762
- return;
42763
- });
42764
- const inverseAngle = (angle) => (360 - angle) % 360;
42765
- const pointsAngle = (p1, p2, direction = 'clockwise') => {
42766
- const startAngle = radiansToDegrees(Math.atan2(p1.y - center.y, p1.x - center.x));
42767
- const endAngle = radiansToDegrees(Math.atan2(p2.y - center.y, p2.x - center.x));
42768
- const arcAngle = (endAngle + (360 - startAngle)) % 360;
42769
- return direction === 'clockwise' ? arcAngle : inverseAngle(arcAngle);
42770
- };
42771
- /**
42772
- * - draw a line for each segment
42773
- * - if two segments aren't connected draw an arc connecting them
42774
- */
42775
- let startPoint;
42776
- // the point where the pen is located
42777
- let currentPoint;
42778
- let lastSegment;
42779
- let path = circleSegments.reduce((path, segment) => {
42780
- if (!segment)
42781
- return path;
42782
- if (!startPoint) {
42783
- startPoint = segment.A;
42784
- path = `M ${segment.A.x},${segment.A.y}`;
42785
- }
42786
- // if the current segment isn't connected to the last one, connect both with an arc
42787
- if (lastSegment && !lastSegment.B.isEqual(segment.A)) {
42788
- const arcAngle = pointsAngle(segment.A, lastSegment.B);
42789
- // angles greater than 180 degrees are marked as large-arc-flag = 1
42790
- path += `A ${rx},${ry} ${rotation} ${arcAngle > 180 ? 1 : 0},0 ${segment.A.x}, ${segment.A.y}`;
42791
- }
42792
- path += ` L ${segment.B.x},${segment.B.y}`;
42793
- currentPoint = segment.B;
42794
- lastSegment = segment;
42795
- return path;
42796
- }, '');
42797
- // if the path isn't closed, close it by drawing an arc
42798
- if (startPoint && currentPoint && !startPoint.isEqual(currentPoint)) {
42799
- const arcAngle = pointsAngle(currentPoint, startPoint, 'counter-clockwise');
42800
- // angles greater than 180 degrees are marked as large-arc-flag = 1
42801
- path += `A ${rx},${ry} ${rotation} ${arcAngle > 180 ? 1 : 0},0 ${startPoint.x}, ${startPoint.y}`;
42802
- }
42803
- // create a new element that will represent the cropped ellipse
42804
- const newElement = index.parse(`<path d="${path}" fill="red"/>`).firstChild;
42805
- const svgAttributes = Object.assign(Object.assign({}, element.svgAttributes), {
42806
- // the x and y values are 0 because all the path coordinates are global
42807
- x: 0, y: 0,
42808
- // the path coordinates are already rotated
42809
- rotate: undefined, d: path });
42810
- Object.assign(newElement, { svgAttributes });
42811
- return newElement;
42812
- }
42813
- case 'rect': {
42814
- const { x = 0, y = 0, width = 0, height = 0, rotate: rawRotation, } = element.svgAttributes;
42815
- const rotation = (rawRotation === null || rawRotation === void 0 ? void 0 : rawRotation.angle) || 0;
42816
- if (!(width && height))
42817
- return element;
42818
- // bottomLeft point
42819
- const origin = new Point({ x, y });
42820
- const rotateAroundOrigin = (p) => new Point(rotate(normalize(p), degreesToRadians(rotation))).plus(origin);
42821
- const normalize = (p) => p.plus({ x: -origin.x, y: -origin.y });
42822
- const topLeft = rotateAroundOrigin(origin.plus({ x: 0, y: -height }));
42823
- const topRight = rotateAroundOrigin(origin.plus({ x: width, y: -height }));
42824
- const bottomRight = rotateAroundOrigin(origin.plus({ x: width, y: 0 }));
42825
- const pointToString = (p) => [p.x, p.y].join();
42826
- const d = `M${pointToString(topLeft)} L${pointToString(topRight)} L${pointToString(bottomRight)} L${pointToString(origin)} L${pointToString(topLeft)}`;
42827
- const el = index.parse(`<path d="${d}"/>`).firstChild;
42828
- const newAttributes = Object.assign(Object.assign({}, element.svgAttributes), { d, x: 0, y: 0 });
42829
- // @ts-ignore
42830
- delete newAttributes.width;
42831
- // @ts-ignore
42832
- delete newAttributes.height;
42833
- delete newAttributes.rotate;
42834
- delete newAttributes.rotation;
42835
- Object.assign(el, {
42836
- svgAttributes: newAttributes,
42837
- });
42838
- return cropSvgElement(svgRect, el);
42839
- }
42840
- // TODO: implement the crop for the following elements
42841
- case 'image':
42842
- default:
42843
- return element;
42844
- }
42845
- return element;
42846
- };
42847
41657
  // TODO: Improve type system to require the correct props for each tagName.
42848
41658
  /** methods to draw SVGElements onto a PDFPage */
42849
41659
  const runnersToPage = (page, options) => ({
42850
- text(element) {
42851
- return __awaiter(this, void 0, void 0, function* () {
42852
- const anchor = element.svgAttributes.textAnchor;
42853
- const dominantBaseline = element.svgAttributes.dominantBaseline;
42854
- const text = element.text.trim().replace(/\s/g, ' ');
42855
- const fontSize = element.svgAttributes.fontSize || 12;
42856
- /** This will find the best font for the provided style in the list */
42857
- function getBestFont(style, fonts) {
42858
- const family = style.fontFamily;
42859
- if (!family)
42860
- return undefined;
42861
- const isBold = style.fontWeight === 'bold' || Number(style.fontWeight) >= 700;
42862
- const isItalic = style.fontStyle === 'italic';
42863
- const getFont = (bold, italic, family) => fonts[family + (bold ? '_bold' : '') + (italic ? '_italic' : '')];
42864
- return (getFont(isBold, isItalic, family) ||
42865
- getFont(isBold, false, family) ||
42866
- getFont(false, isItalic, family) ||
42867
- getFont(false, false, family) ||
42868
- Object.keys(fonts).find((fontFamily) => fontFamily.startsWith(family)));
42869
- }
42870
- const font = options.fonts && getBestFont(element.svgAttributes, options.fonts);
42871
- const textWidth = (font || page.getFont()[0]).widthOfTextAtSize(text, fontSize);
42872
- const textHeight = (font || page.getFont()[0]).heightAtSize(fontSize);
42873
- const offsetX = anchor === 'middle' ? textWidth / 2 : anchor === 'end' ? textWidth : 0;
42874
- const offsetY = dominantBaseline === 'text-before-edge'
42875
- ? textHeight
42876
- : dominantBaseline === 'text-after-edge'
42877
- ? -textHeight
42878
- : dominantBaseline === 'middle'
42879
- ? textHeight / 2
42880
- : 0;
42881
- const point = new Point({
42882
- x: (element.svgAttributes.x || 0) - offsetX,
42883
- y: (element.svgAttributes.y || 0) - offsetY,
42884
- });
42885
- // TODO: compute the right font boundaries to know which characters should be drawed
42886
- // this is an workaround to draw text that are just a little outside the viewbox boundaries
42887
- page.drawText(text, {
42888
- x: point.x,
42889
- y: point.y,
42890
- font,
42891
- size: fontSize,
42892
- color: element.svgAttributes.fill,
42893
- opacity: element.svgAttributes.fillOpacity,
42894
- rotate: element.svgAttributes.rotate,
42895
- });
41660
+ async text(element) {
41661
+ const anchor = element.svgAttributes.textAnchor;
41662
+ const dominantBaseline = element.svgAttributes.dominantBaseline;
41663
+ const text = element.text.trim().replace(/\s/g, ' ');
41664
+ const fontSize = element.svgAttributes.fontSize || 12;
41665
+ /** This will find the best font for the provided style in the list */
41666
+ function getBestFont(style, fonts) {
41667
+ const family = style.fontFamily;
41668
+ if (!family)
41669
+ return undefined;
41670
+ const isBold = style.fontWeight === 'bold' || Number(style.fontWeight) >= 700;
41671
+ const isItalic = style.fontStyle === 'italic';
41672
+ const getFont = (bold, italic, family) => fonts[family + (bold ? '_bold' : '') + (italic ? '_italic' : '')];
41673
+ return (getFont(isBold, isItalic, family) ||
41674
+ getFont(isBold, false, family) ||
41675
+ getFont(false, isItalic, family) ||
41676
+ getFont(false, false, family) ||
41677
+ Object.keys(fonts).find((fontFamily) => fontFamily.startsWith(family)));
41678
+ }
41679
+ const font = options.fonts && getBestFont(element.svgAttributes, options.fonts);
41680
+ const textWidth = (font || page.getFont()[0]).widthOfTextAtSize(text, fontSize);
41681
+ const textHeight = (font || page.getFont()[0]).heightAtSize(fontSize);
41682
+ const offsetX = anchor === 'middle' ? textWidth / 2 : anchor === 'end' ? textWidth : 0;
41683
+ const offsetY = dominantBaseline === 'text-before-edge'
41684
+ ? textHeight
41685
+ : dominantBaseline === 'text-after-edge'
41686
+ ? -textHeight
41687
+ : dominantBaseline === 'middle'
41688
+ ? textHeight / 2
41689
+ : 0;
41690
+ page.drawText(text, {
41691
+ x: -offsetX,
41692
+ y: -offsetY,
41693
+ font,
41694
+ // TODO: the font size should be correctly scaled too
41695
+ size: fontSize,
41696
+ color: element.svgAttributes.fill,
41697
+ opacity: element.svgAttributes.fillOpacity,
41698
+ matrix: element.svgAttributes.matrix,
41699
+ clipSpaces: element.svgAttributes.clipSpaces,
42896
41700
  });
42897
41701
  },
42898
- line(element) {
42899
- return __awaiter(this, void 0, void 0, function* () {
42900
- page.drawLine({
42901
- start: {
42902
- x: element.svgAttributes.x1,
42903
- y: element.svgAttributes.y1,
42904
- },
42905
- end: {
42906
- x: element.svgAttributes.x2,
42907
- y: element.svgAttributes.y2,
42908
- },
42909
- thickness: element.svgAttributes.strokeWidth,
42910
- color: element.svgAttributes.stroke,
42911
- opacity: element.svgAttributes.strokeOpacity,
42912
- lineCap: element.svgAttributes.strokeLineCap,
42913
- });
41702
+ async line(element) {
41703
+ page.drawLine({
41704
+ start: {
41705
+ x: element.svgAttributes.x1 || 0,
41706
+ y: -element.svgAttributes.y1 || 0,
41707
+ },
41708
+ end: {
41709
+ x: element.svgAttributes.x2 || 0,
41710
+ y: -element.svgAttributes.y2 || 0,
41711
+ },
41712
+ thickness: element.svgAttributes.strokeWidth,
41713
+ color: element.svgAttributes.stroke,
41714
+ opacity: element.svgAttributes.strokeOpacity,
41715
+ lineCap: element.svgAttributes.strokeLineCap,
41716
+ matrix: element.svgAttributes.matrix,
41717
+ clipSpaces: element.svgAttributes.clipSpaces,
42914
41718
  });
42915
41719
  },
42916
- path(element) {
42917
- return __awaiter(this, void 0, void 0, function* () {
42918
- if (!element.svgAttributes.d)
42919
- return;
42920
- // See https://jsbin.com/kawifomupa/edit?html,output and
42921
- page.drawSvgPath(element.svgAttributes.d, {
42922
- x: element.svgAttributes.x || 0,
42923
- y: element.svgAttributes.y || 0,
42924
- borderColor: element.svgAttributes.stroke,
42925
- borderWidth: element.svgAttributes.strokeWidth,
42926
- borderOpacity: element.svgAttributes.strokeOpacity,
42927
- borderLineCap: element.svgAttributes.strokeLineCap,
42928
- color: element.svgAttributes.fill,
42929
- opacity: element.svgAttributes.fillOpacity,
42930
- scale: element.svgAttributes.scale,
42931
- rotate: element.svgAttributes.rotate,
42932
- fillRule: element.svgAttributes.fillRule,
42933
- });
41720
+ async path(element) {
41721
+ if (!element.svgAttributes.d)
41722
+ return;
41723
+ // See https://jsbin.com/kawifomupa/edit?html,output and
41724
+ page.drawSvgPath(element.svgAttributes.d, {
41725
+ x: 0,
41726
+ y: 0,
41727
+ borderColor: element.svgAttributes.stroke,
41728
+ borderWidth: element.svgAttributes.strokeWidth,
41729
+ borderOpacity: element.svgAttributes.strokeOpacity,
41730
+ borderLineCap: element.svgAttributes.strokeLineCap,
41731
+ color: element.svgAttributes.fill,
41732
+ opacity: element.svgAttributes.fillOpacity,
41733
+ fillRule: element.svgAttributes.fillRule,
41734
+ matrix: element.svgAttributes.matrix,
41735
+ clipSpaces: element.svgAttributes.clipSpaces,
42934
41736
  });
42935
41737
  },
42936
- image(element) {
42937
- return __awaiter(this, void 0, void 0, function* () {
42938
- const { src } = element.svgAttributes;
42939
- if (!src)
42940
- return;
42941
- const isPng = src.match(/\.png(\?|$)|^data:image\/png;base64/gim);
42942
- const img = isPng
42943
- ? yield page.doc.embedPng(src)
42944
- : yield page.doc.embedJpg(src);
42945
- const { x, y, width, height } = getFittingRectangle(img.width, img.height, element.svgAttributes.width || img.width, element.svgAttributes.height || img.height, element.svgAttributes.preserveAspectRatio);
42946
- page.drawImage(img, {
42947
- x: (element.svgAttributes.x || 0) + x,
42948
- y: (element.svgAttributes.y || 0) - y - height,
42949
- width,
42950
- height,
42951
- opacity: element.svgAttributes.fillOpacity,
42952
- xSkew: element.svgAttributes.skewX,
42953
- ySkew: element.svgAttributes.skewY,
42954
- rotate: element.svgAttributes.rotate,
42955
- });
41738
+ async image(element) {
41739
+ const { src } = element.svgAttributes;
41740
+ if (!src)
41741
+ return;
41742
+ const isPng = src.match(/\.png(\?|$)|^data:image\/png;base64/gim);
41743
+ const img = isPng
41744
+ ? await page.doc.embedPng(src)
41745
+ : await page.doc.embedJpg(src);
41746
+ const { x, y, width, height } = getFittingRectangle(img.width, img.height, element.svgAttributes.width || img.width, element.svgAttributes.height || img.height, element.svgAttributes.preserveAspectRatio);
41747
+ page.drawImage(img, {
41748
+ x,
41749
+ y: -y - height,
41750
+ width,
41751
+ height,
41752
+ opacity: element.svgAttributes.fillOpacity,
41753
+ matrix: element.svgAttributes.matrix,
41754
+ clipSpaces: element.svgAttributes.clipSpaces,
42956
41755
  });
42957
41756
  },
42958
- rect(element) {
42959
- return __awaiter(this, void 0, void 0, function* () {
42960
- if (!element.svgAttributes.fill && !element.svgAttributes.stroke)
42961
- return;
42962
- page.drawRectangle({
42963
- x: element.svgAttributes.x,
42964
- y: element.svgAttributes.y || 0,
42965
- width: element.svgAttributes.width,
42966
- height: element.svgAttributes.height * -1,
42967
- borderColor: element.svgAttributes.stroke,
42968
- borderWidth: element.svgAttributes.strokeWidth,
42969
- borderOpacity: element.svgAttributes.strokeOpacity,
42970
- borderLineCap: element.svgAttributes.strokeLineCap,
42971
- color: element.svgAttributes.fill,
42972
- opacity: element.svgAttributes.fillOpacity,
42973
- xSkew: element.svgAttributes.skewX,
42974
- ySkew: element.svgAttributes.skewY,
42975
- rotate: element.svgAttributes.rotate,
42976
- });
41757
+ async rect(element) {
41758
+ if (!element.svgAttributes.fill && !element.svgAttributes.stroke)
41759
+ return;
41760
+ page.drawRectangle({
41761
+ x: 0,
41762
+ y: 0,
41763
+ width: element.svgAttributes.width,
41764
+ height: element.svgAttributes.height * -1,
41765
+ borderColor: element.svgAttributes.stroke,
41766
+ borderWidth: element.svgAttributes.strokeWidth,
41767
+ borderOpacity: element.svgAttributes.strokeOpacity,
41768
+ borderLineCap: element.svgAttributes.strokeLineCap,
41769
+ color: element.svgAttributes.fill,
41770
+ opacity: element.svgAttributes.fillOpacity,
41771
+ matrix: element.svgAttributes.matrix,
41772
+ clipSpaces: element.svgAttributes.clipSpaces,
42977
41773
  });
42978
41774
  },
42979
- ellipse(element) {
42980
- return __awaiter(this, void 0, void 0, function* () {
42981
- page.drawEllipse({
42982
- x: element.svgAttributes.cx,
42983
- y: element.svgAttributes.cy,
42984
- xScale: element.svgAttributes.rx,
42985
- yScale: element.svgAttributes.ry,
42986
- borderColor: element.svgAttributes.stroke,
42987
- borderWidth: element.svgAttributes.strokeWidth,
42988
- borderOpacity: element.svgAttributes.strokeOpacity,
42989
- borderLineCap: element.svgAttributes.strokeLineCap,
42990
- color: element.svgAttributes.fill,
42991
- opacity: element.svgAttributes.fillOpacity,
42992
- rotate: element.svgAttributes.rotate,
42993
- });
41775
+ async ellipse(element) {
41776
+ page.drawEllipse({
41777
+ x: element.svgAttributes.cx || 0,
41778
+ y: -(element.svgAttributes.cy || 0),
41779
+ xScale: element.svgAttributes.rx,
41780
+ yScale: element.svgAttributes.ry,
41781
+ borderColor: element.svgAttributes.stroke,
41782
+ borderWidth: element.svgAttributes.strokeWidth,
41783
+ borderOpacity: element.svgAttributes.strokeOpacity,
41784
+ borderLineCap: element.svgAttributes.strokeLineCap,
41785
+ color: element.svgAttributes.fill,
41786
+ opacity: element.svgAttributes.fillOpacity,
41787
+ matrix: element.svgAttributes.matrix,
41788
+ clipSpaces: element.svgAttributes.clipSpaces,
42994
41789
  });
42995
41790
  },
42996
- circle(element) {
42997
- return __awaiter(this, void 0, void 0, function* () {
42998
- return runnersToPage(page, options).ellipse(element);
42999
- });
41791
+ async circle(element) {
41792
+ return runnersToPage(page, options).ellipse(element);
43000
41793
  },
43001
41794
  });
43002
- const transform = (converter, name, args) => {
43003
- switch (name) {
43004
- case 'scaleX':
43005
- return transform(converter, 'scale', [args[0], 0]);
43006
- case 'scaleY':
43007
- return transform(converter, 'scale', [0, args[0]]);
43008
- case 'scale':
43009
- const [xScale, yScale = xScale] = args;
43010
- return {
43011
- point: (x, y) => converter.point(x * xScale, y * yScale),
43012
- size: (w, h) => converter.size(w * xScale, h * yScale),
43013
- };
43014
- case 'translateX':
43015
- return transform(converter, 'translate', [args[0], 0]);
43016
- case 'translateY':
43017
- return transform(converter, 'translate', [0, args[0]]);
43018
- case 'translate':
43019
- const [dx, dy = dx] = args;
43020
- return {
43021
- point: (x, y) => converter.point(x + dx, y + dy),
43022
- size: converter.size,
43023
- };
43024
- case 'rotate': {
43025
- if (args.length > 1) {
43026
- const [a, x, y = x] = args;
43027
- let tempResult = transform(converter, 'translate', [x, y]);
43028
- tempResult = transform(tempResult, 'rotate', [a]);
43029
- return transform(tempResult, 'translate', [-x, -y]);
43030
- }
43031
- else {
43032
- const [a] = args;
43033
- const angle = degreesToRadians(a);
43034
- return {
43035
- point: (x, y) => converter.point(x * Math.cos(angle) - y * Math.sin(angle), y * Math.cos(angle) + x * Math.sin(angle)),
43036
- size: converter.size,
43037
- };
43038
- }
43039
- }
43040
- case 'matrix': {
43041
- const [scaleX, skewY, skewX, scaleY, translateX, translateY] = args;
43042
- return {
43043
- point: (x, y) => converter.point(x * scaleX + y * skewX + translateX, x * skewY + y * scaleY + translateY),
43044
- size: (w, h) => converter.size(w * scaleX, h * scaleY),
43045
- };
43046
- }
43047
- case 'skewX': {
43048
- const angle = degreesToRadians(args[0]);
43049
- return {
43050
- point: (x, y) => converter.point((1 + x) * Math.tan(angle), y),
43051
- size: converter.size,
43052
- };
43053
- }
43054
- case 'skewY': {
43055
- const angle = degreesToRadians(args[0]);
43056
- return {
43057
- point: (x, y) => converter.point(x, (1 + y) * Math.tan(angle)),
43058
- size: converter.size,
43059
- };
43060
- }
43061
- default: {
43062
- console.log('transformation unsupported:', name);
43063
- return converter;
43064
- }
43065
- }
43066
- };
43067
41795
  const styleOrAttribute = (attributes, style, attribute, def) => {
43068
41796
  const value = style[attribute] || attributes[attribute];
43069
41797
  if (!value && typeof def !== 'undefined')
@@ -43093,8 +41821,8 @@ const parseColor = (color, inherited) => {
43093
41821
  alpha: parsedColor.alpha ? parsedColor.alpha + '' : undefined,
43094
41822
  };
43095
41823
  };
43096
- const parseAttributes = (element, inherited, converter) => {
43097
- var _a, _b, _c, _d, _e, _f, _g;
41824
+ const parseAttributes = (element, inherited, matrix) => {
41825
+ var _a, _b, _c, _d;
43098
41826
  const attributes = element.attributes;
43099
41827
  const style = parseStyles(attributes.style);
43100
41828
  const widthRaw = styleOrAttribute(attributes, style, 'width', '');
@@ -43150,7 +41878,6 @@ const parseAttributes = (element, inherited, converter) => {
43150
41878
  dominantBaseline: attributes['dominant-baseline'],
43151
41879
  preserveAspectRatio: attributes.preserveAspectRatio,
43152
41880
  };
43153
- let newConverter = converter;
43154
41881
  let transformList = attributes.transform || '';
43155
41882
  // Handle transformations set as direct attributes
43156
41883
  [
@@ -43169,28 +41896,11 @@ const parseAttributes = (element, inherited, converter) => {
43169
41896
  transformList = attributes[name] + ' ' + transformList;
43170
41897
  }
43171
41898
  });
43172
- // skewX, skewY, rotate and scale are handled by the pdf-lib
43173
- ['skewX', 'skewY', 'rotate'].forEach((name) => {
43174
- var _a;
43175
- if (attributes[name]) {
43176
- const d = (_a = attributes[name].match(/-?(\d+\.?|\.)\d*/)) === null || _a === void 0 ? void 0 : _a[0];
43177
- if (d !== undefined) {
43178
- svgAttributes[name] = {
43179
- angle: parseInt(d, 10),
43180
- type: RotationTypes.Degrees,
43181
- };
43182
- }
43183
- }
43184
- });
43185
- if (attributes.scale) {
43186
- const d = (_e = attributes.scale.match(/-?(\d+\.?|\.)\d*/)) === null || _e === void 0 ? void 0 : _e[0];
43187
- if (d !== undefined)
43188
- svgAttributes.scale = parseInt(d, 10);
43189
- }
43190
41899
  // Convert x/y as if it was a translation
43191
41900
  if (x || y) {
43192
41901
  transformList = transformList + `translate(${x || 0} ${y || 0}) `;
43193
41902
  }
41903
+ let newMatrix = matrix;
43194
41904
  // Apply the transformations
43195
41905
  if (transformList) {
43196
41906
  const regexTransform = /(\w+)\((.+?)\)/g;
@@ -43201,295 +41911,38 @@ const parseAttributes = (element, inherited, converter) => {
43201
41911
  .split(/\s*,\s*|\s+/)
43202
41912
  .filter((value) => value.length > 0)
43203
41913
  .map((value) => parseFloat(value));
43204
- const currentConverter = newConverter;
43205
- newConverter = transform(newConverter, name, args);
43206
- const xAxisVector = minus(currentConverter.point(0, 0), currentConverter.point(1, 0));
43207
- const xAxisVectorPostTransform = minus(newConverter.point(0, 0), newConverter.point(1, 0));
43208
- // matrix transform may also represent rotations: https://www.w3.org/TR/SVGTiny12/coords.html
43209
- if (name === 'rotate' || name === 'matrix') {
43210
- // transformations over x and y axis might change the page coord direction
43211
- const { width: xDirection, height: yDirection } = currentConverter.size(1, 1);
43212
- const rotationAdded = name === 'rotate' ? args[0] : radiansToDegrees(angle(xAxisVectorPostTransform, xAxisVector));
43213
- // the page Y coord is inverted so the angle rotation is inverted too
43214
- const pageYDirection = -1;
43215
- newInherited.rotation = degrees(pageYDirection * rotationAdded * Math.sign(xDirection * yDirection) +
43216
- (((_f = inherited.rotation) === null || _f === void 0 ? void 0 : _f.angle) || 0));
43217
- svgAttributes.rotate = newInherited.rotation;
43218
- }
41914
+ newMatrix = combineTransformation(newMatrix, name, args);
43219
41915
  parsed = regexTransform.exec(transformList);
43220
41916
  }
43221
41917
  }
43222
- // x and y were already transformed into a translation. The new reference point is now 0,0
43223
- const { x: newX, y: newY } = newConverter.point(0, 0);
43224
- svgAttributes.x = newX;
43225
- svgAttributes.y = newY;
41918
+ svgAttributes.x = x;
41919
+ svgAttributes.y = y;
43226
41920
  if (attributes.cx || attributes.cy) {
43227
- const { x: newCX, y: newCY } = newConverter.point(cx || 0, cy || 0);
43228
- svgAttributes.cx = newCX;
43229
- svgAttributes.cy = newCY;
41921
+ svgAttributes.cx = cx;
41922
+ svgAttributes.cy = cy;
43230
41923
  }
43231
41924
  if (attributes.rx || attributes.ry || attributes.r) {
43232
- const { width: newRX, height: newRY } = newConverter.size(rx || 0, ry || 0);
43233
- svgAttributes.rx = newRX;
43234
- svgAttributes.ry = newRY;
41925
+ svgAttributes.rx = rx;
41926
+ svgAttributes.ry = ry;
43235
41927
  }
43236
41928
  if (attributes.x1 || attributes.y1) {
43237
- const { x: newX1, y: newY1 } = newConverter.point(x1 || 0, y1 || 0);
43238
- svgAttributes.x1 = newX1;
43239
- svgAttributes.y1 = newY1;
41929
+ svgAttributes.x1 = x1;
41930
+ svgAttributes.y1 = y1;
43240
41931
  }
43241
41932
  if (attributes.x2 || attributes.y2) {
43242
- const { x: newX2, y: newY2 } = newConverter.point(x2 || 0, y2 || 0);
43243
- svgAttributes.x2 = newX2;
43244
- svgAttributes.y2 = newY2;
41933
+ svgAttributes.x2 = x2;
41934
+ svgAttributes.y2 = y2;
43245
41935
  }
43246
41936
  if (attributes.width || attributes.height) {
43247
- const size = newConverter.size(width !== null && width !== void 0 ? width : inherited.width, height !== null && height !== void 0 ? height : inherited.height);
43248
- svgAttributes.width = size.width;
43249
- svgAttributes.height = size.height;
41937
+ svgAttributes.width = width !== null && width !== void 0 ? width : inherited.width;
41938
+ svgAttributes.height = height !== null && height !== void 0 ? height : inherited.height;
43250
41939
  }
43251
- // We convert all the points from the path
43252
41940
  if (attributes.d) {
43253
- const { x: xOrigin, y: yOrigin } = newConverter.point(0, 0);
43254
- // these are the x and y coordinates relative to the svg space, therefore these values weren't parsed by any converter. Each instruction will left the cursor on new position
43255
- let currentX = 0;
43256
- let currentY = 0;
43257
- svgAttributes.d = (_g = attributes.d) === null || _g === void 0 ? void 0 : _g.replace(/(l|m|s|t|q|c|z|a|v|h)([0-9,e\s.-]*)/gi, (command) => {
43258
- var _a, _b;
43259
- const letter = (_a = command.match(/[a-z]/i)) === null || _a === void 0 ? void 0 : _a[0];
43260
- if ((letter === null || letter === void 0 ? void 0 : letter.toLocaleLowerCase()) === 'z')
43261
- return letter;
43262
- // const params = command.match(/([0-9e.-]+)/ig)?.filter(m => m !== '')//.map(v => parseFloat(v))
43263
- const params = (_b = command
43264
- .match(/(-?[0-9]+\.[0-9]+(e[+-]?[0-9]+)?)|(-?\.[0-9]+(e[+-]?[0-9]+)?)|(-?[0-9]+)/gi)) === null || _b === void 0 ? void 0 : _b.filter((m) => m !== ''); // .map(v => parseFloat(v))
43265
- if (!params)
43266
- return letter || '';
43267
- switch (letter === null || letter === void 0 ? void 0 : letter.toLocaleLowerCase()) {
43268
- case 'm':
43269
- case 'l': {
43270
- const groupedParams = groupBy(params, 2);
43271
- return groupedParams
43272
- .map((pair, pairIndex) => {
43273
- const [x, y] = pair;
43274
- const xReal = parseFloatValue(x, inherited.width) || 0;
43275
- const yReal = parseFloatValue(y, innerHeight) || 0;
43276
- if (letter === letter.toLowerCase()) {
43277
- currentX += xReal;
43278
- currentY += yReal;
43279
- }
43280
- else {
43281
- currentX = xReal;
43282
- currentY = yReal;
43283
- }
43284
- const point = newConverter.point(currentX, currentY);
43285
- return ((pairIndex > 0 || letter.toUpperCase() === 'L' ? 'L' : 'M') +
43286
- [point.x - xOrigin, point.y - yOrigin].join(','));
43287
- })
43288
- .join(' ');
43289
- }
43290
- case 'v': {
43291
- return params
43292
- .map((value) => {
43293
- const coord = parseFloatValue(value) || 0;
43294
- if (letter === letter.toLowerCase()) {
43295
- currentY += coord;
43296
- }
43297
- else {
43298
- currentY = coord;
43299
- }
43300
- const point = newConverter.point(currentX, currentY);
43301
- // we can't use 'v' as the final command because rotations might require a different command after the path parsing
43302
- // for instance, a 90 degree rotation would turn a 'v' into an 'h' command
43303
- return `L${point.x - xOrigin} ${point.y - yOrigin}`;
43304
- })
43305
- .join(' ');
43306
- }
43307
- case 'h': {
43308
- return params
43309
- .map((value) => {
43310
- const coord = parseFloatValue(value) || 0;
43311
- if (letter === letter.toLowerCase()) {
43312
- currentX += coord;
43313
- }
43314
- else {
43315
- currentX = coord;
43316
- }
43317
- const point = newConverter.point(currentX, currentY);
43318
- // we can't use 'h' as the final command because rotations might require a different command after the path parsing
43319
- // for instance, a 90 degree rotation would turn a 'h' into an 'v' command
43320
- return `L${point.x - xOrigin} ${point.y - yOrigin}`;
43321
- })
43322
- .join(' ');
43323
- }
43324
- case 'a': {
43325
- const groupedParams = groupBy(params, 7);
43326
- return groupedParams
43327
- .map((p) => {
43328
- const [rxPixel, ryPixel, xAxisRotation = '0', largeArc = '0', sweepFlag = '0', xPixel, yPixel,] = p;
43329
- const realRx = parseFloatValue(rxPixel, inherited.width) || 0;
43330
- const realRy = parseFloatValue(ryPixel, inherited.height) || 0;
43331
- const realX = parseFloatValue(xPixel, inherited.width) || 0;
43332
- const realY = parseFloatValue(yPixel, inherited.height) || 0;
43333
- const { width: newRx, height: newRy } = newConverter.size(realRx, realRy);
43334
- let point;
43335
- if (letter === letter.toLowerCase()) {
43336
- currentX += realX;
43337
- currentY += realY;
43338
- }
43339
- else {
43340
- currentX = realX;
43341
- currentY = realY;
43342
- }
43343
- point = newConverter.point(currentX, currentY);
43344
- // transformations over x and y axis might change the page coord direction
43345
- const { width: xDirection, height: yDirection } = newConverter.size(1, 1);
43346
- // -1 is the default direction
43347
- const pageYDirection = -1 * Math.sign(xDirection * yDirection);
43348
- const oppositeSweepFlag = sweepFlag === '0' ? '1' : '0';
43349
- return [
43350
- letter.toUpperCase(),
43351
- newRx,
43352
- newRy,
43353
- xAxisRotation,
43354
- largeArc,
43355
- pageYDirection === -1 ? oppositeSweepFlag : sweepFlag,
43356
- point.x - xOrigin,
43357
- point.y - yOrigin,
43358
- ].join(' ');
43359
- })
43360
- .join(' ');
43361
- }
43362
- case 'c': {
43363
- const groupedParams = groupBy(params, 6);
43364
- const result = groupedParams
43365
- .map(([c1X, c1Y, c2X, c2Y, xString, yString]) => [
43366
- parseFloatValue(c1X, inherited.width) || 0,
43367
- parseFloatValue(c1Y, inherited.height) || 0,
43368
- parseFloatValue(c2X, inherited.width) || 0,
43369
- parseFloatValue(c2Y, inherited.height) || 0,
43370
- parseFloatValue(xString, inherited.width) || 0,
43371
- parseFloatValue(yString, inherited.height) || 0,
43372
- ])
43373
- .map(([c1X, c1Y, c2X, c2Y, xReal, yReal]) => {
43374
- let controlPoint1X;
43375
- let controlPoint1Y;
43376
- let controlPoint2X;
43377
- let controlPoint2Y;
43378
- if (letter === letter.toLowerCase()) {
43379
- controlPoint1X = currentX + c1X;
43380
- controlPoint1Y = currentY + c1Y;
43381
- controlPoint2X = currentX + c2X;
43382
- controlPoint2Y = currentY + c2Y;
43383
- currentX += xReal;
43384
- currentY += yReal;
43385
- }
43386
- else {
43387
- controlPoint1X = c1X;
43388
- controlPoint1Y = c1Y;
43389
- controlPoint2X = c2X;
43390
- controlPoint2Y = c2Y;
43391
- currentX = xReal;
43392
- currentY = yReal;
43393
- }
43394
- const controlPoint1 = newConverter.point(controlPoint1X, controlPoint1Y);
43395
- const controlPoint2 = newConverter.point(controlPoint2X, controlPoint2Y);
43396
- const point = newConverter.point(currentX, currentY);
43397
- return [
43398
- controlPoint1.x - xOrigin,
43399
- controlPoint1.y - yOrigin,
43400
- controlPoint2.x - xOrigin,
43401
- controlPoint2.y - yOrigin,
43402
- point.x - xOrigin,
43403
- point.y - yOrigin,
43404
- ].join(',');
43405
- })
43406
- .join(' ');
43407
- return (letter === null || letter === void 0 ? void 0 : letter.toUpperCase()) + '' + result;
43408
- }
43409
- case 's': {
43410
- const groupedParams = groupBy(params, 4);
43411
- const result = groupedParams
43412
- // the control point 1 is omitted because it's the reflection of c2
43413
- .map(([c2X, c2Y, xString, yString]) => [
43414
- parseFloatValue(c2X, inherited.width) || 0,
43415
- parseFloatValue(c2Y, inherited.height) || 0,
43416
- parseFloatValue(xString, inherited.width) || 0,
43417
- parseFloatValue(yString, inherited.height) || 0,
43418
- ])
43419
- .map(([c2X, c2Y, xReal, yReal]) => {
43420
- let controlPoint2X;
43421
- let controlPoint2Y;
43422
- if (letter === letter.toLowerCase()) {
43423
- controlPoint2X = currentX + c2X;
43424
- controlPoint2Y = currentY + c2Y;
43425
- currentX += xReal;
43426
- currentY += yReal;
43427
- }
43428
- else {
43429
- controlPoint2X = c2X;
43430
- controlPoint2Y = c2Y;
43431
- currentX = xReal;
43432
- currentY = yReal;
43433
- }
43434
- const controlPoint2 = newConverter.point(controlPoint2X, controlPoint2Y);
43435
- const point = newConverter.point(currentX, currentY);
43436
- return [
43437
- controlPoint2.x - xOrigin,
43438
- controlPoint2.y - yOrigin,
43439
- point.x - xOrigin,
43440
- point.y - yOrigin,
43441
- ].join(',');
43442
- })
43443
- .join(' ');
43444
- return (letter === null || letter === void 0 ? void 0 : letter.toUpperCase()) + '' + result;
43445
- }
43446
- default: {
43447
- const groupedParams = groupBy(params, 2);
43448
- const result = groupedParams
43449
- .map(([xString, yString]) => [
43450
- parseFloatValue(xString, inherited.width) || 0,
43451
- parseFloatValue(yString, inherited.height) || 0,
43452
- ])
43453
- .map(([xReal, yReal]) => {
43454
- if (letter === letter.toLowerCase()) {
43455
- currentX += xReal;
43456
- currentY += yReal;
43457
- }
43458
- else {
43459
- currentX = xReal;
43460
- currentY = yReal;
43461
- }
43462
- const point = newConverter.point(currentX, currentY);
43463
- return [point.x - xOrigin, point.y - yOrigin].join(',');
43464
- })
43465
- .join(' ');
43466
- return (letter === null || letter === void 0 ? void 0 : letter.toUpperCase()) + '' + result;
43467
- }
43468
- }
43469
- });
43470
- }
43471
- if (attributes.viewBox) {
43472
- const viewBox = parseViewBox(attributes.viewBox);
43473
- const size = {
43474
- width: width || inherited.viewBox.width,
43475
- height: height || inherited.viewBox.height,
43476
- };
43477
- const localConverter = getConverterWithAspectRatio(size, viewBox, attributes.preserveAspectRatio);
43478
- const oldConverter = newConverter;
43479
- newConverter = {
43480
- point: (px, py) => {
43481
- const { x: localX, y: localY } = localConverter.point(px, py);
43482
- return oldConverter.point(localX, localY);
43483
- },
43484
- size: (w, h) => {
43485
- const { width: localWidth, height: localHeight } = localConverter.size(w, h);
43486
- return oldConverter.size(localWidth, localHeight);
43487
- },
43488
- };
41941
+ newMatrix = combineTransformation(newMatrix, 'scale', [1, -1]);
41942
+ svgAttributes.d = attributes.d;
43489
41943
  }
43490
- // apply the converter only when there's a local fontSize instruction
43491
41944
  if (fontSizeRaw && newInherited.fontSize) {
43492
- newInherited.fontSize = newConverter.size(1, newInherited.fontSize).height;
41945
+ newInherited.fontSize = newInherited.fontSize;
43493
41946
  }
43494
41947
  if (newInherited.fontFamily) {
43495
41948
  // Handle complex fontFamily like `"Linux Libertine O", serif`
@@ -43498,43 +41951,13 @@ const parseAttributes = (element, inherited, converter) => {
43498
41951
  newInherited.fontFamily = inner[1] || inner[2];
43499
41952
  }
43500
41953
  if (newInherited.strokeWidth) {
43501
- const result = newConverter.size(newInherited.strokeWidth, newInherited.strokeWidth);
43502
- svgAttributes.strokeWidth = Math.max(Math.min(Math.abs(result.width), Math.abs(result.height)), 1);
41954
+ svgAttributes.strokeWidth = newInherited.strokeWidth;
43503
41955
  }
43504
41956
  return {
43505
41957
  inherited: newInherited,
43506
41958
  svgAttributes,
43507
- converter: newConverter,
43508
41959
  tagName: element.tagName,
43509
- };
43510
- };
43511
- const getConverter = (box, viewBox) => {
43512
- const { width, height } = box;
43513
- const { x: xMin, y: yMin, width: viewWidth, height: viewHeight } = viewBox;
43514
- const converter = {
43515
- point: (xReal, yReal) => ({
43516
- x: ((xReal - xMin) / viewWidth) * (width || 0),
43517
- y: ((yReal - yMin) / viewHeight) * (height || 0),
43518
- }),
43519
- size: (wReal, hReal) => ({
43520
- width: (wReal / viewWidth) * (width || 0),
43521
- height: (hReal / viewHeight) * (height || 0),
43522
- }),
43523
- };
43524
- return converter;
43525
- };
43526
- const getConverterWithAspectRatio = (size, viewBox, preserveAspectRatio) => {
43527
- // explanation about how the svg attributes applies transformations to the child elements
43528
- // https://www.w3.org/TR/SVG/coords.html#ComputingAViewportsTransform
43529
- const { x, y, width, height } = getFittingRectangle(viewBox.width, viewBox.height, size.width, size.height, preserveAspectRatio);
43530
- const ratioConverter = getConverter({ width, height }, viewBox);
43531
- // We translate the drawing in the page when the aspect ratio is different, according to the preserveAspectRatio instructions.
43532
- return {
43533
- point: (xReal, yReal) => {
43534
- const P = ratioConverter.point(xReal, yReal);
43535
- return { x: P.x + x, y: P.y + y };
43536
- },
43537
- size: ratioConverter.size,
41960
+ matrix: newMatrix,
43538
41961
  };
43539
41962
  };
43540
41963
  const getFittingRectangle = (originalWidth, originalHeight, targetWidth, targetHeight, preserveAspectRatio) => {
@@ -43572,16 +41995,62 @@ const getFittingRectangle = (originalWidth, originalHeight, targetWidth, targetH
43572
41995
  })();
43573
41996
  return { x, y, width, height };
43574
41997
  };
43575
- const parseHTMLNode = (node, inherited, converter) => {
41998
+ const getAspectRatioTransformation = (matrix, originalWidth, originalHeight, targetWidth, targetHeight, preserveAspectRatio) => {
41999
+ const scaleX = targetWidth / originalWidth;
42000
+ const scaleY = targetHeight / originalHeight;
42001
+ const boxScale = combineTransformation(matrix, 'scale', [
42002
+ scaleX,
42003
+ scaleY
42004
+ ]);
42005
+ if (preserveAspectRatio === 'none') {
42006
+ return {
42007
+ clipBox: boxScale,
42008
+ content: boxScale
42009
+ };
42010
+ }
42011
+ // TODO: the following code works for the 'meet' param but not for the 'slice'
42012
+ const scale = targetWidth > targetHeight ? scaleY : scaleX;
42013
+ const dx = targetWidth - (originalWidth * scale);
42014
+ const dy = targetHeight - (originalHeight * scale);
42015
+ const [x, y] = (() => {
42016
+ switch (preserveAspectRatio) {
42017
+ case 'xMinYMin':
42018
+ return [0, 0];
42019
+ case 'xMidYMin':
42020
+ return [dx / 2, 0];
42021
+ case 'xMaxYMin':
42022
+ return [dx, dy / 2];
42023
+ case 'xMinYMid':
42024
+ return [0, dy];
42025
+ case 'xMaxYMid':
42026
+ return [dx, dy / 2];
42027
+ case 'xMinYMax':
42028
+ return [0, dy];
42029
+ case 'xMidYMax':
42030
+ return [dx / 2, dy];
42031
+ case 'xMaxYMax':
42032
+ return [dx, dy];
42033
+ case 'xMidYMid':
42034
+ default:
42035
+ return [dx / 2, dy / 2];
42036
+ }
42037
+ })();
42038
+ const contentTransform = combineTransformation(combineTransformation(matrix, 'translate', [x, y]), 'scale', [scale]);
42039
+ return {
42040
+ clipBox: boxScale,
42041
+ content: contentTransform
42042
+ };
42043
+ };
42044
+ const parseHTMLNode = (node, inherited, matrix, clipSpaces) => {
43576
42045
  if (node.nodeType === index.NodeType.COMMENT_NODE)
43577
42046
  return [];
43578
42047
  else if (node.nodeType === index.NodeType.TEXT_NODE)
43579
42048
  return [];
43580
42049
  else if (node.tagName === 'g') {
43581
- return parseGroupNode(node, inherited, converter);
42050
+ return parseGroupNode(node, inherited, matrix, clipSpaces);
43582
42051
  }
43583
42052
  else if (node.tagName === 'svg') {
43584
- return parseSvgNode(node, inherited, converter);
42053
+ return parseSvgNode(node, inherited, matrix, clipSpaces);
43585
42054
  }
43586
42055
  else {
43587
42056
  if (node.tagName === 'polygon') {
@@ -43589,36 +42058,69 @@ const parseHTMLNode = (node, inherited, converter) => {
43589
42058
  node.attributes.d = `M${node.attributes.points}Z`;
43590
42059
  delete node.attributes.points;
43591
42060
  }
43592
- const attributes = parseAttributes(node, inherited, converter);
43593
- const svgAttributes = Object.assign(Object.assign({}, attributes.inherited), attributes.svgAttributes);
42061
+ const attributes = parseAttributes(node, inherited, matrix);
42062
+ const svgAttributes = {
42063
+ ...attributes.inherited,
42064
+ ...attributes.svgAttributes,
42065
+ matrix: attributes.matrix,
42066
+ clipSpaces
42067
+ };
43594
42068
  Object.assign(node, { svgAttributes });
43595
42069
  return [node];
43596
42070
  }
43597
42071
  };
43598
- const parseSvgNode = (node, inherited, converter) => {
42072
+ const parseSvgNode = (node, inherited, matrix, clipSpaces) => {
43599
42073
  var _a, _b;
43600
42074
  // if the width/height aren't set, the svg will have the same dimension as the current drawing space
43601
42075
  (_a = node.attributes.width) !== null && _a !== void 0 ? _a : node.setAttribute('width', inherited.viewBox.width + '');
43602
42076
  (_b = node.attributes.height) !== null && _b !== void 0 ? _b : node.setAttribute('height', inherited.viewBox.height + '');
43603
- const attributes = parseAttributes(node, inherited, converter);
42077
+ const attributes = parseAttributes(node, inherited, matrix);
43604
42078
  const result = [];
43605
42079
  const viewBox = node.attributes.viewBox
43606
42080
  ? parseViewBox(node.attributes.viewBox)
43607
42081
  : node.attributes.width && node.attributes.height
43608
42082
  ? parseViewBox(`0 0 ${node.attributes.width} ${node.attributes.height}`)
43609
42083
  : inherited.viewBox;
43610
- const svgRect = new Rectangle(new Point(attributes.converter.point(viewBox.x, viewBox.y)), new Point(attributes.converter.point(viewBox.x + viewBox.width, viewBox.y + viewBox.height)));
42084
+ const x = parseFloat(node.attributes.x) || 0;
42085
+ const y = parseFloat(node.attributes.y) || 0;
42086
+ let newMatrix = combineTransformation(matrix, 'translate', [x, y]);
42087
+ const { clipBox: clipBoxTransform, content: contentTransform } = getAspectRatioTransformation(newMatrix, viewBox.width, viewBox.height, parseFloat(node.attributes.width), parseFloat(node.attributes.height), node.attributes.preserveAspectRatio || 'xMidYMid');
42088
+ const topLeft = applyTransformation(clipBoxTransform, {
42089
+ x: 0,
42090
+ y: 0,
42091
+ });
42092
+ const topRight = applyTransformation(clipBoxTransform, {
42093
+ x: viewBox.width,
42094
+ y: 0,
42095
+ });
42096
+ const bottomRight = applyTransformation(clipBoxTransform, {
42097
+ x: viewBox.width,
42098
+ y: -viewBox.height,
42099
+ });
42100
+ const bottomLeft = applyTransformation(clipBoxTransform, {
42101
+ x: 0,
42102
+ y: -viewBox.height,
42103
+ });
42104
+ const baseClipSpace = {
42105
+ topLeft,
42106
+ topRight,
42107
+ bottomRight,
42108
+ bottomLeft
42109
+ };
42110
+ // TODO: maybe this is the correct transformation
42111
+ // newMatrix = combineTransformation(newMatrix, 'translate', [-baseClipSpace.xMin, -baseClipSpace.yMin])
42112
+ newMatrix = combineTransformation(contentTransform, 'translate', [-viewBox.x, -viewBox.y]);
43611
42113
  node.childNodes.forEach((child) => {
43612
- const parsedNodes = parseHTMLNode(child, Object.assign(Object.assign({}, attributes.inherited), { viewBox }), attributes.converter).map((el) => cropSvgElement(svgRect, el));
42114
+ const parsedNodes = parseHTMLNode(child, { ...attributes.inherited, viewBox }, newMatrix, [...clipSpaces, baseClipSpace]);
43613
42115
  result.push(...parsedNodes);
43614
42116
  });
43615
42117
  return result;
43616
42118
  };
43617
- const parseGroupNode = (node, inherited, converter) => {
43618
- const attributes = parseAttributes(node, inherited, converter);
42119
+ const parseGroupNode = (node, inherited, matrix, clipSpaces) => {
42120
+ const attributes = parseAttributes(node, inherited, matrix);
43619
42121
  const result = [];
43620
42122
  node.childNodes.forEach((child) => {
43621
- result.push(...parseHTMLNode(child, attributes.inherited, attributes.converter));
42123
+ result.push(...parseHTMLNode(child, attributes.inherited, attributes.matrix, clipSpaces));
43622
42124
  });
43623
42125
  return result;
43624
42126
  };
@@ -43645,22 +42147,21 @@ const parseViewBox = (viewBox) => {
43645
42147
  height: heightViewBox,
43646
42148
  };
43647
42149
  };
43648
- const parse$1 = (svg, { width, height, x, y, fontSize }, size, converter) => {
42150
+ const parse$1 = (svg, { width, height, fontSize }, size, matrix) => {
43649
42151
  const htmlElement = index.parse(svg).firstChild;
43650
42152
  if (width)
43651
42153
  htmlElement.setAttribute('width', width + '');
43652
42154
  if (height)
43653
42155
  htmlElement.setAttribute('height', height + '');
43654
- if (x !== undefined)
43655
- htmlElement.setAttribute('x', x + '');
43656
- if (y !== undefined)
43657
- htmlElement.setAttribute('y', size.height - y + '');
43658
42156
  if (fontSize)
43659
42157
  htmlElement.setAttribute('font-size', fontSize + '');
43660
42158
  // TODO: what should be the default viewBox?
43661
- return parseHTMLNode(htmlElement, Object.assign(Object.assign({}, size), { viewBox: parseViewBox(htmlElement.attributes.viewBox || '0 0 1 1') }), converter);
42159
+ return parseHTMLNode(htmlElement, {
42160
+ ...size,
42161
+ viewBox: parseViewBox(htmlElement.attributes.viewBox || '0 0 1 1'),
42162
+ }, matrix, []);
43662
42163
  };
43663
- const drawSvg = (page, svg, options) => __awaiter(void 0, void 0, void 0, function* () {
42164
+ const drawSvg = async (page, svg, options) => {
43664
42165
  if (!svg)
43665
42166
  return;
43666
42167
  const size = page.getSize();
@@ -43685,19 +42186,42 @@ const drawSvg = (page, svg, options) => __awaiter(void 0, void 0, void 0, functi
43685
42186
  .map(([key, val]) => `${key}:${val};`)
43686
42187
  .join(''));
43687
42188
  }
43688
- // The y axis of the page is reverted
43689
- const defaultConverter = {
43690
- point: (xP, yP) => ({ x: xP, y: size.height - yP }),
43691
- size: (w, h) => ({ width: w, height: h }),
43692
- };
42189
+ const baseTransformation = [1, 0, 0, 1, options.x || 0, options.y || 0];
43693
42190
  const runners = runnersToPage(page, options);
43694
- const elements = parse$1(firstChild.outerHTML, options, size, defaultConverter);
43695
- yield elements.reduce((prev, elt) => __awaiter(void 0, void 0, void 0, function* () {
42191
+ const elements = parse$1(firstChild.outerHTML, options, size, baseTransformation);
42192
+ await elements.reduce(async (prev, elt) => {
43696
42193
  var _a;
43697
- yield prev;
42194
+ await prev;
42195
+ // uncomment these lines to draw the clipSpaces
42196
+ // elt.svgAttributes.clipSpaces.forEach(space => {
42197
+ // page.drawLine({
42198
+ // start: space.topLeft,
42199
+ // end: space.topRight,
42200
+ // color: parseColor('#000000')?.rgb,
42201
+ // thickness: 1
42202
+ // })
42203
+ // page.drawLine({
42204
+ // start: space.topRight,
42205
+ // end: space.bottomRight,
42206
+ // color: parseColor('#000000')?.rgb,
42207
+ // thickness: 1
42208
+ // })
42209
+ // page.drawLine({
42210
+ // start: space.bottomRight,
42211
+ // end: space.bottomLeft,
42212
+ // color: parseColor('#000000')?.rgb,
42213
+ // thickness: 1
42214
+ // })
42215
+ // page.drawLine({
42216
+ // start: space.bottomLeft,
42217
+ // end: space.topLeft,
42218
+ // color: parseColor('#000000')?.rgb,
42219
+ // thickness: 1
42220
+ // })
42221
+ // })
43698
42222
  return (_a = runners[elt.tagName]) === null || _a === void 0 ? void 0 : _a.call(runners, elt);
43699
- }), Promise.resolve());
43700
- });
42223
+ }, Promise.resolve());
42224
+ };
43701
42225
 
43702
42226
  /**
43703
42227
  * Represents a single page of a [[PDFDocument]].
@@ -44554,6 +43078,8 @@ class PDFPage {
44554
43078
  y: (_f = options.y) !== null && _f !== void 0 ? _f : this.y,
44555
43079
  lineHeight: (_g = options.lineHeight) !== null && _g !== void 0 ? _g : this.lineHeight,
44556
43080
  graphicsState: graphicsStateKey,
43081
+ matrix: options.matrix,
43082
+ clipSpaces: options.clipSpaces
44557
43083
  }));
44558
43084
  if (options.font) {
44559
43085
  if (oldFont)
@@ -44615,6 +43141,8 @@ class PDFPage {
44615
43141
  xSkew: (_f = options.xSkew) !== null && _f !== void 0 ? _f : degrees(0),
44616
43142
  ySkew: (_g = options.ySkew) !== null && _g !== void 0 ? _g : degrees(0),
44617
43143
  graphicsState: graphicsStateKey,
43144
+ matrix: options.matrix,
43145
+ clipSpaces: options.clipSpaces
44618
43146
  }));
44619
43147
  }
44620
43148
  /**
@@ -44773,6 +43301,8 @@ class PDFPage {
44773
43301
  borderLineCap: (_j = options.borderLineCap) !== null && _j !== void 0 ? _j : undefined,
44774
43302
  graphicsState: graphicsStateKey,
44775
43303
  fillRule: options.fillRule,
43304
+ matrix: options.matrix,
43305
+ clipSpaces: options.clipSpaces
44776
43306
  }));
44777
43307
  }
44778
43308
  /**
@@ -44826,6 +43356,8 @@ class PDFPage {
44826
43356
  dashPhase: (_d = options.dashPhase) !== null && _d !== void 0 ? _d : undefined,
44827
43357
  lineCap: (_e = options.lineCap) !== null && _e !== void 0 ? _e : undefined,
44828
43358
  graphicsState: graphicsStateKey,
43359
+ matrix: options.matrix,
43360
+ clipSpaces: options.clipSpaces,
44829
43361
  }));
44830
43362
  }
44831
43363
  /**
@@ -44896,6 +43428,8 @@ class PDFPage {
44896
43428
  borderDashPhase: (_m = options.borderDashPhase) !== null && _m !== void 0 ? _m : undefined,
44897
43429
  graphicsState: graphicsStateKey,
44898
43430
  borderLineCap: (_o = options.borderLineCap) !== null && _o !== void 0 ? _o : undefined,
43431
+ matrix: options.matrix,
43432
+ clipSpaces: options.clipSpaces,
44899
43433
  }));
44900
43434
  }
44901
43435
  /**
@@ -44920,7 +43454,7 @@ class PDFPage {
44920
43454
  drawSquare(options = {}) {
44921
43455
  const { size } = options;
44922
43456
  assertOrUndefined(size, 'size', ['number']);
44923
- this.drawRectangle(Object.assign(Object.assign({}, options), { width: size, height: size }));
43457
+ this.drawRectangle({ ...options, width: size, height: size });
44924
43458
  }
44925
43459
  /**
44926
43460
  * Draw an ellipse on this page. For example:
@@ -44985,6 +43519,8 @@ class PDFPage {
44985
43519
  borderDashPhase: (_k = options.borderDashPhase) !== null && _k !== void 0 ? _k : undefined,
44986
43520
  borderLineCap: (_l = options.borderLineCap) !== null && _l !== void 0 ? _l : undefined,
44987
43521
  graphicsState: graphicsStateKey,
43522
+ matrix: options.matrix,
43523
+ clipSpaces: options.clipSpaces,
44988
43524
  }));
44989
43525
  }
44990
43526
  /**
@@ -45008,7 +43544,7 @@ class PDFPage {
45008
43544
  drawCircle(options = {}) {
45009
43545
  const { size = 100 } = options;
45010
43546
  assertOrUndefined(size, 'size', ['number']);
45011
- this.drawEllipse(Object.assign(Object.assign({}, options), { xScale: size, yScale: size }));
43547
+ this.drawEllipse({ ...options, xScale: size, yScale: size });
45012
43548
  }
45013
43549
  setOrEmbedFont(font) {
45014
43550
  const oldFont = this.font;
@@ -45032,21 +43568,19 @@ class PDFPage {
45032
43568
  * @param svg The SVG to be drawn.
45033
43569
  * @param options The options to be used when drawing the SVG.
45034
43570
  */
45035
- drawSvg(svg, options = {}) {
43571
+ async drawSvg(svg, options = {}) {
45036
43572
  var _a, _b;
45037
- return __awaiter(this, void 0, void 0, function* () {
45038
- assertIs(svg, 'svg', ['string']);
45039
- assertOrUndefined(options.x, 'options.x', ['number']);
45040
- assertOrUndefined(options.y, 'options.y', ['number']);
45041
- assertOrUndefined(options.width, 'options.width', ['number']);
45042
- assertOrUndefined(options.height, 'options.height', ['number']);
45043
- yield drawSvg(this, svg, {
45044
- x: (_a = options.x) !== null && _a !== void 0 ? _a : this.x,
45045
- y: (_b = options.y) !== null && _b !== void 0 ? _b : this.y,
45046
- fonts: options.fonts,
45047
- width: options.width,
45048
- height: options.height,
45049
- });
43573
+ assertIs(svg, 'svg', ['string']);
43574
+ assertOrUndefined(options.x, 'options.x', ['number']);
43575
+ assertOrUndefined(options.y, 'options.y', ['number']);
43576
+ assertOrUndefined(options.width, 'options.width', ['number']);
43577
+ assertOrUndefined(options.height, 'options.height', ['number']);
43578
+ await drawSvg(this, svg, {
43579
+ x: (_a = options.x) !== null && _a !== void 0 ? _a : this.x,
43580
+ y: (_b = options.y) !== null && _b !== void 0 ? _b : this.y,
43581
+ fonts: options.fonts,
43582
+ width: options.width,
43583
+ height: options.height,
45050
43584
  });
45051
43585
  }
45052
43586
  getFont() {