@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
package/dist/pdf-lib.js CHANGED
@@ -16049,13 +16049,22 @@
16049
16049
  return PDFRawStream.of(this.obj(dict), typedArrayFor(contents));
16050
16050
  }
16051
16051
  flateStream(contents, dict = {}) {
16052
- return this.stream(pako_1$1.deflate(typedArrayFor(contents)), Object.assign(Object.assign({}, dict), { Filter: 'FlateDecode' }));
16052
+ return this.stream(pako_1$1.deflate(typedArrayFor(contents)), {
16053
+ ...dict,
16054
+ Filter: 'FlateDecode',
16055
+ });
16053
16056
  }
16054
16057
  contentStream(operators, dict = {}) {
16055
16058
  return PDFContentStream.of(this.obj(dict), operators);
16056
16059
  }
16057
16060
  formXObject(operators, dict = {}) {
16058
- 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' }));
16061
+ return this.contentStream(operators, {
16062
+ BBox: this.obj([0, 0, 0, 0]),
16063
+ Matrix: this.obj([1, 0, 0, 1, 0, 0]),
16064
+ ...dict,
16065
+ Type: 'XObject',
16066
+ Subtype: 'Form',
16067
+ });
16059
16068
  }
16060
16069
  /*
16061
16070
  * Reference to PDFContentStream that contains a single PDFOperator: `q`.
@@ -16390,43 +16399,6 @@
16390
16399
  }
16391
16400
  PDFObjectCopier.for = (src, dest) => new PDFObjectCopier(src, dest);
16392
16401
 
16393
- /*! *****************************************************************************
16394
- Copyright (c) Microsoft Corporation.
16395
-
16396
- Permission to use, copy, modify, and/or distribute this software for any
16397
- purpose with or without fee is hereby granted.
16398
-
16399
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
16400
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
16401
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16402
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16403
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16404
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16405
- PERFORMANCE OF THIS SOFTWARE.
16406
- ***************************************************************************** */
16407
-
16408
- function __rest(s, e) {
16409
- var t = {};
16410
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
16411
- t[p] = s[p];
16412
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
16413
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
16414
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
16415
- t[p[i]] = s[p[i]];
16416
- }
16417
- return t;
16418
- }
16419
-
16420
- function __awaiter(thisArg, _arguments, P, generator) {
16421
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
16422
- return new (P || (P = Promise))(function (resolve, reject) {
16423
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16424
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16425
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
16426
- step((generator = generator.apply(thisArg, _arguments || [])).next());
16427
- });
16428
- }
16429
-
16430
16402
  /**
16431
16403
  * Entries should be added using the [[addEntry]] and [[addDeletedEntry]]
16432
16404
  * methods **in order of ascending object number**.
@@ -16672,52 +16644,50 @@
16672
16644
  this.context = context;
16673
16645
  this.objectsPerTick = objectsPerTick;
16674
16646
  }
16675
- serializeToBuffer() {
16676
- return __awaiter(this, void 0, void 0, function* () {
16677
- const { size, header, indirectObjects, xref, trailerDict, trailer } = yield this.computeBufferSize();
16678
- let offset = 0;
16679
- const buffer = new Uint8Array(size);
16680
- offset += header.copyBytesInto(buffer, offset);
16647
+ async serializeToBuffer() {
16648
+ const { size, header, indirectObjects, xref, trailerDict, trailer } = await this.computeBufferSize();
16649
+ let offset = 0;
16650
+ const buffer = new Uint8Array(size);
16651
+ offset += header.copyBytesInto(buffer, offset);
16652
+ buffer[offset++] = CharCodes$1.Newline;
16653
+ buffer[offset++] = CharCodes$1.Newline;
16654
+ for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
16655
+ const [ref, object] = indirectObjects[idx];
16656
+ const objectNumber = String(ref.objectNumber);
16657
+ offset += copyStringIntoBuffer(objectNumber, buffer, offset);
16658
+ buffer[offset++] = CharCodes$1.Space;
16659
+ const generationNumber = String(ref.generationNumber);
16660
+ offset += copyStringIntoBuffer(generationNumber, buffer, offset);
16661
+ buffer[offset++] = CharCodes$1.Space;
16662
+ buffer[offset++] = CharCodes$1.o;
16663
+ buffer[offset++] = CharCodes$1.b;
16664
+ buffer[offset++] = CharCodes$1.j;
16681
16665
  buffer[offset++] = CharCodes$1.Newline;
16666
+ offset += object.copyBytesInto(buffer, offset);
16682
16667
  buffer[offset++] = CharCodes$1.Newline;
16683
- for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
16684
- const [ref, object] = indirectObjects[idx];
16685
- const objectNumber = String(ref.objectNumber);
16686
- offset += copyStringIntoBuffer(objectNumber, buffer, offset);
16687
- buffer[offset++] = CharCodes$1.Space;
16688
- const generationNumber = String(ref.generationNumber);
16689
- offset += copyStringIntoBuffer(generationNumber, buffer, offset);
16690
- buffer[offset++] = CharCodes$1.Space;
16691
- buffer[offset++] = CharCodes$1.o;
16692
- buffer[offset++] = CharCodes$1.b;
16693
- buffer[offset++] = CharCodes$1.j;
16694
- buffer[offset++] = CharCodes$1.Newline;
16695
- offset += object.copyBytesInto(buffer, offset);
16696
- buffer[offset++] = CharCodes$1.Newline;
16697
- buffer[offset++] = CharCodes$1.e;
16698
- buffer[offset++] = CharCodes$1.n;
16699
- buffer[offset++] = CharCodes$1.d;
16700
- buffer[offset++] = CharCodes$1.o;
16701
- buffer[offset++] = CharCodes$1.b;
16702
- buffer[offset++] = CharCodes$1.j;
16703
- buffer[offset++] = CharCodes$1.Newline;
16704
- buffer[offset++] = CharCodes$1.Newline;
16705
- const n = object instanceof PDFObjectStream ? object.getObjectsCount() : 1;
16706
- if (this.shouldWaitForTick(n))
16707
- yield waitForTick();
16708
- }
16709
- if (xref) {
16710
- offset += xref.copyBytesInto(buffer, offset);
16711
- buffer[offset++] = CharCodes$1.Newline;
16712
- }
16713
- if (trailerDict) {
16714
- offset += trailerDict.copyBytesInto(buffer, offset);
16715
- buffer[offset++] = CharCodes$1.Newline;
16716
- buffer[offset++] = CharCodes$1.Newline;
16717
- }
16718
- offset += trailer.copyBytesInto(buffer, offset);
16719
- return buffer;
16720
- });
16668
+ buffer[offset++] = CharCodes$1.e;
16669
+ buffer[offset++] = CharCodes$1.n;
16670
+ buffer[offset++] = CharCodes$1.d;
16671
+ buffer[offset++] = CharCodes$1.o;
16672
+ buffer[offset++] = CharCodes$1.b;
16673
+ buffer[offset++] = CharCodes$1.j;
16674
+ buffer[offset++] = CharCodes$1.Newline;
16675
+ buffer[offset++] = CharCodes$1.Newline;
16676
+ const n = object instanceof PDFObjectStream ? object.getObjectsCount() : 1;
16677
+ if (this.shouldWaitForTick(n))
16678
+ await waitForTick();
16679
+ }
16680
+ if (xref) {
16681
+ offset += xref.copyBytesInto(buffer, offset);
16682
+ buffer[offset++] = CharCodes$1.Newline;
16683
+ }
16684
+ if (trailerDict) {
16685
+ offset += trailerDict.copyBytesInto(buffer, offset);
16686
+ buffer[offset++] = CharCodes$1.Newline;
16687
+ buffer[offset++] = CharCodes$1.Newline;
16688
+ }
16689
+ offset += trailer.copyBytesInto(buffer, offset);
16690
+ return buffer;
16721
16691
  }
16722
16692
  computeIndirectObjectSize([ref, object]) {
16723
16693
  const refSize = ref.sizeInBytes() + 3; // 'R' -> 'obj\n'
@@ -16733,28 +16703,26 @@
16733
16703
  ID: this.context.trailerInfo.ID,
16734
16704
  });
16735
16705
  }
16736
- computeBufferSize() {
16737
- return __awaiter(this, void 0, void 0, function* () {
16738
- const header = PDFHeader.forVersion(1, 7);
16739
- let size = header.sizeInBytes() + 2;
16740
- const xref = PDFCrossRefSection.create();
16741
- const indirectObjects = this.context.enumerateIndirectObjects();
16742
- for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
16743
- const indirectObject = indirectObjects[idx];
16744
- const [ref] = indirectObject;
16745
- xref.addEntry(ref, size);
16746
- size += this.computeIndirectObjectSize(indirectObject);
16747
- if (this.shouldWaitForTick(1))
16748
- yield waitForTick();
16749
- }
16750
- const xrefOffset = size;
16751
- size += xref.sizeInBytes() + 1; // '\n'
16752
- const trailerDict = PDFTrailerDict.of(this.createTrailerDict());
16753
- size += trailerDict.sizeInBytes() + 2; // '\n\n'
16754
- const trailer = PDFTrailer.forLastCrossRefSectionOffset(xrefOffset);
16755
- size += trailer.sizeInBytes();
16756
- return { size, header, indirectObjects, xref, trailerDict, trailer };
16757
- });
16706
+ async computeBufferSize() {
16707
+ const header = PDFHeader.forVersion(1, 7);
16708
+ let size = header.sizeInBytes() + 2;
16709
+ const xref = PDFCrossRefSection.create();
16710
+ const indirectObjects = this.context.enumerateIndirectObjects();
16711
+ for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
16712
+ const indirectObject = indirectObjects[idx];
16713
+ const [ref] = indirectObject;
16714
+ xref.addEntry(ref, size);
16715
+ size += this.computeIndirectObjectSize(indirectObject);
16716
+ if (this.shouldWaitForTick(1))
16717
+ await waitForTick();
16718
+ }
16719
+ const xrefOffset = size;
16720
+ size += xref.sizeInBytes() + 1; // '\n'
16721
+ const trailerDict = PDFTrailerDict.of(this.createTrailerDict());
16722
+ size += trailerDict.sizeInBytes() + 2; // '\n\n'
16723
+ const trailer = PDFTrailer.forLastCrossRefSectionOffset(xrefOffset);
16724
+ size += trailer.sizeInBytes();
16725
+ return { size, header, indirectObjects, xref, trailerDict, trailer };
16758
16726
  }
16759
16727
  }
16760
16728
  PDFWriter.forContext = (context, objectsPerTick) => new PDFWriter(context, objectsPerTick);
@@ -16959,63 +16927,61 @@
16959
16927
  this.encodeStreams = encodeStreams;
16960
16928
  this.objectsPerStream = objectsPerStream;
16961
16929
  }
16962
- computeBufferSize() {
16963
- return __awaiter(this, void 0, void 0, function* () {
16964
- let objectNumber = this.context.largestObjectNumber + 1;
16965
- const header = PDFHeader.forVersion(1, 7);
16966
- let size = header.sizeInBytes() + 2;
16967
- const xrefStream = PDFCrossRefStream.create(this.createTrailerDict(), this.encodeStreams);
16968
- const uncompressedObjects = [];
16969
- const compressedObjects = [];
16970
- const objectStreamRefs = [];
16971
- const indirectObjects = this.context.enumerateIndirectObjects();
16972
- for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
16973
- const indirectObject = indirectObjects[idx];
16974
- const [ref, object] = indirectObject;
16975
- const shouldNotCompress = ref === this.context.trailerInfo.Encrypt ||
16976
- object instanceof PDFStream ||
16977
- object instanceof PDFInvalidObject ||
16978
- ref.generationNumber !== 0;
16979
- if (shouldNotCompress) {
16980
- uncompressedObjects.push(indirectObject);
16981
- xrefStream.addUncompressedEntry(ref, size);
16982
- size += this.computeIndirectObjectSize(indirectObject);
16983
- if (this.shouldWaitForTick(1))
16984
- yield waitForTick();
16985
- }
16986
- else {
16987
- let chunk = last(compressedObjects);
16988
- let objectStreamRef = last(objectStreamRefs);
16989
- if (!chunk || chunk.length % this.objectsPerStream === 0) {
16990
- chunk = [];
16991
- compressedObjects.push(chunk);
16992
- objectStreamRef = PDFRef.of(objectNumber++);
16993
- objectStreamRefs.push(objectStreamRef);
16994
- }
16995
- xrefStream.addCompressedEntry(ref, objectStreamRef, chunk.length);
16996
- chunk.push(indirectObject);
16997
- }
16998
- }
16999
- for (let idx = 0, len = compressedObjects.length; idx < len; idx++) {
17000
- const chunk = compressedObjects[idx];
17001
- const ref = objectStreamRefs[idx];
17002
- const objectStream = PDFObjectStream.withContextAndObjects(this.context, chunk, this.encodeStreams);
16930
+ async computeBufferSize() {
16931
+ let objectNumber = this.context.largestObjectNumber + 1;
16932
+ const header = PDFHeader.forVersion(1, 7);
16933
+ let size = header.sizeInBytes() + 2;
16934
+ const xrefStream = PDFCrossRefStream.create(this.createTrailerDict(), this.encodeStreams);
16935
+ const uncompressedObjects = [];
16936
+ const compressedObjects = [];
16937
+ const objectStreamRefs = [];
16938
+ const indirectObjects = this.context.enumerateIndirectObjects();
16939
+ for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
16940
+ const indirectObject = indirectObjects[idx];
16941
+ const [ref, object] = indirectObject;
16942
+ const shouldNotCompress = ref === this.context.trailerInfo.Encrypt ||
16943
+ object instanceof PDFStream ||
16944
+ object instanceof PDFInvalidObject ||
16945
+ ref.generationNumber !== 0;
16946
+ if (shouldNotCompress) {
16947
+ uncompressedObjects.push(indirectObject);
17003
16948
  xrefStream.addUncompressedEntry(ref, size);
17004
- size += this.computeIndirectObjectSize([ref, objectStream]);
17005
- uncompressedObjects.push([ref, objectStream]);
17006
- if (this.shouldWaitForTick(chunk.length))
17007
- yield waitForTick();
17008
- }
17009
- const xrefStreamRef = PDFRef.of(objectNumber++);
17010
- xrefStream.dict.set(PDFName.of('Size'), PDFNumber.of(objectNumber));
17011
- xrefStream.addUncompressedEntry(xrefStreamRef, size);
17012
- const xrefOffset = size;
17013
- size += this.computeIndirectObjectSize([xrefStreamRef, xrefStream]);
17014
- uncompressedObjects.push([xrefStreamRef, xrefStream]);
17015
- const trailer = PDFTrailer.forLastCrossRefSectionOffset(xrefOffset);
17016
- size += trailer.sizeInBytes();
17017
- return { size, header, indirectObjects: uncompressedObjects, trailer };
17018
- });
16949
+ size += this.computeIndirectObjectSize(indirectObject);
16950
+ if (this.shouldWaitForTick(1))
16951
+ await waitForTick();
16952
+ }
16953
+ else {
16954
+ let chunk = last(compressedObjects);
16955
+ let objectStreamRef = last(objectStreamRefs);
16956
+ if (!chunk || chunk.length % this.objectsPerStream === 0) {
16957
+ chunk = [];
16958
+ compressedObjects.push(chunk);
16959
+ objectStreamRef = PDFRef.of(objectNumber++);
16960
+ objectStreamRefs.push(objectStreamRef);
16961
+ }
16962
+ xrefStream.addCompressedEntry(ref, objectStreamRef, chunk.length);
16963
+ chunk.push(indirectObject);
16964
+ }
16965
+ }
16966
+ for (let idx = 0, len = compressedObjects.length; idx < len; idx++) {
16967
+ const chunk = compressedObjects[idx];
16968
+ const ref = objectStreamRefs[idx];
16969
+ const objectStream = PDFObjectStream.withContextAndObjects(this.context, chunk, this.encodeStreams);
16970
+ xrefStream.addUncompressedEntry(ref, size);
16971
+ size += this.computeIndirectObjectSize([ref, objectStream]);
16972
+ uncompressedObjects.push([ref, objectStream]);
16973
+ if (this.shouldWaitForTick(chunk.length))
16974
+ await waitForTick();
16975
+ }
16976
+ const xrefStreamRef = PDFRef.of(objectNumber++);
16977
+ xrefStream.dict.set(PDFName.of('Size'), PDFNumber.of(objectNumber));
16978
+ xrefStream.addUncompressedEntry(xrefStreamRef, size);
16979
+ const xrefOffset = size;
16980
+ size += this.computeIndirectObjectSize([xrefStreamRef, xrefStream]);
16981
+ uncompressedObjects.push([xrefStreamRef, xrefStream]);
16982
+ const trailer = PDFTrailer.forLastCrossRefSectionOffset(xrefOffset);
16983
+ size += trailer.sizeInBytes();
16984
+ return { size, header, indirectObjects: uncompressedObjects, trailer };
17019
16985
  }
17020
16986
  }
17021
16987
  PDFStreamWriter.forContext = (context, objectsPerTick, encodeStreams = true, objectsPerStream = 50) => new PDFStreamWriter(context, objectsPerTick, encodeStreams, objectsPerStream);
@@ -17386,11 +17352,9 @@ end\
17386
17352
  this.baseFontName = '';
17387
17353
  this.glyphCache = Cache.populatedBy(this.allGlyphsInFontSortedById);
17388
17354
  }
17389
- static for(fontkit, fontData, customName, fontFeatures) {
17390
- return __awaiter(this, void 0, void 0, function* () {
17391
- const font = yield fontkit.create(fontData);
17392
- return new CustomFontEmbedder(font, fontData, customName, fontFeatures);
17393
- });
17355
+ static async for(fontkit, fontData, customName, fontFeatures) {
17356
+ const font = await fontkit.create(fontData);
17357
+ return new CustomFontEmbedder(font, fontData, customName, fontFeatures);
17394
17358
  }
17395
17359
  /**
17396
17360
  * Encode the JavaScript string into this font. (JavaScript encodes strings in
@@ -17436,85 +17400,75 @@ end\
17436
17400
  this.customName || context.addRandomSuffix(this.fontName);
17437
17401
  return this.embedFontDict(context, ref);
17438
17402
  }
17439
- embedFontDict(context, ref) {
17440
- return __awaiter(this, void 0, void 0, function* () {
17441
- const cidFontDictRef = yield this.embedCIDFontDict(context);
17442
- const unicodeCMapRef = this.embedUnicodeCmap(context);
17443
- const fontDict = context.obj({
17444
- Type: 'Font',
17445
- Subtype: 'Type0',
17446
- BaseFont: this.baseFontName,
17447
- Encoding: 'Identity-H',
17448
- DescendantFonts: [cidFontDictRef],
17449
- ToUnicode: unicodeCMapRef,
17450
- });
17451
- if (ref) {
17452
- context.assign(ref, fontDict);
17453
- return ref;
17454
- }
17455
- else {
17456
- return context.register(fontDict);
17457
- }
17403
+ async embedFontDict(context, ref) {
17404
+ const cidFontDictRef = await this.embedCIDFontDict(context);
17405
+ const unicodeCMapRef = this.embedUnicodeCmap(context);
17406
+ const fontDict = context.obj({
17407
+ Type: 'Font',
17408
+ Subtype: 'Type0',
17409
+ BaseFont: this.baseFontName,
17410
+ Encoding: 'Identity-H',
17411
+ DescendantFonts: [cidFontDictRef],
17412
+ ToUnicode: unicodeCMapRef,
17458
17413
  });
17414
+ if (ref) {
17415
+ context.assign(ref, fontDict);
17416
+ return ref;
17417
+ }
17418
+ else {
17419
+ return context.register(fontDict);
17420
+ }
17459
17421
  }
17460
17422
  isCFF() {
17461
17423
  return this.font.cff;
17462
17424
  }
17463
- embedCIDFontDict(context) {
17464
- return __awaiter(this, void 0, void 0, function* () {
17465
- const fontDescriptorRef = yield this.embedFontDescriptor(context);
17466
- const cidFontDict = context.obj({
17467
- Type: 'Font',
17468
- Subtype: this.isCFF() ? 'CIDFontType0' : 'CIDFontType2',
17469
- CIDToGIDMap: 'Identity',
17470
- BaseFont: this.baseFontName,
17471
- CIDSystemInfo: {
17472
- Registry: PDFString.of('Adobe'),
17473
- Ordering: PDFString.of('Identity'),
17474
- Supplement: 0,
17475
- },
17476
- FontDescriptor: fontDescriptorRef,
17477
- W: this.computeWidths(),
17478
- });
17479
- return context.register(cidFontDict);
17425
+ async embedCIDFontDict(context) {
17426
+ const fontDescriptorRef = await this.embedFontDescriptor(context);
17427
+ const cidFontDict = context.obj({
17428
+ Type: 'Font',
17429
+ Subtype: this.isCFF() ? 'CIDFontType0' : 'CIDFontType2',
17430
+ CIDToGIDMap: 'Identity',
17431
+ BaseFont: this.baseFontName,
17432
+ CIDSystemInfo: {
17433
+ Registry: PDFString.of('Adobe'),
17434
+ Ordering: PDFString.of('Identity'),
17435
+ Supplement: 0,
17436
+ },
17437
+ FontDescriptor: fontDescriptorRef,
17438
+ W: this.computeWidths(),
17480
17439
  });
17481
- }
17482
- embedFontDescriptor(context) {
17483
- return __awaiter(this, void 0, void 0, function* () {
17484
- const fontStreamRef = yield this.embedFontStream(context);
17485
- const { scale } = this;
17486
- const { italicAngle, ascent, descent, capHeight, xHeight } = this.font;
17487
- const { minX, minY, maxX, maxY } = this.font.bbox;
17488
- const fontDescriptor = context.obj({
17489
- Type: 'FontDescriptor',
17490
- FontName: this.baseFontName,
17491
- Flags: deriveFontFlags(this.font),
17492
- FontBBox: [minX * scale, minY * scale, maxX * scale, maxY * scale],
17493
- ItalicAngle: italicAngle,
17494
- Ascent: ascent * scale,
17495
- Descent: descent * scale,
17496
- CapHeight: (capHeight || ascent) * scale,
17497
- XHeight: (xHeight || 0) * scale,
17498
- // Not sure how to compute/find this, nor is anybody else really:
17499
- // https://stackoverflow.com/questions/35485179/stemv-value-of-the-truetype-font
17500
- StemV: 0,
17501
- [this.isCFF() ? 'FontFile3' : 'FontFile2']: fontStreamRef,
17502
- });
17503
- return context.register(fontDescriptor);
17440
+ return context.register(cidFontDict);
17441
+ }
17442
+ async embedFontDescriptor(context) {
17443
+ const fontStreamRef = await this.embedFontStream(context);
17444
+ const { scale } = this;
17445
+ const { italicAngle, ascent, descent, capHeight, xHeight } = this.font;
17446
+ const { minX, minY, maxX, maxY } = this.font.bbox;
17447
+ const fontDescriptor = context.obj({
17448
+ Type: 'FontDescriptor',
17449
+ FontName: this.baseFontName,
17450
+ Flags: deriveFontFlags(this.font),
17451
+ FontBBox: [minX * scale, minY * scale, maxX * scale, maxY * scale],
17452
+ ItalicAngle: italicAngle,
17453
+ Ascent: ascent * scale,
17454
+ Descent: descent * scale,
17455
+ CapHeight: (capHeight || ascent) * scale,
17456
+ XHeight: (xHeight || 0) * scale,
17457
+ // Not sure how to compute/find this, nor is anybody else really:
17458
+ // https://stackoverflow.com/questions/35485179/stemv-value-of-the-truetype-font
17459
+ StemV: 0,
17460
+ [this.isCFF() ? 'FontFile3' : 'FontFile2']: fontStreamRef,
17504
17461
  });
17462
+ return context.register(fontDescriptor);
17505
17463
  }
17506
- serializeFont() {
17507
- return __awaiter(this, void 0, void 0, function* () {
17508
- return this.fontData;
17509
- });
17464
+ async serializeFont() {
17465
+ return this.fontData;
17510
17466
  }
17511
- embedFontStream(context) {
17512
- return __awaiter(this, void 0, void 0, function* () {
17513
- const fontStream = context.flateStream(yield this.serializeFont(), {
17514
- Subtype: this.isCFF() ? 'CIDFontType0C' : undefined,
17515
- });
17516
- return context.register(fontStream);
17467
+ async embedFontStream(context) {
17468
+ const fontStream = context.flateStream(await this.serializeFont(), {
17469
+ Subtype: this.isCFF() ? 'CIDFontType0C' : undefined,
17517
17470
  });
17471
+ return context.register(fontStream);
17518
17472
  }
17519
17473
  embedUnicodeCmap(context) {
17520
17474
  const cmap = createCmap(this.glyphCache.access(), this.glyphId.bind(this));
@@ -17561,11 +17515,9 @@ end\
17561
17515
  this.glyphCache = Cache.populatedBy(() => this.glyphs);
17562
17516
  this.glyphIdMap = new Map();
17563
17517
  }
17564
- static for(fontkit, fontData, customFontName, fontFeatures) {
17565
- return __awaiter(this, void 0, void 0, function* () {
17566
- const font = yield fontkit.create(fontData);
17567
- return new CustomFontSubsetEmbedder(font, fontData, customFontName, fontFeatures);
17568
- });
17518
+ static async for(fontkit, fontData, customFontName, fontFeatures) {
17519
+ const font = await fontkit.create(fontData);
17520
+ return new CustomFontSubsetEmbedder(font, fontData, customFontName, fontFeatures);
17569
17521
  }
17570
17522
  encodeText(text) {
17571
17523
  const { glyphs } = this.font.layout(text, this.fontFeatures);
@@ -17630,39 +17582,37 @@ end\
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 @@ end\
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 @@ end\
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 @@ end\
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.
@@ -29124,23 +29062,21 @@ end\
29124
29062
  this.firstOffset = dict.lookup(PDFName.of('First'), PDFNumber).asNumber();
29125
29063
  this.objectCount = dict.lookup(PDFName.of('N'), PDFNumber).asNumber();
29126
29064
  }
29127
- parseIntoContext() {
29128
- return __awaiter(this, void 0, void 0, function* () {
29129
- if (this.alreadyParsed) {
29130
- throw new ReparseError('PDFObjectStreamParser', 'parseIntoContext');
29131
- }
29132
- this.alreadyParsed = true;
29133
- const offsetsAndObjectNumbers = this.parseOffsetsAndObjectNumbers();
29134
- for (let idx = 0, len = offsetsAndObjectNumbers.length; idx < len; idx++) {
29135
- const { objectNumber, offset } = offsetsAndObjectNumbers[idx];
29136
- this.bytes.moveTo(this.firstOffset + offset);
29137
- const ref = PDFRef.of(objectNumber, 0);
29138
- const object = this.parseObject(ref);
29139
- this.context.assign(ref, object);
29140
- if (this.shouldWaitForTick())
29141
- yield waitForTick();
29142
- }
29143
- });
29065
+ async parseIntoContext() {
29066
+ if (this.alreadyParsed) {
29067
+ throw new ReparseError('PDFObjectStreamParser', 'parseIntoContext');
29068
+ }
29069
+ this.alreadyParsed = true;
29070
+ const offsetsAndObjectNumbers = this.parseOffsetsAndObjectNumbers();
29071
+ for (let idx = 0, len = offsetsAndObjectNumbers.length; idx < len; idx++) {
29072
+ const { objectNumber, offset } = offsetsAndObjectNumbers[idx];
29073
+ this.bytes.moveTo(this.firstOffset + offset);
29074
+ const ref = PDFRef.of(objectNumber, 0);
29075
+ const object = this.parseObject(ref);
29076
+ this.context.assign(ref, object);
29077
+ if (this.shouldWaitForTick())
29078
+ await waitForTick();
29079
+ }
29144
29080
  }
29145
29081
  parseOffsetsAndObjectNumbers() {
29146
29082
  const offsetsAndObjectNumbers = [];
@@ -29248,29 +29184,27 @@ end\
29248
29184
  this.throwOnInvalidObject = throwOnInvalidObject;
29249
29185
  this.context.isDecrypted = !!(cryptoFactory === null || cryptoFactory === void 0 ? void 0 : cryptoFactory.encryptionKey);
29250
29186
  }
29251
- parseDocument() {
29252
- return __awaiter(this, void 0, void 0, function* () {
29253
- if (this.alreadyParsed) {
29254
- throw new ReparseError('PDFParser', 'parseDocument');
29255
- }
29256
- this.alreadyParsed = true;
29257
- this.context.header = this.parseHeader();
29258
- let prevOffset;
29259
- while (!this.bytes.done()) {
29260
- yield this.parseDocumentSection();
29261
- const offset = this.bytes.offset();
29262
- if (offset === prevOffset) {
29263
- throw new StalledParserError(this.bytes.position());
29264
- }
29265
- prevOffset = offset;
29266
- }
29267
- this.maybeRecoverRoot();
29268
- if (this.context.lookup(PDFRef.of(0))) {
29269
- console.warn('Removing parsed object: 0 0 R');
29270
- this.context.delete(PDFRef.of(0));
29187
+ async parseDocument() {
29188
+ if (this.alreadyParsed) {
29189
+ throw new ReparseError('PDFParser', 'parseDocument');
29190
+ }
29191
+ this.alreadyParsed = true;
29192
+ this.context.header = this.parseHeader();
29193
+ let prevOffset;
29194
+ while (!this.bytes.done()) {
29195
+ await this.parseDocumentSection();
29196
+ const offset = this.bytes.offset();
29197
+ if (offset === prevOffset) {
29198
+ throw new StalledParserError(this.bytes.position());
29271
29199
  }
29272
- return this.context;
29273
- });
29200
+ prevOffset = offset;
29201
+ }
29202
+ this.maybeRecoverRoot();
29203
+ if (this.context.lookup(PDFRef.of(0))) {
29204
+ console.warn('Removing parsed object: 0 0 R');
29205
+ this.context.delete(PDFRef.of(0));
29206
+ }
29207
+ return this.context;
29274
29208
  }
29275
29209
  maybeRecoverRoot() {
29276
29210
  const isValidCatalog = (obj) => obj instanceof PDFDict &&
@@ -29322,30 +29256,28 @@ end\
29322
29256
  return false;
29323
29257
  }
29324
29258
  }
29325
- parseIndirectObject() {
29326
- return __awaiter(this, void 0, void 0, function* () {
29327
- const ref = this.parseIndirectObjectHeader();
29328
- this.skipWhitespaceAndComments();
29329
- const object = this.parseObject(ref);
29330
- this.skipWhitespaceAndComments();
29331
- // if (!this.matchKeyword(Keywords.endobj)) {
29332
- // throw new MissingKeywordError(this.bytes.position(), Keywords.endobj);
29333
- // }
29334
- // TODO: Log a warning if this fails...
29335
- this.matchKeyword(Keywords.endobj);
29336
- if (object instanceof PDFRawStream &&
29337
- object.dict.lookup(PDFName.of('Type')) === PDFName.of('ObjStm')) {
29338
- yield PDFObjectStreamParser.forStream(object, this.shouldWaitForTick).parseIntoContext();
29339
- }
29340
- else if (object instanceof PDFRawStream &&
29341
- object.dict.lookup(PDFName.of('Type')) === PDFName.of('XRef')) {
29342
- PDFXRefStreamParser.forStream(object).parseIntoContext();
29343
- }
29344
- else {
29345
- this.context.assign(ref, object);
29346
- }
29347
- return ref;
29348
- });
29259
+ async parseIndirectObject() {
29260
+ const ref = this.parseIndirectObjectHeader();
29261
+ this.skipWhitespaceAndComments();
29262
+ const object = this.parseObject(ref);
29263
+ this.skipWhitespaceAndComments();
29264
+ // if (!this.matchKeyword(Keywords.endobj)) {
29265
+ // throw new MissingKeywordError(this.bytes.position(), Keywords.endobj);
29266
+ // }
29267
+ // TODO: Log a warning if this fails...
29268
+ this.matchKeyword(Keywords.endobj);
29269
+ if (object instanceof PDFRawStream &&
29270
+ object.dict.lookup(PDFName.of('Type')) === PDFName.of('ObjStm')) {
29271
+ await PDFObjectStreamParser.forStream(object, this.shouldWaitForTick).parseIntoContext();
29272
+ }
29273
+ else if (object instanceof PDFRawStream &&
29274
+ object.dict.lookup(PDFName.of('Type')) === PDFName.of('XRef')) {
29275
+ PDFXRefStreamParser.forStream(object).parseIntoContext();
29276
+ }
29277
+ else {
29278
+ this.context.assign(ref, object);
29279
+ }
29280
+ return ref;
29349
29281
  }
29350
29282
  // TODO: Improve and clean this up
29351
29283
  tryToParseInvalidIndirectObject() {
@@ -29374,26 +29306,24 @@ end\
29374
29306
  this.context.assign(ref, object);
29375
29307
  return ref;
29376
29308
  }
29377
- parseIndirectObjects() {
29378
- return __awaiter(this, void 0, void 0, function* () {
29379
- this.skipWhitespaceAndComments();
29380
- while (!this.bytes.done() && IsDigit[this.bytes.peek()]) {
29381
- const initialOffset = this.bytes.offset();
29382
- try {
29383
- yield this.parseIndirectObject();
29384
- }
29385
- catch (e) {
29386
- // TODO: Add tracing/logging mechanism to track when this happens!
29387
- this.bytes.moveTo(initialOffset);
29388
- this.tryToParseInvalidIndirectObject();
29389
- }
29390
- this.skipWhitespaceAndComments();
29391
- // TODO: Can this be done only when needed, to avoid harming performance?
29392
- this.skipJibberish();
29393
- if (this.shouldWaitForTick())
29394
- yield waitForTick();
29309
+ async parseIndirectObjects() {
29310
+ this.skipWhitespaceAndComments();
29311
+ while (!this.bytes.done() && IsDigit[this.bytes.peek()]) {
29312
+ const initialOffset = this.bytes.offset();
29313
+ try {
29314
+ await this.parseIndirectObject();
29395
29315
  }
29396
- });
29316
+ catch (e) {
29317
+ // TODO: Add tracing/logging mechanism to track when this happens!
29318
+ this.bytes.moveTo(initialOffset);
29319
+ this.tryToParseInvalidIndirectObject();
29320
+ }
29321
+ this.skipWhitespaceAndComments();
29322
+ // TODO: Can this be done only when needed, to avoid harming performance?
29323
+ this.skipJibberish();
29324
+ if (this.shouldWaitForTick())
29325
+ await waitForTick();
29326
+ }
29397
29327
  }
29398
29328
  maybeParseCrossRefSection() {
29399
29329
  this.skipWhitespaceAndComments();
@@ -29453,15 +29383,13 @@ end\
29453
29383
  this.skipWhitespaceAndComments();
29454
29384
  return PDFTrailer.forLastCrossRefSectionOffset(offset);
29455
29385
  }
29456
- parseDocumentSection() {
29457
- return __awaiter(this, void 0, void 0, function* () {
29458
- yield this.parseIndirectObjects();
29459
- this.maybeParseCrossRefSection();
29460
- this.maybeParseTrailerDict();
29461
- this.maybeParseTrailer();
29462
- // TODO: Can this be done only when needed, to avoid harming performance?
29463
- this.skipJibberish();
29464
- });
29386
+ async parseDocumentSection() {
29387
+ await this.parseIndirectObjects();
29388
+ this.maybeParseCrossRefSection();
29389
+ this.maybeParseTrailerDict();
29390
+ this.maybeParseTrailer();
29391
+ // TODO: Can this be done only when needed, to avoid harming performance?
29392
+ this.skipJibberish();
29465
29393
  }
29466
29394
  /**
29467
29395
  * This operation is not necessary for valid PDF files. But some invalid PDFs
@@ -32176,6 +32104,16 @@ end\
32176
32104
  };
32177
32105
  const svgPathToOperators = (path) => apply(parse(path));
32178
32106
 
32107
+ const clipSpace = ({ topLeft, topRight, bottomRight, bottomLeft }) => [
32108
+ moveTo(topLeft.x, topLeft.y),
32109
+ lineTo(topRight.x, topRight.y),
32110
+ lineTo(bottomRight.x, bottomRight.y),
32111
+ lineTo(bottomLeft.x, bottomLeft.y),
32112
+ closePath(),
32113
+ clip(),
32114
+ endPath(),
32115
+ ];
32116
+ const clipSpaces = (spaces) => spaces.flatMap(clipSpace);
32179
32117
  const drawText = (line, options) => [
32180
32118
  pushGraphicsState(),
32181
32119
  options.graphicsState && setGraphicsState(options.graphicsState),
@@ -32191,6 +32129,8 @@ end\
32191
32129
  const operators = [
32192
32130
  pushGraphicsState(),
32193
32131
  options.graphicsState && setGraphicsState(options.graphicsState),
32132
+ ...(options.clipSpaces ? clipSpaces(options.clipSpaces) : []),
32133
+ options.matrix && concatTransformationMatrix(...options.matrix),
32194
32134
  beginText(),
32195
32135
  setFillingColor(options.color),
32196
32136
  setFontAndSize(options.font, options.size),
@@ -32206,6 +32146,8 @@ end\
32206
32146
  const drawImage = (name, options) => [
32207
32147
  pushGraphicsState(),
32208
32148
  options.graphicsState && setGraphicsState(options.graphicsState),
32149
+ ...(options.clipSpaces ? clipSpaces(options.clipSpaces) : []),
32150
+ options.matrix && concatTransformationMatrix(...options.matrix),
32209
32151
  translate(options.x, options.y),
32210
32152
  rotateRadians(toRadians(options.rotate)),
32211
32153
  scale(options.width, options.height),
@@ -32228,6 +32170,8 @@ end\
32228
32170
  return [
32229
32171
  pushGraphicsState(),
32230
32172
  options.graphicsState && setGraphicsState(options.graphicsState),
32173
+ ...(options.clipSpaces ? clipSpaces(options.clipSpaces) : []),
32174
+ options.matrix && concatTransformationMatrix(...options.matrix),
32231
32175
  options.color && setStrokingColor(options.color),
32232
32176
  setLineWidth(options.thickness),
32233
32177
  setDashPattern((_a = options.dashArray) !== null && _a !== void 0 ? _a : [], (_b = options.dashPhase) !== null && _b !== void 0 ? _b : 0),
@@ -32249,6 +32193,8 @@ end\
32249
32193
  setLineWidth(options.borderWidth),
32250
32194
  options.borderLineCap && setLineCap(options.borderLineCap),
32251
32195
  setDashPattern((_a = options.borderDashArray) !== null && _a !== void 0 ? _a : [], (_b = options.borderDashPhase) !== null && _b !== void 0 ? _b : 0),
32196
+ ...(options.clipSpaces ? clipSpaces(options.clipSpaces) : []),
32197
+ options.matrix && concatTransformationMatrix(...options.matrix),
32252
32198
  translate(options.x, options.y),
32253
32199
  rotateRadians(toRadians(options.rotate)),
32254
32200
  skewRadians(toRadians(options.xSkew), toRadians(options.ySkew)),
@@ -32320,6 +32266,8 @@ end\
32320
32266
  options.graphicsState && setGraphicsState(options.graphicsState),
32321
32267
  options.color && setFillingColor(options.color),
32322
32268
  options.borderColor && setStrokingColor(options.borderColor),
32269
+ ...(options.clipSpaces ? clipSpaces(options.clipSpaces) : []),
32270
+ options.matrix && concatTransformationMatrix(...options.matrix),
32323
32271
  setLineWidth(options.borderWidth),
32324
32272
  options.borderLineCap && setLineCap(options.borderLineCap),
32325
32273
  setDashPattern((_a = options.borderDashArray) !== null && _a !== void 0 ? _a : [], (_b = options.borderDashPhase) !== null && _b !== void 0 ? _b : 0),
@@ -32352,6 +32300,8 @@ end\
32352
32300
  return [
32353
32301
  pushGraphicsState(),
32354
32302
  options.graphicsState && setGraphicsState(options.graphicsState),
32303
+ ...(options.clipSpaces ? clipSpaces(options.clipSpaces) : []),
32304
+ options.matrix && concatTransformationMatrix(...options.matrix),
32355
32305
  translate(options.x, options.y),
32356
32306
  rotateRadians(toRadians((_a = options.rotate) !== null && _a !== void 0 ? _a : degrees(0))),
32357
32307
  options.scale && scale(options.scale, options.scale),
@@ -33012,7 +32962,7 @@ end\
33012
32962
  const borderWidth = (_a = bs === null || bs === void 0 ? void 0 : bs.getWidth()) !== null && _a !== void 0 ? _a : 0;
33013
32963
  const rotation = reduceRotation(ap === null || ap === void 0 ? void 0 : ap.getRotation());
33014
32964
  const { width, height } = adjustDimsForRotation(rectangle, rotation);
33015
- const rotate = rotateInPlace(Object.assign(Object.assign({}, rectangle), { rotation }));
32965
+ const rotate = rotateInPlace({ ...rectangle, rotation });
33016
32966
  const black = rgb(0, 0, 0);
33017
32967
  const borderColor = (_b = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBorderColor())) !== null && _b !== void 0 ? _b : black;
33018
32968
  const normalBackgroundColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBackgroundColor());
@@ -33039,21 +32989,37 @@ end\
33039
32989
  normal: {
33040
32990
  on: [
33041
32991
  ...rotate,
33042
- ...drawCheckBox(Object.assign(Object.assign({}, options), { color: normalBackgroundColor, filled: true })),
32992
+ ...drawCheckBox({
32993
+ ...options,
32994
+ color: normalBackgroundColor,
32995
+ filled: true,
32996
+ }),
33043
32997
  ],
33044
32998
  off: [
33045
32999
  ...rotate,
33046
- ...drawCheckBox(Object.assign(Object.assign({}, options), { color: normalBackgroundColor, filled: false })),
33000
+ ...drawCheckBox({
33001
+ ...options,
33002
+ color: normalBackgroundColor,
33003
+ filled: false,
33004
+ }),
33047
33005
  ],
33048
33006
  },
33049
33007
  down: {
33050
33008
  on: [
33051
33009
  ...rotate,
33052
- ...drawCheckBox(Object.assign(Object.assign({}, options), { color: downBackgroundColor, filled: true })),
33010
+ ...drawCheckBox({
33011
+ ...options,
33012
+ color: downBackgroundColor,
33013
+ filled: true,
33014
+ }),
33053
33015
  ],
33054
33016
  off: [
33055
33017
  ...rotate,
33056
- ...drawCheckBox(Object.assign(Object.assign({}, options), { color: downBackgroundColor, filled: false })),
33018
+ ...drawCheckBox({
33019
+ ...options,
33020
+ color: downBackgroundColor,
33021
+ filled: false,
33022
+ }),
33057
33023
  ],
33058
33024
  },
33059
33025
  };
@@ -33069,7 +33035,7 @@ end\
33069
33035
  const borderWidth = (_a = bs === null || bs === void 0 ? void 0 : bs.getWidth()) !== null && _a !== void 0 ? _a : 0;
33070
33036
  const rotation = reduceRotation(ap === null || ap === void 0 ? void 0 : ap.getRotation());
33071
33037
  const { width, height } = adjustDimsForRotation(rectangle, rotation);
33072
- const rotate = rotateInPlace(Object.assign(Object.assign({}, rectangle), { rotation }));
33038
+ const rotate = rotateInPlace({ ...rectangle, rotation });
33073
33039
  const black = rgb(0, 0, 0);
33074
33040
  const borderColor = (_b = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBorderColor())) !== null && _b !== void 0 ? _b : black;
33075
33041
  const normalBackgroundColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBackgroundColor());
@@ -33095,21 +33061,37 @@ end\
33095
33061
  normal: {
33096
33062
  on: [
33097
33063
  ...rotate,
33098
- ...drawRadioButton(Object.assign(Object.assign({}, options), { color: normalBackgroundColor, filled: true })),
33064
+ ...drawRadioButton({
33065
+ ...options,
33066
+ color: normalBackgroundColor,
33067
+ filled: true,
33068
+ }),
33099
33069
  ],
33100
33070
  off: [
33101
33071
  ...rotate,
33102
- ...drawRadioButton(Object.assign(Object.assign({}, options), { color: normalBackgroundColor, filled: false })),
33072
+ ...drawRadioButton({
33073
+ ...options,
33074
+ color: normalBackgroundColor,
33075
+ filled: false,
33076
+ }),
33103
33077
  ],
33104
33078
  },
33105
33079
  down: {
33106
33080
  on: [
33107
33081
  ...rotate,
33108
- ...drawRadioButton(Object.assign(Object.assign({}, options), { color: downBackgroundColor, filled: true })),
33082
+ ...drawRadioButton({
33083
+ ...options,
33084
+ color: downBackgroundColor,
33085
+ filled: true,
33086
+ }),
33109
33087
  ],
33110
33088
  off: [
33111
33089
  ...rotate,
33112
- ...drawRadioButton(Object.assign(Object.assign({}, options), { color: downBackgroundColor, filled: false })),
33090
+ ...drawRadioButton({
33091
+ ...options,
33092
+ color: downBackgroundColor,
33093
+ filled: false,
33094
+ }),
33113
33095
  ],
33114
33096
  },
33115
33097
  };
@@ -33130,7 +33112,7 @@ end\
33130
33112
  const borderWidth = (_d = bs === null || bs === void 0 ? void 0 : bs.getWidth()) !== null && _d !== void 0 ? _d : 0;
33131
33113
  const rotation = reduceRotation(ap === null || ap === void 0 ? void 0 : ap.getRotation());
33132
33114
  const { width, height } = adjustDimsForRotation(rectangle, rotation);
33133
- const rotate = rotateInPlace(Object.assign(Object.assign({}, rectangle), { rotation }));
33115
+ const rotate = rotateInPlace({ ...rectangle, rotation });
33134
33116
  const black = rgb(0, 0, 0);
33135
33117
  const borderColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBorderColor());
33136
33118
  const normalBackgroundColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBackgroundColor());
@@ -33176,11 +33158,19 @@ end\
33176
33158
  return {
33177
33159
  normal: [
33178
33160
  ...rotate,
33179
- ...drawButton(Object.assign(Object.assign({}, options), { color: normalBackgroundColor, textLines: [normalLayout.line] })),
33161
+ ...drawButton({
33162
+ ...options,
33163
+ color: normalBackgroundColor,
33164
+ textLines: [normalLayout.line],
33165
+ }),
33180
33166
  ],
33181
33167
  down: [
33182
33168
  ...rotate,
33183
- ...drawButton(Object.assign(Object.assign({}, options), { color: downBackgroundColor, textLines: [downLayout.line] })),
33169
+ ...drawButton({
33170
+ ...options,
33171
+ color: downBackgroundColor,
33172
+ textLines: [downLayout.line],
33173
+ }),
33184
33174
  ],
33185
33175
  };
33186
33176
  };
@@ -33198,7 +33188,7 @@ end\
33198
33188
  const borderWidth = (_b = bs === null || bs === void 0 ? void 0 : bs.getWidth()) !== null && _b !== void 0 ? _b : 0;
33199
33189
  const rotation = reduceRotation(ap === null || ap === void 0 ? void 0 : ap.getRotation());
33200
33190
  const { width, height } = adjustDimsForRotation(rectangle, rotation);
33201
- const rotate = rotateInPlace(Object.assign(Object.assign({}, rectangle), { rotation }));
33191
+ const rotate = rotateInPlace({ ...rectangle, rotation });
33202
33192
  const black = rgb(0, 0, 0);
33203
33193
  const borderColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBorderColor());
33204
33194
  const normalBackgroundColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBackgroundColor());
@@ -33279,7 +33269,7 @@ end\
33279
33269
  const borderWidth = (_b = bs === null || bs === void 0 ? void 0 : bs.getWidth()) !== null && _b !== void 0 ? _b : 0;
33280
33270
  const rotation = reduceRotation(ap === null || ap === void 0 ? void 0 : ap.getRotation());
33281
33271
  const { width, height } = adjustDimsForRotation(rectangle, rotation);
33282
- const rotate = rotateInPlace(Object.assign(Object.assign({}, rectangle), { rotation }));
33272
+ const rotate = rotateInPlace({ ...rectangle, rotation });
33283
33273
  const black = rgb(0, 0, 0);
33284
33274
  const borderColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBorderColor());
33285
33275
  const normalBackgroundColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBackgroundColor());
@@ -33333,7 +33323,7 @@ end\
33333
33323
  const borderWidth = (_a = bs === null || bs === void 0 ? void 0 : bs.getWidth()) !== null && _a !== void 0 ? _a : 0;
33334
33324
  const rotation = reduceRotation(ap === null || ap === void 0 ? void 0 : ap.getRotation());
33335
33325
  const { width, height } = adjustDimsForRotation(rectangle, rotation);
33336
- const rotate = rotateInPlace(Object.assign(Object.assign({}, rectangle), { rotation }));
33326
+ const rotate = rotateInPlace({ ...rectangle, rotation });
33337
33327
  const black = rgb(0, 0, 0);
33338
33328
  const borderColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBorderColor());
33339
33329
  const normalBackgroundColor = componentsToColor(ap === null || ap === void 0 ? void 0 : ap.getBackgroundColor());
@@ -33451,13 +33441,11 @@ end\
33451
33441
  *
33452
33442
  * @returns Resolves when the embedding is complete.
33453
33443
  */
33454
- embed() {
33455
- return __awaiter(this, void 0, void 0, function* () {
33456
- if (!this.alreadyEmbedded) {
33457
- yield this.embedder.embedIntoContext(this.doc.context, this.ref);
33458
- this.alreadyEmbedded = true;
33459
- }
33460
- });
33444
+ async embed() {
33445
+ if (!this.alreadyEmbedded) {
33446
+ await this.embedder.embedIntoContext(this.doc.context, this.ref);
33447
+ this.alreadyEmbedded = true;
33448
+ }
33461
33449
  }
33462
33450
  }
33463
33451
  /**
@@ -33576,14 +33564,12 @@ end\
33576
33564
  *
33577
33565
  * @returns Resolves when the embedding is complete.
33578
33566
  */
33579
- embed() {
33580
- return __awaiter(this, void 0, void 0, function* () {
33581
- // TODO: Cleanup orphan embedded objects if a font is embedded multiple times...
33582
- if (this.modified) {
33583
- yield this.embedder.embedIntoContext(this.doc.context, this.ref);
33584
- this.modified = false;
33585
- }
33586
- });
33567
+ async embed() {
33568
+ // TODO: Cleanup orphan embedded objects if a font is embedded multiple times...
33569
+ if (this.modified) {
33570
+ await this.embedder.embedIntoContext(this.doc.context, this.ref);
33571
+ this.modified = false;
33572
+ }
33587
33573
  }
33588
33574
  }
33589
33575
  /**
@@ -33682,22 +33668,20 @@ end\
33682
33668
  *
33683
33669
  * @returns Resolves when the embedding is complete.
33684
33670
  */
33685
- embed() {
33686
- return __awaiter(this, void 0, void 0, function* () {
33687
- if (!this.embedder)
33688
- return;
33689
- // The image should only be embedded once. If there's a pending embed
33690
- // operation then wait on it. Otherwise we need to start the embed.
33691
- if (!this.embedTask) {
33692
- const { doc, ref } = this;
33693
- this.embedTask = this.embedder.embedIntoContext(doc.context, ref);
33694
- }
33695
- yield this.embedTask;
33696
- // We clear `this.embedder` so that the indirectly referenced image data
33697
- // can be garbage collected, thus avoiding a memory leak.
33698
- // See https://github.com/Hopding/pdf-lib/pull/1032/files.
33699
- this.embedder = undefined;
33700
- });
33671
+ async embed() {
33672
+ if (!this.embedder)
33673
+ return;
33674
+ // The image should only be embedded once. If there's a pending embed
33675
+ // operation then wait on it. Otherwise we need to start the embed.
33676
+ if (!this.embedTask) {
33677
+ const { doc, ref } = this;
33678
+ this.embedTask = this.embedder.embedIntoContext(doc.context, ref);
33679
+ }
33680
+ await this.embedTask;
33681
+ // We clear `this.embedder` so that the indirectly referenced image data
33682
+ // can be garbage collected, thus avoiding a memory leak.
33683
+ // See https://github.com/Hopding/pdf-lib/pull/1032/files.
33684
+ this.embedder = undefined;
33701
33685
  }
33702
33686
  }
33703
33687
  /**
@@ -34041,7 +34025,7 @@ end\
34041
34025
  const bs = widget.getBorderStyle();
34042
34026
  const borderWidth = (_a = bs === null || bs === void 0 ? void 0 : bs.getWidth()) !== null && _a !== void 0 ? _a : 0;
34043
34027
  const rotation = reduceRotation(ap === null || ap === void 0 ? void 0 : ap.getRotation());
34044
- const rotate = rotateInPlace(Object.assign(Object.assign({}, rectangle), { rotation }));
34028
+ const rotate = rotateInPlace({ ...rectangle, rotation });
34045
34029
  const adj = adjustDimsForRotation(rectangle, rotation);
34046
34030
  const imageDims = image.scaleToFit(adj.width - borderWidth * 2, adj.height - borderWidth * 2);
34047
34031
  // Support borders on images and maybe other properties
@@ -36961,7 +36945,7 @@ end\
36961
36945
  const operators = [
36962
36946
  pushGraphicsState(),
36963
36947
  translate(rectangle.x, rectangle.y),
36964
- ...rotateInPlace(Object.assign(Object.assign({}, rectangle), { rotation: 0 })),
36948
+ ...rotateInPlace({ ...rectangle, rotation: 0 }),
36965
36949
  drawObject(xObjectKey),
36966
36950
  popGraphicsState(),
36967
36951
  ].filter(Boolean);
@@ -37305,39 +37289,37 @@ end\
37305
37289
  *
37306
37290
  * @returns Resolves when the embedding is complete.
37307
37291
  */
37308
- embed() {
37309
- return __awaiter(this, void 0, void 0, function* () {
37310
- if (!this.alreadyEmbedded) {
37311
- const ref = yield this.embedder.embedIntoContext(this.doc.context, this.ref);
37312
- if (!this.doc.catalog.has(PDFName.of('Names'))) {
37313
- this.doc.catalog.set(PDFName.of('Names'), this.doc.context.obj({}));
37314
- }
37315
- const Names = this.doc.catalog.lookup(PDFName.of('Names'), PDFDict);
37316
- if (!Names.has(PDFName.of('EmbeddedFiles'))) {
37317
- Names.set(PDFName.of('EmbeddedFiles'), this.doc.context.obj({}));
37318
- }
37319
- const EmbeddedFiles = Names.lookup(PDFName.of('EmbeddedFiles'), PDFDict);
37320
- if (!EmbeddedFiles.has(PDFName.of('Names'))) {
37321
- EmbeddedFiles.set(PDFName.of('Names'), this.doc.context.obj([]));
37322
- }
37323
- const EFNames = EmbeddedFiles.lookup(PDFName.of('Names'), PDFArray);
37324
- EFNames.push(PDFHexString.fromText(this.embedder.fileName));
37325
- EFNames.push(ref);
37326
- /**
37327
- * The AF-Tag is needed to achieve PDF-A3 compliance for embedded files
37328
- *
37329
- * The following document outlines the uses cases of the associated files (AF) tag.
37330
- * See:
37331
- * https://www.pdfa.org/wp-content/uploads/2018/10/PDF20_AN002-AF.pdf
37332
- */
37333
- if (!this.doc.catalog.has(PDFName.of('AF'))) {
37334
- this.doc.catalog.set(PDFName.of('AF'), this.doc.context.obj([]));
37335
- }
37336
- const AF = this.doc.catalog.lookup(PDFName.of('AF'), PDFArray);
37337
- AF.push(ref);
37338
- this.alreadyEmbedded = true;
37292
+ async embed() {
37293
+ if (!this.alreadyEmbedded) {
37294
+ const ref = await this.embedder.embedIntoContext(this.doc.context, this.ref);
37295
+ if (!this.doc.catalog.has(PDFName.of('Names'))) {
37296
+ this.doc.catalog.set(PDFName.of('Names'), this.doc.context.obj({}));
37339
37297
  }
37340
- });
37298
+ const Names = this.doc.catalog.lookup(PDFName.of('Names'), PDFDict);
37299
+ if (!Names.has(PDFName.of('EmbeddedFiles'))) {
37300
+ Names.set(PDFName.of('EmbeddedFiles'), this.doc.context.obj({}));
37301
+ }
37302
+ const EmbeddedFiles = Names.lookup(PDFName.of('EmbeddedFiles'), PDFDict);
37303
+ if (!EmbeddedFiles.has(PDFName.of('Names'))) {
37304
+ EmbeddedFiles.set(PDFName.of('Names'), this.doc.context.obj([]));
37305
+ }
37306
+ const EFNames = EmbeddedFiles.lookup(PDFName.of('Names'), PDFArray);
37307
+ EFNames.push(PDFHexString.fromText(this.embedder.fileName));
37308
+ EFNames.push(ref);
37309
+ /**
37310
+ * The AF-Tag is needed to achieve PDF-A3 compliance for embedded files
37311
+ *
37312
+ * The following document outlines the uses cases of the associated files (AF) tag.
37313
+ * See:
37314
+ * https://www.pdfa.org/wp-content/uploads/2018/10/PDF20_AN002-AF.pdf
37315
+ */
37316
+ if (!this.doc.catalog.has(PDFName.of('AF'))) {
37317
+ this.doc.catalog.set(PDFName.of('AF'), this.doc.context.obj([]));
37318
+ }
37319
+ const AF = this.doc.catalog.lookup(PDFName.of('AF'), PDFArray);
37320
+ AF.push(ref);
37321
+ this.alreadyEmbedded = true;
37322
+ }
37341
37323
  }
37342
37324
  }
37343
37325
  /**
@@ -37372,28 +37354,26 @@ end\
37372
37354
  *
37373
37355
  * @returns Resolves when the embedding is complete.
37374
37356
  */
37375
- embed() {
37376
- return __awaiter(this, void 0, void 0, function* () {
37377
- if (!this.alreadyEmbedded) {
37378
- const { catalog, context } = this.doc;
37379
- const ref = yield this.embedder.embedIntoContext(this.doc.context, this.ref);
37380
- if (!catalog.has(PDFName.of('Names'))) {
37381
- catalog.set(PDFName.of('Names'), context.obj({}));
37382
- }
37383
- const Names = catalog.lookup(PDFName.of('Names'), PDFDict);
37384
- if (!Names.has(PDFName.of('JavaScript'))) {
37385
- Names.set(PDFName.of('JavaScript'), context.obj({}));
37386
- }
37387
- const Javascript = Names.lookup(PDFName.of('JavaScript'), PDFDict);
37388
- if (!Javascript.has(PDFName.of('Names'))) {
37389
- Javascript.set(PDFName.of('Names'), context.obj([]));
37390
- }
37391
- const JSNames = Javascript.lookup(PDFName.of('Names'), PDFArray);
37392
- JSNames.push(PDFHexString.fromText(this.embedder.scriptName));
37393
- JSNames.push(ref);
37394
- this.alreadyEmbedded = true;
37357
+ async embed() {
37358
+ if (!this.alreadyEmbedded) {
37359
+ const { catalog, context } = this.doc;
37360
+ const ref = await this.embedder.embedIntoContext(this.doc.context, this.ref);
37361
+ if (!catalog.has(PDFName.of('Names'))) {
37362
+ catalog.set(PDFName.of('Names'), context.obj({}));
37395
37363
  }
37396
- });
37364
+ const Names = catalog.lookup(PDFName.of('Names'), PDFDict);
37365
+ if (!Names.has(PDFName.of('JavaScript'))) {
37366
+ Names.set(PDFName.of('JavaScript'), context.obj({}));
37367
+ }
37368
+ const Javascript = Names.lookup(PDFName.of('JavaScript'), PDFDict);
37369
+ if (!Javascript.has(PDFName.of('Names'))) {
37370
+ Javascript.set(PDFName.of('Names'), context.obj([]));
37371
+ }
37372
+ const JSNames = Javascript.lookup(PDFName.of('Names'), PDFArray);
37373
+ JSNames.push(PDFHexString.fromText(this.embedder.scriptName));
37374
+ JSNames.push(ref);
37375
+ this.alreadyEmbedded = true;
37376
+ }
37397
37377
  }
37398
37378
  }
37399
37379
  /**
@@ -37417,21 +37397,19 @@ end\
37417
37397
  static for(script, scriptName) {
37418
37398
  return new JavaScriptEmbedder(script, scriptName);
37419
37399
  }
37420
- embedIntoContext(context, ref) {
37421
- return __awaiter(this, void 0, void 0, function* () {
37422
- const jsActionDict = context.obj({
37423
- Type: 'Action',
37424
- S: 'JavaScript',
37425
- JS: PDFHexString.fromText(this.script),
37426
- });
37427
- if (ref) {
37428
- context.assign(ref, jsActionDict);
37429
- return ref;
37430
- }
37431
- else {
37432
- return context.register(jsActionDict);
37433
- }
37400
+ async embedIntoContext(context, ref) {
37401
+ const jsActionDict = context.obj({
37402
+ Type: 'Action',
37403
+ S: 'JavaScript',
37404
+ JS: PDFHexString.fromText(this.script),
37434
37405
  });
37406
+ if (ref) {
37407
+ context.assign(ref, jsActionDict);
37408
+ return ref;
37409
+ }
37410
+ else {
37411
+ return context.register(jsActionDict);
37412
+ }
37435
37413
  }
37436
37414
  }
37437
37415
 
@@ -39165,42 +39143,38 @@ end\
39165
39143
  * @param options The options to be used when loading the document.
39166
39144
  * @returns Resolves with a document loaded from the input.
39167
39145
  */
39168
- static load(pdf, options = {}) {
39169
- return __awaiter(this, void 0, void 0, function* () {
39170
- const { ignoreEncryption = false, parseSpeed = exports.ParseSpeeds.Slow, throwOnInvalidObject = false, updateMetadata = true, capNumbers = false, password, } = options;
39171
- assertIs(pdf, 'pdf', ['string', Uint8Array, ArrayBuffer]);
39172
- assertIs(ignoreEncryption, 'ignoreEncryption', ['boolean']);
39173
- assertIs(parseSpeed, 'parseSpeed', ['number']);
39174
- assertIs(throwOnInvalidObject, 'throwOnInvalidObject', ['boolean']);
39175
- assertIs(password, 'password', ['string', 'undefined']);
39176
- const bytes = toUint8Array(pdf);
39177
- const context = yield PDFParser.forBytesWithOptions(bytes, parseSpeed, throwOnInvalidObject, capNumbers).parseDocument();
39178
- if (!!context.lookup(context.trailerInfo.Encrypt) && password !== undefined) {
39179
- // Decrypt
39180
- const fileIds = context.lookup(context.trailerInfo.ID, PDFArray);
39181
- const encryptDict = context.lookup(context.trailerInfo.Encrypt, PDFDict);
39182
- const decryptedContext = yield PDFParser.forBytesWithOptions(bytes, parseSpeed, throwOnInvalidObject, capNumbers, new CipherTransformFactory(encryptDict, fileIds.get(0).asBytes(), password)).parseDocument();
39183
- return new PDFDocument(decryptedContext, true, updateMetadata);
39184
- }
39185
- else {
39186
- return new PDFDocument(context, ignoreEncryption, updateMetadata);
39187
- }
39188
- });
39146
+ static async load(pdf, options = {}) {
39147
+ const { ignoreEncryption = false, parseSpeed = exports.ParseSpeeds.Slow, throwOnInvalidObject = false, updateMetadata = true, capNumbers = false, password, } = options;
39148
+ assertIs(pdf, 'pdf', ['string', Uint8Array, ArrayBuffer]);
39149
+ assertIs(ignoreEncryption, 'ignoreEncryption', ['boolean']);
39150
+ assertIs(parseSpeed, 'parseSpeed', ['number']);
39151
+ assertIs(throwOnInvalidObject, 'throwOnInvalidObject', ['boolean']);
39152
+ assertIs(password, 'password', ['string', 'undefined']);
39153
+ const bytes = toUint8Array(pdf);
39154
+ const context = await PDFParser.forBytesWithOptions(bytes, parseSpeed, throwOnInvalidObject, capNumbers).parseDocument();
39155
+ if (!!context.lookup(context.trailerInfo.Encrypt) && password !== undefined) {
39156
+ // Decrypt
39157
+ const fileIds = context.lookup(context.trailerInfo.ID, PDFArray);
39158
+ const encryptDict = context.lookup(context.trailerInfo.Encrypt, PDFDict);
39159
+ const decryptedContext = await PDFParser.forBytesWithOptions(bytes, parseSpeed, throwOnInvalidObject, capNumbers, new CipherTransformFactory(encryptDict, fileIds.get(0).asBytes(), password)).parseDocument();
39160
+ return new PDFDocument(decryptedContext, true, updateMetadata);
39161
+ }
39162
+ else {
39163
+ return new PDFDocument(context, ignoreEncryption, updateMetadata);
39164
+ }
39189
39165
  }
39190
39166
  /**
39191
39167
  * Create a new [[PDFDocument]].
39192
39168
  * @returns Resolves with the newly created document.
39193
39169
  */
39194
- static create(options = {}) {
39195
- return __awaiter(this, void 0, void 0, function* () {
39196
- const { updateMetadata = true } = options;
39197
- const context = PDFContext.create();
39198
- const pageTree = PDFPageTree.withContext(context);
39199
- const pageTreeRef = context.register(pageTree);
39200
- const catalog = PDFCatalog.withContextAndPages(context, pageTreeRef);
39201
- context.trailerInfo.Root = context.register(catalog);
39202
- return new PDFDocument(context, false, updateMetadata);
39203
- });
39170
+ static async create(options = {}) {
39171
+ const { updateMetadata = true } = options;
39172
+ const context = PDFContext.create();
39173
+ const pageTree = PDFPageTree.withContext(context);
39174
+ const pageTreeRef = context.register(pageTree);
39175
+ const catalog = PDFCatalog.withContextAndPages(context, pageTreeRef);
39176
+ context.trailerInfo.Root = context.register(catalog);
39177
+ return new PDFDocument(context, false, updateMetadata);
39204
39178
  }
39205
39179
  /**
39206
39180
  * Register a fontkit instance. This must be done before custom fonts can
@@ -39684,22 +39658,20 @@ end\
39684
39658
  * @param indices The indices of the pages that should be copied.
39685
39659
  * @returns Resolves with an array of pages copied into this document.
39686
39660
  */
39687
- copyPages(srcDoc, indices) {
39688
- return __awaiter(this, void 0, void 0, function* () {
39689
- assertIs(srcDoc, 'srcDoc', [[PDFDocument, 'PDFDocument']]);
39690
- assertIs(indices, 'indices', [Array]);
39691
- yield srcDoc.flush();
39692
- const copier = PDFObjectCopier.for(srcDoc.context, this.context);
39693
- const srcPages = srcDoc.getPages();
39694
- const copiedPages = new Array(indices.length);
39695
- for (let idx = 0, len = indices.length; idx < len; idx++) {
39696
- const srcPage = srcPages[indices[idx]];
39697
- const copiedPage = copier.copy(srcPage.node);
39698
- const ref = this.context.register(copiedPage);
39699
- copiedPages[idx] = PDFPage.of(copiedPage, ref, this);
39700
- }
39701
- return copiedPages;
39702
- });
39661
+ async copyPages(srcDoc, indices) {
39662
+ assertIs(srcDoc, 'srcDoc', [[PDFDocument, 'PDFDocument']]);
39663
+ assertIs(indices, 'indices', [Array]);
39664
+ await srcDoc.flush();
39665
+ const copier = PDFObjectCopier.for(srcDoc.context, this.context);
39666
+ const srcPages = srcDoc.getPages();
39667
+ const copiedPages = new Array(indices.length);
39668
+ for (let idx = 0, len = indices.length; idx < len; idx++) {
39669
+ const srcPage = srcPages[indices[idx]];
39670
+ const copiedPage = copier.copy(srcPage.node);
39671
+ const ref = this.context.register(copiedPage);
39672
+ copiedPages[idx] = PDFPage.of(copiedPage, ref, this);
39673
+ }
39674
+ return copiedPages;
39703
39675
  }
39704
39676
  /**
39705
39677
  * Get a copy of this document.
@@ -39715,42 +39687,40 @@ end\
39715
39687
  *
39716
39688
  * @returns Resolves with a copy this document.
39717
39689
  */
39718
- copy() {
39719
- return __awaiter(this, void 0, void 0, function* () {
39720
- const pdfCopy = yield PDFDocument.create();
39721
- const contentPages = yield pdfCopy.copyPages(this, this.getPageIndices());
39722
- for (let idx = 0, len = contentPages.length; idx < len; idx++) {
39723
- pdfCopy.addPage(contentPages[idx]);
39724
- }
39725
- if (this.getAuthor() !== undefined) {
39726
- pdfCopy.setAuthor(this.getAuthor());
39727
- }
39728
- if (this.getCreationDate() !== undefined) {
39729
- pdfCopy.setCreationDate(this.getCreationDate());
39730
- }
39731
- if (this.getCreator() !== undefined) {
39732
- pdfCopy.setCreator(this.getCreator());
39733
- }
39734
- if (this.getModificationDate() !== undefined) {
39735
- pdfCopy.setModificationDate(this.getModificationDate());
39736
- }
39737
- if (this.getProducer() !== undefined) {
39738
- pdfCopy.setProducer(this.getProducer());
39739
- }
39740
- if (this.getSubject() !== undefined) {
39741
- pdfCopy.setSubject(this.getSubject());
39742
- }
39743
- if (this.getTitle() !== undefined) {
39744
- pdfCopy.setTitle(this.getTitle());
39745
- }
39746
- pdfCopy.defaultWordBreaks = this.defaultWordBreaks;
39747
- return pdfCopy;
39748
- });
39749
- }
39750
- /**
39751
- * Add JavaScript to this document. The supplied `script` is executed when the
39752
- * document is opened. The `script` can be used to perform some operation
39753
- * when the document is opened (e.g. logging to the console), or it can be
39690
+ async copy() {
39691
+ const pdfCopy = await PDFDocument.create();
39692
+ const contentPages = await pdfCopy.copyPages(this, this.getPageIndices());
39693
+ for (let idx = 0, len = contentPages.length; idx < len; idx++) {
39694
+ pdfCopy.addPage(contentPages[idx]);
39695
+ }
39696
+ if (this.getAuthor() !== undefined) {
39697
+ pdfCopy.setAuthor(this.getAuthor());
39698
+ }
39699
+ if (this.getCreationDate() !== undefined) {
39700
+ pdfCopy.setCreationDate(this.getCreationDate());
39701
+ }
39702
+ if (this.getCreator() !== undefined) {
39703
+ pdfCopy.setCreator(this.getCreator());
39704
+ }
39705
+ if (this.getModificationDate() !== undefined) {
39706
+ pdfCopy.setModificationDate(this.getModificationDate());
39707
+ }
39708
+ if (this.getProducer() !== undefined) {
39709
+ pdfCopy.setProducer(this.getProducer());
39710
+ }
39711
+ if (this.getSubject() !== undefined) {
39712
+ pdfCopy.setSubject(this.getSubject());
39713
+ }
39714
+ if (this.getTitle() !== undefined) {
39715
+ pdfCopy.setTitle(this.getTitle());
39716
+ }
39717
+ pdfCopy.defaultWordBreaks = this.defaultWordBreaks;
39718
+ return pdfCopy;
39719
+ }
39720
+ /**
39721
+ * Add JavaScript to this document. The supplied `script` is executed when the
39722
+ * document is opened. The `script` can be used to perform some operation
39723
+ * when the document is opened (e.g. logging to the console), or it can be
39754
39724
  * used to define a function that can be referenced later in a JavaScript
39755
39725
  * action. For example:
39756
39726
  * ```js
@@ -39834,23 +39804,21 @@ end\
39834
39804
  * @param name The name of the file to be attached.
39835
39805
  * @returns Resolves when the attachment is complete.
39836
39806
  */
39837
- attach(attachment, name, options = {}) {
39838
- return __awaiter(this, void 0, void 0, function* () {
39839
- assertIs(attachment, 'attachment', ['string', Uint8Array, ArrayBuffer]);
39840
- assertIs(name, 'name', ['string']);
39841
- assertOrUndefined(options.mimeType, 'mimeType', ['string']);
39842
- assertOrUndefined(options.description, 'description', ['string']);
39843
- assertOrUndefined(options.creationDate, 'options.creationDate', [Date]);
39844
- assertOrUndefined(options.modificationDate, 'options.modificationDate', [
39845
- Date,
39846
- ]);
39847
- assertIsOneOfOrUndefined(options.afRelationship, 'options.afRelationship', exports.AFRelationship);
39848
- const bytes = toUint8Array(attachment);
39849
- const embedder = FileEmbedder.for(bytes, name, options);
39850
- const ref = this.context.nextRef();
39851
- const embeddedFile = PDFEmbeddedFile.of(ref, this, embedder);
39852
- this.embeddedFiles.push(embeddedFile);
39853
- });
39807
+ async attach(attachment, name, options = {}) {
39808
+ assertIs(attachment, 'attachment', ['string', Uint8Array, ArrayBuffer]);
39809
+ assertIs(name, 'name', ['string']);
39810
+ assertOrUndefined(options.mimeType, 'mimeType', ['string']);
39811
+ assertOrUndefined(options.description, 'description', ['string']);
39812
+ assertOrUndefined(options.creationDate, 'options.creationDate', [Date]);
39813
+ assertOrUndefined(options.modificationDate, 'options.modificationDate', [
39814
+ Date,
39815
+ ]);
39816
+ assertIsOneOfOrUndefined(options.afRelationship, 'options.afRelationship', exports.AFRelationship);
39817
+ const bytes = toUint8Array(attachment);
39818
+ const embedder = FileEmbedder.for(bytes, name, options);
39819
+ const ref = this.context.nextRef();
39820
+ const embeddedFile = PDFEmbeddedFile.of(ref, this, embedder);
39821
+ this.embeddedFiles.push(embeddedFile);
39854
39822
  }
39855
39823
  /**
39856
39824
  * Embed a font into this document. The input data can be provided in multiple
@@ -39887,30 +39855,28 @@ end\
39887
39855
  * @param options The options to be used when embedding the font.
39888
39856
  * @returns Resolves with the embedded font.
39889
39857
  */
39890
- embedFont(font, options = {}) {
39891
- return __awaiter(this, void 0, void 0, function* () {
39892
- const { subset = false, customName, features } = options;
39893
- assertIs(font, 'font', ['string', Uint8Array, ArrayBuffer]);
39894
- assertIs(subset, 'subset', ['boolean']);
39895
- let embedder;
39896
- if (isStandardFont(font)) {
39897
- embedder = StandardFontEmbedder.for(font, customName);
39898
- }
39899
- else if (canBeConvertedToUint8Array(font)) {
39900
- const bytes = toUint8Array(font);
39901
- const fontkit = this.assertFontkit();
39902
- embedder = subset
39903
- ? yield CustomFontSubsetEmbedder.for(fontkit, bytes, customName, features)
39904
- : yield CustomFontEmbedder.for(fontkit, bytes, customName, features);
39905
- }
39906
- else {
39907
- throw new TypeError('`font` must be one of `StandardFonts | string | Uint8Array | ArrayBuffer`');
39908
- }
39909
- const ref = this.context.nextRef();
39910
- const pdfFont = PDFFont.of(ref, this, embedder);
39911
- this.fonts.push(pdfFont);
39912
- return pdfFont;
39913
- });
39858
+ async embedFont(font, options = {}) {
39859
+ const { subset = false, customName, features } = options;
39860
+ assertIs(font, 'font', ['string', Uint8Array, ArrayBuffer]);
39861
+ assertIs(subset, 'subset', ['boolean']);
39862
+ let embedder;
39863
+ if (isStandardFont(font)) {
39864
+ embedder = StandardFontEmbedder.for(font, customName);
39865
+ }
39866
+ else if (canBeConvertedToUint8Array(font)) {
39867
+ const bytes = toUint8Array(font);
39868
+ const fontkit = this.assertFontkit();
39869
+ embedder = subset
39870
+ ? await CustomFontSubsetEmbedder.for(fontkit, bytes, customName, features)
39871
+ : await CustomFontEmbedder.for(fontkit, bytes, customName, features);
39872
+ }
39873
+ else {
39874
+ throw new TypeError('`font` must be one of `StandardFonts | string | Uint8Array | ArrayBuffer`');
39875
+ }
39876
+ const ref = this.context.nextRef();
39877
+ const pdfFont = PDFFont.of(ref, this, embedder);
39878
+ this.fonts.push(pdfFont);
39879
+ return pdfFont;
39914
39880
  }
39915
39881
  /**
39916
39882
  * Embed a standard font into this document.
@@ -39964,16 +39930,14 @@ end\
39964
39930
  * @param jpg The input data for a JPEG image.
39965
39931
  * @returns Resolves with the embedded image.
39966
39932
  */
39967
- embedJpg(jpg) {
39968
- return __awaiter(this, void 0, void 0, function* () {
39969
- assertIs(jpg, 'jpg', ['string', Uint8Array, ArrayBuffer]);
39970
- const bytes = toUint8Array(jpg);
39971
- const embedder = yield JpegEmbedder.for(bytes);
39972
- const ref = this.context.nextRef();
39973
- const pdfImage = PDFImage.of(ref, this, embedder);
39974
- this.images.push(pdfImage);
39975
- return pdfImage;
39976
- });
39933
+ async embedJpg(jpg) {
39934
+ assertIs(jpg, 'jpg', ['string', Uint8Array, ArrayBuffer]);
39935
+ const bytes = toUint8Array(jpg);
39936
+ const embedder = await JpegEmbedder.for(bytes);
39937
+ const ref = this.context.nextRef();
39938
+ const pdfImage = PDFImage.of(ref, this, embedder);
39939
+ this.images.push(pdfImage);
39940
+ return pdfImage;
39977
39941
  }
39978
39942
  /**
39979
39943
  * Embed a PNG image into this document. The input data can be provided in
@@ -40005,16 +39969,14 @@ end\
40005
39969
  * @param png The input data for a PNG image.
40006
39970
  * @returns Resolves with the embedded image.
40007
39971
  */
40008
- embedPng(png) {
40009
- return __awaiter(this, void 0, void 0, function* () {
40010
- assertIs(png, 'png', ['string', Uint8Array, ArrayBuffer]);
40011
- const bytes = toUint8Array(png);
40012
- const embedder = yield PngEmbedder.for(bytes);
40013
- const ref = this.context.nextRef();
40014
- const pdfImage = PDFImage.of(ref, this, embedder);
40015
- this.images.push(pdfImage);
40016
- return pdfImage;
40017
- });
39972
+ async embedPng(png) {
39973
+ assertIs(png, 'png', ['string', Uint8Array, ArrayBuffer]);
39974
+ const bytes = toUint8Array(png);
39975
+ const embedder = await PngEmbedder.for(bytes);
39976
+ const ref = this.context.nextRef();
39977
+ const pdfImage = PDFImage.of(ref, this, embedder);
39978
+ this.images.push(pdfImage);
39979
+ return pdfImage;
40018
39980
  }
40019
39981
  /**
40020
39982
  * Embed one or more PDF pages into this document.
@@ -40036,19 +39998,17 @@ end\
40036
39998
  * @param indices The indices of the pages that should be embedded.
40037
39999
  * @returns Resolves with an array of the embedded pages.
40038
40000
  */
40039
- embedPdf(pdf, indices = [0]) {
40040
- return __awaiter(this, void 0, void 0, function* () {
40041
- assertIs(pdf, 'pdf', [
40042
- 'string',
40043
- Uint8Array,
40044
- ArrayBuffer,
40045
- [PDFDocument, 'PDFDocument'],
40046
- ]);
40047
- assertIs(indices, 'indices', [Array]);
40048
- const srcDoc = pdf instanceof PDFDocument ? pdf : yield PDFDocument.load(pdf);
40049
- const srcPages = pluckIndices(srcDoc.getPages(), indices);
40050
- return this.embedPages(srcPages);
40051
- });
40001
+ async embedPdf(pdf, indices = [0]) {
40002
+ assertIs(pdf, 'pdf', [
40003
+ 'string',
40004
+ Uint8Array,
40005
+ ArrayBuffer,
40006
+ [PDFDocument, 'PDFDocument'],
40007
+ ]);
40008
+ assertIs(indices, 'indices', [Array]);
40009
+ const srcDoc = pdf instanceof PDFDocument ? pdf : await PDFDocument.load(pdf);
40010
+ const srcPages = pluckIndices(srcDoc.getPages(), indices);
40011
+ return this.embedPages(srcPages);
40052
40012
  }
40053
40013
  /**
40054
40014
  * Embed a single PDF page into this document.
@@ -40082,12 +40042,10 @@ end\
40082
40042
  * page anywhere it is drawn.
40083
40043
  * @returns Resolves with the embedded pdf page.
40084
40044
  */
40085
- embedPage(page, boundingBox, transformationMatrix) {
40086
- return __awaiter(this, void 0, void 0, function* () {
40087
- assertIs(page, 'page', [[PDFPage, 'PDFPage']]);
40088
- const [embeddedPage] = yield this.embedPages([page], [boundingBox], [transformationMatrix]);
40089
- return embeddedPage;
40090
- });
40045
+ async embedPage(page, boundingBox, transformationMatrix) {
40046
+ assertIs(page, 'page', [[PDFPage, 'PDFPage']]);
40047
+ const [embeddedPage] = await this.embedPages([page], [boundingBox], [transformationMatrix]);
40048
+ return embeddedPage;
40091
40049
  }
40092
40050
  /**
40093
40051
  * Embed one or more PDF pages into this document.
@@ -40117,34 +40075,32 @@ end\
40117
40075
  * (each page's transformation will apply anywhere it is drawn).
40118
40076
  * @returns Resolves with an array of the embedded pdf pages.
40119
40077
  */
40120
- embedPages(pages, boundingBoxes = [], transformationMatrices = []) {
40121
- return __awaiter(this, void 0, void 0, function* () {
40122
- if (pages.length === 0)
40123
- return [];
40124
- // Assert all pages have the same context
40125
- for (let idx = 0, len = pages.length - 1; idx < len; idx++) {
40126
- const currPage = pages[idx];
40127
- const nextPage = pages[idx + 1];
40128
- if (currPage.node.context !== nextPage.node.context) {
40129
- throw new PageEmbeddingMismatchedContextError();
40130
- }
40131
- }
40132
- const context = pages[0].node.context;
40133
- const maybeCopyPage = context === this.context
40134
- ? (p) => p
40135
- : PDFObjectCopier.for(context, this.context).copy;
40136
- const embeddedPages = new Array(pages.length);
40137
- for (let idx = 0, len = pages.length; idx < len; idx++) {
40138
- const page = maybeCopyPage(pages[idx].node);
40139
- const box = boundingBoxes[idx];
40140
- const matrix = transformationMatrices[idx];
40141
- const embedder = yield PDFPageEmbedder.for(page, box, matrix);
40142
- const ref = this.context.nextRef();
40143
- embeddedPages[idx] = PDFEmbeddedPage.of(ref, this, embedder);
40144
- }
40145
- this.embeddedPages.push(...embeddedPages);
40146
- return embeddedPages;
40147
- });
40078
+ async embedPages(pages, boundingBoxes = [], transformationMatrices = []) {
40079
+ if (pages.length === 0)
40080
+ return [];
40081
+ // Assert all pages have the same context
40082
+ for (let idx = 0, len = pages.length - 1; idx < len; idx++) {
40083
+ const currPage = pages[idx];
40084
+ const nextPage = pages[idx + 1];
40085
+ if (currPage.node.context !== nextPage.node.context) {
40086
+ throw new PageEmbeddingMismatchedContextError();
40087
+ }
40088
+ }
40089
+ const context = pages[0].node.context;
40090
+ const maybeCopyPage = context === this.context
40091
+ ? (p) => p
40092
+ : PDFObjectCopier.for(context, this.context).copy;
40093
+ const embeddedPages = new Array(pages.length);
40094
+ for (let idx = 0, len = pages.length; idx < len; idx++) {
40095
+ const page = maybeCopyPage(pages[idx].node);
40096
+ const box = boundingBoxes[idx];
40097
+ const matrix = transformationMatrices[idx];
40098
+ const embedder = await PDFPageEmbedder.for(page, box, matrix);
40099
+ const ref = this.context.nextRef();
40100
+ embeddedPages[idx] = PDFEmbeddedPage.of(ref, this, embedder);
40101
+ }
40102
+ this.embeddedPages.push(...embeddedPages);
40103
+ return embeddedPages;
40148
40104
  }
40149
40105
  /**
40150
40106
  * > **NOTE:** You shouldn't need to call this method directly. The [[save]]
@@ -40156,14 +40112,12 @@ end\
40156
40112
  *
40157
40113
  * @returns Resolves when the flush is complete.
40158
40114
  */
40159
- flush() {
40160
- return __awaiter(this, void 0, void 0, function* () {
40161
- yield this.embedAll(this.fonts);
40162
- yield this.embedAll(this.images);
40163
- yield this.embedAll(this.embeddedPages);
40164
- yield this.embedAll(this.embeddedFiles);
40165
- yield this.embedAll(this.javaScripts);
40166
- });
40115
+ async flush() {
40116
+ await this.embedAll(this.fonts);
40117
+ await this.embedAll(this.images);
40118
+ await this.embedAll(this.embeddedPages);
40119
+ await this.embedAll(this.embeddedFiles);
40120
+ await this.embedAll(this.javaScripts);
40167
40121
  }
40168
40122
  /**
40169
40123
  * Serialize this document to an array of bytes making up a PDF file.
@@ -40181,24 +40135,22 @@ end\
40181
40135
  * @param options The options to be used when saving the document.
40182
40136
  * @returns Resolves with the bytes of the serialized document.
40183
40137
  */
40184
- save(options = {}) {
40185
- return __awaiter(this, void 0, void 0, function* () {
40186
- const { useObjectStreams = true, addDefaultPage = true, objectsPerTick = 50, updateFieldAppearances = true, } = options;
40187
- assertIs(useObjectStreams, 'useObjectStreams', ['boolean']);
40188
- assertIs(addDefaultPage, 'addDefaultPage', ['boolean']);
40189
- assertIs(objectsPerTick, 'objectsPerTick', ['number']);
40190
- assertIs(updateFieldAppearances, 'updateFieldAppearances', ['boolean']);
40191
- if (addDefaultPage && this.getPageCount() === 0)
40192
- this.addPage();
40193
- if (updateFieldAppearances) {
40194
- const form = this.formCache.getValue();
40195
- if (form)
40196
- form.updateFieldAppearances();
40197
- }
40198
- yield this.flush();
40199
- const Writer = useObjectStreams ? PDFStreamWriter : PDFWriter;
40200
- return Writer.forContext(this.context, objectsPerTick).serializeToBuffer();
40201
- });
40138
+ async save(options = {}) {
40139
+ const { useObjectStreams = true, addDefaultPage = true, objectsPerTick = 50, updateFieldAppearances = true, } = options;
40140
+ assertIs(useObjectStreams, 'useObjectStreams', ['boolean']);
40141
+ assertIs(addDefaultPage, 'addDefaultPage', ['boolean']);
40142
+ assertIs(objectsPerTick, 'objectsPerTick', ['number']);
40143
+ assertIs(updateFieldAppearances, 'updateFieldAppearances', ['boolean']);
40144
+ if (addDefaultPage && this.getPageCount() === 0)
40145
+ this.addPage();
40146
+ if (updateFieldAppearances) {
40147
+ const form = this.formCache.getValue();
40148
+ if (form)
40149
+ form.updateFieldAppearances();
40150
+ }
40151
+ await this.flush();
40152
+ const Writer = useObjectStreams ? PDFStreamWriter : PDFWriter;
40153
+ return Writer.forContext(this.context, objectsPerTick).serializeToBuffer();
40202
40154
  }
40203
40155
  /**
40204
40156
  * Serialize this document to a base64 encoded string or data URI making up a
@@ -40215,14 +40167,12 @@ end\
40215
40167
  * @returns Resolves with a base64 encoded string or data URI of the
40216
40168
  * serialized document.
40217
40169
  */
40218
- saveAsBase64(options = {}) {
40219
- return __awaiter(this, void 0, void 0, function* () {
40220
- const { dataUri = false } = options, otherOptions = __rest(options, ["dataUri"]);
40221
- assertIs(dataUri, 'dataUri', ['boolean']);
40222
- const bytes = yield this.save(otherOptions);
40223
- const base64 = encodeToBase64(bytes);
40224
- return dataUri ? `data:application/pdf;base64,${base64}` : base64;
40225
- });
40170
+ async saveAsBase64(options = {}) {
40171
+ const { dataUri = false, ...otherOptions } = options;
40172
+ assertIs(dataUri, 'dataUri', ['boolean']);
40173
+ const bytes = await this.save(otherOptions);
40174
+ const base64 = encodeToBase64(bytes);
40175
+ return dataUri ? `data:application/pdf;base64,${base64}` : base64;
40226
40176
  }
40227
40177
  findPageForAnnotationRef(ref) {
40228
40178
  const pages = this.getPages();
@@ -40235,12 +40185,10 @@ end\
40235
40185
  }
40236
40186
  return undefined;
40237
40187
  }
40238
- embedAll(embeddables) {
40239
- return __awaiter(this, void 0, void 0, function* () {
40240
- for (let idx = 0, len = embeddables.length; idx < len; idx++) {
40241
- yield embeddables[idx].embed();
40242
- }
40243
- });
40188
+ async embedAll(embeddables) {
40189
+ for (let idx = 0, len = embeddables.length; idx < len; idx++) {
40190
+ await embeddables[idx].embed();
40191
+ }
40244
40192
  }
40245
40193
  updateInfoDict() {
40246
40194
  const pdfLib = `pdf-lib (https://github.com/Hopding/pdf-lib)`;
@@ -41603,772 +41551,70 @@ end\
41603
41551
 
41604
41552
  var index = /*@__PURE__*/unwrapExports(dist);
41605
41553
 
41606
- /** This value represents the precision we accept for float values */
41607
- const FLOAT_APPROXIMATION = 0.000001;
41608
- /** Calculates the distance between 2 points */
41609
- const distance = (A, B) => norm(vector(A, B));
41610
- const distanceCoords = (A, B) => norm(minus(B, A));
41611
- /** Calculates the distance denoted by a vector */
41612
- const norm = (vect) => Math.sqrt(vect.x * vect.x + vect.y * vect.y);
41613
- /** Calculates the orthogonal vector of provided vector */
41614
- const orthogonal = ({ x, y }) => ({
41615
- x: -y,
41616
- y: x,
41617
- });
41618
- /** Check if 2 vectors are proportional */
41619
- const isColinear = ({ x: ux, y: uy }, { x: vx, y: vy }) => isEqual(ux * vy, uy * vx);
41620
- /** Check if 2 floating values can be considered equals */
41621
- const isEqual = (a, b) => Math.round(Math.abs(a - b) / FLOAT_APPROXIMATION) === 0;
41622
- /** Calculate the scalar product between 2 vectors */
41623
- const scalar = ({ x: ux, y: uy }, { x: vx, y: vy }) => ux * vx + uy * vy;
41624
- /** Calculate the sum of 2 vectors */
41625
- const plus = ({ x: ux, y: uy }, { x: vx, y: vy }) => ({ x: ux + vx, y: uy + vy });
41626
- /** Calculate the vector multiplied by a scalar */
41627
- const times = ({ x, y }, k = 1) => ({
41628
- x: k * x,
41629
- y: k * y,
41630
- });
41631
- /** Calculate the difference of 2 vectors */
41632
- const minus = (u, v) => plus(u, times(v, -1));
41633
- /** Returns the vector between 2 points. */
41634
- const vector = (A, B) => minus(B.toCoords(), A.toCoords());
41635
- /**
41636
- * Returns the angle between the vector and the horizontal axis (Ox).
41637
- * The return value is between -PI and PI.
41638
- * @returns {number} angle in radian between -Pi and Pi
41639
- */
41640
- const orientation = ({ x, y }) => {
41641
- const alpha = Math.acos(x / Math.sqrt(x * x + y * y));
41642
- return y > 0 ? alpha : -alpha;
41643
- };
41644
- /** Returns the unit vector associated to the provided vector,
41645
- * or the Null vector (0, 0) if the vector is null
41646
- */
41647
- const unitVector = (u) => {
41648
- const l = norm(u);
41649
- return l > 0 ? times(u, 1 / l) : u;
41650
- };
41651
- /** Returns the angle from u to v in radian */
41652
- const angle = (u, v, previousAngle = 0) => {
41653
- let sweep = orientation(v) - orientation(u);
41654
- // If the angle has the same sign as the arc orientation, we return the angle as is
41655
- // Otherwise, we need to correct the value, adding or removing 2π
41656
- while (Math.abs(previousAngle - sweep) > Math.PI) {
41657
- sweep += Math.sign(previousAngle - sweep) * 2 * Math.PI;
41658
- }
41659
- return sweep;
41660
- };
41661
- /** Returns the angle between the lines (BA) and (BC) in radian
41662
- * @returns {number} the angle in radian, between -Pi and Pi
41663
- */
41664
- const angleABC = (A, B, C, previousAngle = 0) => angle(vector(B, A), vector(B, C), previousAngle);
41665
- /** Rotate the vector by an angle in radian */
41666
- const rotate = (vect, teta) => {
41667
- const { x, y } = vect;
41668
- const nx = x * Math.cos(teta) - y * Math.sin(teta);
41669
- const ny = y * Math.cos(teta) + x * Math.sin(teta);
41670
- return { x: nx, y: ny };
41671
- };
41672
-
41673
- class GraphElement {
41674
- distance(P) {
41675
- const H = this.orthoProjection(P);
41676
- return distance(H, P);
41677
- }
41678
- }
41679
-
41680
- class Point extends GraphElement {
41681
- constructor(coords = { x: 0, y: 0 }) {
41682
- super();
41683
- this.x = coords.x;
41684
- this.y = coords.y;
41685
- }
41686
- toCoords() {
41687
- return { x: this.x, y: this.y };
41688
- }
41689
- isEqual(element) {
41690
- if (!(element instanceof Point))
41691
- return false;
41692
- const A = this.toCoords();
41693
- const B = element.toCoords();
41694
- return isEqual(A.x, B.x) && isEqual(A.y, B.y);
41695
- }
41696
- orthoProjection() {
41697
- return new Point(this.toCoords());
41698
- }
41699
- plus(vect) {
41700
- const P = new Point(plus(this.toCoords(), vect));
41701
- return P;
41702
- }
41703
- }
41704
- Point.type = 'PointFixed';
41705
-
41706
- class Circle extends GraphElement {
41707
- constructor(O = new Point(), r = 1) {
41708
- super();
41709
- this.O = O;
41710
- this.r = r;
41711
- }
41712
- ray() {
41713
- return this.r;
41714
- }
41715
- center() {
41716
- return this.O;
41717
- }
41718
- /** This is used to standardize type Circle | Arc */
41719
- getCircle() {
41720
- return this;
41721
- }
41722
- isEqual(element) {
41723
- return (element instanceof Circle &&
41724
- this.center().isEqual(element.center()) &&
41725
- isEqual(this.ray(), element.ray()));
41726
- }
41727
- includes(P) {
41728
- return isEqual(distance(this.center(), P), this.ray());
41729
- }
41730
- orthoProjection(P) {
41731
- const center = this.center().toCoords();
41732
- const coords = P.toCoords();
41733
- if (distanceCoords(coords, center) < this.ray())
41734
- return P;
41735
- const vect = times(unitVector(minus(coords, center)), this.ray());
41736
- return new Point(plus(center, vect));
41737
- }
41738
- }
41554
+ const identityMatrix = [1, 0, 0, 1, 0, 0];
41739
41555
 
41740
- class Arc extends GraphElement {
41741
- constructor(O = new Point(), A = new Point(), B = new Point(), lastSweep = 0) {
41742
- super();
41743
- this.O = O;
41744
- this.A = A;
41745
- this.B = B;
41746
- this.lastSweep = lastSweep;
41747
- }
41748
- center() {
41749
- return this.O;
41750
- }
41751
- origin() {
41752
- return this.A;
41753
- }
41754
- destination() {
41755
- return this.getCircle().orthoProjection(this.B);
41756
- }
41757
- sweep() {
41758
- this.lastSweep = angleABC(this.origin(), this.center(), this.destination(), this.lastSweep);
41759
- return this.lastSweep;
41760
- }
41761
- ray() {
41762
- return distance(this.center(), this.origin());
41763
- }
41764
- isEqual(element) {
41765
- if (!(element instanceof Arc))
41766
- return false;
41767
- const dest = this.destination();
41768
- const o = this.origin();
41769
- const eDest = element.destination();
41770
- const eO = element.origin();
41771
- return (this.getCircle().isEqual(element.getCircle()) &&
41772
- ((dest.isEqual(eDest) && o.isEqual(eO)) ||
41773
- (dest.isEqual(eO) && o.isEqual(eDest))));
41774
- }
41775
- getCircle() {
41776
- const circle = new Circle(this.center(), this.ray());
41777
- return circle;
41778
- }
41779
- originVect() {
41780
- return vector(this.center(), this.origin());
41781
- }
41782
- middle() {
41783
- const halfSweep = this.sweep() / 2;
41784
- const mid = this.center().plus(rotate(vector(this.center(), this.origin()), halfSweep));
41785
- return mid;
41786
- }
41787
- includes(P) {
41788
- // As angles are returned between -π and π, we need the middle of the arc
41789
- return (this.getCircle().includes(P) &&
41790
- Math.abs(angleABC(this.middle(), this.center(), P)) <=
41791
- Math.abs(this.sweep() / 2));
41792
- }
41793
- orthoProjection(P) {
41794
- const H = this.getCircle().orthoProjection(P);
41795
- if (this.includes(H))
41796
- return H;
41797
- else {
41798
- const origin = this.origin().toCoords();
41799
- const destination = this.destination().toCoords();
41800
- // Returns the closest between origin and destination
41801
- const coords = distanceCoords(H.toCoords(), origin) <
41802
- distanceCoords(H.toCoords(), destination)
41803
- ? origin
41804
- : destination;
41805
- return new Point(coords);
41556
+ const combineMatrix = ([a, b, c, d, e, f], [a2, b2, c2, d2, e2, f2]) => [
41557
+ a * a2 + c * b2,
41558
+ b * a2 + d * b2,
41559
+ a * c2 + c * d2,
41560
+ b * c2 + d * d2,
41561
+ a * e2 + c * f2 + e,
41562
+ b * e2 + d * f2 + f,
41563
+ ];
41564
+ const applyTransformation = ([a, b, c, d, e, f], { x, y }) => ({
41565
+ x: a * x + c * y + e,
41566
+ y: b * x + d * y + f
41567
+ });
41568
+ const transformationToMatrix = (name, args) => {
41569
+ switch (name) {
41570
+ case 'scale':
41571
+ case 'scaleX':
41572
+ case 'scaleY': {
41573
+ // [sx 0 0 sy 0 0]
41574
+ const [sx, sy = sx] = args;
41575
+ return [name === 'scaleY' ? 1 : sx, 0, 0, name === 'scaleX' ? 1 : sy, 0, 0];
41806
41576
  }
41807
- }
41808
- }
41809
-
41810
- class Plot extends GraphElement {
41811
- constructor(points = []) {
41812
- super();
41813
- this.points = points;
41814
- }
41815
- getPoints() {
41816
- return [...this.points];
41817
- }
41818
- translate(translationVector) {
41819
- this.points = this.points.map((point) => plus(point, translationVector));
41820
- }
41821
- isEqual(element) {
41822
- if (!(element instanceof Plot))
41823
- return false;
41824
- const points = this.getPoints().map((coord) => new Point(coord));
41825
- const points2 = element.getPoints().map((coord) => new Point(coord));
41826
- return (points.every((point, i) => point.isEqual(points2[i])) ||
41827
- points.reverse().every((point, i) => point.isEqual(points2[i])));
41828
- }
41829
- orthoProjection(P) {
41830
- const points = this.getPoints();
41831
- const orthos = points
41832
- .slice(0, -1)
41833
- .map((pt, i) => new Segment(new Point(pt), new Point(points[i + 1])))
41834
- .map((seg) => seg.orthoProjection(P));
41835
- let min = Number.POSITIVE_INFINITY;
41836
- let closest = new Point(points[0]);
41837
- orthos.forEach((ortho) => {
41838
- const d = ortho.distance(P);
41839
- if (d < min) {
41840
- min = d;
41841
- closest = ortho;
41842
- }
41843
- });
41844
- return closest;
41845
- }
41846
- }
41847
-
41848
- class Rectangle extends GraphElement {
41849
- constructor(start = new Point(), end = new Point()) {
41850
- super();
41851
- this.start = start;
41852
- this.end = end;
41853
- }
41854
- getSize() {
41855
- const start = this.start.toCoords();
41856
- const end = this.end.toCoords();
41857
- return {
41858
- width: Math.abs(start.x - end.x),
41859
- height: Math.abs(start.y - end.y),
41860
- };
41861
- }
41862
- getCoords() {
41863
- const start = this.start.toCoords();
41864
- const end = this.end.toCoords();
41865
- return {
41866
- x: Math.min(start.x, end.x),
41867
- y: Math.max(start.y, end.y),
41868
- };
41869
- }
41870
- getStart() {
41871
- const start = new Point(this.getCoords());
41872
- return start;
41873
- }
41874
- getEnd() {
41875
- const { width, height } = this.getSize();
41876
- const end = new Point(this.getStart()).plus({ x: width, y: -height });
41877
- return end;
41878
- }
41879
- center() {
41880
- const center = new Segment(this.getStart(), this.getEnd()).middle();
41881
- return center;
41882
- }
41883
- isEqual(element) {
41884
- return (element instanceof Rectangle &&
41885
- this.getStart().isEqual(element.getStart()) &&
41886
- this.getEnd().isEqual(element.getEnd()));
41887
- }
41888
- orthoProjection(P) {
41889
- const { x, y } = this.getCoords();
41890
- const end = this.getEnd().toCoords();
41891
- const { x: Px, y: Py } = P.toCoords();
41892
- const Hx = Px < x ? x : Px > end.x ? end.x : Px;
41893
- const Hy = Py > y ? y : Py < end.y ? end.y : Py;
41894
- return new Point({ x: Hx, y: Hy });
41895
- }
41896
- }
41897
- Rectangle.type = 'Rectangle';
41898
-
41899
- function intersections(A, B) {
41900
- if (A instanceof Point || B instanceof Point)
41901
- return [];
41902
- else if (A instanceof Text || B instanceof Text)
41903
- return [];
41904
- else if (A instanceof Image || B instanceof Image)
41905
- return [];
41906
- // TODO: calculate the coords of the intersection: https://www.emathzone.com/tutorials/geometry/intersection-of-line-and-ellipse.html
41907
- else if (A instanceof Line)
41908
- return intersectionsLine(A, B);
41909
- else if (A instanceof Segment) {
41910
- return intersectionsLine(A.getLine(), B).filter((P) => A.includes(new Point(P)));
41911
- }
41912
- else if (A instanceof Circle)
41913
- return intersectionsCircle(A, B);
41914
- else if (A instanceof Arc) {
41915
- return intersectionsCircle(A.getCircle(), B).filter((P) => A.includes(new Point(P)));
41916
- }
41917
- else if (A instanceof Plot)
41918
- return intersectionsPlot(A, B);
41919
- else if (A instanceof Rectangle)
41920
- return intersectionsRectangle(A, B);
41921
- else if (A instanceof Ellipse)
41922
- return intersectionsEllipse(A, B);
41923
- return A;
41924
- }
41925
- function intersectionsLine(A, B) {
41926
- if (B instanceof Line)
41927
- return intersectionLine(A, B);
41928
- else if (B instanceof Segment) {
41929
- return intersectionLine(A, B.getLine()).filter((P) => B.includes(new Point(P)));
41930
- }
41931
- else if (B instanceof Circle)
41932
- return intersectionCircleLine(B, A);
41933
- else if (B instanceof Arc) {
41934
- return intersectionsCircle(B.getCircle(), A).filter((P) => B.includes(new Point(P)));
41935
- }
41936
- else if (B instanceof Plot)
41937
- return intersectionsPlot(B, A);
41938
- else if (B instanceof Rectangle)
41939
- return intersectionsRectangle(B, A);
41940
- else if (B instanceof Ellipse)
41941
- return intersectionsEllipse(B, A);
41942
- return B;
41943
- }
41944
- function intersectionsEllipse(A, B) {
41945
- if (B instanceof Line)
41946
- return intersectionsLineAndEllipse(A, B);
41947
- else if (B instanceof Segment) {
41948
- return intersectionsEllipse(A, B.getLine()).filter((P) => B.includes(new Point(P)));
41949
- }
41950
- // TODO:
41951
- // else if (B instanceof Circle) return intersectionEllipseCircle(B, A)
41952
- else if (B instanceof Circle)
41953
- return [];
41954
- // TODO:
41955
- // else if (B instanceof Ellipse) return intersectionEllipseEllipse(B, A)
41956
- else if (B instanceof Ellipse)
41957
- return [];
41958
- else if (B instanceof Arc) {
41959
- return intersectionsEllipse(A, B.getCircle()).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
- return B;
41966
- }
41967
- function intersectionsLineAndEllipse(A, B) {
41968
- const center = A.center().toCoords();
41969
- const a = A.a();
41970
- const b = A.b();
41971
- const rotation = A.rotation();
41972
- const isLineParallel2YAxis = isEqual(B.dirVect().x, 0);
41973
- // this is a dummy value to represent a point on the line
41974
- const p1Y = isLineParallel2YAxis ? 1 : B.y(1);
41975
- const p1X = isLineParallel2YAxis ? B.origin().toCoords().x : 1;
41976
- const p1 = { x: p1X, y: p1Y };
41977
- // this is a dummy value to represent a point on the line
41978
- const p2Y = isLineParallel2YAxis ? 2 : B.y(2);
41979
- const p2X = isLineParallel2YAxis ? B.origin().toCoords().x : 2;
41980
- const p2 = { x: p2X, y: p2Y };
41981
- const p1Normalized = rotate({ x: p1.x - center.x, y: p1.y - center.y }, -rotation);
41982
- const p2Normalized = rotate({ x: p2.x - center.x, y: p2.y - center.y }, -rotation);
41983
- const angular = (p1Normalized.y - p2Normalized.y) / (p1Normalized.x - p2Normalized.x);
41984
- const linear = p1Normalized.y - angular * p1Normalized.x;
41985
- const lineY = (x) => angular * x + linear;
41986
- const denormalize = (coord) => {
41987
- const rotated = rotate(coord, rotation);
41988
- return {
41989
- x: rotated.x + center.x,
41990
- y: rotated.y + center.y,
41991
- };
41992
- };
41993
- // Intersection with vertical line
41994
- if (isEqual(p1Normalized.x - p2Normalized.x, 0)) {
41995
- const x = p1Normalized.x;
41996
- const delta = b ** 2 - (x ** 2 * b ** 2) / a ** 2;
41997
- if (delta < 0)
41998
- return [];
41999
- else if (delta === 0) {
42000
- return [{ x, y: 0 }].map(denormalize);
41577
+ case 'translate':
41578
+ case 'translateX':
41579
+ case 'translateY': {
41580
+ // [1 0 0 1 tx ty]
41581
+ const [tx, ty = tx] = args;
41582
+ // -ty is necessary because the pdf's y axis is inverted
41583
+ return [1, 0, 0, 1, name === 'translateY' ? 0 : tx, name === 'translateX' ? 0 : -ty];
42001
41584
  }
42002
- else {
42003
- const y1 = Math.sqrt((b ** 2 * (a ** 2 - x ** 2)) / a ** 2);
42004
- const y2 = -y1;
42005
- return [
42006
- { x, y: y1 },
42007
- { x, y: y2 },
42008
- ].map(denormalize);
42009
- }
42010
- }
42011
- // Intersection with any line
42012
- // the quadratic equation is:
42013
- // alpha * x ** 2 + beta * x + gamma = 0
42014
- const alpha = a ** 2 * angular ** 2 + b ** 2;
42015
- const beta = 2 * a ** 2 * (angular * linear);
42016
- const gamma = a ** 2 * (linear ** 2 - b ** 2);
42017
- const delta = beta ** 2 - 4 * alpha * gamma;
42018
- if (delta < 0)
42019
- return [];
42020
- else if (delta === 0) {
42021
- const x = -(beta ** 2) / (2 * alpha);
42022
- const y = lineY(x);
42023
- return [{ x, y }].map(denormalize);
42024
- }
42025
- else {
42026
- const x1 = (-beta + Math.sqrt(delta)) / (2 * alpha);
42027
- const y1 = lineY(x1);
42028
- const x2 = (-beta - Math.sqrt(delta)) / (2 * alpha);
42029
- const y2 = lineY(x2);
42030
- return [
42031
- { x: x1, y: y1 },
42032
- { x: x2, y: y2 },
42033
- ].map(denormalize);
42034
- }
42035
- }
42036
- function intersectionLine(A, B) {
42037
- if (isColinear(A.dirVect(), B.dirVect()))
42038
- return [];
42039
- else {
42040
- const { x: ux, y: uy } = A.dirVect();
42041
- const { x: vx, y: vy } = B.dirVect();
42042
- const { x: xA, y: yA } = A.origin().toCoords();
42043
- const { x: xB, y: yB } = B.origin().toCoords();
42044
- const x = (ux * (vx * (yA - yB) + vy * xB) - uy * vx * xA) / (ux * vy - uy * vx);
42045
- const y = (uy * (vy * (xA - xB) + vx * yB) - ux * vy * yA) / (uy * vx - ux * vy);
42046
- return [{ x, y }];
42047
- }
42048
- }
42049
- function intersectionsPlot(A, B) {
42050
- const points = A.getPoints().map((pt) => new Point(pt));
42051
- const head = points.pop();
42052
- const segments = points.map((pt, i) => new Segment(pt, points[i + 1] || head));
42053
- // @ts-ignore
42054
- const inters = segments.map((s) => intersections(s, B)).flat();
42055
- return inters;
42056
- }
42057
- function intersectionsRectangle(A, B) {
42058
- const P1 = A.getCoords();
42059
- const P3 = A.getEnd();
42060
- const P2 = { x: P1.x, y: P3.y };
42061
- const P4 = { x: P3.x, y: P1.y };
42062
- return intersections(new Plot([P1, P2, P3, P4, P1]), B);
42063
- }
42064
- function intersectionCircleLine(A, B) {
42065
- const rA = A.ray();
42066
- const O = A.center();
42067
- const H = B.orthoProjection(O);
42068
- const OH = distance(O, H);
42069
- // The line is tangeant
42070
- if (isEqual(OH, rA))
42071
- return [H];
42072
- // The line is too far from the circle
42073
- else if (OH > A.ray())
42074
- return [];
42075
- // The line cut the circle in 2 points
42076
- else {
42077
- // Pythagore
42078
- const HP = Math.sqrt(rA * rA - OH * OH);
42079
- const vect = unitVector(B.dirVect());
42080
- return [H.plus(times(vect, HP)), H.plus(times(vect, -HP))];
42081
- }
42082
- }
42083
- function intersectionCircle(A, B) {
42084
- const oA = A.center();
42085
- const oB = B.center();
42086
- const rA = A.ray();
42087
- const rB = B.ray();
42088
- const axis = vector(oA, oB);
42089
- const CC = norm(axis);
42090
- // The circles are tangeant
42091
- if (isEqual(CC, rA + rB))
42092
- return [A.orthoProjection(oB).toCoords()];
42093
- // The circles are too far from eachother
42094
- else if (CC > rA + rB)
42095
- return [];
42096
- // The intersections belong to an orthogonal axis
42097
- else {
42098
- const ratio = 1 / 2 + (rA * rA - rB * rB) / (CC * CC) / 2;
42099
- const H = oA.plus(times(axis, ratio));
42100
- return intersectionCircleLine(A, new Line(H, H.plus(orthogonal(axis))));
42101
- }
42102
- }
42103
- function intersectionsCircle(A, B) {
42104
- if (B instanceof Circle)
42105
- return intersectionCircle(A, B);
42106
- else if (B instanceof Line)
42107
- return intersectionCircleLine(A, B);
42108
- else if (B instanceof Segment) {
42109
- return intersectionCircleLine(A, B.getLine()).filter((P) => B.includes(new Point(P)));
42110
- }
42111
- else if (B instanceof Arc) {
42112
- return intersectionCircle(A, B.getCircle()).filter((P) => B.includes(new Point(P)));
42113
- }
42114
- else if (B instanceof Plot)
42115
- return intersectionsPlot(B, A);
42116
- else if (B instanceof Rectangle)
42117
- return intersectionsRectangle(B, A);
42118
- else if (B instanceof Ellipse)
42119
- return intersectionsEllipse(B, A);
42120
- return B;
42121
- }
42122
- function getIntersections(elements) {
42123
- const checked = [];
42124
- const inters = [];
42125
- elements.forEach((elt) => {
42126
- checked.forEach((e) => inters.push(...intersections(e, elt)));
42127
- checked.push(elt);
42128
- });
42129
- return inters;
42130
- }
42131
-
42132
- class Line extends GraphElement {
42133
- constructor(A = new Point(), B = new Point()) {
42134
- super();
42135
- this.A = A;
42136
- this.B = B;
42137
- }
42138
- origin() {
42139
- return this.A;
42140
- }
42141
- dirVect() {
42142
- return vector(this.A, this.B);
42143
- }
42144
- /** Line equation */
42145
- y(x) {
42146
- const a = this.a();
42147
- const b = this.b();
42148
- return a * x + b;
42149
- }
42150
- /** The slope */
42151
- a() {
42152
- const dirVect = this.dirVect();
42153
- return dirVect.y / dirVect.x;
42154
- }
42155
- /** Origin y coordinate */
42156
- b() {
42157
- const O = this.origin().toCoords();
42158
- const a = this.a();
42159
- return O.y - a * O.x;
42160
- }
42161
- isEqual(element) {
42162
- const vect = this.dirVect();
42163
- return (element instanceof Line &&
42164
- isColinear(vect, element.dirVect()) &&
42165
- (isEqual(vect.x, 0)
42166
- ? // We need to take care of the case of the vertical line
42167
- isEqual(this.origin().toCoords().x, element.origin().toCoords().x)
42168
- : isEqual(this.b(), element.b())));
42169
- }
42170
- /** Reversed line equation */
42171
- x(y) {
42172
- const dirVect = this.dirVect();
42173
- return ((y - this.b()) * dirVect.x) / dirVect.y;
42174
- }
42175
- includes(P) {
42176
- const { x, y } = P.toCoords();
42177
- const vect = this.dirVect();
42178
- return isEqual(vect.x, 0)
42179
- ? isEqual(this.origin().toCoords().x, x)
42180
- : isEqual(this.y(x), y);
42181
- }
42182
- /** This is used to standarsize type Segment | HalfLine | Line */
42183
- getLine() {
42184
- const line = new Line(this.origin(), this.B);
42185
- return line;
42186
- }
42187
- orthoProjection(P) {
42188
- const vectOrtho = orthogonal(this.dirVect());
42189
- const A = new Point(P.toCoords());
42190
- const ortho = new Line(A, A.plus(vectOrtho));
42191
- const H = intersectionLine(this, ortho)[0];
42192
- return new Point(H);
42193
- }
42194
- }
42195
-
42196
- class Segment extends GraphElement {
42197
- constructor(A = new Point(), B = new Point()) {
42198
- super();
42199
- this.A = A;
42200
- this.B = B;
42201
- }
42202
- origin() {
42203
- return this.A;
42204
- }
42205
- destination() {
42206
- return this.B;
42207
- }
42208
- dirVect() {
42209
- return vector(this.origin(), this.destination());
42210
- }
42211
- length() {
42212
- return distance(this.destination(), this.origin());
42213
- }
42214
- isEqual(element) {
42215
- if (!(element instanceof Segment))
42216
- return false;
42217
- const o = this.origin();
42218
- const dest = this.destination();
42219
- const oE = element.origin();
42220
- const destE = element.destination();
42221
- return (element instanceof Segment &&
42222
- ((o.isEqual(oE) && dest.isEqual(destE)) ||
42223
- (o.isEqual(destE) && dest.isEqual(oE))));
42224
- }
42225
- /** Returns an equivalent line object */
42226
- getLine() {
42227
- const line = new Line(this.origin(), this.destination());
42228
- return line;
42229
- }
42230
- includes(P) {
42231
- const vect = this.dirVect();
42232
- const otherVect = vector(this.origin(), P);
42233
- // The vectors are not even colinear
42234
- if (!isColinear(vect, otherVect))
42235
- return false;
42236
- // The point is behind the origin
42237
- else if (scalar(vect, otherVect) < 0)
42238
- return false;
42239
- // The point is after the destination
42240
- else if (norm(vect) < norm(otherVect))
42241
- return false;
42242
- else
42243
- return true;
42244
- }
42245
- middle() {
42246
- const mid = new Point(plus(this.origin().toCoords(), times(this.dirVect(), 0.5)));
42247
- return mid;
42248
- }
42249
- orthoProjection(P) {
42250
- const H = this.getLine().orthoProjection(P);
42251
- const vect = this.dirVect();
42252
- const origin = this.origin().toCoords();
42253
- const destination = this.destination().toCoords();
42254
- const otherVect = vector(this.origin(), H);
42255
- // The point is before the origin
42256
- if (scalar(vect, otherVect) < 0)
42257
- return new Point(origin);
42258
- // The point is after the destination
42259
- else if (norm(vect) < norm(otherVect))
42260
- return new Point(destination);
42261
- // The point is within the segment
42262
- else
42263
- return H;
42264
- }
42265
- }
42266
- Segment.type = 'Segment';
42267
-
42268
- class Ellipse extends GraphElement {
42269
- constructor(A = new Point(), B = new Point(), C = new Point()) {
42270
- super();
42271
- this.A = A;
42272
- this.B = B;
42273
- this.C = C;
42274
- }
42275
- center() {
42276
- const center = this.axis().middle();
42277
- return center;
42278
- }
42279
- axis() {
42280
- const axis = new Segment(this.A, this.B);
42281
- return axis;
42282
- }
42283
- a() {
42284
- const axis = this.axis();
42285
- return Math.max(axis.length() / 2, axis.distance(this.C));
42286
- }
42287
- b() {
42288
- const axis = this.axis();
42289
- return Math.min(axis.length() / 2, axis.distance(this.C));
42290
- }
42291
- rotation() {
42292
- const axis = this.axis();
42293
- return axis.length() / 2 > axis.distance(this.C)
42294
- ? orientation(axis.dirVect())
42295
- : orientation(orthogonal(axis.dirVect()));
42296
- }
42297
- getSize() {
42298
- return { width: 2 * this.a(), height: 2 * this.b() };
42299
- }
42300
- isEqual(element) {
42301
- if (!(element instanceof Ellipse))
42302
- return false;
42303
- const a = this.a();
42304
- const b = this.b();
42305
- const rotation = this.rotation();
42306
- const eltA = element.a();
42307
- const eltB = element.b();
42308
- const eltRotation = element.rotation();
42309
- // If the main axis is the same on both ellipse
42310
- if (eltA < eltB === a < b) {
42311
- // The rotation is equivalent module PI as the element is symetrical
42312
- return (isEqual(eltA, a) &&
42313
- isEqual(eltB, b) &&
42314
- isEqual(rotation + (Math.PI % Math.PI), eltRotation + (Math.PI % Math.PI)));
42315
- }
42316
- // If the small axis is different
42317
- else {
42318
- // We add a rotation of PI / 2 to emulate the fact that the main axis are actually orthogonal
42319
- return (isEqual(eltA, b) &&
42320
- isEqual(eltB, a) &&
42321
- isEqual(rotation + (Math.PI % Math.PI), eltRotation + (((3 * Math.PI) / 2) % Math.PI)));
42322
- }
42323
- }
42324
- includes(P) {
42325
- const { x, y } = P.toCoords();
42326
- const { x: cx, y: cy } = this.center().toCoords();
42327
- const teta = this.rotation();
42328
- return isEqual(Math.pow(((x - cx) * Math.cos(teta) + (y - cy) * Math.sin(teta)) / this.a(), 2) +
42329
- Math.pow(((x - cx) * Math.sin(teta) - (y - cy) * Math.cos(teta)) / this.b(), 2), 1);
42330
- }
42331
- orthoProjection(P) {
42332
- // We will consider that the parametric projection is a correct approximation of the distance for the current case, even if it is not orthogonal
42333
- const C = this.center();
42334
- const axis = this.axis();
42335
- const CP = vector(C, P);
42336
- const teta = angle(axis.dirVect(), vector(C, P));
42337
- const ray = this.polarRay(teta);
42338
- if (distance(P, this.center()) < ray)
42339
- return P;
42340
- const vect = times(unitVector(CP), ray);
42341
- return new Point(this.center().plus(vect).toCoords());
42342
- }
42343
- polarRay(teta) {
42344
- const a = this.a();
42345
- const b = this.b();
42346
- const excentricity = Math.sqrt(Math.abs(a * a - b * b)) / Math.max(a, b);
42347
- return (Math.min(a, b) / Math.sqrt(1 - Math.pow(excentricity * Math.cos(teta), 2)));
42348
- }
42349
- }
42350
-
42351
- /**
42352
- * take an array of T and turn it into an 2D-array where each sub array has n elements
42353
- * ex: [1,2,3,4] -> [[1,2], [3, 4]]
42354
- * @param arr the array of elements
42355
- * @param n the size of each sub array
42356
- */
42357
- const groupBy = (arr, n) => {
42358
- if (arr.length <= n)
42359
- return [arr];
42360
- return arr === null || arr === void 0 ? void 0 : arr.reduce((acc, curr, i) => {
42361
- const index = Math.floor(i / n);
42362
- if (i % n) {
42363
- acc[index].push(curr);
41585
+ case 'rotate': {
41586
+ // [cos(a) sin(a) -sin(a) cos(a) 0 0]
41587
+ const [a, x = 0, y = 0] = args;
41588
+ const t1 = transformationToMatrix('translate', [x, y]);
41589
+ const t2 = transformationToMatrix('translate', [-x, -y]);
41590
+ // -args[0] -> the '-' operator is necessary because the pdf rotation system is inverted
41591
+ const aRadians = degreesToRadians(-a);
41592
+ const r = [Math.cos(aRadians), Math.sin(aRadians), -Math.sin(aRadians), Math.cos(aRadians), 0, 0];
41593
+ // rotation around a point is the combination of: translate * rotate * (-translate)
41594
+ return combineMatrix(combineMatrix(t1, r), t2);
41595
+ }
41596
+ case 'skewY':
41597
+ case 'skewX': {
41598
+ // [1 tan(a) 0 1 0 0]
41599
+ // [1 0 tan(a) 1 0 0]
41600
+ // -args[0] -> the '-' operator is necessary because the pdf rotation system is inverted
41601
+ const a = degreesToRadians(-args[0]);
41602
+ const skew = Math.tan(a);
41603
+ const skewX = name === 'skewX' ? skew : 0;
41604
+ const skewY = name === 'skewY' ? skew : 0;
41605
+ return [1, skewY, skewX, 1, 0, 0];
42364
41606
  }
42365
- else {
42366
- acc.push([curr]);
41607
+ case 'matrix': {
41608
+ const [a, b, c, d, e, f] = args;
41609
+ const r = transformationToMatrix('scale', [1, -1]);
41610
+ const m = [a, b, c, d, e, f];
41611
+ return combineMatrix(combineMatrix(r, m), r);
42367
41612
  }
42368
- return acc;
42369
- }, []);
41613
+ default:
41614
+ return identityMatrix;
41615
+ }
42370
41616
  };
42371
- const isCoordinateInsideTheRect = (dot, rect) => isEqual(0, distance(dot, rect.orthoProjection(dot)));
41617
+ const combineTransformation = (matrix, name, args) => combineMatrix(matrix, transformationToMatrix(name, args));
42372
41618
  const StrokeLineCapMap = {
42373
41619
  butt: exports.LineCapStyle.Butt,
42374
41620
  round: exports.LineCapStyle.Round,
@@ -42383,662 +41629,144 @@ end\
42383
41629
  miter: exports.LineJoinStyle.Miter,
42384
41630
  round: exports.LineJoinStyle.Round,
42385
41631
  };
42386
- const getInnerSegment = (start, end, rect) => {
42387
- const isStartInside = isCoordinateInsideTheRect(start, rect);
42388
- const isEndInside = isCoordinateInsideTheRect(end, rect);
42389
- let resultLineStart = start;
42390
- let resultLineEnd = end;
42391
- // it means that the segment is already inside the rect
42392
- if (isEndInside && isStartInside)
42393
- return new Segment(start, end);
42394
- const line = new Segment(start, end);
42395
- const intersection = getIntersections([rect, line]);
42396
- // if there's no intersection it means that the line doesn't intersects the svgRect and isn't visible
42397
- if (intersection.length === 0)
42398
- return;
42399
- if (!isStartInside) {
42400
- // replace the line start point by the nearest intersection
42401
- const nearestPoint = intersection.sort((p1, p2) => distanceCoords(start, p1) - distanceCoords(start, p2))[0];
42402
- resultLineStart = new Point(nearestPoint);
42403
- }
42404
- if (!isEndInside) {
42405
- // replace the line start point by the nearest intersection
42406
- const nearestPoint = intersection.sort((p1, p2) => distanceCoords(end, p1) - distanceCoords(end, p2))[0];
42407
- resultLineEnd = new Point(nearestPoint);
42408
- }
42409
- return new Segment(resultLineStart, resultLineEnd);
42410
- };
42411
- const cropSvgElement = (svgRect, element) => {
42412
- var _a, _b;
42413
- switch (element.tagName) {
42414
- case 'text': {
42415
- const fontSize = element.svgAttributes.fontSize || 12;
42416
- // TODO: compute the right font boundaries to know which characters should be drawn
42417
- // this is an workaround to draw text that are just a little outside the viewbox boundaries
42418
- const start = new Point({
42419
- x: element.svgAttributes.x || 0,
42420
- y: element.svgAttributes.y || 0,
42421
- });
42422
- const paddingRect = new Rectangle(new Point({
42423
- x: svgRect.start.x - fontSize,
42424
- y: svgRect.start.y + fontSize,
42425
- }), new Point({ x: svgRect.end.x + fontSize, y: svgRect.end.y - fontSize }));
42426
- if (!isCoordinateInsideTheRect(start, paddingRect)) {
42427
- element.set_content('');
42428
- }
42429
- break;
42430
- }
42431
- case 'line': {
42432
- const start = new Point({
42433
- x: element.svgAttributes.x1,
42434
- y: element.svgAttributes.y1,
42435
- });
42436
- const end = new Point({
42437
- x: element.svgAttributes.x2,
42438
- y: element.svgAttributes.y2,
42439
- });
42440
- const line = getInnerSegment(start, end, svgRect);
42441
- element.svgAttributes.x1 = line ? line.A.x : 0;
42442
- element.svgAttributes.x2 = line ? line.B.x : 0;
42443
- element.svgAttributes.y1 = line ? line.A.y : 0;
42444
- element.svgAttributes.y2 = line ? line.B.y : 0;
42445
- break;
42446
- }
42447
- case 'path': {
42448
- // the path origin coordinate
42449
- const basePoint = new Point({
42450
- x: element.svgAttributes.x || 0,
42451
- y: element.svgAttributes.y || 0,
42452
- });
42453
- const normalizePoint = (p) => new Point({ x: p.x - basePoint.x, y: p.y - basePoint.y });
42454
- /**
42455
- *
42456
- * @param origin is the origin of the current drawing in the page coordinate system
42457
- * @param command the path instruction
42458
- * @param params the instruction params
42459
- * @returns the point where the next instruction starts and the new instruction text
42460
- */
42461
- const handlePath = (origin, command, params) => {
42462
- switch (command) {
42463
- case 'm':
42464
- case 'M': {
42465
- const isLocalInstruction = command === command.toLocaleLowerCase();
42466
- const nextPoint = new Point({
42467
- x: (isLocalInstruction ? origin.x : basePoint.x) + params[0],
42468
- y: (isLocalInstruction ? origin.y : basePoint.y) + params[1],
42469
- });
42470
- return {
42471
- point: nextPoint,
42472
- command: `${command}${params[0]},${params[1]}`,
42473
- };
42474
- }
42475
- case 'v':
42476
- case 'V':
42477
- case 'h':
42478
- case 'H':
42479
- case 'l':
42480
- case 'L': {
42481
- const isLocalInstruction = ['l', 'v', 'h'].includes(command);
42482
- const getNextPoint = () => {
42483
- switch (command.toLocaleLowerCase()) {
42484
- case 'l':
42485
- return new Point({
42486
- x: (isLocalInstruction ? origin.x : basePoint.x) + params[0],
42487
- y: (isLocalInstruction ? origin.y : basePoint.y) + params[1],
42488
- });
42489
- case 'v':
42490
- return new Point({
42491
- x: origin.x,
42492
- y: (isLocalInstruction ? origin.y : basePoint.y) + params[0],
42493
- });
42494
- case 'h':
42495
- return new Point({
42496
- x: (isLocalInstruction ? origin.x : basePoint.x) + params[0],
42497
- y: origin.y,
42498
- });
42499
- default:
42500
- return new Point({
42501
- x: 0,
42502
- y: 0,
42503
- });
42504
- }
42505
- };
42506
- const nextPoint = getNextPoint();
42507
- const normalizedNext = normalizePoint(nextPoint);
42508
- let endPoint = new Point({ x: nextPoint.x, y: nextPoint.y });
42509
- let startPoint = new Point({ x: origin.x, y: origin.y });
42510
- const result = getInnerSegment(startPoint, endPoint, svgRect);
42511
- if (!result) {
42512
- return {
42513
- point: nextPoint,
42514
- command: `M${normalizedNext.x},${normalizedNext.y}`,
42515
- };
42516
- }
42517
- // if the point wasn't moved it means that it's inside the rect
42518
- const isStartInside = result.A.isEqual(startPoint);
42519
- const isEndInside = result.B.isEqual(endPoint);
42520
- // the intersection points are referencing the pdf coordinates, it's necessary to convert these points to the path's origin point
42521
- endPoint = normalizePoint(new Point(result.B.toCoords()));
42522
- startPoint = normalizePoint(new Point(result.A.toCoords()));
42523
- const startInstruction = isStartInside
42524
- ? ''
42525
- : `M${startPoint.x},${startPoint.y}`;
42526
- const endInstruction = isEndInside
42527
- ? ''
42528
- : `M${normalizedNext.x},${normalizedNext.y}`;
42529
- return {
42530
- point: nextPoint,
42531
- command: `${startInstruction} L${endPoint.x},${endPoint.y} ${endInstruction} `,
42532
- };
42533
- }
42534
- case 'a':
42535
- case 'A': {
42536
- const isLocalInstruction = command === 'a';
42537
- const [, , , , , x, y] = params;
42538
- const nextPoint = new Point({
42539
- x: (isLocalInstruction ? origin.x : basePoint.x) + x,
42540
- y: (isLocalInstruction ? origin.y : basePoint.y) + y,
42541
- });
42542
- // TODO: implement the code to fit the Elliptical Arc Curve instructions into the viewbox
42543
- return {
42544
- point: nextPoint,
42545
- command: `${command} ${params.map((p) => `${p}`).join()}`,
42546
- };
42547
- }
42548
- case 'c':
42549
- case 'C': {
42550
- const isLocalInstruction = command === 'c';
42551
- let x = 0;
42552
- let y = 0;
42553
- for (let pendingParams = params; pendingParams.length > 0; pendingParams = pendingParams.slice(6)) {
42554
- const [, , , , pendingX, pendingY] = pendingParams;
42555
- if (isLocalInstruction) {
42556
- x += pendingX;
42557
- y += pendingY;
42558
- }
42559
- else {
42560
- x = pendingX;
42561
- y = pendingY;
42562
- }
42563
- }
42564
- const nextPoint = new Point({
42565
- x: (isLocalInstruction ? origin.x : basePoint.x) + x,
42566
- y: (isLocalInstruction ? origin.y : basePoint.y) + y,
42567
- });
42568
- // TODO: implement the code to fit the Cubic Bézier Curve instructions into the viewbox
42569
- return {
42570
- point: nextPoint,
42571
- command: `${command} ${params.map((p) => `${p}`).join()}`,
42572
- };
42573
- }
42574
- case 's':
42575
- case 'S':
42576
- const isLocalInstruction = command === 's';
42577
- let x = 0;
42578
- let y = 0;
42579
- for (let pendingParams = params; pendingParams.length > 0; pendingParams = pendingParams.slice(4)) {
42580
- const [, , pendingX, pendingY] = pendingParams;
42581
- x += pendingX;
42582
- y += pendingY;
42583
- }
42584
- const nextPoint = new Point({
42585
- x: (isLocalInstruction ? origin.x : basePoint.x) + x,
42586
- y: (isLocalInstruction ? origin.y : basePoint.y) + y,
42587
- });
42588
- return {
42589
- point: nextPoint,
42590
- command: `${command} ${params.map((p) => `${p}`).join()}`,
42591
- };
42592
- case 'q':
42593
- case 'Q': {
42594
- const isLocalInstruction = command === 'q';
42595
- const [, , x, y] = params;
42596
- const nextPoint = new Point({
42597
- x: (isLocalInstruction ? origin.x : basePoint.x) + x,
42598
- y: (isLocalInstruction ? origin.y : basePoint.y) + y,
42599
- });
42600
- // TODO: implement the code to fit the Quadratic Bézier Curve instructions into the viewbox
42601
- return {
42602
- point: nextPoint,
42603
- command: `${command} ${params.map((p) => `${p}`).join()}`,
42604
- };
42605
- }
42606
- // TODO: Handle the remaining svg instructions: t,q
42607
- default:
42608
- return {
42609
- point: origin,
42610
- command: `${command} ${params.map((p) => `${p}`).join()}`,
42611
- };
42612
- }
42613
- };
42614
- 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);
42615
- let currentPoint = new Point({ x: basePoint.x, y: basePoint.y });
42616
- const newPath = commands === null || commands === void 0 ? void 0 : commands.map((command) => {
42617
- var _a, _b;
42618
- const letter = (_a = command.match(/[a-z]/i)) === null || _a === void 0 ? void 0 : _a[0];
42619
- const params = (_b = command
42620
- .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));
42621
- if (letter && params) {
42622
- const result = handlePath(currentPoint, letter, params);
42623
- if (result) {
42624
- currentPoint = result.point;
42625
- return result.command;
42626
- }
42627
- }
42628
- return command;
42629
- }).join(' ');
42630
- element.svgAttributes.d = newPath;
42631
- break;
42632
- }
42633
- case 'ellipse':
42634
- case 'circle': {
42635
- if (element.svgAttributes.cx === undefined ||
42636
- element.svgAttributes.cy === undefined ||
42637
- element.svgAttributes.rx === undefined ||
42638
- element.svgAttributes.ry === undefined) {
42639
- break;
42640
- }
42641
- const { cx = 0, cy = 0, rx = 0, ry = 0 } = element.svgAttributes;
42642
- const center = new Point({
42643
- x: cx,
42644
- y: cy,
42645
- });
42646
- const rotation = ((_b = element.svgAttributes.rotation) === null || _b === void 0 ? void 0 : _b.angle) || 0;
42647
- // these points are relative to the ellipse's center
42648
- const a = new Point(rotate({ x: -rx, y: 0 }, degreesToRadians(rotation)));
42649
- const b = new Point(rotate({ x: rx, y: 0 }, degreesToRadians(rotation)));
42650
- const c = new Point(rotate({ x: 0, y: ry }, degreesToRadians(rotation)));
42651
- // these points are relative to the real coordinate system
42652
- const A = center.plus(a);
42653
- const B = center.plus(b);
42654
- const C = center.plus(c);
42655
- const ellipse = new Ellipse(A, B, C);
42656
- const intersections = getIntersections([svgRect, ellipse]);
42657
- const isCenterInsideRect = isCoordinateInsideTheRect(center, svgRect);
42658
- /**
42659
- * if there are less than 2 intersection, there are two possibilities:
42660
- * - the ellipse is outside the viewbox and therefore isn't visible
42661
- * - the ellipse is inside the viewbox and don't need to be cropped
42662
- */
42663
- if (intersections.length < 2) {
42664
- !isCenterInsideRect && element.setAttribute('rx', '0');
42665
- !isCenterInsideRect && (element.svgAttributes.rx = 0);
42666
- !isCenterInsideRect && element.setAttribute('ry', '0');
42667
- !isCenterInsideRect && (element.svgAttributes.ry = 0);
42668
- break;
42669
- }
42670
- // viewbox rectangle coordinates
42671
- const P1 = new Point(svgRect.getCoords());
42672
- const P3 = new Point(svgRect.getEnd());
42673
- const P2 = new Point({ x: P3.x, y: P1.y });
42674
- const P4 = new Point({ x: P1.x, y: P3.y });
42675
- const top = new Segment(P1, P2);
42676
- const right = new Segment(P2, P3);
42677
- const bottom = new Segment(P3, P4);
42678
- const left = new Segment(P4, P1);
42679
- // Warning: keep the order of the segments, it's important when building the path that will represent the ellipse
42680
- const rectSegments = [top, right, bottom, left];
42681
- const isPointInsideEllipse = (P) => (P.x - cx) ** 2 / rx ** 2 + (P.y - cy) ** 2 / ry ** 2 <= 1;
42682
- // check if the rect boundaries are inside the circle
42683
- const isRectInsideEllipse = isPointInsideEllipse(P1) &&
42684
- isPointInsideEllipse(P2) &&
42685
- isPointInsideEllipse(P3) &&
42686
- isPointInsideEllipse(P4);
42687
- // the segments that are intersecting the circle. And, therefore, are lines that are cropping the drawing
42688
- const circleSegments = isRectInsideEllipse
42689
- ? rectSegments
42690
- : rectSegments.map((segment, i) => {
42691
- const [p1, p2] = getIntersections([segment, ellipse])
42692
- // it's important to sort the segment's point because it impacts the angle of the arc, the points are sorted on clockwise direction
42693
- .sort((p1, p2) => {
42694
- // top
42695
- if (i === 0) {
42696
- return p1.x - p2.x;
42697
- // right
42698
- }
42699
- else if (i === 1) {
42700
- return p2.y - p1.y;
42701
- // bottom
42702
- }
42703
- else if (i === 2) {
42704
- return p2.x - p1.x;
42705
- // left
42706
- }
42707
- else {
42708
- return p1.y - p2.y;
42709
- }
42710
- });
42711
- if (p1 && p2) {
42712
- return new Segment(new Point(p1), new Point(p2));
42713
- // if the other point isn't inside the circle it means that the circle isn't cropped by the segment
42714
- }
42715
- else if (p1 &&
42716
- (isPointInsideEllipse(segment.A) ||
42717
- isPointInsideEllipse(segment.B))) {
42718
- const intersectionPoint = new Point(p1);
42719
- const innerPoint = isPointInsideEllipse(segment.A)
42720
- ? segment.A
42721
- : segment.B;
42722
- // ensures that the segment is always following the clockwise direction
42723
- const start = innerPoint.isEqual(segment.A)
42724
- ? innerPoint
42725
- : intersectionPoint;
42726
- const end = innerPoint.isEqual(segment.A)
42727
- ? intersectionPoint
42728
- : innerPoint;
42729
- return new Segment(start, end);
42730
- // 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
42731
- }
42732
- else if (!(p1 && p2) &&
42733
- isPointInsideEllipse(segment.A) &&
42734
- isPointInsideEllipse(segment.B)) {
42735
- return segment;
42736
- }
42737
- return;
42738
- });
42739
- const inverseAngle = (angle) => (360 - angle) % 360;
42740
- const pointsAngle = (p1, p2, direction = 'clockwise') => {
42741
- const startAngle = radiansToDegrees(Math.atan2(p1.y - center.y, p1.x - center.x));
42742
- const endAngle = radiansToDegrees(Math.atan2(p2.y - center.y, p2.x - center.x));
42743
- const arcAngle = (endAngle + (360 - startAngle)) % 360;
42744
- return direction === 'clockwise' ? arcAngle : inverseAngle(arcAngle);
42745
- };
42746
- /**
42747
- * - draw a line for each segment
42748
- * - if two segments aren't connected draw an arc connecting them
42749
- */
42750
- let startPoint;
42751
- // the point where the pen is located
42752
- let currentPoint;
42753
- let lastSegment;
42754
- let path = circleSegments.reduce((path, segment) => {
42755
- if (!segment)
42756
- return path;
42757
- if (!startPoint) {
42758
- startPoint = segment.A;
42759
- path = `M ${segment.A.x},${segment.A.y}`;
42760
- }
42761
- // if the current segment isn't connected to the last one, connect both with an arc
42762
- if (lastSegment && !lastSegment.B.isEqual(segment.A)) {
42763
- const arcAngle = pointsAngle(segment.A, lastSegment.B);
42764
- // angles greater than 180 degrees are marked as large-arc-flag = 1
42765
- path += `A ${rx},${ry} ${rotation} ${arcAngle > 180 ? 1 : 0},0 ${segment.A.x}, ${segment.A.y}`;
42766
- }
42767
- path += ` L ${segment.B.x},${segment.B.y}`;
42768
- currentPoint = segment.B;
42769
- lastSegment = segment;
42770
- return path;
42771
- }, '');
42772
- // if the path isn't closed, close it by drawing an arc
42773
- if (startPoint && currentPoint && !startPoint.isEqual(currentPoint)) {
42774
- const arcAngle = pointsAngle(currentPoint, startPoint, 'counter-clockwise');
42775
- // angles greater than 180 degrees are marked as large-arc-flag = 1
42776
- path += `A ${rx},${ry} ${rotation} ${arcAngle > 180 ? 1 : 0},0 ${startPoint.x}, ${startPoint.y}`;
42777
- }
42778
- // create a new element that will represent the cropped ellipse
42779
- const newElement = index.parse(`<path d="${path}" fill="red"/>`).firstChild;
42780
- const svgAttributes = Object.assign(Object.assign({}, element.svgAttributes), {
42781
- // the x and y values are 0 because all the path coordinates are global
42782
- x: 0, y: 0,
42783
- // the path coordinates are already rotated
42784
- rotate: undefined, d: path });
42785
- Object.assign(newElement, { svgAttributes });
42786
- return newElement;
42787
- }
42788
- case 'rect': {
42789
- const { x = 0, y = 0, width = 0, height = 0, rotate: rawRotation, } = element.svgAttributes;
42790
- const rotation = (rawRotation === null || rawRotation === void 0 ? void 0 : rawRotation.angle) || 0;
42791
- if (!(width && height))
42792
- return element;
42793
- // bottomLeft point
42794
- const origin = new Point({ x, y });
42795
- const rotateAroundOrigin = (p) => new Point(rotate(normalize(p), degreesToRadians(rotation))).plus(origin);
42796
- const normalize = (p) => p.plus({ x: -origin.x, y: -origin.y });
42797
- const topLeft = rotateAroundOrigin(origin.plus({ x: 0, y: -height }));
42798
- const topRight = rotateAroundOrigin(origin.plus({ x: width, y: -height }));
42799
- const bottomRight = rotateAroundOrigin(origin.plus({ x: width, y: 0 }));
42800
- const pointToString = (p) => [p.x, p.y].join();
42801
- const d = `M${pointToString(topLeft)} L${pointToString(topRight)} L${pointToString(bottomRight)} L${pointToString(origin)} L${pointToString(topLeft)}`;
42802
- const el = index.parse(`<path d="${d}"/>`).firstChild;
42803
- const newAttributes = Object.assign(Object.assign({}, element.svgAttributes), { d, x: 0, y: 0 });
42804
- // @ts-ignore
42805
- delete newAttributes.width;
42806
- // @ts-ignore
42807
- delete newAttributes.height;
42808
- delete newAttributes.rotate;
42809
- delete newAttributes.rotation;
42810
- Object.assign(el, {
42811
- svgAttributes: newAttributes,
42812
- });
42813
- return cropSvgElement(svgRect, el);
42814
- }
42815
- // TODO: implement the crop for the following elements
42816
- case 'image':
42817
- default:
42818
- return element;
42819
- }
42820
- return element;
42821
- };
42822
41632
  // TODO: Improve type system to require the correct props for each tagName.
42823
41633
  /** methods to draw SVGElements onto a PDFPage */
42824
41634
  const runnersToPage = (page, options) => ({
42825
- text(element) {
42826
- return __awaiter(this, void 0, void 0, function* () {
42827
- const anchor = element.svgAttributes.textAnchor;
42828
- const dominantBaseline = element.svgAttributes.dominantBaseline;
42829
- const text = element.text.trim().replace(/\s/g, ' ');
42830
- const fontSize = element.svgAttributes.fontSize || 12;
42831
- /** This will find the best font for the provided style in the list */
42832
- function getBestFont(style, fonts) {
42833
- const family = style.fontFamily;
42834
- if (!family)
42835
- return undefined;
42836
- const isBold = style.fontWeight === 'bold' || Number(style.fontWeight) >= 700;
42837
- const isItalic = style.fontStyle === 'italic';
42838
- const getFont = (bold, italic, family) => fonts[family + (bold ? '_bold' : '') + (italic ? '_italic' : '')];
42839
- return (getFont(isBold, isItalic, family) ||
42840
- getFont(isBold, false, family) ||
42841
- getFont(false, isItalic, family) ||
42842
- getFont(false, false, family) ||
42843
- Object.keys(fonts).find((fontFamily) => fontFamily.startsWith(family)));
42844
- }
42845
- const font = options.fonts && getBestFont(element.svgAttributes, options.fonts);
42846
- const textWidth = (font || page.getFont()[0]).widthOfTextAtSize(text, fontSize);
42847
- const textHeight = (font || page.getFont()[0]).heightAtSize(fontSize);
42848
- const offsetX = anchor === 'middle' ? textWidth / 2 : anchor === 'end' ? textWidth : 0;
42849
- const offsetY = dominantBaseline === 'text-before-edge'
42850
- ? textHeight
42851
- : dominantBaseline === 'text-after-edge'
42852
- ? -textHeight
42853
- : dominantBaseline === 'middle'
42854
- ? textHeight / 2
42855
- : 0;
42856
- const point = new Point({
42857
- x: (element.svgAttributes.x || 0) - offsetX,
42858
- y: (element.svgAttributes.y || 0) - offsetY,
42859
- });
42860
- // TODO: compute the right font boundaries to know which characters should be drawed
42861
- // this is an workaround to draw text that are just a little outside the viewbox boundaries
42862
- page.drawText(text, {
42863
- x: point.x,
42864
- y: point.y,
42865
- font,
42866
- size: fontSize,
42867
- color: element.svgAttributes.fill,
42868
- opacity: element.svgAttributes.fillOpacity,
42869
- rotate: element.svgAttributes.rotate,
42870
- });
41635
+ async text(element) {
41636
+ const anchor = element.svgAttributes.textAnchor;
41637
+ const dominantBaseline = element.svgAttributes.dominantBaseline;
41638
+ const text = element.text.trim().replace(/\s/g, ' ');
41639
+ const fontSize = element.svgAttributes.fontSize || 12;
41640
+ /** This will find the best font for the provided style in the list */
41641
+ function getBestFont(style, fonts) {
41642
+ const family = style.fontFamily;
41643
+ if (!family)
41644
+ return undefined;
41645
+ const isBold = style.fontWeight === 'bold' || Number(style.fontWeight) >= 700;
41646
+ const isItalic = style.fontStyle === 'italic';
41647
+ const getFont = (bold, italic, family) => fonts[family + (bold ? '_bold' : '') + (italic ? '_italic' : '')];
41648
+ return (getFont(isBold, isItalic, family) ||
41649
+ getFont(isBold, false, family) ||
41650
+ getFont(false, isItalic, family) ||
41651
+ getFont(false, false, family) ||
41652
+ Object.keys(fonts).find((fontFamily) => fontFamily.startsWith(family)));
41653
+ }
41654
+ const font = options.fonts && getBestFont(element.svgAttributes, options.fonts);
41655
+ const textWidth = (font || page.getFont()[0]).widthOfTextAtSize(text, fontSize);
41656
+ const textHeight = (font || page.getFont()[0]).heightAtSize(fontSize);
41657
+ const offsetX = anchor === 'middle' ? textWidth / 2 : anchor === 'end' ? textWidth : 0;
41658
+ const offsetY = dominantBaseline === 'text-before-edge'
41659
+ ? textHeight
41660
+ : dominantBaseline === 'text-after-edge'
41661
+ ? -textHeight
41662
+ : dominantBaseline === 'middle'
41663
+ ? textHeight / 2
41664
+ : 0;
41665
+ page.drawText(text, {
41666
+ x: -offsetX,
41667
+ y: -offsetY,
41668
+ font,
41669
+ // TODO: the font size should be correctly scaled too
41670
+ size: fontSize,
41671
+ color: element.svgAttributes.fill,
41672
+ opacity: element.svgAttributes.fillOpacity,
41673
+ matrix: element.svgAttributes.matrix,
41674
+ clipSpaces: element.svgAttributes.clipSpaces,
42871
41675
  });
42872
41676
  },
42873
- line(element) {
42874
- return __awaiter(this, void 0, void 0, function* () {
42875
- page.drawLine({
42876
- start: {
42877
- x: element.svgAttributes.x1,
42878
- y: element.svgAttributes.y1,
42879
- },
42880
- end: {
42881
- x: element.svgAttributes.x2,
42882
- y: element.svgAttributes.y2,
42883
- },
42884
- thickness: element.svgAttributes.strokeWidth,
42885
- color: element.svgAttributes.stroke,
42886
- opacity: element.svgAttributes.strokeOpacity,
42887
- lineCap: element.svgAttributes.strokeLineCap,
42888
- });
41677
+ async line(element) {
41678
+ page.drawLine({
41679
+ start: {
41680
+ x: element.svgAttributes.x1 || 0,
41681
+ y: -element.svgAttributes.y1 || 0,
41682
+ },
41683
+ end: {
41684
+ x: element.svgAttributes.x2 || 0,
41685
+ y: -element.svgAttributes.y2 || 0,
41686
+ },
41687
+ thickness: element.svgAttributes.strokeWidth,
41688
+ color: element.svgAttributes.stroke,
41689
+ opacity: element.svgAttributes.strokeOpacity,
41690
+ lineCap: element.svgAttributes.strokeLineCap,
41691
+ matrix: element.svgAttributes.matrix,
41692
+ clipSpaces: element.svgAttributes.clipSpaces,
42889
41693
  });
42890
41694
  },
42891
- path(element) {
42892
- return __awaiter(this, void 0, void 0, function* () {
42893
- if (!element.svgAttributes.d)
42894
- return;
42895
- // See https://jsbin.com/kawifomupa/edit?html,output and
42896
- page.drawSvgPath(element.svgAttributes.d, {
42897
- x: element.svgAttributes.x || 0,
42898
- y: element.svgAttributes.y || 0,
42899
- borderColor: element.svgAttributes.stroke,
42900
- borderWidth: element.svgAttributes.strokeWidth,
42901
- borderOpacity: element.svgAttributes.strokeOpacity,
42902
- borderLineCap: element.svgAttributes.strokeLineCap,
42903
- color: element.svgAttributes.fill,
42904
- opacity: element.svgAttributes.fillOpacity,
42905
- scale: element.svgAttributes.scale,
42906
- rotate: element.svgAttributes.rotate,
42907
- fillRule: element.svgAttributes.fillRule,
42908
- });
41695
+ async path(element) {
41696
+ if (!element.svgAttributes.d)
41697
+ return;
41698
+ // See https://jsbin.com/kawifomupa/edit?html,output and
41699
+ page.drawSvgPath(element.svgAttributes.d, {
41700
+ x: 0,
41701
+ y: 0,
41702
+ borderColor: element.svgAttributes.stroke,
41703
+ borderWidth: element.svgAttributes.strokeWidth,
41704
+ borderOpacity: element.svgAttributes.strokeOpacity,
41705
+ borderLineCap: element.svgAttributes.strokeLineCap,
41706
+ color: element.svgAttributes.fill,
41707
+ opacity: element.svgAttributes.fillOpacity,
41708
+ fillRule: element.svgAttributes.fillRule,
41709
+ matrix: element.svgAttributes.matrix,
41710
+ clipSpaces: element.svgAttributes.clipSpaces,
42909
41711
  });
42910
41712
  },
42911
- image(element) {
42912
- return __awaiter(this, void 0, void 0, function* () {
42913
- const { src } = element.svgAttributes;
42914
- if (!src)
42915
- return;
42916
- const isPng = src.match(/\.png(\?|$)|^data:image\/png;base64/gim);
42917
- const img = isPng
42918
- ? yield page.doc.embedPng(src)
42919
- : yield page.doc.embedJpg(src);
42920
- const { x, y, width, height } = getFittingRectangle(img.width, img.height, element.svgAttributes.width || img.width, element.svgAttributes.height || img.height, element.svgAttributes.preserveAspectRatio);
42921
- page.drawImage(img, {
42922
- x: (element.svgAttributes.x || 0) + x,
42923
- y: (element.svgAttributes.y || 0) - y - height,
42924
- width,
42925
- height,
42926
- opacity: element.svgAttributes.fillOpacity,
42927
- xSkew: element.svgAttributes.skewX,
42928
- ySkew: element.svgAttributes.skewY,
42929
- rotate: element.svgAttributes.rotate,
42930
- });
41713
+ async image(element) {
41714
+ const { src } = element.svgAttributes;
41715
+ if (!src)
41716
+ return;
41717
+ const isPng = src.match(/\.png(\?|$)|^data:image\/png;base64/gim);
41718
+ const img = isPng
41719
+ ? await page.doc.embedPng(src)
41720
+ : await page.doc.embedJpg(src);
41721
+ const { x, y, width, height } = getFittingRectangle(img.width, img.height, element.svgAttributes.width || img.width, element.svgAttributes.height || img.height, element.svgAttributes.preserveAspectRatio);
41722
+ page.drawImage(img, {
41723
+ x,
41724
+ y: -y - height,
41725
+ width,
41726
+ height,
41727
+ opacity: element.svgAttributes.fillOpacity,
41728
+ matrix: element.svgAttributes.matrix,
41729
+ clipSpaces: element.svgAttributes.clipSpaces,
42931
41730
  });
42932
41731
  },
42933
- rect(element) {
42934
- return __awaiter(this, void 0, void 0, function* () {
42935
- if (!element.svgAttributes.fill && !element.svgAttributes.stroke)
42936
- return;
42937
- page.drawRectangle({
42938
- x: element.svgAttributes.x,
42939
- y: element.svgAttributes.y || 0,
42940
- width: element.svgAttributes.width,
42941
- height: element.svgAttributes.height * -1,
42942
- borderColor: element.svgAttributes.stroke,
42943
- borderWidth: element.svgAttributes.strokeWidth,
42944
- borderOpacity: element.svgAttributes.strokeOpacity,
42945
- borderLineCap: element.svgAttributes.strokeLineCap,
42946
- color: element.svgAttributes.fill,
42947
- opacity: element.svgAttributes.fillOpacity,
42948
- xSkew: element.svgAttributes.skewX,
42949
- ySkew: element.svgAttributes.skewY,
42950
- rotate: element.svgAttributes.rotate,
42951
- });
41732
+ async rect(element) {
41733
+ if (!element.svgAttributes.fill && !element.svgAttributes.stroke)
41734
+ return;
41735
+ page.drawRectangle({
41736
+ x: 0,
41737
+ y: 0,
41738
+ width: element.svgAttributes.width,
41739
+ height: element.svgAttributes.height * -1,
41740
+ borderColor: element.svgAttributes.stroke,
41741
+ borderWidth: element.svgAttributes.strokeWidth,
41742
+ borderOpacity: element.svgAttributes.strokeOpacity,
41743
+ borderLineCap: element.svgAttributes.strokeLineCap,
41744
+ color: element.svgAttributes.fill,
41745
+ opacity: element.svgAttributes.fillOpacity,
41746
+ matrix: element.svgAttributes.matrix,
41747
+ clipSpaces: element.svgAttributes.clipSpaces,
42952
41748
  });
42953
41749
  },
42954
- ellipse(element) {
42955
- return __awaiter(this, void 0, void 0, function* () {
42956
- page.drawEllipse({
42957
- x: element.svgAttributes.cx,
42958
- y: element.svgAttributes.cy,
42959
- xScale: element.svgAttributes.rx,
42960
- yScale: element.svgAttributes.ry,
42961
- borderColor: element.svgAttributes.stroke,
42962
- borderWidth: element.svgAttributes.strokeWidth,
42963
- borderOpacity: element.svgAttributes.strokeOpacity,
42964
- borderLineCap: element.svgAttributes.strokeLineCap,
42965
- color: element.svgAttributes.fill,
42966
- opacity: element.svgAttributes.fillOpacity,
42967
- rotate: element.svgAttributes.rotate,
42968
- });
41750
+ async ellipse(element) {
41751
+ page.drawEllipse({
41752
+ x: element.svgAttributes.cx || 0,
41753
+ y: -(element.svgAttributes.cy || 0),
41754
+ xScale: element.svgAttributes.rx,
41755
+ yScale: element.svgAttributes.ry,
41756
+ borderColor: element.svgAttributes.stroke,
41757
+ borderWidth: element.svgAttributes.strokeWidth,
41758
+ borderOpacity: element.svgAttributes.strokeOpacity,
41759
+ borderLineCap: element.svgAttributes.strokeLineCap,
41760
+ color: element.svgAttributes.fill,
41761
+ opacity: element.svgAttributes.fillOpacity,
41762
+ matrix: element.svgAttributes.matrix,
41763
+ clipSpaces: element.svgAttributes.clipSpaces,
42969
41764
  });
42970
41765
  },
42971
- circle(element) {
42972
- return __awaiter(this, void 0, void 0, function* () {
42973
- return runnersToPage(page, options).ellipse(element);
42974
- });
41766
+ async circle(element) {
41767
+ return runnersToPage(page, options).ellipse(element);
42975
41768
  },
42976
41769
  });
42977
- const transform = (converter, name, args) => {
42978
- switch (name) {
42979
- case 'scaleX':
42980
- return transform(converter, 'scale', [args[0], 0]);
42981
- case 'scaleY':
42982
- return transform(converter, 'scale', [0, args[0]]);
42983
- case 'scale':
42984
- const [xScale, yScale = xScale] = args;
42985
- return {
42986
- point: (x, y) => converter.point(x * xScale, y * yScale),
42987
- size: (w, h) => converter.size(w * xScale, h * yScale),
42988
- };
42989
- case 'translateX':
42990
- return transform(converter, 'translate', [args[0], 0]);
42991
- case 'translateY':
42992
- return transform(converter, 'translate', [0, args[0]]);
42993
- case 'translate':
42994
- const [dx, dy = dx] = args;
42995
- return {
42996
- point: (x, y) => converter.point(x + dx, y + dy),
42997
- size: converter.size,
42998
- };
42999
- case 'rotate': {
43000
- if (args.length > 1) {
43001
- const [a, x, y = x] = args;
43002
- let tempResult = transform(converter, 'translate', [x, y]);
43003
- tempResult = transform(tempResult, 'rotate', [a]);
43004
- return transform(tempResult, 'translate', [-x, -y]);
43005
- }
43006
- else {
43007
- const [a] = args;
43008
- const angle = degreesToRadians(a);
43009
- return {
43010
- point: (x, y) => converter.point(x * Math.cos(angle) - y * Math.sin(angle), y * Math.cos(angle) + x * Math.sin(angle)),
43011
- size: converter.size,
43012
- };
43013
- }
43014
- }
43015
- case 'matrix': {
43016
- const [scaleX, skewY, skewX, scaleY, translateX, translateY] = args;
43017
- return {
43018
- point: (x, y) => converter.point(x * scaleX + y * skewX + translateX, x * skewY + y * scaleY + translateY),
43019
- size: (w, h) => converter.size(w * scaleX, h * scaleY),
43020
- };
43021
- }
43022
- case 'skewX': {
43023
- const angle = degreesToRadians(args[0]);
43024
- return {
43025
- point: (x, y) => converter.point((1 + x) * Math.tan(angle), y),
43026
- size: converter.size,
43027
- };
43028
- }
43029
- case 'skewY': {
43030
- const angle = degreesToRadians(args[0]);
43031
- return {
43032
- point: (x, y) => converter.point(x, (1 + y) * Math.tan(angle)),
43033
- size: converter.size,
43034
- };
43035
- }
43036
- default: {
43037
- console.log('transformation unsupported:', name);
43038
- return converter;
43039
- }
43040
- }
43041
- };
43042
41770
  const styleOrAttribute = (attributes, style, attribute, def) => {
43043
41771
  const value = style[attribute] || attributes[attribute];
43044
41772
  if (!value && typeof def !== 'undefined')
@@ -43068,8 +41796,8 @@ end\
43068
41796
  alpha: parsedColor.alpha ? parsedColor.alpha + '' : undefined,
43069
41797
  };
43070
41798
  };
43071
- const parseAttributes = (element, inherited, converter) => {
43072
- var _a, _b, _c, _d, _e, _f, _g;
41799
+ const parseAttributes = (element, inherited, matrix) => {
41800
+ var _a, _b, _c, _d;
43073
41801
  const attributes = element.attributes;
43074
41802
  const style = parseStyles(attributes.style);
43075
41803
  const widthRaw = styleOrAttribute(attributes, style, 'width', '');
@@ -43125,7 +41853,6 @@ end\
43125
41853
  dominantBaseline: attributes['dominant-baseline'],
43126
41854
  preserveAspectRatio: attributes.preserveAspectRatio,
43127
41855
  };
43128
- let newConverter = converter;
43129
41856
  let transformList = attributes.transform || '';
43130
41857
  // Handle transformations set as direct attributes
43131
41858
  [
@@ -43144,28 +41871,11 @@ end\
43144
41871
  transformList = attributes[name] + ' ' + transformList;
43145
41872
  }
43146
41873
  });
43147
- // skewX, skewY, rotate and scale are handled by the pdf-lib
43148
- ['skewX', 'skewY', 'rotate'].forEach((name) => {
43149
- var _a;
43150
- if (attributes[name]) {
43151
- const d = (_a = attributes[name].match(/-?(\d+\.?|\.)\d*/)) === null || _a === void 0 ? void 0 : _a[0];
43152
- if (d !== undefined) {
43153
- svgAttributes[name] = {
43154
- angle: parseInt(d, 10),
43155
- type: exports.RotationTypes.Degrees,
43156
- };
43157
- }
43158
- }
43159
- });
43160
- if (attributes.scale) {
43161
- const d = (_e = attributes.scale.match(/-?(\d+\.?|\.)\d*/)) === null || _e === void 0 ? void 0 : _e[0];
43162
- if (d !== undefined)
43163
- svgAttributes.scale = parseInt(d, 10);
43164
- }
43165
41874
  // Convert x/y as if it was a translation
43166
41875
  if (x || y) {
43167
41876
  transformList = transformList + `translate(${x || 0} ${y || 0}) `;
43168
41877
  }
41878
+ let newMatrix = matrix;
43169
41879
  // Apply the transformations
43170
41880
  if (transformList) {
43171
41881
  const regexTransform = /(\w+)\((.+?)\)/g;
@@ -43176,295 +41886,38 @@ end\
43176
41886
  .split(/\s*,\s*|\s+/)
43177
41887
  .filter((value) => value.length > 0)
43178
41888
  .map((value) => parseFloat(value));
43179
- const currentConverter = newConverter;
43180
- newConverter = transform(newConverter, name, args);
43181
- const xAxisVector = minus(currentConverter.point(0, 0), currentConverter.point(1, 0));
43182
- const xAxisVectorPostTransform = minus(newConverter.point(0, 0), newConverter.point(1, 0));
43183
- // matrix transform may also represent rotations: https://www.w3.org/TR/SVGTiny12/coords.html
43184
- if (name === 'rotate' || name === 'matrix') {
43185
- // transformations over x and y axis might change the page coord direction
43186
- const { width: xDirection, height: yDirection } = currentConverter.size(1, 1);
43187
- const rotationAdded = name === 'rotate' ? args[0] : radiansToDegrees(angle(xAxisVectorPostTransform, xAxisVector));
43188
- // the page Y coord is inverted so the angle rotation is inverted too
43189
- const pageYDirection = -1;
43190
- newInherited.rotation = degrees(pageYDirection * rotationAdded * Math.sign(xDirection * yDirection) +
43191
- (((_f = inherited.rotation) === null || _f === void 0 ? void 0 : _f.angle) || 0));
43192
- svgAttributes.rotate = newInherited.rotation;
43193
- }
41889
+ newMatrix = combineTransformation(newMatrix, name, args);
43194
41890
  parsed = regexTransform.exec(transformList);
43195
41891
  }
43196
41892
  }
43197
- // x and y were already transformed into a translation. The new reference point is now 0,0
43198
- const { x: newX, y: newY } = newConverter.point(0, 0);
43199
- svgAttributes.x = newX;
43200
- svgAttributes.y = newY;
41893
+ svgAttributes.x = x;
41894
+ svgAttributes.y = y;
43201
41895
  if (attributes.cx || attributes.cy) {
43202
- const { x: newCX, y: newCY } = newConverter.point(cx || 0, cy || 0);
43203
- svgAttributes.cx = newCX;
43204
- svgAttributes.cy = newCY;
41896
+ svgAttributes.cx = cx;
41897
+ svgAttributes.cy = cy;
43205
41898
  }
43206
41899
  if (attributes.rx || attributes.ry || attributes.r) {
43207
- const { width: newRX, height: newRY } = newConverter.size(rx || 0, ry || 0);
43208
- svgAttributes.rx = newRX;
43209
- svgAttributes.ry = newRY;
41900
+ svgAttributes.rx = rx;
41901
+ svgAttributes.ry = ry;
43210
41902
  }
43211
41903
  if (attributes.x1 || attributes.y1) {
43212
- const { x: newX1, y: newY1 } = newConverter.point(x1 || 0, y1 || 0);
43213
- svgAttributes.x1 = newX1;
43214
- svgAttributes.y1 = newY1;
41904
+ svgAttributes.x1 = x1;
41905
+ svgAttributes.y1 = y1;
43215
41906
  }
43216
41907
  if (attributes.x2 || attributes.y2) {
43217
- const { x: newX2, y: newY2 } = newConverter.point(x2 || 0, y2 || 0);
43218
- svgAttributes.x2 = newX2;
43219
- svgAttributes.y2 = newY2;
41908
+ svgAttributes.x2 = x2;
41909
+ svgAttributes.y2 = y2;
43220
41910
  }
43221
41911
  if (attributes.width || attributes.height) {
43222
- const size = newConverter.size(width !== null && width !== void 0 ? width : inherited.width, height !== null && height !== void 0 ? height : inherited.height);
43223
- svgAttributes.width = size.width;
43224
- svgAttributes.height = size.height;
41912
+ svgAttributes.width = width !== null && width !== void 0 ? width : inherited.width;
41913
+ svgAttributes.height = height !== null && height !== void 0 ? height : inherited.height;
43225
41914
  }
43226
- // We convert all the points from the path
43227
41915
  if (attributes.d) {
43228
- const { x: xOrigin, y: yOrigin } = newConverter.point(0, 0);
43229
- // 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
43230
- let currentX = 0;
43231
- let currentY = 0;
43232
- 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) => {
43233
- var _a, _b;
43234
- const letter = (_a = command.match(/[a-z]/i)) === null || _a === void 0 ? void 0 : _a[0];
43235
- if ((letter === null || letter === void 0 ? void 0 : letter.toLocaleLowerCase()) === 'z')
43236
- return letter;
43237
- // const params = command.match(/([0-9e.-]+)/ig)?.filter(m => m !== '')//.map(v => parseFloat(v))
43238
- const params = (_b = command
43239
- .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))
43240
- if (!params)
43241
- return letter || '';
43242
- switch (letter === null || letter === void 0 ? void 0 : letter.toLocaleLowerCase()) {
43243
- case 'm':
43244
- case 'l': {
43245
- const groupedParams = groupBy(params, 2);
43246
- return groupedParams
43247
- .map((pair, pairIndex) => {
43248
- const [x, y] = pair;
43249
- const xReal = parseFloatValue(x, inherited.width) || 0;
43250
- const yReal = parseFloatValue(y, innerHeight) || 0;
43251
- if (letter === letter.toLowerCase()) {
43252
- currentX += xReal;
43253
- currentY += yReal;
43254
- }
43255
- else {
43256
- currentX = xReal;
43257
- currentY = yReal;
43258
- }
43259
- const point = newConverter.point(currentX, currentY);
43260
- return ((pairIndex > 0 || letter.toUpperCase() === 'L' ? 'L' : 'M') +
43261
- [point.x - xOrigin, point.y - yOrigin].join(','));
43262
- })
43263
- .join(' ');
43264
- }
43265
- case 'v': {
43266
- return params
43267
- .map((value) => {
43268
- const coord = parseFloatValue(value) || 0;
43269
- if (letter === letter.toLowerCase()) {
43270
- currentY += coord;
43271
- }
43272
- else {
43273
- currentY = coord;
43274
- }
43275
- const point = newConverter.point(currentX, currentY);
43276
- // we can't use 'v' as the final command because rotations might require a different command after the path parsing
43277
- // for instance, a 90 degree rotation would turn a 'v' into an 'h' command
43278
- return `L${point.x - xOrigin} ${point.y - yOrigin}`;
43279
- })
43280
- .join(' ');
43281
- }
43282
- case 'h': {
43283
- return params
43284
- .map((value) => {
43285
- const coord = parseFloatValue(value) || 0;
43286
- if (letter === letter.toLowerCase()) {
43287
- currentX += coord;
43288
- }
43289
- else {
43290
- currentX = coord;
43291
- }
43292
- const point = newConverter.point(currentX, currentY);
43293
- // we can't use 'h' as the final command because rotations might require a different command after the path parsing
43294
- // for instance, a 90 degree rotation would turn a 'h' into an 'v' command
43295
- return `L${point.x - xOrigin} ${point.y - yOrigin}`;
43296
- })
43297
- .join(' ');
43298
- }
43299
- case 'a': {
43300
- const groupedParams = groupBy(params, 7);
43301
- return groupedParams
43302
- .map((p) => {
43303
- const [rxPixel, ryPixel, xAxisRotation = '0', largeArc = '0', sweepFlag = '0', xPixel, yPixel,] = p;
43304
- const realRx = parseFloatValue(rxPixel, inherited.width) || 0;
43305
- const realRy = parseFloatValue(ryPixel, inherited.height) || 0;
43306
- const realX = parseFloatValue(xPixel, inherited.width) || 0;
43307
- const realY = parseFloatValue(yPixel, inherited.height) || 0;
43308
- const { width: newRx, height: newRy } = newConverter.size(realRx, realRy);
43309
- let point;
43310
- if (letter === letter.toLowerCase()) {
43311
- currentX += realX;
43312
- currentY += realY;
43313
- }
43314
- else {
43315
- currentX = realX;
43316
- currentY = realY;
43317
- }
43318
- point = newConverter.point(currentX, currentY);
43319
- // transformations over x and y axis might change the page coord direction
43320
- const { width: xDirection, height: yDirection } = newConverter.size(1, 1);
43321
- // -1 is the default direction
43322
- const pageYDirection = -1 * Math.sign(xDirection * yDirection);
43323
- const oppositeSweepFlag = sweepFlag === '0' ? '1' : '0';
43324
- return [
43325
- letter.toUpperCase(),
43326
- newRx,
43327
- newRy,
43328
- xAxisRotation,
43329
- largeArc,
43330
- pageYDirection === -1 ? oppositeSweepFlag : sweepFlag,
43331
- point.x - xOrigin,
43332
- point.y - yOrigin,
43333
- ].join(' ');
43334
- })
43335
- .join(' ');
43336
- }
43337
- case 'c': {
43338
- const groupedParams = groupBy(params, 6);
43339
- const result = groupedParams
43340
- .map(([c1X, c1Y, c2X, c2Y, xString, yString]) => [
43341
- parseFloatValue(c1X, inherited.width) || 0,
43342
- parseFloatValue(c1Y, inherited.height) || 0,
43343
- parseFloatValue(c2X, inherited.width) || 0,
43344
- parseFloatValue(c2Y, inherited.height) || 0,
43345
- parseFloatValue(xString, inherited.width) || 0,
43346
- parseFloatValue(yString, inherited.height) || 0,
43347
- ])
43348
- .map(([c1X, c1Y, c2X, c2Y, xReal, yReal]) => {
43349
- let controlPoint1X;
43350
- let controlPoint1Y;
43351
- let controlPoint2X;
43352
- let controlPoint2Y;
43353
- if (letter === letter.toLowerCase()) {
43354
- controlPoint1X = currentX + c1X;
43355
- controlPoint1Y = currentY + c1Y;
43356
- controlPoint2X = currentX + c2X;
43357
- controlPoint2Y = currentY + c2Y;
43358
- currentX += xReal;
43359
- currentY += yReal;
43360
- }
43361
- else {
43362
- controlPoint1X = c1X;
43363
- controlPoint1Y = c1Y;
43364
- controlPoint2X = c2X;
43365
- controlPoint2Y = c2Y;
43366
- currentX = xReal;
43367
- currentY = yReal;
43368
- }
43369
- const controlPoint1 = newConverter.point(controlPoint1X, controlPoint1Y);
43370
- const controlPoint2 = newConverter.point(controlPoint2X, controlPoint2Y);
43371
- const point = newConverter.point(currentX, currentY);
43372
- return [
43373
- controlPoint1.x - xOrigin,
43374
- controlPoint1.y - yOrigin,
43375
- controlPoint2.x - xOrigin,
43376
- controlPoint2.y - yOrigin,
43377
- point.x - xOrigin,
43378
- point.y - yOrigin,
43379
- ].join(',');
43380
- })
43381
- .join(' ');
43382
- return (letter === null || letter === void 0 ? void 0 : letter.toUpperCase()) + '' + result;
43383
- }
43384
- case 's': {
43385
- const groupedParams = groupBy(params, 4);
43386
- const result = groupedParams
43387
- // the control point 1 is omitted because it's the reflection of c2
43388
- .map(([c2X, c2Y, xString, yString]) => [
43389
- parseFloatValue(c2X, inherited.width) || 0,
43390
- parseFloatValue(c2Y, inherited.height) || 0,
43391
- parseFloatValue(xString, inherited.width) || 0,
43392
- parseFloatValue(yString, inherited.height) || 0,
43393
- ])
43394
- .map(([c2X, c2Y, xReal, yReal]) => {
43395
- let controlPoint2X;
43396
- let controlPoint2Y;
43397
- if (letter === letter.toLowerCase()) {
43398
- controlPoint2X = currentX + c2X;
43399
- controlPoint2Y = currentY + c2Y;
43400
- currentX += xReal;
43401
- currentY += yReal;
43402
- }
43403
- else {
43404
- controlPoint2X = c2X;
43405
- controlPoint2Y = c2Y;
43406
- currentX = xReal;
43407
- currentY = yReal;
43408
- }
43409
- const controlPoint2 = newConverter.point(controlPoint2X, controlPoint2Y);
43410
- const point = newConverter.point(currentX, currentY);
43411
- return [
43412
- controlPoint2.x - xOrigin,
43413
- controlPoint2.y - yOrigin,
43414
- point.x - xOrigin,
43415
- point.y - yOrigin,
43416
- ].join(',');
43417
- })
43418
- .join(' ');
43419
- return (letter === null || letter === void 0 ? void 0 : letter.toUpperCase()) + '' + result;
43420
- }
43421
- default: {
43422
- const groupedParams = groupBy(params, 2);
43423
- const result = groupedParams
43424
- .map(([xString, yString]) => [
43425
- parseFloatValue(xString, inherited.width) || 0,
43426
- parseFloatValue(yString, inherited.height) || 0,
43427
- ])
43428
- .map(([xReal, yReal]) => {
43429
- if (letter === letter.toLowerCase()) {
43430
- currentX += xReal;
43431
- currentY += yReal;
43432
- }
43433
- else {
43434
- currentX = xReal;
43435
- currentY = yReal;
43436
- }
43437
- const point = newConverter.point(currentX, currentY);
43438
- return [point.x - xOrigin, point.y - yOrigin].join(',');
43439
- })
43440
- .join(' ');
43441
- return (letter === null || letter === void 0 ? void 0 : letter.toUpperCase()) + '' + result;
43442
- }
43443
- }
43444
- });
43445
- }
43446
- if (attributes.viewBox) {
43447
- const viewBox = parseViewBox(attributes.viewBox);
43448
- const size = {
43449
- width: width || inherited.viewBox.width,
43450
- height: height || inherited.viewBox.height,
43451
- };
43452
- const localConverter = getConverterWithAspectRatio(size, viewBox, attributes.preserveAspectRatio);
43453
- const oldConverter = newConverter;
43454
- newConverter = {
43455
- point: (px, py) => {
43456
- const { x: localX, y: localY } = localConverter.point(px, py);
43457
- return oldConverter.point(localX, localY);
43458
- },
43459
- size: (w, h) => {
43460
- const { width: localWidth, height: localHeight } = localConverter.size(w, h);
43461
- return oldConverter.size(localWidth, localHeight);
43462
- },
43463
- };
41916
+ newMatrix = combineTransformation(newMatrix, 'scale', [1, -1]);
41917
+ svgAttributes.d = attributes.d;
43464
41918
  }
43465
- // apply the converter only when there's a local fontSize instruction
43466
41919
  if (fontSizeRaw && newInherited.fontSize) {
43467
- newInherited.fontSize = newConverter.size(1, newInherited.fontSize).height;
41920
+ newInherited.fontSize = newInherited.fontSize;
43468
41921
  }
43469
41922
  if (newInherited.fontFamily) {
43470
41923
  // Handle complex fontFamily like `"Linux Libertine O", serif`
@@ -43473,43 +41926,13 @@ end\
43473
41926
  newInherited.fontFamily = inner[1] || inner[2];
43474
41927
  }
43475
41928
  if (newInherited.strokeWidth) {
43476
- const result = newConverter.size(newInherited.strokeWidth, newInherited.strokeWidth);
43477
- svgAttributes.strokeWidth = Math.max(Math.min(Math.abs(result.width), Math.abs(result.height)), 1);
41929
+ svgAttributes.strokeWidth = newInherited.strokeWidth;
43478
41930
  }
43479
41931
  return {
43480
41932
  inherited: newInherited,
43481
41933
  svgAttributes,
43482
- converter: newConverter,
43483
41934
  tagName: element.tagName,
43484
- };
43485
- };
43486
- const getConverter = (box, viewBox) => {
43487
- const { width, height } = box;
43488
- const { x: xMin, y: yMin, width: viewWidth, height: viewHeight } = viewBox;
43489
- const converter = {
43490
- point: (xReal, yReal) => ({
43491
- x: ((xReal - xMin) / viewWidth) * (width || 0),
43492
- y: ((yReal - yMin) / viewHeight) * (height || 0),
43493
- }),
43494
- size: (wReal, hReal) => ({
43495
- width: (wReal / viewWidth) * (width || 0),
43496
- height: (hReal / viewHeight) * (height || 0),
43497
- }),
43498
- };
43499
- return converter;
43500
- };
43501
- const getConverterWithAspectRatio = (size, viewBox, preserveAspectRatio) => {
43502
- // explanation about how the svg attributes applies transformations to the child elements
43503
- // https://www.w3.org/TR/SVG/coords.html#ComputingAViewportsTransform
43504
- const { x, y, width, height } = getFittingRectangle(viewBox.width, viewBox.height, size.width, size.height, preserveAspectRatio);
43505
- const ratioConverter = getConverter({ width, height }, viewBox);
43506
- // We translate the drawing in the page when the aspect ratio is different, according to the preserveAspectRatio instructions.
43507
- return {
43508
- point: (xReal, yReal) => {
43509
- const P = ratioConverter.point(xReal, yReal);
43510
- return { x: P.x + x, y: P.y + y };
43511
- },
43512
- size: ratioConverter.size,
41935
+ matrix: newMatrix,
43513
41936
  };
43514
41937
  };
43515
41938
  const getFittingRectangle = (originalWidth, originalHeight, targetWidth, targetHeight, preserveAspectRatio) => {
@@ -43547,16 +41970,62 @@ end\
43547
41970
  })();
43548
41971
  return { x, y, width, height };
43549
41972
  };
43550
- const parseHTMLNode = (node, inherited, converter) => {
41973
+ const getAspectRatioTransformation = (matrix, originalWidth, originalHeight, targetWidth, targetHeight, preserveAspectRatio) => {
41974
+ const scaleX = targetWidth / originalWidth;
41975
+ const scaleY = targetHeight / originalHeight;
41976
+ const boxScale = combineTransformation(matrix, 'scale', [
41977
+ scaleX,
41978
+ scaleY
41979
+ ]);
41980
+ if (preserveAspectRatio === 'none') {
41981
+ return {
41982
+ clipBox: boxScale,
41983
+ content: boxScale
41984
+ };
41985
+ }
41986
+ // TODO: the following code works for the 'meet' param but not for the 'slice'
41987
+ const scale = targetWidth > targetHeight ? scaleY : scaleX;
41988
+ const dx = targetWidth - (originalWidth * scale);
41989
+ const dy = targetHeight - (originalHeight * scale);
41990
+ const [x, y] = (() => {
41991
+ switch (preserveAspectRatio) {
41992
+ case 'xMinYMin':
41993
+ return [0, 0];
41994
+ case 'xMidYMin':
41995
+ return [dx / 2, 0];
41996
+ case 'xMaxYMin':
41997
+ return [dx, dy / 2];
41998
+ case 'xMinYMid':
41999
+ return [0, dy];
42000
+ case 'xMaxYMid':
42001
+ return [dx, dy / 2];
42002
+ case 'xMinYMax':
42003
+ return [0, dy];
42004
+ case 'xMidYMax':
42005
+ return [dx / 2, dy];
42006
+ case 'xMaxYMax':
42007
+ return [dx, dy];
42008
+ case 'xMidYMid':
42009
+ default:
42010
+ return [dx / 2, dy / 2];
42011
+ }
42012
+ })();
42013
+ const contentTransform = combineTransformation(combineTransformation(matrix, 'translate', [x, y]), 'scale', [scale]);
42014
+ return {
42015
+ clipBox: boxScale,
42016
+ content: contentTransform
42017
+ };
42018
+ };
42019
+ const parseHTMLNode = (node, inherited, matrix, clipSpaces) => {
43551
42020
  if (node.nodeType === index.NodeType.COMMENT_NODE)
43552
42021
  return [];
43553
42022
  else if (node.nodeType === index.NodeType.TEXT_NODE)
43554
42023
  return [];
43555
42024
  else if (node.tagName === 'g') {
43556
- return parseGroupNode(node, inherited, converter);
42025
+ return parseGroupNode(node, inherited, matrix, clipSpaces);
43557
42026
  }
43558
42027
  else if (node.tagName === 'svg') {
43559
- return parseSvgNode(node, inherited, converter);
42028
+ return parseSvgNode(node, inherited, matrix, clipSpaces);
43560
42029
  }
43561
42030
  else {
43562
42031
  if (node.tagName === 'polygon') {
@@ -43564,36 +42033,69 @@ end\
43564
42033
  node.attributes.d = `M${node.attributes.points}Z`;
43565
42034
  delete node.attributes.points;
43566
42035
  }
43567
- const attributes = parseAttributes(node, inherited, converter);
43568
- const svgAttributes = Object.assign(Object.assign({}, attributes.inherited), attributes.svgAttributes);
42036
+ const attributes = parseAttributes(node, inherited, matrix);
42037
+ const svgAttributes = {
42038
+ ...attributes.inherited,
42039
+ ...attributes.svgAttributes,
42040
+ matrix: attributes.matrix,
42041
+ clipSpaces
42042
+ };
43569
42043
  Object.assign(node, { svgAttributes });
43570
42044
  return [node];
43571
42045
  }
43572
42046
  };
43573
- const parseSvgNode = (node, inherited, converter) => {
42047
+ const parseSvgNode = (node, inherited, matrix, clipSpaces) => {
43574
42048
  var _a, _b;
43575
42049
  // if the width/height aren't set, the svg will have the same dimension as the current drawing space
43576
42050
  (_a = node.attributes.width) !== null && _a !== void 0 ? _a : node.setAttribute('width', inherited.viewBox.width + '');
43577
42051
  (_b = node.attributes.height) !== null && _b !== void 0 ? _b : node.setAttribute('height', inherited.viewBox.height + '');
43578
- const attributes = parseAttributes(node, inherited, converter);
42052
+ const attributes = parseAttributes(node, inherited, matrix);
43579
42053
  const result = [];
43580
42054
  const viewBox = node.attributes.viewBox
43581
42055
  ? parseViewBox(node.attributes.viewBox)
43582
42056
  : node.attributes.width && node.attributes.height
43583
42057
  ? parseViewBox(`0 0 ${node.attributes.width} ${node.attributes.height}`)
43584
42058
  : inherited.viewBox;
43585
- 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)));
42059
+ const x = parseFloat(node.attributes.x) || 0;
42060
+ const y = parseFloat(node.attributes.y) || 0;
42061
+ let newMatrix = combineTransformation(matrix, 'translate', [x, y]);
42062
+ const { clipBox: clipBoxTransform, content: contentTransform } = getAspectRatioTransformation(newMatrix, viewBox.width, viewBox.height, parseFloat(node.attributes.width), parseFloat(node.attributes.height), node.attributes.preserveAspectRatio || 'xMidYMid');
42063
+ const topLeft = applyTransformation(clipBoxTransform, {
42064
+ x: 0,
42065
+ y: 0,
42066
+ });
42067
+ const topRight = applyTransformation(clipBoxTransform, {
42068
+ x: viewBox.width,
42069
+ y: 0,
42070
+ });
42071
+ const bottomRight = applyTransformation(clipBoxTransform, {
42072
+ x: viewBox.width,
42073
+ y: -viewBox.height,
42074
+ });
42075
+ const bottomLeft = applyTransformation(clipBoxTransform, {
42076
+ x: 0,
42077
+ y: -viewBox.height,
42078
+ });
42079
+ const baseClipSpace = {
42080
+ topLeft,
42081
+ topRight,
42082
+ bottomRight,
42083
+ bottomLeft
42084
+ };
42085
+ // TODO: maybe this is the correct transformation
42086
+ // newMatrix = combineTransformation(newMatrix, 'translate', [-baseClipSpace.xMin, -baseClipSpace.yMin])
42087
+ newMatrix = combineTransformation(contentTransform, 'translate', [-viewBox.x, -viewBox.y]);
43586
42088
  node.childNodes.forEach((child) => {
43587
- const parsedNodes = parseHTMLNode(child, Object.assign(Object.assign({}, attributes.inherited), { viewBox }), attributes.converter).map((el) => cropSvgElement(svgRect, el));
42089
+ const parsedNodes = parseHTMLNode(child, { ...attributes.inherited, viewBox }, newMatrix, [...clipSpaces, baseClipSpace]);
43588
42090
  result.push(...parsedNodes);
43589
42091
  });
43590
42092
  return result;
43591
42093
  };
43592
- const parseGroupNode = (node, inherited, converter) => {
43593
- const attributes = parseAttributes(node, inherited, converter);
42094
+ const parseGroupNode = (node, inherited, matrix, clipSpaces) => {
42095
+ const attributes = parseAttributes(node, inherited, matrix);
43594
42096
  const result = [];
43595
42097
  node.childNodes.forEach((child) => {
43596
- result.push(...parseHTMLNode(child, attributes.inherited, attributes.converter));
42098
+ result.push(...parseHTMLNode(child, attributes.inherited, attributes.matrix, clipSpaces));
43597
42099
  });
43598
42100
  return result;
43599
42101
  };
@@ -43620,22 +42122,21 @@ end\
43620
42122
  height: heightViewBox,
43621
42123
  };
43622
42124
  };
43623
- const parse$1 = (svg, { width, height, x, y, fontSize }, size, converter) => {
42125
+ const parse$1 = (svg, { width, height, fontSize }, size, matrix) => {
43624
42126
  const htmlElement = index.parse(svg).firstChild;
43625
42127
  if (width)
43626
42128
  htmlElement.setAttribute('width', width + '');
43627
42129
  if (height)
43628
42130
  htmlElement.setAttribute('height', height + '');
43629
- if (x !== undefined)
43630
- htmlElement.setAttribute('x', x + '');
43631
- if (y !== undefined)
43632
- htmlElement.setAttribute('y', size.height - y + '');
43633
42131
  if (fontSize)
43634
42132
  htmlElement.setAttribute('font-size', fontSize + '');
43635
42133
  // TODO: what should be the default viewBox?
43636
- return parseHTMLNode(htmlElement, Object.assign(Object.assign({}, size), { viewBox: parseViewBox(htmlElement.attributes.viewBox || '0 0 1 1') }), converter);
42134
+ return parseHTMLNode(htmlElement, {
42135
+ ...size,
42136
+ viewBox: parseViewBox(htmlElement.attributes.viewBox || '0 0 1 1'),
42137
+ }, matrix, []);
43637
42138
  };
43638
- const drawSvg = (page, svg, options) => __awaiter(void 0, void 0, void 0, function* () {
42139
+ const drawSvg = async (page, svg, options) => {
43639
42140
  if (!svg)
43640
42141
  return;
43641
42142
  const size = page.getSize();
@@ -43660,19 +42161,42 @@ end\
43660
42161
  .map(([key, val]) => `${key}:${val};`)
43661
42162
  .join(''));
43662
42163
  }
43663
- // The y axis of the page is reverted
43664
- const defaultConverter = {
43665
- point: (xP, yP) => ({ x: xP, y: size.height - yP }),
43666
- size: (w, h) => ({ width: w, height: h }),
43667
- };
42164
+ const baseTransformation = [1, 0, 0, 1, options.x || 0, options.y || 0];
43668
42165
  const runners = runnersToPage(page, options);
43669
- const elements = parse$1(firstChild.outerHTML, options, size, defaultConverter);
43670
- yield elements.reduce((prev, elt) => __awaiter(void 0, void 0, void 0, function* () {
42166
+ const elements = parse$1(firstChild.outerHTML, options, size, baseTransformation);
42167
+ await elements.reduce(async (prev, elt) => {
43671
42168
  var _a;
43672
- yield prev;
42169
+ await prev;
42170
+ // uncomment these lines to draw the clipSpaces
42171
+ // elt.svgAttributes.clipSpaces.forEach(space => {
42172
+ // page.drawLine({
42173
+ // start: space.topLeft,
42174
+ // end: space.topRight,
42175
+ // color: parseColor('#000000')?.rgb,
42176
+ // thickness: 1
42177
+ // })
42178
+ // page.drawLine({
42179
+ // start: space.topRight,
42180
+ // end: space.bottomRight,
42181
+ // color: parseColor('#000000')?.rgb,
42182
+ // thickness: 1
42183
+ // })
42184
+ // page.drawLine({
42185
+ // start: space.bottomRight,
42186
+ // end: space.bottomLeft,
42187
+ // color: parseColor('#000000')?.rgb,
42188
+ // thickness: 1
42189
+ // })
42190
+ // page.drawLine({
42191
+ // start: space.bottomLeft,
42192
+ // end: space.topLeft,
42193
+ // color: parseColor('#000000')?.rgb,
42194
+ // thickness: 1
42195
+ // })
42196
+ // })
43673
42197
  return (_a = runners[elt.tagName]) === null || _a === void 0 ? void 0 : _a.call(runners, elt);
43674
- }), Promise.resolve());
43675
- });
42198
+ }, Promise.resolve());
42199
+ };
43676
42200
 
43677
42201
  /**
43678
42202
  * Represents a single page of a [[PDFDocument]].
@@ -44529,6 +43053,8 @@ end\
44529
43053
  y: (_f = options.y) !== null && _f !== void 0 ? _f : this.y,
44530
43054
  lineHeight: (_g = options.lineHeight) !== null && _g !== void 0 ? _g : this.lineHeight,
44531
43055
  graphicsState: graphicsStateKey,
43056
+ matrix: options.matrix,
43057
+ clipSpaces: options.clipSpaces
44532
43058
  }));
44533
43059
  if (options.font) {
44534
43060
  if (oldFont)
@@ -44590,6 +43116,8 @@ end\
44590
43116
  xSkew: (_f = options.xSkew) !== null && _f !== void 0 ? _f : degrees(0),
44591
43117
  ySkew: (_g = options.ySkew) !== null && _g !== void 0 ? _g : degrees(0),
44592
43118
  graphicsState: graphicsStateKey,
43119
+ matrix: options.matrix,
43120
+ clipSpaces: options.clipSpaces
44593
43121
  }));
44594
43122
  }
44595
43123
  /**
@@ -44748,6 +43276,8 @@ end\
44748
43276
  borderLineCap: (_j = options.borderLineCap) !== null && _j !== void 0 ? _j : undefined,
44749
43277
  graphicsState: graphicsStateKey,
44750
43278
  fillRule: options.fillRule,
43279
+ matrix: options.matrix,
43280
+ clipSpaces: options.clipSpaces
44751
43281
  }));
44752
43282
  }
44753
43283
  /**
@@ -44801,6 +43331,8 @@ end\
44801
43331
  dashPhase: (_d = options.dashPhase) !== null && _d !== void 0 ? _d : undefined,
44802
43332
  lineCap: (_e = options.lineCap) !== null && _e !== void 0 ? _e : undefined,
44803
43333
  graphicsState: graphicsStateKey,
43334
+ matrix: options.matrix,
43335
+ clipSpaces: options.clipSpaces,
44804
43336
  }));
44805
43337
  }
44806
43338
  /**
@@ -44871,6 +43403,8 @@ end\
44871
43403
  borderDashPhase: (_m = options.borderDashPhase) !== null && _m !== void 0 ? _m : undefined,
44872
43404
  graphicsState: graphicsStateKey,
44873
43405
  borderLineCap: (_o = options.borderLineCap) !== null && _o !== void 0 ? _o : undefined,
43406
+ matrix: options.matrix,
43407
+ clipSpaces: options.clipSpaces,
44874
43408
  }));
44875
43409
  }
44876
43410
  /**
@@ -44895,7 +43429,7 @@ end\
44895
43429
  drawSquare(options = {}) {
44896
43430
  const { size } = options;
44897
43431
  assertOrUndefined(size, 'size', ['number']);
44898
- this.drawRectangle(Object.assign(Object.assign({}, options), { width: size, height: size }));
43432
+ this.drawRectangle({ ...options, width: size, height: size });
44899
43433
  }
44900
43434
  /**
44901
43435
  * Draw an ellipse on this page. For example:
@@ -44960,6 +43494,8 @@ end\
44960
43494
  borderDashPhase: (_k = options.borderDashPhase) !== null && _k !== void 0 ? _k : undefined,
44961
43495
  borderLineCap: (_l = options.borderLineCap) !== null && _l !== void 0 ? _l : undefined,
44962
43496
  graphicsState: graphicsStateKey,
43497
+ matrix: options.matrix,
43498
+ clipSpaces: options.clipSpaces,
44963
43499
  }));
44964
43500
  }
44965
43501
  /**
@@ -44983,7 +43519,7 @@ end\
44983
43519
  drawCircle(options = {}) {
44984
43520
  const { size = 100 } = options;
44985
43521
  assertOrUndefined(size, 'size', ['number']);
44986
- this.drawEllipse(Object.assign(Object.assign({}, options), { xScale: size, yScale: size }));
43522
+ this.drawEllipse({ ...options, xScale: size, yScale: size });
44987
43523
  }
44988
43524
  setOrEmbedFont(font) {
44989
43525
  const oldFont = this.font;
@@ -45007,21 +43543,19 @@ end\
45007
43543
  * @param svg The SVG to be drawn.
45008
43544
  * @param options The options to be used when drawing the SVG.
45009
43545
  */
45010
- drawSvg(svg, options = {}) {
43546
+ async drawSvg(svg, options = {}) {
45011
43547
  var _a, _b;
45012
- return __awaiter(this, void 0, void 0, function* () {
45013
- assertIs(svg, 'svg', ['string']);
45014
- assertOrUndefined(options.x, 'options.x', ['number']);
45015
- assertOrUndefined(options.y, 'options.y', ['number']);
45016
- assertOrUndefined(options.width, 'options.width', ['number']);
45017
- assertOrUndefined(options.height, 'options.height', ['number']);
45018
- yield drawSvg(this, svg, {
45019
- x: (_a = options.x) !== null && _a !== void 0 ? _a : this.x,
45020
- y: (_b = options.y) !== null && _b !== void 0 ? _b : this.y,
45021
- fonts: options.fonts,
45022
- width: options.width,
45023
- height: options.height,
45024
- });
43548
+ assertIs(svg, 'svg', ['string']);
43549
+ assertOrUndefined(options.x, 'options.x', ['number']);
43550
+ assertOrUndefined(options.y, 'options.y', ['number']);
43551
+ assertOrUndefined(options.width, 'options.width', ['number']);
43552
+ assertOrUndefined(options.height, 'options.height', ['number']);
43553
+ await drawSvg(this, svg, {
43554
+ x: (_a = options.x) !== null && _a !== void 0 ? _a : this.x,
43555
+ y: (_b = options.y) !== null && _b !== void 0 ? _b : this.y,
43556
+ fonts: options.fonts,
43557
+ width: options.width,
43558
+ height: options.height,
45025
43559
  });
45026
43560
  }
45027
43561
  getFont() {