@vaadin-component-factory/vcf-pdf-viewer 0.9.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/README.md +1 -1
  2. package/package.json +42 -26
  3. package/{src/display → pdfjs/dist}/display_utils.js +344 -139
  4. package/{src/display → pdfjs/dist}/fetch_stream.js +115 -97
  5. package/pdfjs/dist/l10n_utils.js +140 -0
  6. package/{src/shared → pdfjs/dist}/message_handler.js +243 -259
  7. package/{src/display → pdfjs/dist}/network.js +149 -87
  8. package/{src/display/content_disposition.js → pdfjs/dist/network_utils.js} +167 -55
  9. package/{src/display → pdfjs/dist}/node_stream.js +133 -98
  10. package/pdfjs/dist/pdf.js +12778 -0
  11. package/pdfjs/dist/pdf_link_service.js +638 -0
  12. package/pdfjs/dist/pdf_rendering_queue.js +199 -0
  13. package/pdfjs/dist/pdf_thumbnail_viewer.js +819 -0
  14. package/pdfjs/dist/pdf_viewer.js +3598 -0
  15. package/pdfjs/dist/ui_utils.js +1033 -0
  16. package/{src/shared → pdfjs/dist}/util.js +301 -287
  17. package/pdfjs/dist/worker.js +62813 -0
  18. package/src/vcf-pdf-viewer.js +98 -46
  19. package/theme/lumo/vcf-pdf-viewer-styles.js +4 -4
  20. package/theme/material/vcf-pdf-viewer-styles.js +4 -4
  21. package/theme/material/vcf-pdf-viewer.js +2 -2
  22. package/src/core/.eslintrc +0 -13
  23. package/src/core/annotation.js +0 -2948
  24. package/src/core/arithmetic_decoder.js +0 -182
  25. package/src/core/ascii_85_stream.js +0 -98
  26. package/src/core/ascii_hex_stream.js +0 -79
  27. package/src/core/base_stream.js +0 -110
  28. package/src/core/bidi.js +0 -438
  29. package/src/core/calibri_factors.js +0 -308
  30. package/src/core/catalog.js +0 -1459
  31. package/src/core/ccitt.js +0 -1062
  32. package/src/core/ccitt_stream.js +0 -60
  33. package/src/core/cff_font.js +0 -116
  34. package/src/core/cff_parser.js +0 -1949
  35. package/src/core/charsets.js +0 -119
  36. package/src/core/chunked_stream.js +0 -557
  37. package/src/core/cmap.js +0 -1039
  38. package/src/core/colorspace.js +0 -1533
  39. package/src/core/core_utils.js +0 -464
  40. package/src/core/crypto.js +0 -1900
  41. package/src/core/decode_stream.js +0 -170
  42. package/src/core/decrypt_stream.js +0 -59
  43. package/src/core/default_appearance.js +0 -99
  44. package/src/core/document.js +0 -1456
  45. package/src/core/encodings.js +0 -301
  46. package/src/core/evaluator.js +0 -4601
  47. package/src/core/file_spec.js +0 -108
  48. package/src/core/flate_stream.js +0 -402
  49. package/src/core/font_renderer.js +0 -882
  50. package/src/core/fonts.js +0 -3260
  51. package/src/core/fonts_utils.js +0 -221
  52. package/src/core/function.js +0 -1257
  53. package/src/core/glyf.js +0 -706
  54. package/src/core/glyphlist.js +0 -4558
  55. package/src/core/helvetica_factors.js +0 -353
  56. package/src/core/image.js +0 -802
  57. package/src/core/image_utils.js +0 -291
  58. package/src/core/jbig2.js +0 -2572
  59. package/src/core/jbig2_stream.js +0 -73
  60. package/src/core/jpeg_stream.js +0 -105
  61. package/src/core/jpg.js +0 -1416
  62. package/src/core/jpx.js +0 -2343
  63. package/src/core/jpx_stream.js +0 -87
  64. package/src/core/liberationsans_widths.js +0 -221
  65. package/src/core/lzw_stream.js +0 -150
  66. package/src/core/metadata_parser.js +0 -146
  67. package/src/core/metrics.js +0 -2970
  68. package/src/core/murmurhash3.js +0 -139
  69. package/src/core/myriadpro_factors.js +0 -290
  70. package/src/core/name_number_tree.js +0 -153
  71. package/src/core/object_loader.js +0 -149
  72. package/src/core/opentype_file_builder.js +0 -154
  73. package/src/core/operator_list.js +0 -734
  74. package/src/core/parser.js +0 -1416
  75. package/src/core/pattern.js +0 -985
  76. package/src/core/pdf_manager.js +0 -217
  77. package/src/core/predictor_stream.js +0 -238
  78. package/src/core/primitives.js +0 -402
  79. package/src/core/ps_parser.js +0 -272
  80. package/src/core/run_length_stream.js +0 -61
  81. package/src/core/segoeui_factors.js +0 -308
  82. package/src/core/standard_fonts.js +0 -817
  83. package/src/core/stream.js +0 -103
  84. package/src/core/struct_tree.js +0 -335
  85. package/src/core/to_unicode_map.js +0 -103
  86. package/src/core/type1_font.js +0 -421
  87. package/src/core/type1_parser.js +0 -776
  88. package/src/core/unicode.js +0 -1649
  89. package/src/core/worker.js +0 -848
  90. package/src/core/worker_stream.js +0 -135
  91. package/src/core/writer.js +0 -278
  92. package/src/core/xfa/bind.js +0 -652
  93. package/src/core/xfa/builder.js +0 -207
  94. package/src/core/xfa/config.js +0 -1926
  95. package/src/core/xfa/connection_set.js +0 -202
  96. package/src/core/xfa/data.js +0 -82
  97. package/src/core/xfa/datasets.js +0 -76
  98. package/src/core/xfa/factory.js +0 -111
  99. package/src/core/xfa/fonts.js +0 -181
  100. package/src/core/xfa/formcalc_lexer.js +0 -385
  101. package/src/core/xfa/formcalc_parser.js +0 -1340
  102. package/src/core/xfa/html_utils.js +0 -639
  103. package/src/core/xfa/layout.js +0 -383
  104. package/src/core/xfa/locale_set.js +0 -345
  105. package/src/core/xfa/namespaces.js +0 -81
  106. package/src/core/xfa/parser.js +0 -184
  107. package/src/core/xfa/setup.js +0 -38
  108. package/src/core/xfa/signature.js +0 -40
  109. package/src/core/xfa/som.js +0 -338
  110. package/src/core/xfa/stylesheet.js +0 -40
  111. package/src/core/xfa/template.js +0 -6260
  112. package/src/core/xfa/text.js +0 -290
  113. package/src/core/xfa/unknown.js +0 -29
  114. package/src/core/xfa/utils.js +0 -217
  115. package/src/core/xfa/xdp.js +0 -59
  116. package/src/core/xfa/xfa_object.js +0 -1130
  117. package/src/core/xfa/xhtml.js +0 -543
  118. package/src/core/xfa_fonts.js +0 -208
  119. package/src/core/xml_parser.js +0 -507
  120. package/src/core/xref.js +0 -899
  121. package/src/display/annotation_layer.js +0 -2107
  122. package/src/display/annotation_storage.js +0 -113
  123. package/src/display/api.js +0 -3292
  124. package/src/display/base_factory.js +0 -180
  125. package/src/display/canvas.js +0 -2828
  126. package/src/display/font_loader.js +0 -484
  127. package/src/display/metadata.js +0 -41
  128. package/src/display/network_utils.js +0 -100
  129. package/src/display/node_utils.js +0 -83
  130. package/src/display/optional_content_config.js +0 -189
  131. package/src/display/pattern_helper.js +0 -659
  132. package/src/display/svg.js +0 -1709
  133. package/src/display/text_layer.js +0 -847
  134. package/src/display/transport_stream.js +0 -303
  135. package/src/display/worker_options.js +0 -40
  136. package/src/display/xfa_layer.js +0 -204
  137. package/src/doc_helper.js +0 -25
  138. package/src/images/logo.svg +0 -41
  139. package/src/interfaces.js +0 -169
  140. package/src/license_header.js +0 -14
  141. package/src/license_header_libre.js +0 -21
  142. package/src/pdf.image_decoders.js +0 -46
  143. package/src/pdf.js +0 -146
  144. package/src/pdf.sandbox.external.js +0 -181
  145. package/src/pdf.sandbox.js +0 -151
  146. package/src/pdf.scripting.js +0 -25
  147. package/src/pdf.worker.entry.js +0 -19
  148. package/src/pdf.worker.js +0 -23
  149. package/src/scripting_api/aform.js +0 -608
  150. package/src/scripting_api/app.js +0 -621
  151. package/src/scripting_api/color.js +0 -129
  152. package/src/scripting_api/common.js +0 -58
  153. package/src/scripting_api/console.js +0 -38
  154. package/src/scripting_api/constants.js +0 -208
  155. package/src/scripting_api/doc.js +0 -1195
  156. package/src/scripting_api/error.js +0 -23
  157. package/src/scripting_api/event.js +0 -232
  158. package/src/scripting_api/field.js +0 -620
  159. package/src/scripting_api/fullscreen.js +0 -145
  160. package/src/scripting_api/initialization.js +0 -223
  161. package/src/scripting_api/pdf_object.js +0 -24
  162. package/src/scripting_api/print_params.js +0 -146
  163. package/src/scripting_api/proxy.js +0 -139
  164. package/src/scripting_api/thermometer.js +0 -69
  165. package/src/scripting_api/util.js +0 -581
  166. package/src/shared/.eslintrc +0 -13
  167. package/src/shared/cffStandardStrings.js +0 -311
  168. package/src/shared/compatibility.js +0 -114
  169. package/src/shared/fonts_utils.js +0 -429
  170. package/src/shared/is_node.js +0 -27
  171. package/src/shared/scripting_utils.js +0 -85
  172. package/src/worker_loader.js +0 -32
@@ -1,3292 +0,0 @@
1
- /* Copyright 2012 Mozilla Foundation
2
- *
3
- * Licensed under the Apache License, Version 2.0 (the "License");
4
- * you may not use this file except in compliance with the License.
5
- * You may obtain a copy of the License at
6
- *
7
- * http://www.apache.org/licenses/LICENSE-2.0
8
- *
9
- * Unless required by applicable law or agreed to in writing, software
10
- * distributed under the License is distributed on an "AS IS" BASIS,
11
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- * See the License for the specific language governing permissions and
13
- * limitations under the License.
14
- */
15
-
16
- /**
17
- * @module pdfjsLib
18
- */
19
-
20
- import {
21
- AbortException,
22
- assert,
23
- createPromiseCapability,
24
- getVerbosityLevel,
25
- info,
26
- InvalidPDFException,
27
- isArrayBuffer,
28
- isSameOrigin,
29
- MissingPDFException,
30
- PasswordException,
31
- setVerbosityLevel,
32
- shadow,
33
- stringToBytes,
34
- UnexpectedResponseException,
35
- UnknownErrorException,
36
- unreachable,
37
- warn,
38
- } from "../shared/util.js";
39
- import {
40
- deprecated,
41
- DOMCanvasFactory,
42
- DOMCMapReaderFactory,
43
- DOMStandardFontDataFactory,
44
- isDataScheme,
45
- loadScript,
46
- PageViewport,
47
- RenderingCancelledException,
48
- StatTimer,
49
- } from "./display_utils.js";
50
- import { FontFaceObject, FontLoader } from "./font_loader.js";
51
- import {
52
- NodeCanvasFactory,
53
- NodeCMapReaderFactory,
54
- NodeStandardFontDataFactory,
55
- } from "./node_utils.js";
56
- import { AnnotationStorage } from "./annotation_storage.js";
57
- import { CanvasGraphics } from "./canvas.js";
58
- import { GlobalWorkerOptions } from "./worker_options.js";
59
- import { isNodeJS } from "../shared/is_node.js";
60
- import { MessageHandler } from "../shared/message_handler.js";
61
- import { Metadata } from "./metadata.js";
62
- import { OptionalContentConfig } from "./optional_content_config.js";
63
- import { PDFDataTransportStream } from "./transport_stream.js";
64
-
65
- const DEFAULT_RANGE_CHUNK_SIZE = 65536; // 2^16 = 65536
66
- const RENDERING_CANCELLED_TIMEOUT = 100; // ms
67
-
68
- const DefaultCanvasFactory =
69
- (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) && isNodeJS
70
- ? NodeCanvasFactory
71
- : DOMCanvasFactory;
72
- const DefaultCMapReaderFactory =
73
- (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) && isNodeJS
74
- ? NodeCMapReaderFactory
75
- : DOMCMapReaderFactory;
76
- const DefaultStandardFontDataFactory =
77
- (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) && isNodeJS
78
- ? NodeStandardFontDataFactory
79
- : DOMStandardFontDataFactory;
80
-
81
- /**
82
- * @typedef {function} IPDFStreamFactory
83
- * @param {DocumentInitParameters} params - The document initialization
84
- * parameters. The "url" key is always present.
85
- * @returns {Promise} A promise, which is resolved with an instance of
86
- * {IPDFStream}.
87
- * @ignore
88
- */
89
-
90
- /**
91
- * @type IPDFStreamFactory
92
- * @private
93
- */
94
- let createPDFNetworkStream;
95
-
96
- /**
97
- * Sets the function that instantiates an {IPDFStream} as an alternative PDF
98
- * data transport.
99
- *
100
- * @param {IPDFStreamFactory} pdfNetworkStreamFactory - The factory function
101
- * that takes document initialization parameters (including a "url") and
102
- * returns a promise which is resolved with an instance of {IPDFStream}.
103
- * @ignore
104
- */
105
- function setPDFNetworkStreamFactory(pdfNetworkStreamFactory) {
106
- createPDFNetworkStream = pdfNetworkStreamFactory;
107
- }
108
-
109
- /**
110
- * @typedef { Int8Array | Uint8Array | Uint8ClampedArray |
111
- * Int16Array | Uint16Array |
112
- * Int32Array | Uint32Array | Float32Array |
113
- * Float64Array
114
- * } TypedArray
115
- */
116
-
117
- /**
118
- * @typedef {Object} RefProxy
119
- * @property {number} num
120
- * @property {number} gen
121
- */
122
-
123
- /**
124
- * Document initialization / loading parameters object.
125
- *
126
- * @typedef {Object} DocumentInitParameters
127
- * @property {string|URL} [url] - The URL of the PDF.
128
- * @property {TypedArray|Array<number>|string} [data] - Binary PDF data. Use
129
- * typed arrays (Uint8Array) to improve the memory usage. If PDF data is
130
- * BASE64-encoded, use `atob()` to convert it to a binary string first.
131
- * @property {Object} [httpHeaders] - Basic authentication headers.
132
- * @property {boolean} [withCredentials] - Indicates whether or not
133
- * cross-site Access-Control requests should be made using credentials such
134
- * as cookies or authorization headers. The default is `false`.
135
- * @property {string} [password] - For decrypting password-protected PDFs.
136
- * @property {TypedArray} [initialData] - A typed array with the first portion
137
- * or all of the pdf data. Used by the extension since some data is already
138
- * loaded before the switch to range requests.
139
- * @property {number} [length] - The PDF file length. It's used for progress
140
- * reports and range requests operations.
141
- * @property {PDFDataRangeTransport} [range] - Allows for using a custom range
142
- * transport implementation.
143
- * @property {number} [rangeChunkSize] - Specify maximum number of bytes fetched
144
- * per range request. The default value is {@link DEFAULT_RANGE_CHUNK_SIZE}.
145
- * @property {PDFWorker} [worker] - The worker that will be used for loading and
146
- * parsing the PDF data.
147
- * @property {number} [verbosity] - Controls the logging level; the constants
148
- * from {@link VerbosityLevel} should be used.
149
- * @property {string} [docBaseUrl] - The base URL of the document, used when
150
- * attempting to recover valid absolute URLs for annotations, and outline
151
- * items, that (incorrectly) only specify relative URLs.
152
- * @property {string} [cMapUrl] - The URL where the predefined Adobe CMaps are
153
- * located. Include the trailing slash.
154
- * @property {boolean} [cMapPacked] - Specifies if the Adobe CMaps are binary
155
- * packed or not.
156
- * @property {Object} [CMapReaderFactory] - The factory that will be used when
157
- * reading built-in CMap files. Providing a custom factory is useful for
158
- * environments without Fetch API or `XMLHttpRequest` support, such as
159
- * Node.js. The default value is {DOMCMapReaderFactory}.
160
- * @property {boolean} [useSystemFonts] - When `true`, fonts that aren't
161
- * embedded in the PDF document will fallback to a system font.
162
- * The default value is `true` in web environments and `false` in Node.js;
163
- * unless `disableFontFace === true` in which case this defaults to `false`
164
- * regardless of the environment (to prevent completely broken fonts).
165
- * @property {string} [standardFontDataUrl] - The URL where the standard font
166
- * files are located. Include the trailing slash.
167
- * @property {Object} [StandardFontDataFactory] - The factory that will be used
168
- * when reading the standard font files. Providing a custom factory is useful
169
- * for environments without Fetch API or `XMLHttpRequest` support, such as
170
- * Node.js. The default value is {DOMStandardFontDataFactory}.
171
- * @property {boolean} [useWorkerFetch] - Enable using the Fetch API in the
172
- * worker-thread when reading CMap and standard font files. When `true`,
173
- * the `CMapReaderFactory` and `StandardFontDataFactory` options are ignored.
174
- * The default value is `true` in web environments and `false` in Node.js.
175
- * @property {boolean} [stopAtErrors] - Reject certain promises, e.g.
176
- * `getOperatorList`, `getTextContent`, and `RenderTask`, when the associated
177
- * PDF data cannot be successfully parsed, instead of attempting to recover
178
- * whatever possible of the data. The default value is `false`.
179
- * @property {number} [maxImageSize] - The maximum allowed image size in total
180
- * pixels, i.e. width * height. Images above this value will not be rendered.
181
- * Use -1 for no limit, which is also the default value.
182
- * @property {boolean} [isEvalSupported] - Determines if we can evaluate strings
183
- * as JavaScript. Primarily used to improve performance of font rendering, and
184
- * when parsing PDF functions. The default value is `true`.
185
- * @property {boolean} [disableFontFace] - By default fonts are converted to
186
- * OpenType fonts and loaded via the Font Loading API or `@font-face` rules.
187
- * If disabled, fonts will be rendered using a built-in font renderer that
188
- * constructs the glyphs with primitive path commands.
189
- * The default value is `false` in web environments and `true` in Node.js.
190
- * @property {boolean} [fontExtraProperties] - Include additional properties,
191
- * which are unused during rendering of PDF documents, when exporting the
192
- * parsed font data from the worker-thread. This may be useful for debugging
193
- * purposes (and backwards compatibility), but note that it will lead to
194
- * increased memory usage. The default value is `false`.
195
- * @property {boolean} [enableXfa] - Render Xfa forms if any.
196
- * The default value is `false`.
197
- * @property {HTMLDocument} [ownerDocument] - Specify an explicit document
198
- * context to create elements with and to load resources, such as fonts,
199
- * into. Defaults to the current document.
200
- * @property {boolean} [disableRange] - Disable range request loading of PDF
201
- * files. When enabled, and if the server supports partial content requests,
202
- * then the PDF will be fetched in chunks. The default value is `false`.
203
- * @property {boolean} [disableStream] - Disable streaming of PDF file data.
204
- * By default PDF.js attempts to load PDF files in chunks. The default value
205
- * is `false`.
206
- * @property {boolean} [disableAutoFetch] - Disable pre-fetching of PDF file
207
- * data. When range requests are enabled PDF.js will automatically keep
208
- * fetching more data even if it isn't needed to display the current page.
209
- * The default value is `false`.
210
- *
211
- * NOTE: It is also necessary to disable streaming, see above, in order for
212
- * disabling of pre-fetching to work correctly.
213
- * @property {boolean} [pdfBug] - Enables special hooks for debugging PDF.js
214
- * (see `web/debugger.js`). The default value is `false`.
215
- */
216
-
217
- /**
218
- * This is the main entry point for loading a PDF and interacting with it.
219
- *
220
- * NOTE: If a URL is used to fetch the PDF data a standard Fetch API call (or
221
- * XHR as fallback) is used, which means it must follow same origin rules,
222
- * e.g. no cross-domain requests without CORS.
223
- *
224
- * @param {string|URL|TypedArray|PDFDataRangeTransport|DocumentInitParameters}
225
- * src - Can be a URL where a PDF file is located, a typed array (Uint8Array)
226
- * already populated with data, or a parameter object.
227
- * @returns {PDFDocumentLoadingTask}
228
- */
229
- function getDocument(src) {
230
- const task = new PDFDocumentLoadingTask();
231
-
232
- let source;
233
- if (typeof src === "string" || src instanceof URL) {
234
- source = { url: src };
235
- } else if (isArrayBuffer(src)) {
236
- source = { data: src };
237
- } else if (src instanceof PDFDataRangeTransport) {
238
- source = { range: src };
239
- } else {
240
- if (typeof src !== "object") {
241
- throw new Error(
242
- "Invalid parameter in getDocument, " +
243
- "need either string, URL, Uint8Array, or parameter object."
244
- );
245
- }
246
- if (!src.url && !src.data && !src.range) {
247
- throw new Error(
248
- "Invalid parameter object: need either .data, .range or .url"
249
- );
250
- }
251
- source = src;
252
- }
253
- const params = Object.create(null);
254
- let rangeTransport = null,
255
- worker = null;
256
-
257
- for (const key in source) {
258
- const value = source[key];
259
-
260
- switch (key) {
261
- case "url":
262
- if (typeof window !== "undefined") {
263
- try {
264
- // The full path is required in the 'url' field.
265
- params[key] = new URL(value, window.location).href;
266
- continue;
267
- } catch (ex) {
268
- warn(`Cannot create valid URL: "${ex}".`);
269
- }
270
- } else if (typeof value === "string" || value instanceof URL) {
271
- params[key] = value.toString(); // Support Node.js environments.
272
- continue;
273
- }
274
- throw new Error(
275
- "Invalid PDF url data: " +
276
- "either string or URL-object is expected in the url property."
277
- );
278
- case "range":
279
- rangeTransport = value;
280
- continue;
281
- case "worker":
282
- worker = value;
283
- continue;
284
- case "data":
285
- // Converting string or array-like data to Uint8Array.
286
- if (
287
- typeof PDFJSDev !== "undefined" &&
288
- PDFJSDev.test("GENERIC") &&
289
- isNodeJS &&
290
- typeof Buffer !== "undefined" && // eslint-disable-line no-undef
291
- value instanceof Buffer // eslint-disable-line no-undef
292
- ) {
293
- params[key] = new Uint8Array(value);
294
- } else if (value instanceof Uint8Array) {
295
- break; // Use the data as-is when it's already a Uint8Array.
296
- } else if (typeof value === "string") {
297
- params[key] = stringToBytes(value);
298
- } else if (
299
- typeof value === "object" &&
300
- value !== null &&
301
- !isNaN(value.length)
302
- ) {
303
- params[key] = new Uint8Array(value);
304
- } else if (isArrayBuffer(value)) {
305
- params[key] = new Uint8Array(value);
306
- } else {
307
- throw new Error(
308
- "Invalid PDF binary data: either typed array, " +
309
- "string, or array-like object is expected in the data property."
310
- );
311
- }
312
- continue;
313
- }
314
- params[key] = value;
315
- }
316
-
317
- params.rangeChunkSize = params.rangeChunkSize || DEFAULT_RANGE_CHUNK_SIZE;
318
- params.CMapReaderFactory =
319
- params.CMapReaderFactory || DefaultCMapReaderFactory;
320
- params.StandardFontDataFactory =
321
- params.StandardFontDataFactory || DefaultStandardFontDataFactory;
322
- params.ignoreErrors = params.stopAtErrors !== true;
323
- params.fontExtraProperties = params.fontExtraProperties === true;
324
- params.pdfBug = params.pdfBug === true;
325
- params.enableXfa = params.enableXfa === true;
326
-
327
- if (
328
- typeof params.docBaseUrl !== "string" ||
329
- isDataScheme(params.docBaseUrl)
330
- ) {
331
- // Ignore "data:"-URLs, since they can't be used to recover valid absolute
332
- // URLs anyway. We want to avoid sending them to the worker-thread, since
333
- // they contain the *entire* PDF document and can thus be arbitrarily long.
334
- params.docBaseUrl = null;
335
- }
336
- if (!Number.isInteger(params.maxImageSize)) {
337
- params.maxImageSize = -1;
338
- }
339
- if (typeof params.useWorkerFetch !== "boolean") {
340
- params.useWorkerFetch =
341
- params.CMapReaderFactory === DOMCMapReaderFactory &&
342
- params.StandardFontDataFactory === DOMStandardFontDataFactory;
343
- }
344
- if (typeof params.isEvalSupported !== "boolean") {
345
- params.isEvalSupported = true;
346
- }
347
- if (typeof params.disableFontFace !== "boolean") {
348
- params.disableFontFace =
349
- (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) && isNodeJS;
350
- }
351
- if (typeof params.useSystemFonts !== "boolean") {
352
- params.useSystemFonts =
353
- !(
354
- (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) &&
355
- isNodeJS
356
- ) && !params.disableFontFace;
357
- }
358
- if (typeof params.ownerDocument === "undefined") {
359
- params.ownerDocument = globalThis.document;
360
- }
361
-
362
- if (typeof params.disableRange !== "boolean") {
363
- params.disableRange = false;
364
- }
365
- if (typeof params.disableStream !== "boolean") {
366
- params.disableStream = false;
367
- }
368
- if (typeof params.disableAutoFetch !== "boolean") {
369
- params.disableAutoFetch = false;
370
- }
371
-
372
- // Set the main-thread verbosity level.
373
- setVerbosityLevel(params.verbosity);
374
-
375
- if (!worker) {
376
- const workerParams = {
377
- verbosity: params.verbosity,
378
- port: GlobalWorkerOptions.workerPort,
379
- };
380
- // Worker was not provided -- creating and owning our own. If message port
381
- // is specified in global worker options, using it.
382
- worker = workerParams.port
383
- ? PDFWorker.fromPort(workerParams)
384
- : new PDFWorker(workerParams);
385
- task._worker = worker;
386
- }
387
- const docId = task.docId;
388
- worker.promise
389
- .then(function () {
390
- if (task.destroyed) {
391
- throw new Error("Loading aborted");
392
- }
393
-
394
- const workerIdPromise = _fetchDocument(
395
- worker,
396
- params,
397
- rangeTransport,
398
- docId
399
- );
400
- const networkStreamPromise = new Promise(function (resolve) {
401
- let networkStream;
402
- if (rangeTransport) {
403
- networkStream = new PDFDataTransportStream(
404
- {
405
- length: params.length,
406
- initialData: params.initialData,
407
- progressiveDone: params.progressiveDone,
408
- contentDispositionFilename: params.contentDispositionFilename,
409
- disableRange: params.disableRange,
410
- disableStream: params.disableStream,
411
- },
412
- rangeTransport
413
- );
414
- } else if (!params.data) {
415
- networkStream = createPDFNetworkStream({
416
- url: params.url,
417
- length: params.length,
418
- httpHeaders: params.httpHeaders,
419
- withCredentials: params.withCredentials,
420
- rangeChunkSize: params.rangeChunkSize,
421
- disableRange: params.disableRange,
422
- disableStream: params.disableStream,
423
- });
424
- }
425
- resolve(networkStream);
426
- });
427
-
428
- return Promise.all([workerIdPromise, networkStreamPromise]).then(
429
- function ([workerId, networkStream]) {
430
- if (task.destroyed) {
431
- throw new Error("Loading aborted");
432
- }
433
-
434
- const messageHandler = new MessageHandler(
435
- docId,
436
- workerId,
437
- worker.port
438
- );
439
- messageHandler.postMessageTransfers = worker.postMessageTransfers;
440
- const transport = new WorkerTransport(
441
- messageHandler,
442
- task,
443
- networkStream,
444
- params
445
- );
446
- task._transport = transport;
447
- messageHandler.send("Ready", null);
448
- }
449
- );
450
- })
451
- .catch(task._capability.reject);
452
-
453
- return task;
454
- }
455
-
456
- /**
457
- * Starts fetching of specified PDF document/data.
458
- *
459
- * @param {PDFWorker} worker
460
- * @param {Object} source
461
- * @param {PDFDataRangeTransport} pdfDataRangeTransport
462
- * @param {string} docId - Unique document ID, used in `MessageHandler`.
463
- * @returns {Promise} A promise that is resolved when the worker ID of the
464
- * `MessageHandler` is known.
465
- * @private
466
- */
467
- function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
468
- if (worker.destroyed) {
469
- return Promise.reject(new Error("Worker was destroyed"));
470
- }
471
-
472
- if (pdfDataRangeTransport) {
473
- source.length = pdfDataRangeTransport.length;
474
- source.initialData = pdfDataRangeTransport.initialData;
475
- source.progressiveDone = pdfDataRangeTransport.progressiveDone;
476
- source.contentDispositionFilename =
477
- pdfDataRangeTransport.contentDispositionFilename;
478
- }
479
- return worker.messageHandler
480
- .sendWithPromise("GetDocRequest", {
481
- docId,
482
- apiVersion:
483
- typeof PDFJSDev !== "undefined" && !PDFJSDev.test("TESTING")
484
- ? PDFJSDev.eval("BUNDLE_VERSION")
485
- : null,
486
- // Only send the required properties, and *not* the entire object.
487
- source: {
488
- data: source.data,
489
- url: source.url,
490
- password: source.password,
491
- disableAutoFetch: source.disableAutoFetch,
492
- rangeChunkSize: source.rangeChunkSize,
493
- length: source.length,
494
- },
495
- maxImageSize: source.maxImageSize,
496
- disableFontFace: source.disableFontFace,
497
- postMessageTransfers: worker.postMessageTransfers,
498
- docBaseUrl: source.docBaseUrl,
499
- ignoreErrors: source.ignoreErrors,
500
- isEvalSupported: source.isEvalSupported,
501
- fontExtraProperties: source.fontExtraProperties,
502
- enableXfa: source.enableXfa,
503
- useSystemFonts: source.useSystemFonts,
504
- cMapUrl: source.useWorkerFetch ? source.cMapUrl : null,
505
- standardFontDataUrl: source.useWorkerFetch
506
- ? source.standardFontDataUrl
507
- : null,
508
- })
509
- .then(function (workerId) {
510
- if (worker.destroyed) {
511
- throw new Error("Worker was destroyed");
512
- }
513
- return workerId;
514
- });
515
- }
516
-
517
- /**
518
- * @typedef {Object} OnProgressParameters
519
- * @property {number} loaded - Currently loaded number of bytes.
520
- * @property {number} total - Total number of bytes in the PDF file.
521
- */
522
-
523
- /**
524
- * The loading task controls the operations required to load a PDF document
525
- * (such as network requests) and provides a way to listen for completion,
526
- * after which individual pages can be rendered.
527
- *
528
- * @typedef {Object} PDFDocumentLoadingTask
529
- * @property {string} docId - Unique identifier for the document loading task.
530
- * @property {boolean} destroyed - Whether the loading task is destroyed or not.
531
- * @property {function} [onPassword] - Callback to request a password if a wrong
532
- * or no password was provided. The callback receives two parameters: a
533
- * function that should be called with the new password, and a reason (see
534
- * {@link PasswordResponses}).
535
- * @property {function} [onProgress] - Callback to be able to monitor the
536
- * loading progress of the PDF file (necessary to implement e.g. a loading
537
- * bar). The callback receives an {@link OnProgressParameters} argument.
538
- * @property {function} [onUnsupportedFeature] - Callback for when an
539
- * unsupported feature is used in the PDF document. The callback receives an
540
- * {@link UNSUPPORTED_FEATURES} argument.
541
- * @property {Promise<PDFDocumentProxy>} promise - Promise for document loading
542
- * task completion.
543
- * @property {function} destroy - Abort all network requests and destroy
544
- * the worker. Returns a promise that is resolved when destruction is
545
- * completed.
546
- */
547
-
548
- /**
549
- * @type {any}
550
- * @ignore
551
- */
552
- const PDFDocumentLoadingTask = (function PDFDocumentLoadingTaskClosure() {
553
- let nextDocumentId = 0;
554
-
555
- /**
556
- * The loading task controls the operations required to load a PDF document
557
- * (such as network requests) and provides a way to listen for completion,
558
- * after which individual pages can be rendered.
559
- */
560
- // eslint-disable-next-line no-shadow
561
- class PDFDocumentLoadingTask {
562
- constructor() {
563
- this._capability = createPromiseCapability();
564
- this._transport = null;
565
- this._worker = null;
566
-
567
- /**
568
- * Unique identifier for the document loading task.
569
- * @type {string}
570
- */
571
- this.docId = "d" + nextDocumentId++;
572
-
573
- /**
574
- * Whether the loading task is destroyed or not.
575
- * @type {boolean}
576
- */
577
- this.destroyed = false;
578
-
579
- /**
580
- * Callback to request a password if a wrong or no password was provided.
581
- * The callback receives two parameters: a function that should be called
582
- * with the new password, and a reason (see {@link PasswordResponses}).
583
- * @type {function}
584
- */
585
- this.onPassword = null;
586
-
587
- /**
588
- * Callback to be able to monitor the loading progress of the PDF file
589
- * (necessary to implement e.g. a loading bar).
590
- * The callback receives an {@link OnProgressParameters} argument.
591
- * @type {function}
592
- */
593
- this.onProgress = null;
594
-
595
- /**
596
- * Callback for when an unsupported feature is used in the PDF document.
597
- * The callback receives an {@link UNSUPPORTED_FEATURES} argument.
598
- * @type {function}
599
- */
600
- this.onUnsupportedFeature = null;
601
- }
602
-
603
- /**
604
- * Promise for document loading task completion.
605
- * @type {Promise<PDFDocumentProxy>}
606
- */
607
- get promise() {
608
- return this._capability.promise;
609
- }
610
-
611
- /**
612
- * @returns {Promise<void>} A promise that is resolved when destruction is
613
- * completed.
614
- */
615
- destroy() {
616
- this.destroyed = true;
617
-
618
- const transportDestroyed = !this._transport
619
- ? Promise.resolve()
620
- : this._transport.destroy();
621
- return transportDestroyed.then(() => {
622
- this._transport = null;
623
- if (this._worker) {
624
- this._worker.destroy();
625
- this._worker = null;
626
- }
627
- });
628
- }
629
- }
630
- return PDFDocumentLoadingTask;
631
- })();
632
-
633
- /**
634
- * Abstract class to support range requests file loading.
635
- */
636
- class PDFDataRangeTransport {
637
- /**
638
- * @param {number} length
639
- * @param {Uint8Array} initialData
640
- * @param {boolean} [progressiveDone]
641
- * @param {string} [contentDispositionFilename]
642
- */
643
- constructor(
644
- length,
645
- initialData,
646
- progressiveDone = false,
647
- contentDispositionFilename = null
648
- ) {
649
- this.length = length;
650
- this.initialData = initialData;
651
- this.progressiveDone = progressiveDone;
652
- this.contentDispositionFilename = contentDispositionFilename;
653
-
654
- this._rangeListeners = [];
655
- this._progressListeners = [];
656
- this._progressiveReadListeners = [];
657
- this._progressiveDoneListeners = [];
658
- this._readyCapability = createPromiseCapability();
659
- }
660
-
661
- addRangeListener(listener) {
662
- this._rangeListeners.push(listener);
663
- }
664
-
665
- addProgressListener(listener) {
666
- this._progressListeners.push(listener);
667
- }
668
-
669
- addProgressiveReadListener(listener) {
670
- this._progressiveReadListeners.push(listener);
671
- }
672
-
673
- addProgressiveDoneListener(listener) {
674
- this._progressiveDoneListeners.push(listener);
675
- }
676
-
677
- onDataRange(begin, chunk) {
678
- for (const listener of this._rangeListeners) {
679
- listener(begin, chunk);
680
- }
681
- }
682
-
683
- onDataProgress(loaded, total) {
684
- this._readyCapability.promise.then(() => {
685
- for (const listener of this._progressListeners) {
686
- listener(loaded, total);
687
- }
688
- });
689
- }
690
-
691
- onDataProgressiveRead(chunk) {
692
- this._readyCapability.promise.then(() => {
693
- for (const listener of this._progressiveReadListeners) {
694
- listener(chunk);
695
- }
696
- });
697
- }
698
-
699
- onDataProgressiveDone() {
700
- this._readyCapability.promise.then(() => {
701
- for (const listener of this._progressiveDoneListeners) {
702
- listener();
703
- }
704
- });
705
- }
706
-
707
- transportReady() {
708
- this._readyCapability.resolve();
709
- }
710
-
711
- requestDataRange(begin, end) {
712
- unreachable("Abstract method PDFDataRangeTransport.requestDataRange");
713
- }
714
-
715
- abort() {}
716
- }
717
-
718
- /**
719
- * Proxy to a `PDFDocument` in the worker thread.
720
- */
721
- class PDFDocumentProxy {
722
- constructor(pdfInfo, transport) {
723
- this._pdfInfo = pdfInfo;
724
- this._transport = transport;
725
-
726
- if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
727
- Object.defineProperty(this, "fingerprint", {
728
- get() {
729
- deprecated(
730
- "`PDFDocumentProxy.fingerprint`, " +
731
- "please use `PDFDocumentProxy.fingerprints` instead."
732
- );
733
- return this.fingerprints[0];
734
- },
735
- });
736
- }
737
- }
738
-
739
- /**
740
- * @type {AnnotationStorage} Storage for annotation data in forms.
741
- */
742
- get annotationStorage() {
743
- return this._transport.annotationStorage;
744
- }
745
-
746
- /**
747
- * @type {number} Total number of pages in the PDF file.
748
- */
749
- get numPages() {
750
- return this._pdfInfo.numPages;
751
- }
752
-
753
- /**
754
- * @type {Array<string, string|null>} A (not guaranteed to be) unique ID to
755
- * identify the PDF document.
756
- * NOTE: The first element will always be defined for all PDF documents,
757
- * whereas the second element is only defined for *modified* PDF documents.
758
- */
759
- get fingerprints() {
760
- return this._pdfInfo.fingerprints;
761
- }
762
-
763
- /**
764
- * @type {boolean} True if only XFA form.
765
- */
766
- get isPureXfa() {
767
- return !!this._transport._htmlForXfa;
768
- }
769
-
770
- /**
771
- * NOTE: This is (mostly) intended to support printing of XFA forms.
772
- *
773
- * @type {Object | null} An object representing a HTML tree structure
774
- * to render the XFA, or `null` when no XFA form exists.
775
- */
776
- get allXfaHtml() {
777
- return this._transport._htmlForXfa;
778
- }
779
-
780
- /**
781
- * @param {number} pageNumber - The page number to get. The first page is 1.
782
- * @returns {Promise<PDFPageProxy>} A promise that is resolved with
783
- * a {@link PDFPageProxy} object.
784
- */
785
- getPage(pageNumber) {
786
- return this._transport.getPage(pageNumber);
787
- }
788
-
789
- /**
790
- * @param {RefProxy} ref - The page reference.
791
- * @returns {Promise<number>} A promise that is resolved with the page index,
792
- * starting from zero, that is associated with the reference.
793
- */
794
- getPageIndex(ref) {
795
- return this._transport.getPageIndex(ref);
796
- }
797
-
798
- /**
799
- * @returns {Promise<Object<string, Array<any>>>} A promise that is resolved
800
- * with a mapping from named destinations to references.
801
- *
802
- * This can be slow for large documents. Use `getDestination` instead.
803
- */
804
- getDestinations() {
805
- return this._transport.getDestinations();
806
- }
807
-
808
- /**
809
- * @param {string} id - The named destination to get.
810
- * @returns {Promise<Array<any> | null>} A promise that is resolved with all
811
- * information of the given named destination, or `null` when the named
812
- * destination is not present in the PDF file.
813
- */
814
- getDestination(id) {
815
- return this._transport.getDestination(id);
816
- }
817
-
818
- /**
819
- * @returns {Promise<Array<string> | null>} A promise that is resolved with
820
- * an {Array} containing the page labels that correspond to the page
821
- * indexes, or `null` when no page labels are present in the PDF file.
822
- */
823
- getPageLabels() {
824
- return this._transport.getPageLabels();
825
- }
826
-
827
- /**
828
- * @returns {Promise<string>} A promise that is resolved with a {string}
829
- * containing the page layout name.
830
- */
831
- getPageLayout() {
832
- return this._transport.getPageLayout();
833
- }
834
-
835
- /**
836
- * @returns {Promise<string>} A promise that is resolved with a {string}
837
- * containing the page mode name.
838
- */
839
- getPageMode() {
840
- return this._transport.getPageMode();
841
- }
842
-
843
- /**
844
- * @returns {Promise<Object | null>} A promise that is resolved with an
845
- * {Object} containing the viewer preferences, or `null` when no viewer
846
- * preferences are present in the PDF file.
847
- */
848
- getViewerPreferences() {
849
- return this._transport.getViewerPreferences();
850
- }
851
-
852
- /**
853
- * @returns {Promise<any | null>} A promise that is resolved with an {Array}
854
- * containing the destination, or `null` when no open action is present
855
- * in the PDF.
856
- */
857
- getOpenAction() {
858
- return this._transport.getOpenAction();
859
- }
860
-
861
- /**
862
- * @returns {Promise<any>} A promise that is resolved with a lookup table
863
- * for mapping named attachments to their content.
864
- */
865
- getAttachments() {
866
- return this._transport.getAttachments();
867
- }
868
-
869
- /**
870
- * @returns {Promise<Array<string> | null>} A promise that is resolved with
871
- * an {Array} of all the JavaScript strings in the name tree, or `null`
872
- * if no JavaScript exists.
873
- */
874
- getJavaScript() {
875
- return this._transport.getJavaScript();
876
- }
877
-
878
- /**
879
- * @returns {Promise<Object | null>} A promise that is resolved with
880
- * an {Object} with the JavaScript actions:
881
- * - from the name tree (like getJavaScript);
882
- * - from A or AA entries in the catalog dictionary.
883
- * , or `null` if no JavaScript exists.
884
- */
885
- getJSActions() {
886
- return this._transport.getDocJSActions();
887
- }
888
-
889
- /**
890
- * @typedef {Object} OutlineNode
891
- * @property {string} title
892
- * @property {boolean} bold
893
- * @property {boolean} italic
894
- * @property {Uint8ClampedArray} color - The color in RGB format to use for
895
- * display purposes.
896
- * @property {string | Array<any> | null} dest
897
- * @property {string | null} url
898
- * @property {string | undefined} unsafeUrl
899
- * @property {boolean | undefined} newWindow
900
- * @property {number | undefined} count
901
- * @property {Array<OutlineNode>} items
902
- */
903
-
904
- /**
905
- * @returns {Promise<Array<OutlineNode>>} A promise that is resolved with an
906
- * {Array} that is a tree outline (if it has one) of the PDF file.
907
- */
908
- getOutline() {
909
- return this._transport.getOutline();
910
- }
911
-
912
- /**
913
- * @returns {Promise<OptionalContentConfig>} A promise that is resolved with
914
- * an {@link OptionalContentConfig} that contains all the optional content
915
- * groups (assuming that the document has any).
916
- */
917
- getOptionalContentConfig() {
918
- return this._transport.getOptionalContentConfig();
919
- }
920
-
921
- /**
922
- * @returns {Promise<Array<number> | null>} A promise that is resolved with
923
- * an {Array} that contains the permission flags for the PDF document, or
924
- * `null` when no permissions are present in the PDF file.
925
- */
926
- getPermissions() {
927
- return this._transport.getPermissions();
928
- }
929
-
930
- /**
931
- * @returns {Promise<{ info: Object, metadata: Metadata }>} A promise that is
932
- * resolved with an {Object} that has `info` and `metadata` properties.
933
- * `info` is an {Object} filled with anything available in the information
934
- * dictionary and similarly `metadata` is a {Metadata} object with
935
- * information from the metadata section of the PDF.
936
- */
937
- getMetadata() {
938
- return this._transport.getMetadata();
939
- }
940
-
941
- /**
942
- * @typedef {Object} MarkInfo
943
- * Properties correspond to Table 321 of the PDF 32000-1:2008 spec.
944
- * @property {boolean} Marked
945
- * @property {boolean} UserProperties
946
- * @property {boolean} Suspects
947
- */
948
-
949
- /**
950
- * @returns {Promise<MarkInfo | null>} A promise that is resolved with
951
- * a {MarkInfo} object that contains the MarkInfo flags for the PDF
952
- * document, or `null` when no MarkInfo values are present in the PDF file.
953
- */
954
- getMarkInfo() {
955
- return this._transport.getMarkInfo();
956
- }
957
-
958
- /**
959
- * @returns {Promise<TypedArray>} A promise that is resolved with a
960
- * {TypedArray} that has the raw data from the PDF.
961
- */
962
- getData() {
963
- return this._transport.getData();
964
- }
965
-
966
- /**
967
- * @returns {Promise<{ length: number }>} A promise that is resolved when the
968
- * document's data is loaded. It is resolved with an {Object} that contains
969
- * the `length` property that indicates size of the PDF data in bytes.
970
- */
971
- getDownloadInfo() {
972
- return this._transport.downloadInfoCapability.promise;
973
- }
974
-
975
- /**
976
- * @typedef {Object} PDFDocumentStats
977
- * @property {Object<string, boolean>} streamTypes - Used stream types in the
978
- * document (an item is set to true if specific stream ID was used in the
979
- * document).
980
- * @property {Object<string, boolean>} fontTypes - Used font types in the
981
- * document (an item is set to true if specific font ID was used in the
982
- * document).
983
- */
984
-
985
- /**
986
- * @returns {Promise<PDFDocumentStats>} A promise this is resolved with
987
- * current statistics about document structures (see
988
- * {@link PDFDocumentStats}).
989
- */
990
- getStats() {
991
- return this._transport.getStats();
992
- }
993
-
994
- /**
995
- * Cleans up resources allocated by the document on both the main and worker
996
- * threads.
997
- *
998
- * NOTE: Do not, under any circumstances, call this method when rendering is
999
- * currently ongoing since that may lead to rendering errors.
1000
- *
1001
- * @param {boolean} [keepLoadedFonts] - Let fonts remain attached to the DOM.
1002
- * NOTE: This will increase persistent memory usage, hence don't use this
1003
- * option unless absolutely necessary. The default value is `false`.
1004
- * @returns {Promise} A promise that is resolved when clean-up has finished.
1005
- */
1006
- cleanup(keepLoadedFonts = false) {
1007
- return this._transport.startCleanup(keepLoadedFonts || this.isPureXfa);
1008
- }
1009
-
1010
- /**
1011
- * Destroys the current document instance and terminates the worker.
1012
- */
1013
- destroy() {
1014
- return this.loadingTask.destroy();
1015
- }
1016
-
1017
- /**
1018
- * @type {DocumentInitParameters} A subset of the current
1019
- * {DocumentInitParameters}, which are needed in the viewer.
1020
- */
1021
- get loadingParams() {
1022
- return this._transport.loadingParams;
1023
- }
1024
-
1025
- /**
1026
- * @type {PDFDocumentLoadingTask} The loadingTask for the current document.
1027
- */
1028
- get loadingTask() {
1029
- return this._transport.loadingTask;
1030
- }
1031
-
1032
- /**
1033
- * @returns {Promise<Uint8Array>} A promise that is resolved with a
1034
- * {Uint8Array} containing the full data of the saved document.
1035
- */
1036
- saveDocument() {
1037
- if (
1038
- (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) &&
1039
- this._transport.annotationStorage.size <= 0
1040
- ) {
1041
- deprecated(
1042
- "saveDocument called while `annotationStorage` is empty, " +
1043
- "please use the getData-method instead."
1044
- );
1045
- }
1046
- return this._transport.saveDocument();
1047
- }
1048
-
1049
- /**
1050
- * @returns {Promise<Array<Object> | null>} A promise that is resolved with an
1051
- * {Array<Object>} containing /AcroForm field data for the JS sandbox,
1052
- * or `null` when no field data is present in the PDF file.
1053
- */
1054
- getFieldObjects() {
1055
- return this._transport.getFieldObjects();
1056
- }
1057
-
1058
- /**
1059
- * @returns {Promise<boolean>} A promise that is resolved with `true`
1060
- * if some /AcroForm fields have JavaScript actions.
1061
- */
1062
- hasJSActions() {
1063
- return this._transport.hasJSActions();
1064
- }
1065
-
1066
- /**
1067
- * @returns {Promise<Array<string> | null>} A promise that is resolved with an
1068
- * {Array<string>} containing IDs of annotations that have a calculation
1069
- * action, or `null` when no such annotations are present in the PDF file.
1070
- */
1071
- getCalculationOrderIds() {
1072
- return this._transport.getCalculationOrderIds();
1073
- }
1074
- }
1075
-
1076
- /**
1077
- * Page getViewport parameters.
1078
- *
1079
- * @typedef {Object} GetViewportParameters
1080
- * @property {number} scale - The desired scale of the viewport.
1081
- * @property {number} [rotation] - The desired rotation, in degrees, of
1082
- * the viewport. If omitted it defaults to the page rotation.
1083
- * @property {number} [offsetX] - The horizontal, i.e. x-axis, offset.
1084
- * The default value is `0`.
1085
- * @property {number} [offsetY] - The vertical, i.e. y-axis, offset.
1086
- * The default value is `0`.
1087
- * @property {boolean} [dontFlip] - If true, the y-axis will not be
1088
- * flipped. The default value is `false`.
1089
- */
1090
-
1091
- /**
1092
- * Page getTextContent parameters.
1093
- *
1094
- * @typedef {Object} getTextContentParameters
1095
- * @property {boolean} normalizeWhitespace - Replaces all occurrences of
1096
- * whitespace with standard spaces (0x20). The default value is `false`.
1097
- * @property {boolean} disableCombineTextItems - Do not attempt to combine
1098
- * same line {@link TextItem}'s. The default value is `false`.
1099
- * @property {boolean} [includeMarkedContent] - When true include marked
1100
- * content items in the items array of TextContent. The default is `false`.
1101
- */
1102
-
1103
- /**
1104
- * Page text content.
1105
- *
1106
- * @typedef {Object} TextContent
1107
- * @property {Array<TextItem | TextMarkedContent>} items - Array of
1108
- * {@link TextItem} and {@link TextMarkedContent} objects. TextMarkedContent
1109
- * items are included when includeMarkedContent is true.
1110
- * @property {Object<string, TextStyle>} styles - {@link TextStyle} objects,
1111
- * indexed by font name.
1112
- */
1113
-
1114
- /**
1115
- * Page text content part.
1116
- *
1117
- * @typedef {Object} TextItem
1118
- * @property {string} str - Text content.
1119
- * @property {string} dir - Text direction: 'ttb', 'ltr' or 'rtl'.
1120
- * @property {Array<any>} transform - Transformation matrix.
1121
- * @property {number} width - Width in device space.
1122
- * @property {number} height - Height in device space.
1123
- * @property {string} fontName - Font name used by PDF.js for converted font.
1124
- * @property {boolean} hasEOL - Indicating if the text content is followed by a
1125
- * line-break.
1126
- */
1127
-
1128
- /**
1129
- * Page text marked content part.
1130
- *
1131
- * @typedef {Object} TextMarkedContent
1132
- * @property {string} type - Either 'beginMarkedContent',
1133
- * 'beginMarkedContentProps', or 'endMarkedContent'.
1134
- * @property {string} id - The marked content identifier. Only used for type
1135
- * 'beginMarkedContentProps'.
1136
- */
1137
-
1138
- /**
1139
- * Text style.
1140
- *
1141
- * @typedef {Object} TextStyle
1142
- * @property {number} ascent - Font ascent.
1143
- * @property {number} descent - Font descent.
1144
- * @property {boolean} vertical - Whether or not the text is in vertical mode.
1145
- * @property {string} fontFamily - The possible font family.
1146
- */
1147
-
1148
- /**
1149
- * Page annotation parameters.
1150
- *
1151
- * @typedef {Object} GetAnnotationsParameters
1152
- * @property {string} [intent] - Determines the annotations that are fetched,
1153
- * can be either 'display' (viewable annotations) or 'print' (printable
1154
- * annotations). If the parameter is omitted, all annotations are fetched.
1155
- */
1156
-
1157
- /**
1158
- * Page render parameters.
1159
- *
1160
- * @typedef {Object} RenderParameters
1161
- * @property {Object} canvasContext - A 2D context of a DOM Canvas object.
1162
- * @property {PageViewport} viewport - Rendering viewport obtained by calling
1163
- * the `PDFPageProxy.getViewport` method.
1164
- * @property {string} [intent] - Rendering intent, can be 'display' or 'print'.
1165
- * The default value is 'display'.
1166
- * @property {boolean} [renderInteractiveForms] - Whether or not interactive
1167
- * form elements are rendered in the display layer. If so, we do not render
1168
- * them on the canvas as well. The default value is `false`.
1169
- * @property {Array<any>} [transform] - Additional transform, applied just
1170
- * before viewport transform.
1171
- * @property {Object} [imageLayer] - An object that has `beginLayout`,
1172
- * `endLayout` and `appendImage` functions.
1173
- * @property {Object} [canvasFactory] - The factory instance that will be used
1174
- * when creating canvases. The default value is {new DOMCanvasFactory()}.
1175
- * @property {Object | string} [background] - Background to use for the canvas.
1176
- * Any valid `canvas.fillStyle` can be used: a `DOMString` parsed as CSS
1177
- * <color> value, a `CanvasGradient` object (a linear or radial gradient) or
1178
- * a `CanvasPattern` object (a repetitive image). The default value is
1179
- * 'rgb(255,255,255)'.
1180
- * @property {boolean} [includeAnnotationStorage] - Render stored interactive
1181
- * form element data, from the {@link AnnotationStorage}-instance, onto the
1182
- * canvas itself; useful e.g. for printing. The default value is `false`.
1183
- * @property {Promise<OptionalContentConfig>} [optionalContentConfigPromise] -
1184
- * A promise that should resolve with an {@link OptionalContentConfig}
1185
- * created from `PDFDocumentProxy.getOptionalContentConfig`. If `null`,
1186
- * the configuration will be fetched automatically with the default visibility
1187
- * states set.
1188
- */
1189
-
1190
- /**
1191
- * Page getOperatorList parameters.
1192
- *
1193
- * @typedef {Object} GetOperatorListParameters
1194
- * @property {string} [intent] - Rendering intent, can be 'display' or 'print'.
1195
- * The default value is 'display'.
1196
- */
1197
-
1198
- /**
1199
- * Structure tree node. The root node will have a role "Root".
1200
- *
1201
- * @typedef {Object} StructTreeNode
1202
- * @property {Array<StructTreeNode | StructTreeContent>} children - Array of
1203
- * {@link StructTreeNode} and {@link StructTreeContent} objects.
1204
- * @property {string} role - element's role, already mapped if a role map exists
1205
- * in the PDF.
1206
- */
1207
-
1208
- /**
1209
- * Structure tree content.
1210
- *
1211
- * @typedef {Object} StructTreeContent
1212
- * @property {string} type - either "content" for page and stream structure
1213
- * elements or "object" for object references.
1214
- * @property {string} id - unique id that will map to the text layer.
1215
- */
1216
-
1217
- /**
1218
- * PDF page operator list.
1219
- *
1220
- * @typedef {Object} PDFOperatorList
1221
- * @property {Array<number>} fnArray - Array containing the operator functions.
1222
- * @property {Array<any>} argsArray - Array containing the arguments of the
1223
- * functions.
1224
- */
1225
-
1226
- /**
1227
- * Proxy to a `PDFPage` in the worker thread.
1228
- */
1229
- class PDFPageProxy {
1230
- constructor(pageIndex, pageInfo, transport, ownerDocument, pdfBug = false) {
1231
- this._pageIndex = pageIndex;
1232
- this._pageInfo = pageInfo;
1233
- this._ownerDocument = ownerDocument;
1234
- this._transport = transport;
1235
- this._stats = pdfBug ? new StatTimer() : null;
1236
- this._pdfBug = pdfBug;
1237
- this.commonObjs = transport.commonObjs;
1238
- this.objs = new PDFObjects();
1239
-
1240
- this.cleanupAfterRender = false;
1241
- this.pendingCleanup = false;
1242
- this._intentStates = new Map();
1243
- this.destroyed = false;
1244
- }
1245
-
1246
- /**
1247
- * @type {number} Page number of the page. First page is 1.
1248
- */
1249
- get pageNumber() {
1250
- return this._pageIndex + 1;
1251
- }
1252
-
1253
- /**
1254
- * @type {number} The number of degrees the page is rotated clockwise.
1255
- */
1256
- get rotate() {
1257
- return this._pageInfo.rotate;
1258
- }
1259
-
1260
- /**
1261
- * @type {RefProxy | null} The reference that points to this page.
1262
- */
1263
- get ref() {
1264
- return this._pageInfo.ref;
1265
- }
1266
-
1267
- /**
1268
- * @type {number} The default size of units in 1/72nds of an inch.
1269
- */
1270
- get userUnit() {
1271
- return this._pageInfo.userUnit;
1272
- }
1273
-
1274
- /**
1275
- * @type {Array<number>} An array of the visible portion of the PDF page in
1276
- * user space units [x1, y1, x2, y2].
1277
- */
1278
- get view() {
1279
- return this._pageInfo.view;
1280
- }
1281
-
1282
- /**
1283
- * @param {GetViewportParameters} params - Viewport parameters.
1284
- * @returns {PageViewport} Contains 'width' and 'height' properties
1285
- * along with transforms required for rendering.
1286
- */
1287
- getViewport({
1288
- scale,
1289
- rotation = this.rotate,
1290
- offsetX = 0,
1291
- offsetY = 0,
1292
- dontFlip = false,
1293
- } = {}) {
1294
- return new PageViewport({
1295
- viewBox: this.view,
1296
- scale,
1297
- rotation,
1298
- offsetX,
1299
- offsetY,
1300
- dontFlip,
1301
- });
1302
- }
1303
-
1304
- /**
1305
- * @param {GetAnnotationsParameters} params - Annotation parameters.
1306
- * @returns {Promise<Array<any>>} A promise that is resolved with an
1307
- * {Array} of the annotation objects.
1308
- */
1309
- getAnnotations({ intent = null } = {}) {
1310
- const renderingIntent =
1311
- intent === "display" || intent === "print" ? intent : null;
1312
-
1313
- if (
1314
- !this._annotationsPromise ||
1315
- this._annotationsIntent !== renderingIntent
1316
- ) {
1317
- this._annotationsPromise = this._transport.getAnnotations(
1318
- this._pageIndex,
1319
- renderingIntent
1320
- );
1321
- this._annotationsIntent = renderingIntent;
1322
- }
1323
- return this._annotationsPromise;
1324
- }
1325
-
1326
- /**
1327
- * @returns {Promise<Object>} A promise that is resolved with an
1328
- * {Object} with JS actions.
1329
- */
1330
- getJSActions() {
1331
- return (this._jsActionsPromise ||= this._transport.getPageJSActions(
1332
- this._pageIndex
1333
- ));
1334
- }
1335
-
1336
- /**
1337
- * @returns {Promise<Object | null>} A promise that is resolved with
1338
- * an {Object} with a fake DOM object (a tree structure where elements
1339
- * are {Object} with a name, attributes (class, style, ...), value and
1340
- * children, very similar to a HTML DOM tree), or `null` if no XFA exists.
1341
- */
1342
- async getXfa() {
1343
- return this._transport._htmlForXfa?.children[this._pageIndex] || null;
1344
- }
1345
-
1346
- /**
1347
- * Begins the process of rendering a page to the desired context.
1348
- *
1349
- * @param {RenderParameters} params - Page render parameters.
1350
- * @returns {RenderTask} An object that contains a promise that is
1351
- * resolved when the page finishes rendering.
1352
- */
1353
- render({
1354
- canvasContext,
1355
- viewport,
1356
- intent = "display",
1357
- renderInteractiveForms = false,
1358
- transform = null,
1359
- imageLayer = null,
1360
- canvasFactory = null,
1361
- background = null,
1362
- includeAnnotationStorage = false,
1363
- optionalContentConfigPromise = null,
1364
- }) {
1365
- if (this._stats) {
1366
- this._stats.time("Overall");
1367
- }
1368
-
1369
- const renderingIntent = intent === "print" ? "print" : "display";
1370
- // If there was a pending destroy, cancel it so no cleanup happens during
1371
- // this call to render.
1372
- this.pendingCleanup = false;
1373
-
1374
- if (!optionalContentConfigPromise) {
1375
- optionalContentConfigPromise = this._transport.getOptionalContentConfig();
1376
- }
1377
-
1378
- let intentState = this._intentStates.get(renderingIntent);
1379
- if (!intentState) {
1380
- intentState = Object.create(null);
1381
- this._intentStates.set(renderingIntent, intentState);
1382
- }
1383
-
1384
- // Ensure that a pending `streamReader` cancel timeout is always aborted.
1385
- if (intentState.streamReaderCancelTimeout) {
1386
- clearTimeout(intentState.streamReaderCancelTimeout);
1387
- intentState.streamReaderCancelTimeout = null;
1388
- }
1389
-
1390
- const canvasFactoryInstance =
1391
- canvasFactory ||
1392
- new DefaultCanvasFactory({ ownerDocument: this._ownerDocument });
1393
- const annotationStorage = includeAnnotationStorage
1394
- ? this._transport.annotationStorage.serializable
1395
- : null;
1396
-
1397
- // If there's no displayReadyCapability yet, then the operatorList
1398
- // was never requested before. Make the request and create the promise.
1399
- if (!intentState.displayReadyCapability) {
1400
- intentState.displayReadyCapability = createPromiseCapability();
1401
- intentState.operatorList = {
1402
- fnArray: [],
1403
- argsArray: [],
1404
- lastChunk: false,
1405
- };
1406
-
1407
- if (this._stats) {
1408
- this._stats.time("Page Request");
1409
- }
1410
- this._pumpOperatorList({
1411
- pageIndex: this._pageIndex,
1412
- intent: renderingIntent,
1413
- renderInteractiveForms: renderInteractiveForms === true,
1414
- annotationStorage,
1415
- });
1416
- }
1417
-
1418
- const complete = error => {
1419
- intentState.renderTasks.delete(internalRenderTask);
1420
-
1421
- // Attempt to reduce memory usage during *printing*, by always running
1422
- // cleanup once rendering has finished (regardless of cleanupAfterRender).
1423
- if (this.cleanupAfterRender || renderingIntent === "print") {
1424
- this.pendingCleanup = true;
1425
- }
1426
- this._tryCleanup();
1427
-
1428
- if (error) {
1429
- internalRenderTask.capability.reject(error);
1430
-
1431
- this._abortOperatorList({
1432
- intentState,
1433
- reason: error,
1434
- });
1435
- } else {
1436
- internalRenderTask.capability.resolve();
1437
- }
1438
- if (this._stats) {
1439
- this._stats.timeEnd("Rendering");
1440
- this._stats.timeEnd("Overall");
1441
- }
1442
- };
1443
-
1444
- const internalRenderTask = new InternalRenderTask({
1445
- callback: complete,
1446
- // Only include the required properties, and *not* the entire object.
1447
- params: {
1448
- canvasContext,
1449
- viewport,
1450
- transform,
1451
- imageLayer,
1452
- background,
1453
- },
1454
- objs: this.objs,
1455
- commonObjs: this.commonObjs,
1456
- operatorList: intentState.operatorList,
1457
- pageIndex: this._pageIndex,
1458
- canvasFactory: canvasFactoryInstance,
1459
- useRequestAnimationFrame: renderingIntent !== "print",
1460
- pdfBug: this._pdfBug,
1461
- });
1462
-
1463
- (intentState.renderTasks ||= new Set()).add(internalRenderTask);
1464
- const renderTask = internalRenderTask.task;
1465
-
1466
- Promise.all([
1467
- intentState.displayReadyCapability.promise,
1468
- optionalContentConfigPromise,
1469
- ])
1470
- .then(([transparency, optionalContentConfig]) => {
1471
- if (this.pendingCleanup) {
1472
- complete();
1473
- return;
1474
- }
1475
- if (this._stats) {
1476
- this._stats.time("Rendering");
1477
- }
1478
- internalRenderTask.initializeGraphics({
1479
- transparency,
1480
- optionalContentConfig,
1481
- });
1482
- internalRenderTask.operatorListChanged();
1483
- })
1484
- .catch(complete);
1485
-
1486
- return renderTask;
1487
- }
1488
-
1489
- /**
1490
- * @param {GetOperatorListParameters} params - Page getOperatorList
1491
- * parameters.
1492
- * @returns {Promise<PDFOperatorList>} A promise resolved with an
1493
- * {@link PDFOperatorList} object that represents the page's operator list.
1494
- */
1495
- getOperatorList({ intent = "display" } = {}) {
1496
- function operatorListChanged() {
1497
- if (intentState.operatorList.lastChunk) {
1498
- intentState.opListReadCapability.resolve(intentState.operatorList);
1499
-
1500
- intentState.renderTasks.delete(opListTask);
1501
- }
1502
- }
1503
-
1504
- const renderingIntent = `oplist-${
1505
- intent === "print" ? "print" : "display"
1506
- }`;
1507
- let intentState = this._intentStates.get(renderingIntent);
1508
- if (!intentState) {
1509
- intentState = Object.create(null);
1510
- this._intentStates.set(renderingIntent, intentState);
1511
- }
1512
- let opListTask;
1513
-
1514
- if (!intentState.opListReadCapability) {
1515
- opListTask = Object.create(null);
1516
- opListTask.operatorListChanged = operatorListChanged;
1517
- intentState.opListReadCapability = createPromiseCapability();
1518
- (intentState.renderTasks ||= new Set()).add(opListTask);
1519
- intentState.operatorList = {
1520
- fnArray: [],
1521
- argsArray: [],
1522
- lastChunk: false,
1523
- };
1524
-
1525
- if (this._stats) {
1526
- this._stats.time("Page Request");
1527
- }
1528
- this._pumpOperatorList({
1529
- pageIndex: this._pageIndex,
1530
- intent: renderingIntent,
1531
- });
1532
- }
1533
- return intentState.opListReadCapability.promise;
1534
- }
1535
-
1536
- /**
1537
- * @param {getTextContentParameters} params - getTextContent parameters.
1538
- * @returns {ReadableStream} Stream for reading text content chunks.
1539
- */
1540
- streamTextContent({
1541
- normalizeWhitespace = false,
1542
- disableCombineTextItems = false,
1543
- includeMarkedContent = false,
1544
- } = {}) {
1545
- const TEXT_CONTENT_CHUNK_SIZE = 100;
1546
-
1547
- return this._transport.messageHandler.sendWithStream(
1548
- "GetTextContent",
1549
- {
1550
- pageIndex: this._pageIndex,
1551
- normalizeWhitespace: normalizeWhitespace === true,
1552
- combineTextItems: disableCombineTextItems !== true,
1553
- includeMarkedContent: includeMarkedContent === true,
1554
- },
1555
- {
1556
- highWaterMark: TEXT_CONTENT_CHUNK_SIZE,
1557
- size(textContent) {
1558
- return textContent.items.length;
1559
- },
1560
- }
1561
- );
1562
- }
1563
-
1564
- /**
1565
- * @param {getTextContentParameters} params - getTextContent parameters.
1566
- * @returns {Promise<TextContent>} A promise that is resolved with a
1567
- * {@link TextContent} object that represents the page's text content.
1568
- */
1569
- getTextContent(params = {}) {
1570
- const readableStream = this.streamTextContent(params);
1571
-
1572
- return new Promise(function (resolve, reject) {
1573
- function pump() {
1574
- reader.read().then(function ({ value, done }) {
1575
- if (done) {
1576
- resolve(textContent);
1577
- return;
1578
- }
1579
- Object.assign(textContent.styles, value.styles);
1580
- textContent.items.push(...value.items);
1581
- pump();
1582
- }, reject);
1583
- }
1584
-
1585
- const reader = readableStream.getReader();
1586
- const textContent = {
1587
- items: [],
1588
- styles: Object.create(null),
1589
- };
1590
- pump();
1591
- });
1592
- }
1593
-
1594
- /**
1595
- * @returns {Promise<StructTreeNode>} A promise that is resolved with a
1596
- * {@link StructTreeNode} object that represents the page's structure tree,
1597
- * or `null` when no structure tree is present for the current page.
1598
- */
1599
- getStructTree() {
1600
- return (this._structTreePromise ||= this._transport.getStructTree(
1601
- this._pageIndex
1602
- ));
1603
- }
1604
-
1605
- /**
1606
- * Destroys the page object.
1607
- * @private
1608
- */
1609
- _destroy() {
1610
- this.destroyed = true;
1611
- this._transport.pageCache[this._pageIndex] = null;
1612
-
1613
- const waitOn = [];
1614
- for (const [intent, intentState] of this._intentStates) {
1615
- this._abortOperatorList({
1616
- intentState,
1617
- reason: new Error("Page was destroyed."),
1618
- force: true,
1619
- });
1620
-
1621
- if (intent.startsWith("oplist-")) {
1622
- // Avoid errors below, since the renderTasks are just stubs.
1623
- continue;
1624
- }
1625
- for (const internalRenderTask of intentState.renderTasks) {
1626
- waitOn.push(internalRenderTask.completed);
1627
- internalRenderTask.cancel();
1628
- }
1629
- }
1630
- this.objs.clear();
1631
- this._annotationsPromise = null;
1632
- this._jsActionsPromise = null;
1633
- this._structTreePromise = null;
1634
- this.pendingCleanup = false;
1635
- return Promise.all(waitOn);
1636
- }
1637
-
1638
- /**
1639
- * Cleans up resources allocated by the page.
1640
- *
1641
- * @param {boolean} [resetStats] - Reset page stats, if enabled.
1642
- * The default value is `false`.
1643
- * @returns {boolean} Indicates if clean-up was successfully run.
1644
- */
1645
- cleanup(resetStats = false) {
1646
- this.pendingCleanup = true;
1647
- return this._tryCleanup(resetStats);
1648
- }
1649
-
1650
- /**
1651
- * Attempts to clean up if rendering is in a state where that's possible.
1652
- * @private
1653
- */
1654
- _tryCleanup(resetStats = false) {
1655
- if (!this.pendingCleanup) {
1656
- return false;
1657
- }
1658
- for (const { renderTasks, operatorList } of this._intentStates.values()) {
1659
- if (renderTasks.size > 0 || !operatorList.lastChunk) {
1660
- return false;
1661
- }
1662
- }
1663
-
1664
- this._intentStates.clear();
1665
- this.objs.clear();
1666
- this._annotationsPromise = null;
1667
- this._jsActionsPromise = null;
1668
- this._structTreePromise = null;
1669
- if (resetStats && this._stats) {
1670
- this._stats = new StatTimer();
1671
- }
1672
- this.pendingCleanup = false;
1673
- return true;
1674
- }
1675
-
1676
- /**
1677
- * @private
1678
- */
1679
- _startRenderPage(transparency, intent) {
1680
- const intentState = this._intentStates.get(intent);
1681
- if (!intentState) {
1682
- return; // Rendering was cancelled.
1683
- }
1684
- if (this._stats) {
1685
- this._stats.timeEnd("Page Request");
1686
- }
1687
- // TODO Refactor RenderPageRequest to separate rendering
1688
- // and operator list logic
1689
- if (intentState.displayReadyCapability) {
1690
- intentState.displayReadyCapability.resolve(transparency);
1691
- }
1692
- }
1693
-
1694
- /**
1695
- * @private
1696
- */
1697
- _renderPageChunk(operatorListChunk, intentState) {
1698
- // Add the new chunk to the current operator list.
1699
- for (let i = 0, ii = operatorListChunk.length; i < ii; i++) {
1700
- intentState.operatorList.fnArray.push(operatorListChunk.fnArray[i]);
1701
- intentState.operatorList.argsArray.push(operatorListChunk.argsArray[i]);
1702
- }
1703
- intentState.operatorList.lastChunk = operatorListChunk.lastChunk;
1704
-
1705
- // Notify all the rendering tasks there are more operators to be consumed.
1706
- for (const internalRenderTask of intentState.renderTasks) {
1707
- internalRenderTask.operatorListChanged();
1708
- }
1709
-
1710
- if (operatorListChunk.lastChunk) {
1711
- this._tryCleanup();
1712
- }
1713
- }
1714
-
1715
- /**
1716
- * @private
1717
- */
1718
- _pumpOperatorList(args) {
1719
- assert(
1720
- args.intent,
1721
- 'PDFPageProxy._pumpOperatorList: Expected "intent" argument.'
1722
- );
1723
-
1724
- const readableStream = this._transport.messageHandler.sendWithStream(
1725
- "GetOperatorList",
1726
- args
1727
- );
1728
- const reader = readableStream.getReader();
1729
-
1730
- const intentState = this._intentStates.get(args.intent);
1731
- intentState.streamReader = reader;
1732
-
1733
- const pump = () => {
1734
- reader.read().then(
1735
- ({ value, done }) => {
1736
- if (done) {
1737
- intentState.streamReader = null;
1738
- return;
1739
- }
1740
- if (this._transport.destroyed) {
1741
- return; // Ignore any pending requests if the worker was terminated.
1742
- }
1743
- this._renderPageChunk(value, intentState);
1744
- pump();
1745
- },
1746
- reason => {
1747
- intentState.streamReader = null;
1748
-
1749
- if (this._transport.destroyed) {
1750
- return; // Ignore any pending requests if the worker was terminated.
1751
- }
1752
- if (intentState.operatorList) {
1753
- // Mark operator list as complete.
1754
- intentState.operatorList.lastChunk = true;
1755
-
1756
- for (const internalRenderTask of intentState.renderTasks) {
1757
- internalRenderTask.operatorListChanged();
1758
- }
1759
- this._tryCleanup();
1760
- }
1761
-
1762
- if (intentState.displayReadyCapability) {
1763
- intentState.displayReadyCapability.reject(reason);
1764
- } else if (intentState.opListReadCapability) {
1765
- intentState.opListReadCapability.reject(reason);
1766
- } else {
1767
- throw reason;
1768
- }
1769
- }
1770
- );
1771
- };
1772
- pump();
1773
- }
1774
-
1775
- /**
1776
- * @private
1777
- */
1778
- _abortOperatorList({ intentState, reason, force = false }) {
1779
- assert(
1780
- reason instanceof Error ||
1781
- (typeof reason === "object" && reason !== null),
1782
- 'PDFPageProxy._abortOperatorList: Expected "reason" argument.'
1783
- );
1784
-
1785
- if (!intentState.streamReader) {
1786
- return;
1787
- }
1788
- if (!force) {
1789
- // Ensure that an Error occurring in *only* one `InternalRenderTask`, e.g.
1790
- // multiple render() calls on the same canvas, won't break all rendering.
1791
- if (intentState.renderTasks.size > 0) {
1792
- return;
1793
- }
1794
- // Don't immediately abort parsing on the worker-thread when rendering is
1795
- // cancelled, since that will unnecessarily delay re-rendering when (for
1796
- // partially parsed pages) e.g. zooming/rotation occurs in the viewer.
1797
- if (reason instanceof RenderingCancelledException) {
1798
- intentState.streamReaderCancelTimeout = setTimeout(() => {
1799
- this._abortOperatorList({ intentState, reason, force: true });
1800
- intentState.streamReaderCancelTimeout = null;
1801
- }, RENDERING_CANCELLED_TIMEOUT);
1802
- return;
1803
- }
1804
- }
1805
- intentState.streamReader.cancel(new AbortException(reason?.message));
1806
- intentState.streamReader = null;
1807
-
1808
- if (this._transport.destroyed) {
1809
- return; // Ignore any pending requests if the worker was terminated.
1810
- }
1811
- // Remove the current `intentState`, since a cancelled `getOperatorList`
1812
- // call on the worker-thread cannot be re-started...
1813
- for (const [intent, curIntentState] of this._intentStates) {
1814
- if (curIntentState === intentState) {
1815
- this._intentStates.delete(intent);
1816
- break;
1817
- }
1818
- }
1819
- // ... and force clean-up to ensure that any old state is always removed.
1820
- this.cleanup();
1821
- }
1822
-
1823
- /**
1824
- * @type {Object} Returns page stats, if enabled; returns `null` otherwise.
1825
- */
1826
- get stats() {
1827
- return this._stats;
1828
- }
1829
- }
1830
-
1831
- class LoopbackPort {
1832
- constructor() {
1833
- this._listeners = [];
1834
- this._deferred = Promise.resolve(undefined);
1835
- }
1836
-
1837
- postMessage(obj, transfers) {
1838
- function cloneValue(value) {
1839
- // Trying to perform a structured clone close to the spec, including
1840
- // transfers.
1841
- if (
1842
- typeof value === "function" ||
1843
- typeof value === "symbol" ||
1844
- value instanceof URL
1845
- ) {
1846
- throw new Error(
1847
- `LoopbackPort.postMessage - cannot clone: ${value?.toString()}`
1848
- );
1849
- }
1850
-
1851
- if (typeof value !== "object" || value === null) {
1852
- return value;
1853
- }
1854
- if (cloned.has(value)) {
1855
- // already cloned the object
1856
- return cloned.get(value);
1857
- }
1858
- let buffer, result;
1859
- if ((buffer = value.buffer) && isArrayBuffer(buffer)) {
1860
- // We found object with ArrayBuffer (typed array).
1861
- if (transfers?.includes(buffer)) {
1862
- result = new value.constructor(
1863
- buffer,
1864
- value.byteOffset,
1865
- value.byteLength
1866
- );
1867
- } else {
1868
- result = new value.constructor(value);
1869
- }
1870
- cloned.set(value, result);
1871
- return result;
1872
- }
1873
- if (value instanceof Map) {
1874
- result = new Map();
1875
- cloned.set(value, result); // Adding to cache now for cyclic references.
1876
- for (const [key, val] of value) {
1877
- result.set(key, cloneValue(val));
1878
- }
1879
- return result;
1880
- }
1881
- if (value instanceof Set) {
1882
- result = new Set();
1883
- cloned.set(value, result); // Adding to cache now for cyclic references.
1884
- for (const val of value) {
1885
- result.add(cloneValue(val));
1886
- }
1887
- return result;
1888
- }
1889
- result = Array.isArray(value) ? [] : Object.create(null);
1890
- cloned.set(value, result); // Adding to cache now for cyclic references.
1891
- // Cloning all value and object properties, however ignoring properties
1892
- // defined via getter.
1893
- for (const i in value) {
1894
- let desc,
1895
- p = value;
1896
- while (!(desc = Object.getOwnPropertyDescriptor(p, i))) {
1897
- p = Object.getPrototypeOf(p);
1898
- }
1899
- if (typeof desc.value === "undefined") {
1900
- continue;
1901
- }
1902
- if (typeof desc.value === "function" && !value.hasOwnProperty?.(i)) {
1903
- continue;
1904
- }
1905
- result[i] = cloneValue(desc.value);
1906
- }
1907
- return result;
1908
- }
1909
-
1910
- const cloned = new WeakMap();
1911
- const event = { data: cloneValue(obj) };
1912
-
1913
- this._deferred.then(() => {
1914
- for (const listener of this._listeners) {
1915
- listener.call(this, event);
1916
- }
1917
- });
1918
- }
1919
-
1920
- addEventListener(name, listener) {
1921
- this._listeners.push(listener);
1922
- }
1923
-
1924
- removeEventListener(name, listener) {
1925
- const i = this._listeners.indexOf(listener);
1926
- this._listeners.splice(i, 1);
1927
- }
1928
-
1929
- terminate() {
1930
- this._listeners.length = 0;
1931
- }
1932
- }
1933
-
1934
- /**
1935
- * @typedef {Object} PDFWorkerParameters
1936
- * @property {string} [name] - The name of the worker.
1937
- * @property {Object} [port] - The `workerPort` object.
1938
- * @property {number} [verbosity] - Controls the logging level; the
1939
- * constants from {@link VerbosityLevel} should be used.
1940
- */
1941
-
1942
- /** @type {any} */
1943
- const PDFWorker = (function PDFWorkerClosure() {
1944
- const pdfWorkerPorts = new WeakMap();
1945
- let isWorkerDisabled = false;
1946
- let fallbackWorkerSrc;
1947
- let nextFakeWorkerId = 0;
1948
- let fakeWorkerCapability;
1949
-
1950
- if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("GENERIC")) {
1951
- // eslint-disable-next-line no-undef
1952
- if (isNodeJS && typeof __non_webpack_require__ === "function") {
1953
- // Workers aren't supported in Node.js, force-disabling them there.
1954
- isWorkerDisabled = true;
1955
-
1956
- if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("LIB")) {
1957
- fallbackWorkerSrc = "../pdf.worker.js";
1958
- } else {
1959
- fallbackWorkerSrc = "./pdf.worker.js";
1960
- }
1961
- } else if (typeof document === "object" && "currentScript" in document) {
1962
- const pdfjsFilePath = document.currentScript?.src;
1963
- if (pdfjsFilePath) {
1964
- fallbackWorkerSrc = pdfjsFilePath.replace(
1965
- /(\.(?:min\.)?js)(\?.*)?$/i,
1966
- ".worker$1$2"
1967
- );
1968
- }
1969
- }
1970
- }
1971
-
1972
- function getWorkerSrc() {
1973
- if (GlobalWorkerOptions.workerSrc) {
1974
- return GlobalWorkerOptions.workerSrc;
1975
- }
1976
- if (typeof fallbackWorkerSrc !== "undefined") {
1977
- if (!isNodeJS) {
1978
- deprecated('No "GlobalWorkerOptions.workerSrc" specified.');
1979
- }
1980
- return fallbackWorkerSrc;
1981
- }
1982
- throw new Error('No "GlobalWorkerOptions.workerSrc" specified.');
1983
- }
1984
-
1985
- function getMainThreadWorkerMessageHandler() {
1986
- let mainWorkerMessageHandler;
1987
- try {
1988
- mainWorkerMessageHandler = globalThis.pdfjsWorker?.WorkerMessageHandler;
1989
- } catch (ex) {
1990
- /* Ignore errors. */
1991
- }
1992
- return mainWorkerMessageHandler || null;
1993
- }
1994
-
1995
- // Loads worker code into main thread.
1996
- function setupFakeWorkerGlobal() {
1997
- if (fakeWorkerCapability) {
1998
- return fakeWorkerCapability.promise;
1999
- }
2000
- fakeWorkerCapability = createPromiseCapability();
2001
-
2002
- const loader = async function () {
2003
- const mainWorkerMessageHandler = getMainThreadWorkerMessageHandler();
2004
-
2005
- if (mainWorkerMessageHandler) {
2006
- // The worker was already loaded using e.g. a `<script>` tag.
2007
- return mainWorkerMessageHandler;
2008
- }
2009
- if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("PRODUCTION")) {
2010
- const worker = await import("../core/worker.js");
2011
- return worker.WorkerMessageHandler;
2012
- }
2013
- if (
2014
- PDFJSDev.test("GENERIC") &&
2015
- isNodeJS &&
2016
- // eslint-disable-next-line no-undef
2017
- typeof __non_webpack_require__ === "function"
2018
- ) {
2019
- // Since bundlers, such as Webpack, cannot be told to leave `require`
2020
- // statements alone we are thus forced to jump through hoops in order
2021
- // to prevent `Critical dependency: ...` warnings in third-party
2022
- // deployments of the built `pdf.js`/`pdf.worker.js` files; see
2023
- // https://github.com/webpack/webpack/issues/8826
2024
- //
2025
- // The following hack is based on the assumption that code running in
2026
- // Node.js won't ever be affected by e.g. Content Security Policies that
2027
- // prevent the use of `eval`. If that ever occurs, we should revert this
2028
- // to a normal `__non_webpack_require__` statement and simply document
2029
- // the Webpack warnings instead (telling users to ignore them).
2030
- //
2031
- // eslint-disable-next-line no-eval
2032
- const worker = eval("require")(getWorkerSrc());
2033
- return worker.WorkerMessageHandler;
2034
- }
2035
- await loadScript(getWorkerSrc());
2036
- return window.pdfjsWorker.WorkerMessageHandler;
2037
- };
2038
- loader().then(fakeWorkerCapability.resolve, fakeWorkerCapability.reject);
2039
-
2040
- return fakeWorkerCapability.promise;
2041
- }
2042
-
2043
- function createCDNWrapper(url) {
2044
- // We will rely on blob URL's property to specify origin.
2045
- // We want this function to fail in case if createObjectURL or Blob do not
2046
- // exist or fail for some reason -- our Worker creation will fail anyway.
2047
- const wrapper = "importScripts('" + url + "');";
2048
- return URL.createObjectURL(new Blob([wrapper]));
2049
- }
2050
-
2051
- /**
2052
- * PDF.js web worker abstraction that controls the instantiation of PDF
2053
- * documents. Message handlers are used to pass information from the main
2054
- * thread to the worker thread and vice versa. If the creation of a web
2055
- * worker is not possible, a "fake" worker will be used instead.
2056
- */
2057
- // eslint-disable-next-line no-shadow
2058
- class PDFWorker {
2059
- /**
2060
- * @param {PDFWorkerParameters} params - Worker initialization parameters.
2061
- */
2062
- constructor({
2063
- name = null,
2064
- port = null,
2065
- verbosity = getVerbosityLevel(),
2066
- } = {}) {
2067
- if (port && pdfWorkerPorts.has(port)) {
2068
- throw new Error("Cannot use more than one PDFWorker per port");
2069
- }
2070
-
2071
- this.name = name;
2072
- this.destroyed = false;
2073
- this.postMessageTransfers = true;
2074
- this.verbosity = verbosity;
2075
-
2076
- this._readyCapability = createPromiseCapability();
2077
- this._port = null;
2078
- this._webWorker = null;
2079
- this._messageHandler = null;
2080
-
2081
- if (port) {
2082
- pdfWorkerPorts.set(port, this);
2083
- this._initializeFromPort(port);
2084
- return;
2085
- }
2086
- this._initialize();
2087
- }
2088
-
2089
- get promise() {
2090
- return this._readyCapability.promise;
2091
- }
2092
-
2093
- get port() {
2094
- return this._port;
2095
- }
2096
-
2097
- get messageHandler() {
2098
- return this._messageHandler;
2099
- }
2100
-
2101
- _initializeFromPort(port) {
2102
- this._port = port;
2103
- this._messageHandler = new MessageHandler("main", "worker", port);
2104
- this._messageHandler.on("ready", function () {
2105
- // Ignoring 'ready' event -- MessageHandler shall be already initialized
2106
- // and ready to accept the messages.
2107
- });
2108
- this._readyCapability.resolve();
2109
- }
2110
-
2111
- _initialize() {
2112
- // If worker support isn't disabled explicit and the browser has worker
2113
- // support, create a new web worker and test if it/the browser fulfills
2114
- // all requirements to run parts of pdf.js in a web worker.
2115
- // Right now, the requirement is, that an Uint8Array is still an
2116
- // Uint8Array as it arrives on the worker. (Chrome added this with v.15.)
2117
- if (
2118
- typeof Worker !== "undefined" &&
2119
- !isWorkerDisabled &&
2120
- !getMainThreadWorkerMessageHandler()
2121
- ) {
2122
- let workerSrc = getWorkerSrc();
2123
-
2124
- try {
2125
- // Wraps workerSrc path into blob URL, if the former does not belong
2126
- // to the same origin.
2127
- if (
2128
- typeof PDFJSDev !== "undefined" &&
2129
- PDFJSDev.test("GENERIC") &&
2130
- !isSameOrigin(window.location.href, workerSrc)
2131
- ) {
2132
- workerSrc = createCDNWrapper(
2133
- new URL(workerSrc, window.location).href
2134
- );
2135
- }
2136
-
2137
- // Some versions of FF can't create a worker on localhost, see:
2138
- // https://bugzilla.mozilla.org/show_bug.cgi?id=683280
2139
- const worker = new Worker(workerSrc);
2140
- const messageHandler = new MessageHandler("main", "worker", worker);
2141
- const terminateEarly = () => {
2142
- worker.removeEventListener("error", onWorkerError);
2143
- messageHandler.destroy();
2144
- worker.terminate();
2145
- if (this.destroyed) {
2146
- this._readyCapability.reject(new Error("Worker was destroyed"));
2147
- } else {
2148
- // Fall back to fake worker if the termination is caused by an
2149
- // error (e.g. NetworkError / SecurityError).
2150
- this._setupFakeWorker();
2151
- }
2152
- };
2153
-
2154
- const onWorkerError = () => {
2155
- if (!this._webWorker) {
2156
- // Worker failed to initialize due to an error. Clean up and fall
2157
- // back to the fake worker.
2158
- terminateEarly();
2159
- }
2160
- };
2161
- worker.addEventListener("error", onWorkerError);
2162
-
2163
- messageHandler.on("test", data => {
2164
- worker.removeEventListener("error", onWorkerError);
2165
- if (this.destroyed) {
2166
- terminateEarly();
2167
- return; // worker was destroyed
2168
- }
2169
- if (data) {
2170
- // supportTypedArray
2171
- this._messageHandler = messageHandler;
2172
- this._port = worker;
2173
- this._webWorker = worker;
2174
- if (!data.supportTransfers) {
2175
- this.postMessageTransfers = false;
2176
- }
2177
- this._readyCapability.resolve();
2178
- // Send global setting, e.g. verbosity level.
2179
- messageHandler.send("configure", {
2180
- verbosity: this.verbosity,
2181
- });
2182
- } else {
2183
- this._setupFakeWorker();
2184
- messageHandler.destroy();
2185
- worker.terminate();
2186
- }
2187
- });
2188
-
2189
- messageHandler.on("ready", data => {
2190
- worker.removeEventListener("error", onWorkerError);
2191
- if (this.destroyed) {
2192
- terminateEarly();
2193
- return; // worker was destroyed
2194
- }
2195
- try {
2196
- sendTest();
2197
- } catch (e) {
2198
- // We need fallback to a faked worker.
2199
- this._setupFakeWorker();
2200
- }
2201
- });
2202
-
2203
- const sendTest = () => {
2204
- const testObj = new Uint8Array([
2205
- this.postMessageTransfers ? 255 : 0,
2206
- ]);
2207
- // Some versions of Opera throw a DATA_CLONE_ERR on serializing the
2208
- // typed array. Also, checking if we can use transfers.
2209
- try {
2210
- messageHandler.send("test", testObj, [testObj.buffer]);
2211
- } catch (ex) {
2212
- warn("Cannot use postMessage transfers.");
2213
- testObj[0] = 0;
2214
- messageHandler.send("test", testObj);
2215
- }
2216
- };
2217
-
2218
- // It might take time for worker to initialize (especially when AMD
2219
- // loader is used). We will try to send test immediately, and then
2220
- // when 'ready' message will arrive. The worker shall process only
2221
- // first received 'test'.
2222
- sendTest();
2223
- return;
2224
- } catch (e) {
2225
- info("The worker has been disabled.");
2226
- }
2227
- }
2228
- // Either workers are disabled, not supported or have thrown an exception.
2229
- // Thus, we fallback to a faked worker.
2230
- this._setupFakeWorker();
2231
- }
2232
-
2233
- _setupFakeWorker() {
2234
- if (!isWorkerDisabled) {
2235
- warn("Setting up fake worker.");
2236
- isWorkerDisabled = true;
2237
- }
2238
-
2239
- setupFakeWorkerGlobal()
2240
- .then(WorkerMessageHandler => {
2241
- if (this.destroyed) {
2242
- this._readyCapability.reject(new Error("Worker was destroyed"));
2243
- return;
2244
- }
2245
- const port = new LoopbackPort();
2246
- this._port = port;
2247
-
2248
- // All fake workers use the same port, making id unique.
2249
- const id = "fake" + nextFakeWorkerId++;
2250
-
2251
- // If the main thread is our worker, setup the handling for the
2252
- // messages -- the main thread sends to it self.
2253
- const workerHandler = new MessageHandler(id + "_worker", id, port);
2254
- WorkerMessageHandler.setup(workerHandler, port);
2255
-
2256
- const messageHandler = new MessageHandler(id, id + "_worker", port);
2257
- this._messageHandler = messageHandler;
2258
- this._readyCapability.resolve();
2259
- // Send global setting, e.g. verbosity level.
2260
- messageHandler.send("configure", {
2261
- verbosity: this.verbosity,
2262
- });
2263
- })
2264
- .catch(reason => {
2265
- this._readyCapability.reject(
2266
- new Error(`Setting up fake worker failed: "${reason.message}".`)
2267
- );
2268
- });
2269
- }
2270
-
2271
- /**
2272
- * Destroys the worker instance.
2273
- */
2274
- destroy() {
2275
- this.destroyed = true;
2276
- if (this._webWorker) {
2277
- // We need to terminate only web worker created resource.
2278
- this._webWorker.terminate();
2279
- this._webWorker = null;
2280
- }
2281
- pdfWorkerPorts.delete(this._port);
2282
- this._port = null;
2283
- if (this._messageHandler) {
2284
- this._messageHandler.destroy();
2285
- this._messageHandler = null;
2286
- }
2287
- }
2288
-
2289
- /**
2290
- * @param {PDFWorkerParameters} params - The worker initialization
2291
- * parameters.
2292
- */
2293
- static fromPort(params) {
2294
- if (!params || !params.port) {
2295
- throw new Error("PDFWorker.fromPort - invalid method signature.");
2296
- }
2297
- if (pdfWorkerPorts.has(params.port)) {
2298
- return pdfWorkerPorts.get(params.port);
2299
- }
2300
- return new PDFWorker(params);
2301
- }
2302
-
2303
- static getWorkerSrc() {
2304
- return getWorkerSrc();
2305
- }
2306
- }
2307
- return PDFWorker;
2308
- })();
2309
-
2310
- /**
2311
- * For internal use only.
2312
- * @ignore
2313
- */
2314
- class WorkerTransport {
2315
- constructor(messageHandler, loadingTask, networkStream, params) {
2316
- this.messageHandler = messageHandler;
2317
- this.loadingTask = loadingTask;
2318
- this.commonObjs = new PDFObjects();
2319
- this.fontLoader = new FontLoader({
2320
- docId: loadingTask.docId,
2321
- onUnsupportedFeature: this._onUnsupportedFeature.bind(this),
2322
- ownerDocument: params.ownerDocument,
2323
- styleElement: params.styleElement,
2324
- });
2325
- this._params = params;
2326
-
2327
- if (!params.useWorkerFetch) {
2328
- this.CMapReaderFactory = new params.CMapReaderFactory({
2329
- baseUrl: params.cMapUrl,
2330
- isCompressed: params.cMapPacked,
2331
- });
2332
- this.StandardFontDataFactory = new params.StandardFontDataFactory({
2333
- baseUrl: params.standardFontDataUrl,
2334
- });
2335
- }
2336
-
2337
- this.destroyed = false;
2338
- this.destroyCapability = null;
2339
- this._passwordCapability = null;
2340
-
2341
- this._networkStream = networkStream;
2342
- this._fullReader = null;
2343
- this._lastProgress = null;
2344
-
2345
- this.pageCache = [];
2346
- this.pagePromises = [];
2347
- this.downloadInfoCapability = createPromiseCapability();
2348
-
2349
- this.setupMessageHandler();
2350
- }
2351
-
2352
- get annotationStorage() {
2353
- return shadow(this, "annotationStorage", new AnnotationStorage());
2354
- }
2355
-
2356
- destroy() {
2357
- if (this.destroyCapability) {
2358
- return this.destroyCapability.promise;
2359
- }
2360
-
2361
- this.destroyed = true;
2362
- this.destroyCapability = createPromiseCapability();
2363
-
2364
- if (this._passwordCapability) {
2365
- this._passwordCapability.reject(
2366
- new Error("Worker was destroyed during onPassword callback")
2367
- );
2368
- }
2369
-
2370
- const waitOn = [];
2371
- // We need to wait for all renderings to be completed, e.g.
2372
- // timeout/rAF can take a long time.
2373
- for (const page of this.pageCache) {
2374
- if (page) {
2375
- waitOn.push(page._destroy());
2376
- }
2377
- }
2378
- this.pageCache.length = 0;
2379
- this.pagePromises.length = 0;
2380
- // Allow `AnnotationStorage`-related clean-up when destroying the document.
2381
- if (this.hasOwnProperty("annotationStorage")) {
2382
- this.annotationStorage.resetModified();
2383
- }
2384
- // We also need to wait for the worker to finish its long running tasks.
2385
- const terminated = this.messageHandler.sendWithPromise("Terminate", null);
2386
- waitOn.push(terminated);
2387
-
2388
- Promise.all(waitOn).then(() => {
2389
- this.commonObjs.clear();
2390
- this.fontLoader.clear();
2391
- this._hasJSActionsPromise = null;
2392
-
2393
- if (this._networkStream) {
2394
- this._networkStream.cancelAllRequests(
2395
- new AbortException("Worker was terminated.")
2396
- );
2397
- }
2398
-
2399
- if (this.messageHandler) {
2400
- this.messageHandler.destroy();
2401
- this.messageHandler = null;
2402
- }
2403
- this.destroyCapability.resolve();
2404
- }, this.destroyCapability.reject);
2405
- return this.destroyCapability.promise;
2406
- }
2407
-
2408
- setupMessageHandler() {
2409
- const { messageHandler, loadingTask } = this;
2410
-
2411
- messageHandler.on("GetReader", (data, sink) => {
2412
- assert(
2413
- this._networkStream,
2414
- "GetReader - no `IPDFStream` instance available."
2415
- );
2416
- this._fullReader = this._networkStream.getFullReader();
2417
- this._fullReader.onProgress = evt => {
2418
- this._lastProgress = {
2419
- loaded: evt.loaded,
2420
- total: evt.total,
2421
- };
2422
- };
2423
- sink.onPull = () => {
2424
- this._fullReader
2425
- .read()
2426
- .then(function ({ value, done }) {
2427
- if (done) {
2428
- sink.close();
2429
- return;
2430
- }
2431
- assert(
2432
- isArrayBuffer(value),
2433
- "GetReader - expected an ArrayBuffer."
2434
- );
2435
- // Enqueue data chunk into sink, and transfer it
2436
- // to other side as `Transferable` object.
2437
- sink.enqueue(new Uint8Array(value), 1, [value]);
2438
- })
2439
- .catch(reason => {
2440
- sink.error(reason);
2441
- });
2442
- };
2443
-
2444
- sink.onCancel = reason => {
2445
- this._fullReader.cancel(reason);
2446
-
2447
- sink.ready.catch(readyReason => {
2448
- if (this.destroyed) {
2449
- return; // Ignore any pending requests if the worker was terminated.
2450
- }
2451
- throw readyReason;
2452
- });
2453
- };
2454
- });
2455
-
2456
- messageHandler.on("ReaderHeadersReady", data => {
2457
- const headersCapability = createPromiseCapability();
2458
- const fullReader = this._fullReader;
2459
- fullReader.headersReady.then(() => {
2460
- // If stream or range are disabled, it's our only way to report
2461
- // loading progress.
2462
- if (!fullReader.isStreamingSupported || !fullReader.isRangeSupported) {
2463
- if (this._lastProgress && loadingTask.onProgress) {
2464
- loadingTask.onProgress(this._lastProgress);
2465
- }
2466
- fullReader.onProgress = evt => {
2467
- if (loadingTask.onProgress) {
2468
- loadingTask.onProgress({
2469
- loaded: evt.loaded,
2470
- total: evt.total,
2471
- });
2472
- }
2473
- };
2474
- }
2475
-
2476
- headersCapability.resolve({
2477
- isStreamingSupported: fullReader.isStreamingSupported,
2478
- isRangeSupported: fullReader.isRangeSupported,
2479
- contentLength: fullReader.contentLength,
2480
- });
2481
- }, headersCapability.reject);
2482
-
2483
- return headersCapability.promise;
2484
- });
2485
-
2486
- messageHandler.on("GetRangeReader", (data, sink) => {
2487
- assert(
2488
- this._networkStream,
2489
- "GetRangeReader - no `IPDFStream` instance available."
2490
- );
2491
- const rangeReader = this._networkStream.getRangeReader(
2492
- data.begin,
2493
- data.end
2494
- );
2495
-
2496
- // When streaming is enabled, it's possible that the data requested here
2497
- // has already been fetched via the `_fullRequestReader` implementation.
2498
- // However, given that the PDF data is loaded asynchronously on the
2499
- // main-thread and then sent via `postMessage` to the worker-thread,
2500
- // it may not have been available during parsing (hence the attempt to
2501
- // use range requests here).
2502
- //
2503
- // To avoid wasting time and resources here, we'll thus *not* dispatch
2504
- // range requests if the data was already loaded but has not been sent to
2505
- // the worker-thread yet (which will happen via the `_fullRequestReader`).
2506
- if (!rangeReader) {
2507
- sink.close();
2508
- return;
2509
- }
2510
-
2511
- sink.onPull = () => {
2512
- rangeReader
2513
- .read()
2514
- .then(function ({ value, done }) {
2515
- if (done) {
2516
- sink.close();
2517
- return;
2518
- }
2519
- assert(
2520
- isArrayBuffer(value),
2521
- "GetRangeReader - expected an ArrayBuffer."
2522
- );
2523
- sink.enqueue(new Uint8Array(value), 1, [value]);
2524
- })
2525
- .catch(reason => {
2526
- sink.error(reason);
2527
- });
2528
- };
2529
-
2530
- sink.onCancel = reason => {
2531
- rangeReader.cancel(reason);
2532
-
2533
- sink.ready.catch(readyReason => {
2534
- if (this.destroyed) {
2535
- return; // Ignore any pending requests if the worker was terminated.
2536
- }
2537
- throw readyReason;
2538
- });
2539
- };
2540
- });
2541
-
2542
- messageHandler.on("GetDoc", ({ pdfInfo }) => {
2543
- this._numPages = pdfInfo.numPages;
2544
- this._htmlForXfa = pdfInfo.htmlForXfa;
2545
- delete pdfInfo.htmlForXfa;
2546
- loadingTask._capability.resolve(new PDFDocumentProxy(pdfInfo, this));
2547
- });
2548
-
2549
- messageHandler.on("DocException", function (ex) {
2550
- let reason;
2551
- switch (ex.name) {
2552
- case "PasswordException":
2553
- reason = new PasswordException(ex.message, ex.code);
2554
- break;
2555
- case "InvalidPDFException":
2556
- reason = new InvalidPDFException(ex.message);
2557
- break;
2558
- case "MissingPDFException":
2559
- reason = new MissingPDFException(ex.message);
2560
- break;
2561
- case "UnexpectedResponseException":
2562
- reason = new UnexpectedResponseException(ex.message, ex.status);
2563
- break;
2564
- case "UnknownErrorException":
2565
- reason = new UnknownErrorException(ex.message, ex.details);
2566
- break;
2567
- }
2568
- if (!(reason instanceof Error)) {
2569
- const msg = "DocException - expected a valid Error.";
2570
- if (
2571
- typeof PDFJSDev === "undefined" ||
2572
- PDFJSDev.test("!PRODUCTION || TESTING")
2573
- ) {
2574
- unreachable(msg);
2575
- } else {
2576
- warn(msg);
2577
- }
2578
- }
2579
- loadingTask._capability.reject(reason);
2580
- });
2581
-
2582
- messageHandler.on("PasswordRequest", exception => {
2583
- this._passwordCapability = createPromiseCapability();
2584
-
2585
- if (loadingTask.onPassword) {
2586
- const updatePassword = password => {
2587
- this._passwordCapability.resolve({
2588
- password,
2589
- });
2590
- };
2591
- try {
2592
- loadingTask.onPassword(updatePassword, exception.code);
2593
- } catch (ex) {
2594
- this._passwordCapability.reject(ex);
2595
- }
2596
- } else {
2597
- this._passwordCapability.reject(
2598
- new PasswordException(exception.message, exception.code)
2599
- );
2600
- }
2601
- return this._passwordCapability.promise;
2602
- });
2603
-
2604
- messageHandler.on("DataLoaded", data => {
2605
- // For consistency: Ensure that progress is always reported when the
2606
- // entire PDF file has been loaded, regardless of how it was fetched.
2607
- if (loadingTask.onProgress) {
2608
- loadingTask.onProgress({
2609
- loaded: data.length,
2610
- total: data.length,
2611
- });
2612
- }
2613
- this.downloadInfoCapability.resolve(data);
2614
- });
2615
-
2616
- messageHandler.on("StartRenderPage", data => {
2617
- if (this.destroyed) {
2618
- return; // Ignore any pending requests if the worker was terminated.
2619
- }
2620
-
2621
- const page = this.pageCache[data.pageIndex];
2622
- page._startRenderPage(data.transparency, data.intent);
2623
- });
2624
-
2625
- messageHandler.on("commonobj", data => {
2626
- if (this.destroyed) {
2627
- return; // Ignore any pending requests if the worker was terminated.
2628
- }
2629
-
2630
- const [id, type, exportedData] = data;
2631
- if (this.commonObjs.has(id)) {
2632
- return;
2633
- }
2634
-
2635
- switch (type) {
2636
- case "Font":
2637
- const params = this._params;
2638
-
2639
- if ("error" in exportedData) {
2640
- const exportedError = exportedData.error;
2641
- warn(`Error during font loading: ${exportedError}`);
2642
- this.commonObjs.resolve(id, exportedError);
2643
- break;
2644
- }
2645
-
2646
- let fontRegistry = null;
2647
- if (params.pdfBug && globalThis.FontInspector?.enabled) {
2648
- fontRegistry = {
2649
- registerFont(font, url) {
2650
- globalThis.FontInspector.fontAdded(font, url);
2651
- },
2652
- };
2653
- }
2654
- const font = new FontFaceObject(exportedData, {
2655
- isEvalSupported: params.isEvalSupported,
2656
- disableFontFace: params.disableFontFace,
2657
- ignoreErrors: params.ignoreErrors,
2658
- onUnsupportedFeature: this._onUnsupportedFeature.bind(this),
2659
- fontRegistry,
2660
- });
2661
-
2662
- this.fontLoader
2663
- .bind(font)
2664
- .catch(reason => {
2665
- return messageHandler.sendWithPromise("FontFallback", { id });
2666
- })
2667
- .finally(() => {
2668
- if (!params.fontExtraProperties && font.data) {
2669
- // Immediately release the `font.data` property once the font
2670
- // has been attached to the DOM, since it's no longer needed,
2671
- // rather than waiting for a `PDFDocumentProxy.cleanup` call.
2672
- // Since `font.data` could be very large, e.g. in some cases
2673
- // multiple megabytes, this will help reduce memory usage.
2674
- font.data = null;
2675
- }
2676
- this.commonObjs.resolve(id, font);
2677
- });
2678
- break;
2679
- case "FontPath":
2680
- case "Image":
2681
- this.commonObjs.resolve(id, exportedData);
2682
- break;
2683
- default:
2684
- throw new Error(`Got unknown common object type ${type}`);
2685
- }
2686
- });
2687
-
2688
- messageHandler.on("obj", data => {
2689
- if (this.destroyed) {
2690
- // Ignore any pending requests if the worker was terminated.
2691
- return undefined;
2692
- }
2693
-
2694
- const [id, pageIndex, type, imageData] = data;
2695
- const pageProxy = this.pageCache[pageIndex];
2696
- if (pageProxy.objs.has(id)) {
2697
- return undefined;
2698
- }
2699
-
2700
- switch (type) {
2701
- case "Image":
2702
- pageProxy.objs.resolve(id, imageData);
2703
-
2704
- // Heuristic that will allow us not to store large data.
2705
- const MAX_IMAGE_SIZE_TO_STORE = 8000000;
2706
- if (imageData?.data?.length > MAX_IMAGE_SIZE_TO_STORE) {
2707
- pageProxy.cleanupAfterRender = true;
2708
- }
2709
- break;
2710
- case "Pattern":
2711
- pageProxy.objs.resolve(id, imageData);
2712
- break;
2713
- default:
2714
- throw new Error(`Got unknown object type ${type}`);
2715
- }
2716
- return undefined;
2717
- });
2718
-
2719
- messageHandler.on("DocProgress", data => {
2720
- if (this.destroyed) {
2721
- return; // Ignore any pending requests if the worker was terminated.
2722
- }
2723
-
2724
- if (loadingTask.onProgress) {
2725
- loadingTask.onProgress({
2726
- loaded: data.loaded,
2727
- total: data.total,
2728
- });
2729
- }
2730
- });
2731
-
2732
- messageHandler.on(
2733
- "UnsupportedFeature",
2734
- this._onUnsupportedFeature.bind(this)
2735
- );
2736
-
2737
- messageHandler.on("FetchBuiltInCMap", data => {
2738
- if (this.destroyed) {
2739
- return Promise.reject(new Error("Worker was destroyed."));
2740
- }
2741
- if (!this.CMapReaderFactory) {
2742
- return Promise.reject(
2743
- new Error(
2744
- "CMapReaderFactory not initialized, see the `useWorkerFetch` parameter."
2745
- )
2746
- );
2747
- }
2748
- return this.CMapReaderFactory.fetch(data);
2749
- });
2750
-
2751
- messageHandler.on("FetchStandardFontData", data => {
2752
- if (this.destroyed) {
2753
- return Promise.reject(new Error("Worker was destroyed."));
2754
- }
2755
- if (!this.StandardFontDataFactory) {
2756
- return Promise.reject(
2757
- new Error(
2758
- "StandardFontDataFactory not initialized, see the `useWorkerFetch` parameter."
2759
- )
2760
- );
2761
- }
2762
- return this.StandardFontDataFactory.fetch(data);
2763
- });
2764
- }
2765
-
2766
- _onUnsupportedFeature({ featureId }) {
2767
- if (this.destroyed) {
2768
- return; // Ignore any pending requests if the worker was terminated.
2769
- }
2770
- if (this.loadingTask.onUnsupportedFeature) {
2771
- this.loadingTask.onUnsupportedFeature(featureId);
2772
- }
2773
- }
2774
-
2775
- getData() {
2776
- return this.messageHandler.sendWithPromise("GetData", null);
2777
- }
2778
-
2779
- getPage(pageNumber) {
2780
- if (
2781
- !Number.isInteger(pageNumber) ||
2782
- pageNumber <= 0 ||
2783
- pageNumber > this._numPages
2784
- ) {
2785
- return Promise.reject(new Error("Invalid page request"));
2786
- }
2787
-
2788
- const pageIndex = pageNumber - 1;
2789
- if (pageIndex in this.pagePromises) {
2790
- return this.pagePromises[pageIndex];
2791
- }
2792
- const promise = this.messageHandler
2793
- .sendWithPromise("GetPage", {
2794
- pageIndex,
2795
- })
2796
- .then(pageInfo => {
2797
- if (this.destroyed) {
2798
- throw new Error("Transport destroyed");
2799
- }
2800
- const page = new PDFPageProxy(
2801
- pageIndex,
2802
- pageInfo,
2803
- this,
2804
- this._params.ownerDocument,
2805
- this._params.pdfBug
2806
- );
2807
- this.pageCache[pageIndex] = page;
2808
- return page;
2809
- });
2810
- this.pagePromises[pageIndex] = promise;
2811
- return promise;
2812
- }
2813
-
2814
- getPageIndex(ref) {
2815
- return this.messageHandler
2816
- .sendWithPromise("GetPageIndex", {
2817
- ref,
2818
- })
2819
- .catch(function (reason) {
2820
- return Promise.reject(new Error(reason));
2821
- });
2822
- }
2823
-
2824
- getAnnotations(pageIndex, intent) {
2825
- return this.messageHandler.sendWithPromise("GetAnnotations", {
2826
- pageIndex,
2827
- intent,
2828
- });
2829
- }
2830
-
2831
- saveDocument() {
2832
- return this.messageHandler
2833
- .sendWithPromise("SaveDocument", {
2834
- isPureXfa: !!this._htmlForXfa,
2835
- numPages: this._numPages,
2836
- annotationStorage: this.annotationStorage.serializable,
2837
- filename: this._fullReader?.filename ?? null,
2838
- })
2839
- .finally(() => {
2840
- this.annotationStorage.resetModified();
2841
- });
2842
- }
2843
-
2844
- getFieldObjects() {
2845
- return this.messageHandler.sendWithPromise("GetFieldObjects", null);
2846
- }
2847
-
2848
- hasJSActions() {
2849
- return (this._hasJSActionsPromise ||= this.messageHandler.sendWithPromise(
2850
- "HasJSActions",
2851
- null
2852
- ));
2853
- }
2854
-
2855
- getCalculationOrderIds() {
2856
- return this.messageHandler.sendWithPromise("GetCalculationOrderIds", null);
2857
- }
2858
-
2859
- getDestinations() {
2860
- return this.messageHandler.sendWithPromise("GetDestinations", null);
2861
- }
2862
-
2863
- getDestination(id) {
2864
- if (typeof id !== "string") {
2865
- return Promise.reject(new Error("Invalid destination request."));
2866
- }
2867
- return this.messageHandler.sendWithPromise("GetDestination", {
2868
- id,
2869
- });
2870
- }
2871
-
2872
- getPageLabels() {
2873
- return this.messageHandler.sendWithPromise("GetPageLabels", null);
2874
- }
2875
-
2876
- getPageLayout() {
2877
- return this.messageHandler.sendWithPromise("GetPageLayout", null);
2878
- }
2879
-
2880
- getPageMode() {
2881
- return this.messageHandler.sendWithPromise("GetPageMode", null);
2882
- }
2883
-
2884
- getViewerPreferences() {
2885
- return this.messageHandler.sendWithPromise("GetViewerPreferences", null);
2886
- }
2887
-
2888
- getOpenAction() {
2889
- return this.messageHandler.sendWithPromise("GetOpenAction", null);
2890
- }
2891
-
2892
- getAttachments() {
2893
- return this.messageHandler.sendWithPromise("GetAttachments", null);
2894
- }
2895
-
2896
- getJavaScript() {
2897
- return this.messageHandler.sendWithPromise("GetJavaScript", null);
2898
- }
2899
-
2900
- getDocJSActions() {
2901
- return this.messageHandler.sendWithPromise("GetDocJSActions", null);
2902
- }
2903
-
2904
- getPageJSActions(pageIndex) {
2905
- return this.messageHandler.sendWithPromise("GetPageJSActions", {
2906
- pageIndex,
2907
- });
2908
- }
2909
-
2910
- getStructTree(pageIndex) {
2911
- return this.messageHandler.sendWithPromise("GetStructTree", {
2912
- pageIndex,
2913
- });
2914
- }
2915
-
2916
- getOutline() {
2917
- return this.messageHandler.sendWithPromise("GetOutline", null);
2918
- }
2919
-
2920
- getOptionalContentConfig() {
2921
- return this.messageHandler
2922
- .sendWithPromise("GetOptionalContentConfig", null)
2923
- .then(results => {
2924
- return new OptionalContentConfig(results);
2925
- });
2926
- }
2927
-
2928
- getPermissions() {
2929
- return this.messageHandler.sendWithPromise("GetPermissions", null);
2930
- }
2931
-
2932
- getMetadata() {
2933
- return this.messageHandler
2934
- .sendWithPromise("GetMetadata", null)
2935
- .then(results => {
2936
- return {
2937
- info: results[0],
2938
- metadata: results[1] ? new Metadata(results[1]) : null,
2939
- contentDispositionFilename: this._fullReader?.filename ?? null,
2940
- contentLength: this._fullReader?.contentLength ?? null,
2941
- };
2942
- });
2943
- }
2944
-
2945
- getMarkInfo() {
2946
- return this.messageHandler.sendWithPromise("GetMarkInfo", null);
2947
- }
2948
-
2949
- getStats() {
2950
- return this.messageHandler.sendWithPromise("GetStats", null);
2951
- }
2952
-
2953
- async startCleanup(keepLoadedFonts = false) {
2954
- await this.messageHandler.sendWithPromise("Cleanup", null);
2955
-
2956
- if (this.destroyed) {
2957
- return; // No need to manually clean-up when destruction has started.
2958
- }
2959
- for (let i = 0, ii = this.pageCache.length; i < ii; i++) {
2960
- const page = this.pageCache[i];
2961
- if (!page) {
2962
- continue;
2963
- }
2964
- const cleanupSuccessful = page.cleanup();
2965
-
2966
- if (!cleanupSuccessful) {
2967
- throw new Error(`startCleanup: Page ${i + 1} is currently rendering.`);
2968
- }
2969
- }
2970
- this.commonObjs.clear();
2971
- if (!keepLoadedFonts) {
2972
- this.fontLoader.clear();
2973
- }
2974
- this._hasJSActionsPromise = null;
2975
- }
2976
-
2977
- get loadingParams() {
2978
- const params = this._params;
2979
- return shadow(this, "loadingParams", {
2980
- disableAutoFetch: params.disableAutoFetch,
2981
- });
2982
- }
2983
- }
2984
-
2985
- /**
2986
- * A PDF document and page is built of many objects. E.g. there are objects for
2987
- * fonts, images, rendering code, etc. These objects may get processed inside of
2988
- * a worker. This class implements some basic methods to manage these objects.
2989
- * @ignore
2990
- */
2991
- class PDFObjects {
2992
- constructor() {
2993
- this._objs = Object.create(null);
2994
- }
2995
-
2996
- /**
2997
- * Ensures there is an object defined for `objId`.
2998
- * @private
2999
- */
3000
- _ensureObj(objId) {
3001
- if (this._objs[objId]) {
3002
- return this._objs[objId];
3003
- }
3004
- return (this._objs[objId] = {
3005
- capability: createPromiseCapability(),
3006
- data: null,
3007
- resolved: false,
3008
- });
3009
- }
3010
-
3011
- /**
3012
- * If called *without* callback, this returns the data of `objId` but the
3013
- * object needs to be resolved. If it isn't, this method throws.
3014
- *
3015
- * If called *with* a callback, the callback is called with the data of the
3016
- * object once the object is resolved. That means, if you call this method
3017
- * and the object is already resolved, the callback gets called right away.
3018
- */
3019
- get(objId, callback = null) {
3020
- // If there is a callback, then the get can be async and the object is
3021
- // not required to be resolved right now.
3022
- if (callback) {
3023
- this._ensureObj(objId).capability.promise.then(callback);
3024
- return null;
3025
- }
3026
- // If there isn't a callback, the user expects to get the resolved data
3027
- // directly.
3028
- const obj = this._objs[objId];
3029
- // If there isn't an object yet or the object isn't resolved, then the
3030
- // data isn't ready yet!
3031
- if (!obj || !obj.resolved) {
3032
- throw new Error(`Requesting object that isn't resolved yet ${objId}.`);
3033
- }
3034
- return obj.data;
3035
- }
3036
-
3037
- has(objId) {
3038
- const obj = this._objs[objId];
3039
- return obj?.resolved || false;
3040
- }
3041
-
3042
- /**
3043
- * Resolves the object `objId` with optional `data`.
3044
- */
3045
- resolve(objId, data) {
3046
- const obj = this._ensureObj(objId);
3047
-
3048
- obj.resolved = true;
3049
- obj.data = data;
3050
- obj.capability.resolve(data);
3051
- }
3052
-
3053
- clear() {
3054
- this._objs = Object.create(null);
3055
- }
3056
- }
3057
-
3058
- /**
3059
- * Allows controlling of the rendering tasks.
3060
- */
3061
- class RenderTask {
3062
- constructor(internalRenderTask) {
3063
- this._internalRenderTask = internalRenderTask;
3064
-
3065
- /**
3066
- * Callback for incremental rendering -- a function that will be called
3067
- * each time the rendering is paused. To continue rendering call the
3068
- * function that is the first argument to the callback.
3069
- * @type {function}
3070
- */
3071
- this.onContinue = null;
3072
- }
3073
-
3074
- /**
3075
- * Promise for rendering task completion.
3076
- * @type {Promise<void>}
3077
- */
3078
- get promise() {
3079
- return this._internalRenderTask.capability.promise;
3080
- }
3081
-
3082
- /**
3083
- * Cancels the rendering task. If the task is currently rendering it will
3084
- * not be cancelled until graphics pauses with a timeout. The promise that
3085
- * this object extends will be rejected when cancelled.
3086
- */
3087
- cancel() {
3088
- this._internalRenderTask.cancel();
3089
- }
3090
- }
3091
-
3092
- /**
3093
- * For internal use only.
3094
- * @ignore
3095
- */
3096
- const InternalRenderTask = (function InternalRenderTaskClosure() {
3097
- const canvasInRendering = new WeakSet();
3098
-
3099
- // eslint-disable-next-line no-shadow
3100
- class InternalRenderTask {
3101
- constructor({
3102
- callback,
3103
- params,
3104
- objs,
3105
- commonObjs,
3106
- operatorList,
3107
- pageIndex,
3108
- canvasFactory,
3109
- useRequestAnimationFrame = false,
3110
- pdfBug = false,
3111
- }) {
3112
- this.callback = callback;
3113
- this.params = params;
3114
- this.objs = objs;
3115
- this.commonObjs = commonObjs;
3116
- this.operatorListIdx = null;
3117
- this.operatorList = operatorList;
3118
- this._pageIndex = pageIndex;
3119
- this.canvasFactory = canvasFactory;
3120
- this._pdfBug = pdfBug;
3121
-
3122
- this.running = false;
3123
- this.graphicsReadyCallback = null;
3124
- this.graphicsReady = false;
3125
- this._useRequestAnimationFrame =
3126
- useRequestAnimationFrame === true && typeof window !== "undefined";
3127
- this.cancelled = false;
3128
- this.capability = createPromiseCapability();
3129
- this.task = new RenderTask(this);
3130
- // caching this-bound methods
3131
- this._cancelBound = this.cancel.bind(this);
3132
- this._continueBound = this._continue.bind(this);
3133
- this._scheduleNextBound = this._scheduleNext.bind(this);
3134
- this._nextBound = this._next.bind(this);
3135
- this._canvas = params.canvasContext.canvas;
3136
- }
3137
-
3138
- get completed() {
3139
- return this.capability.promise.catch(function () {
3140
- // Ignoring errors, since we only want to know when rendering is
3141
- // no longer pending.
3142
- });
3143
- }
3144
-
3145
- initializeGraphics({ transparency = false, optionalContentConfig }) {
3146
- if (this.cancelled) {
3147
- return;
3148
- }
3149
- if (this._canvas) {
3150
- if (canvasInRendering.has(this._canvas)) {
3151
- throw new Error(
3152
- "Cannot use the same canvas during multiple render() operations. " +
3153
- "Use different canvas or ensure previous operations were " +
3154
- "cancelled or completed."
3155
- );
3156
- }
3157
- canvasInRendering.add(this._canvas);
3158
- }
3159
-
3160
- if (this._pdfBug && globalThis.StepperManager?.enabled) {
3161
- this.stepper = globalThis.StepperManager.create(this._pageIndex);
3162
- this.stepper.init(this.operatorList);
3163
- this.stepper.nextBreakPoint = this.stepper.getNextBreakPoint();
3164
- }
3165
- const { canvasContext, viewport, transform, imageLayer, background } =
3166
- this.params;
3167
-
3168
- this.gfx = new CanvasGraphics(
3169
- canvasContext,
3170
- this.commonObjs,
3171
- this.objs,
3172
- this.canvasFactory,
3173
- imageLayer,
3174
- optionalContentConfig
3175
- );
3176
- this.gfx.beginDrawing({
3177
- transform,
3178
- viewport,
3179
- transparency,
3180
- background,
3181
- });
3182
- this.operatorListIdx = 0;
3183
- this.graphicsReady = true;
3184
- if (this.graphicsReadyCallback) {
3185
- this.graphicsReadyCallback();
3186
- }
3187
- }
3188
-
3189
- cancel(error = null) {
3190
- this.running = false;
3191
- this.cancelled = true;
3192
- if (this.gfx) {
3193
- this.gfx.endDrawing();
3194
- }
3195
- if (this._canvas) {
3196
- canvasInRendering.delete(this._canvas);
3197
- }
3198
- this.callback(
3199
- error ||
3200
- new RenderingCancelledException(
3201
- `Rendering cancelled, page ${this._pageIndex + 1}`,
3202
- "canvas"
3203
- )
3204
- );
3205
- }
3206
-
3207
- operatorListChanged() {
3208
- if (!this.graphicsReady) {
3209
- if (!this.graphicsReadyCallback) {
3210
- this.graphicsReadyCallback = this._continueBound;
3211
- }
3212
- return;
3213
- }
3214
-
3215
- if (this.stepper) {
3216
- this.stepper.updateOperatorList(this.operatorList);
3217
- }
3218
-
3219
- if (this.running) {
3220
- return;
3221
- }
3222
- this._continue();
3223
- }
3224
-
3225
- _continue() {
3226
- this.running = true;
3227
- if (this.cancelled) {
3228
- return;
3229
- }
3230
- if (this.task.onContinue) {
3231
- this.task.onContinue(this._scheduleNextBound);
3232
- } else {
3233
- this._scheduleNext();
3234
- }
3235
- }
3236
-
3237
- _scheduleNext() {
3238
- if (this._useRequestAnimationFrame) {
3239
- window.requestAnimationFrame(() => {
3240
- this._nextBound().catch(this._cancelBound);
3241
- });
3242
- } else {
3243
- Promise.resolve().then(this._nextBound).catch(this._cancelBound);
3244
- }
3245
- }
3246
-
3247
- async _next() {
3248
- if (this.cancelled) {
3249
- return;
3250
- }
3251
- this.operatorListIdx = this.gfx.executeOperatorList(
3252
- this.operatorList,
3253
- this.operatorListIdx,
3254
- this._continueBound,
3255
- this.stepper
3256
- );
3257
- if (this.operatorListIdx === this.operatorList.argsArray.length) {
3258
- this.running = false;
3259
- if (this.operatorList.lastChunk) {
3260
- this.gfx.endDrawing();
3261
- if (this._canvas) {
3262
- canvasInRendering.delete(this._canvas);
3263
- }
3264
- this.callback();
3265
- }
3266
- }
3267
- }
3268
- }
3269
- return InternalRenderTask;
3270
- })();
3271
-
3272
- /** @type {string} */
3273
- const version =
3274
- typeof PDFJSDev !== "undefined" ? PDFJSDev.eval("BUNDLE_VERSION") : null;
3275
- /** @type {string} */
3276
- const build =
3277
- typeof PDFJSDev !== "undefined" ? PDFJSDev.eval("BUNDLE_BUILD") : null;
3278
-
3279
- export {
3280
- build,
3281
- DefaultCanvasFactory,
3282
- DefaultCMapReaderFactory,
3283
- DefaultStandardFontDataFactory,
3284
- getDocument,
3285
- LoopbackPort,
3286
- PDFDataRangeTransport,
3287
- PDFDocumentProxy,
3288
- PDFPageProxy,
3289
- PDFWorker,
3290
- setPDFNetworkStreamFactory,
3291
- version,
3292
- };